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

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

part 3

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