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

Last change on this file was a64f926, checked in by KostaFortumanov <kfortumanov@…>, 3 years ago

project complete

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