source: src/main/java/it/finki/charitable/controller/DonationPostController.java@ b8dc761

Last change on this file since b8dc761 was b8dc761, checked in by NikolaCenevski <cenevskinikola@…>, 2 years ago

part 2

  • Property mode set to 100644
File size: 14.3 KB
Line 
1package it.finki.charitable.controller;
2
3import it.finki.charitable.entities.*;
4import it.finki.charitable.services.*;
5import it.finki.charitable.util.FileUploadUtil;
6import org.springframework.data.domain.*;
7import org.springframework.format.annotation.DateTimeFormat;
8import org.springframework.security.core.context.SecurityContextHolder;
9import org.springframework.stereotype.Controller;
10import org.springframework.ui.Model;
11import org.springframework.util.StringUtils;
12import org.springframework.web.bind.annotation.*;
13import org.springframework.web.multipart.MultipartFile;
14
15import java.io.IOException;
16import java.time.Duration;
17import java.time.LocalDate;
18import java.util.*;
19import java.util.stream.Collectors;
20
21@Controller
22public class DonationPostController {
23
24 private final DonationPostService donationPostService;
25 private final UserService userService;
26 private final FundsCollectedService fundsCollectedService;
27 private final DonationInformationService donationInformationService;
28 private final ReportPostService reportPostService;
29 private final ReasonService reasonService;
30
31 public DonationPostController(DonationPostService donationPostService, UserService userService, FundsCollectedService fundsCollectedService, DonationInformationService donationInformationService, ReportPostService reportPostService, ReasonService reasonService) {
32 this.donationPostService = donationPostService;
33 this.userService = userService;
34 this.fundsCollectedService = fundsCollectedService;
35 this.donationInformationService = donationInformationService;
36 this.reportPostService = reportPostService;
37 this.reasonService = reasonService;
38 }
39
40 @RequestMapping("/upload")
41 public String upload() {
42 return "upload";
43 }
44
45 @RequestMapping(value = "/newPost", method = RequestMethod.POST)
46 public String newPost(Model model,
47 @RequestParam String title,
48 @RequestParam String fundsNeeded,
49 @RequestParam String currency,
50 @RequestParam String description,
51 @RequestParam String telekom,
52 @RequestParam String a1,
53 @RequestParam(defaultValue = "2020-01-01") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate dateDue,
54 @RequestParam String bankAccount,
55 @RequestParam MultipartFile titleImage,
56 @RequestParam MultipartFile[] images,
57 @RequestParam MultipartFile[] moderatorImages) {
58
59 System.out.println(moderatorImages.length);
60 if(titleImage.isEmpty() || (moderatorImages.length == 1 && moderatorImages[0].isEmpty())) {
61 model.addAttribute("error", true);
62 return "upload";
63 }
64
65 if(title.isBlank() || fundsNeeded.isBlank() || currency.isBlank() || description.isBlank() || bankAccount.isBlank() || dateDue.equals(LocalDate.of(2020,1,1))) {
66 model.addAttribute("error", true);
67 return "upload";
68 }
69
70 DonationPost post = new DonationPost();
71 post.setTitle(title);
72
73 try {
74 float funds = Float.parseFloat(fundsNeeded);
75 if (funds <= 0) {
76 model.addAttribute("error", true);
77 return "upload";
78 }
79 post.setFundsNeeded(funds);
80 } catch (NumberFormatException e) {
81 model.addAttribute("error", true);
82 return "upload";
83 }
84
85 post.setCurrency(currency);
86 post.setDescription(description);
87 post.setDateDue(dateDue);
88 post.setBankAccount(bankAccount);
89 post.setApproved(false);
90 post.setCreatedAt(LocalDate.now());
91 long totalDays = Duration.between(post.getCreatedAt().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays();
92 if(totalDays < 10)
93 post.setRiskFactor(0);
94
95 List<String> phoneNumbers = Arrays.asList(telekom, a1);
96
97 List<String> photos = new ArrayList<>();
98 photos.add(StringUtils.cleanPath(Objects.requireNonNull(titleImage.getOriginalFilename())));
99 Arrays.stream(images).filter(i -> !i.isEmpty()).forEach(i -> photos.add(StringUtils.cleanPath(Objects.requireNonNull(i.getOriginalFilename()))));
100
101 List<MultipartFile> files = new ArrayList<>();
102 files.add(titleImage);
103 files.addAll(Arrays.stream(images).filter(i -> !i.isEmpty()).collect(Collectors.toList()));
104
105 List<String> moderatorPhotos = new ArrayList<>();
106 Arrays.stream(moderatorImages).forEach(i -> moderatorPhotos.add(StringUtils.cleanPath(Objects.requireNonNull(i.getOriginalFilename()))));
107
108 post.setPhoneNumbers(phoneNumbers);
109 post.setImages(photos);
110 post.setModeratorImages(moderatorPhotos);
111
112 AppUser user = (AppUser) model.getAttribute("user");
113 post.setUser(user);
114
115 DonationPost savedPost = donationPostService.save(post);
116
117 for (MultipartFile file : files) {
118 String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
119 String uploadDir = "post-photos/" + savedPost.getId();
120 try {
121 FileUploadUtil.saveFile(uploadDir, fileName, file);
122 } catch (IOException e) {
123 e.printStackTrace();
124 }
125
126 }
127
128 for (MultipartFile file : moderatorImages) {
129
130 String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
131 String uploadDir = "moderator-photos/" + savedPost.getId();
132 try {
133 FileUploadUtil.saveFile(uploadDir, fileName, file);
134 } catch (IOException e) {
135 e.printStackTrace();
136 }
137 }
138
139 return "upload";
140 }
141
142 @RequestMapping("/album")
143 public String album(Model model,
144 @RequestParam int page,
145 @RequestParam String sort,
146 @RequestParam(required = false, defaultValue = "desc") String order,
147 @RequestParam(required = false, defaultValue = "all") String groupBy) {
148
149 Sort s = Sort.by(sort);
150 s = order.equals("asc") ? s.ascending() : s.descending();
151 Pageable pageable = PageRequest.of(page - 1, 6, s);
152 Page<DonationPost> postList;
153 postList = donationPostService.findPaginated(page, 6, sort, order, true);
154
155 if (!groupBy.equals("all")) {
156 List<DonationPost> allPosts = donationPostService.findAllByApproved(true);
157
158 if (sort.equals("title")) {
159 if (order.equals("asc")) {
160 allPosts.sort(Comparator.comparing(DonationPost::getTitle, (s1, s2) -> s1.compareToIgnoreCase(s2)));
161 } else {
162 allPosts.sort(Comparator.comparing(DonationPost::getTitle, (s1, s2) -> s2.compareToIgnoreCase(s1)));
163 }
164 } else if (sort.equals("dateDue")) {
165 if (order.equals("asc")) {
166 allPosts.sort(Comparator.comparing(DonationPost::getDateDue));
167 } else {
168 allPosts.sort(Comparator.comparing(DonationPost::getDateDue).reversed());
169 }
170 } else if (sort.equals("fundsNeeded")) {
171 if (order.equals("asc")) {
172 allPosts.sort(Comparator.comparing(DonationPost::getFundsNeeded));
173 } else {
174 allPosts.sort(Comparator.comparing(DonationPost::getFundsNeeded).reversed());
175 }
176 } else if (sort.equals("riskFactor")) {
177 if (order.equals("asc")) {
178 allPosts.sort(Comparator.comparing(DonationPost::getRiskFactor));
179 } else {
180 allPosts.sort(Comparator.comparing(DonationPost::getRiskFactor).reversed());
181 }
182 }
183
184 if (groupBy.equals("completed")) {
185 List<DonationPost> completed = allPosts.stream()
186 .filter(post -> post.getTotalFundsCollected() >= post.getFundsNeeded())
187 .collect(Collectors.toList());
188
189 int start = (int) pageable.getOffset();
190 int end = Math.min((start + pageable.getPageSize()), completed.size());
191 if (start <= end) {
192 postList = new PageImpl<>(completed.subList(start, end), pageable, completed.size());
193 }
194 } else if (groupBy.equals("expired")) {
195 List<DonationPost> expired = allPosts.stream().filter(post -> {
196 double fundsCollected = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
197 return LocalDate.now().isAfter(post.getDateDue()) && fundsCollected < post.getFundsNeeded();
198 }).collect(Collectors.toList());
199
200 int start = (int) pageable.getOffset();
201 int end = Math.min((start + pageable.getPageSize()), expired.size());
202 if (start <= end) {
203 postList = new PageImpl<>(expired.subList(start, end), pageable, expired.size());
204 }
205 }
206 }
207
208 if (postList.getTotalElements() == 0) {
209 model.addAttribute("noPosts", true);
210 return "album";
211 }
212 model.addAttribute("totalPages", postList.getTotalPages());
213 model.addAttribute("postList", postList);
214 return "album";
215 }
216
217 @RequestMapping("/post")
218 public String showPost(Model model, @RequestParam Long postid) {
219 DonationPost post = donationPostService.getById(postid);
220 if (post == null) {
221 model.addAttribute("notFound", true);
222 return "post";
223 }
224
225 AppUser currentUser = (AppUser) model.getAttribute("user");
226 if (post.getApproved() || (post.getUser().getUsername().equals(currentUser.getUsername()) && !post.getApproved())) {
227 AppUser user = post.getUser();
228 Moderator moderator = post.getModerator();
229 model.addAttribute("post", post);
230 model.addAttribute("createdByFirstName", user.getFirstName());
231 model.addAttribute("createdByLastName", user.getLastName());
232 if (moderator != null) {
233 model.addAttribute("moderatorFirstName", moderator.getFirstName());
234 model.addAttribute("moderatorLastName", moderator.getLastName());
235 }
236 } else {
237 model.addAttribute("notFound", true);
238 }
239 return "post";
240 }
241
242 @RequestMapping(value="/donate", method = RequestMethod.POST)
243 public String donate(Model model, @RequestParam Long postid,
244 @RequestParam String cardName,
245 @RequestParam String cardNumber,
246 @RequestParam String expiryDate,
247 @RequestParam String cvv,
248 @RequestParam String amount) {
249
250 DonationPost post = donationPostService.getById(postid);
251 if(post == null || !post.getApproved()) {
252 return "index";
253 }
254
255 float donatedAmount;
256 try {
257 donatedAmount = Float.parseFloat(amount);
258 if (donatedAmount <= 0) {
259 return String.format("redirect:/post?postid=%d&error", postid);
260 }
261 } catch (NumberFormatException e) {
262 return String.format("redirect:/post?postid=%d&error", postid);
263 }
264
265 FundsCollected funds = new FundsCollected("Online donation", donatedAmount);
266 fundsCollectedService.save(funds);
267
268 post.getFundsCollected().add(funds);
269 post.setTotalFundsCollected(post.getTotalFundsCollected() + donatedAmount);
270
271 if(post.getRiskFactor() != 101) {
272 post.setRiskFactor(getRisk(post));
273 }
274
275 donationPostService.save(post);
276
277 DonationInformation donationInformation = new DonationInformation(donatedAmount, post.getId(), post.getTitle());
278 donationInformationService.save(donationInformation);
279 MainUser user = (MainUser) userService.loadUserByUsername(SecurityContextHolder.getContext().getAuthentication().getName());
280 user.getDonationInformation().add(donationInformation);
281 userService.saveUser(user);
282
283 return String.format("redirect:/post?postid=%d", postid);
284 }
285
286 @RequestMapping(value="/report", method = RequestMethod.POST)
287 public String report(@RequestParam Long postid,
288 @RequestParam String description) {
289
290 DonationPost donationPost = donationPostService.getById(postid);
291 ReportPost reportPost = reportPostService.findByDonationPost(donationPost);
292 if (reportPost == null) {
293 reportPost = new ReportPost();
294 reportPost.setDonationPost(donationPost);
295 }
296
297 Reason reason = new Reason();
298 AppUser user = (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
299 reason.setUser(user);
300 reason.setDescription(description);
301 reasonService.save(reason);
302 reportPost.getReasons().add(reason);
303 reportPost.setNumReports(reportPost.getNumReports() + 1);
304 reportPostService.save(reportPost);
305 return String.format("redirect:/post?postid=%d", postid);
306 }
307
308 @ModelAttribute("user")
309 public AppUser addAttributes() {
310 if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
311
312 String email = SecurityContextHolder.getContext().getAuthentication().getName();
313 return userService.loadUserByUsername(email);
314 }
315 return null;
316 }
317
318 private Integer getRisk(DonationPost post) {
319 float dailyAverage = post.getTotalFundsCollected() / (Duration.between(post.getCreatedAt().atTime(0, 0, 0), LocalDate.now().atTime(0, 0, 0)).toDays()+1);
320 float neededAverage = (post.getFundsNeeded() - post.getTotalFundsCollected()) / (Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays()+1);
321
322 System.out.println(dailyAverage + " " + neededAverage);
323 int risk = (int) (dailyAverage / neededAverage * 100);
324
325 if(risk > 100) {
326 risk = 100;
327 }
328
329 if(Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays() == 0) {
330 risk = 0;
331 }
332
333 if(post.getFundsNeeded() <= post.getTotalFundsCollected()) {
334 risk = 101;
335 }
336
337 return risk;
338 }
339}
Note: See TracBrowser for help on using the repository browser.