diff --git a/src/main/java/com/ffii/lioner/config/WebConfig.java b/src/main/java/com/ffii/lioner/config/WebConfig.java index 5de3580..8228048 100644 --- a/src/main/java/com/ffii/lioner/config/WebConfig.java +++ b/src/main/java/com/ffii/lioner/config/WebConfig.java @@ -1,6 +1,5 @@ package com.ffii.lioner.config; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; @@ -11,9 +10,6 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { - - @Value("${host.url}") - private String url; // @Override // public void addCorsMappings(CorsRegistry registry) { @@ -26,12 +22,25 @@ public class WebConfig implements WebMvcConfigurer { // } @Override public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**") - .allowedOrigins("http://localhost:3000") // *Adjust to your React app's URL* - .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") - .allowedHeaders("*") - .allowCredentials(true); - } + registry.addMapping("/**") // Apply to all API endpoints + .allowedHeaders("*") + // **** CRITICAL FIX HERE **** + .allowedOrigins( + "http://localhost", // If you test locally via Nginx at http://localhost + "http://127.0.0.1", // Sometimes browsers resolve localhost to 127.0.0.1 + "http://52.175.15.19", // Your 2fi-uat frontend IP + "http://localhost:3000" // If you ever run React dev server directly + // Add any other specific domains/IPs/ports where your frontend will be hosted + ) + // You had .exposedHeaders("filename") - keep if you need to read custom response headers + .exposedHeaders("filename") + // You had .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD") - This is missing "OPTIONS" + .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS") // **** IMPORTANT: Add OPTIONS **** + // You had .allowedHeaders("*") duplicated - harmless, but the first one is enough + // .allowedHeaders("*") + .allowCredentials(true) + .maxAge(3600); // Recommended: Caches preflight results for 1 hour +} @Bean public InternalResourceViewResolver defaultViewResolver() { diff --git a/src/main/java/com/ffii/lioner/modules/common/mail/service/MailSenderService.java b/src/main/java/com/ffii/lioner/modules/common/mail/service/MailSenderService.java index 4071803..2956380 100644 --- a/src/main/java/com/ffii/lioner/modules/common/mail/service/MailSenderService.java +++ b/src/main/java/com/ffii/lioner/modules/common/mail/service/MailSenderService.java @@ -2,7 +2,6 @@ package com.ffii.lioner.modules.common.mail.service; import java.util.Properties; -import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.stereotype.Service; @@ -19,7 +18,6 @@ public class MailSenderService { private JavaMailSender sender; private MailSMTP mailConfigCachs; - @Value("${emsd.webservice.required}") private Boolean ldapWebServiceRequired; public MailSenderService(SettingsService settingsService) { diff --git a/src/main/java/com/ffii/lioner/modules/lioner/service/TodoReminderService.java b/src/main/java/com/ffii/lioner/modules/lioner/service/TodoReminderService.java deleted file mode 100644 index 51624a2..0000000 --- a/src/main/java/com/ffii/lioner/modules/lioner/service/TodoReminderService.java +++ /dev/null @@ -1,783 +0,0 @@ -package com.ffii.lioner.modules.lioner.service; - -import java.io.UnsupportedEncodingException; -import java.text.ParseException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import com.ffii.lioner.modules.lioner.entity.Application; -import com.ffii.lioner.modules.lioner.entity.Event; -import com.ffii.lioner.modules.lioner.entity.TodoReminder; -import com.ffii.lioner.modules.lioner.entity.TodoReminderEmailLog; -import com.ffii.lioner.modules.lioner.entity.TodoReminderRepository; -import com.ffii.lioner.modules.common.SecurityUtils; -import com.ffii.lioner.modules.common.SettingNames; -import com.ffii.lioner.modules.common.mail.pojo.MailRequest; -import com.ffii.lioner.modules.common.mail.service.MailService; -import com.ffii.lioner.modules.common.service.AuditLogService; -import com.ffii.lioner.modules.master.entity.Division; -import com.ffii.lioner.modules.master.entity.SubDivision; -import com.ffii.lioner.modules.master.service.DivisionService; -import com.ffii.lioner.modules.master.service.SubDivisionService; -import com.ffii.lioner.modules.settings.service.SettingsService; -import com.ffii.lioner.modules.user.entity.User; -import com.ffii.lioner.modules.user.service.UserService; -import com.ffii.core.support.AbstractBaseEntityService; -import com.ffii.core.support.JdbcDao; -import com.ffii.core.utils.JsonUtils; - -import jakarta.mail.internet.InternetAddress; -import jakarta.persistence.Table; - -@Service -public class TodoReminderService extends AbstractBaseEntityService { - private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - - private Integer reminderBefore; - private Integer reminderInterval; - private Integer reminderLimit; - private Integer reminderMaxValue; - private Integer reminderEventWithin; - private EventService eventService; - private MailService mailService; - private UserService userService; - private DivisionService divisionService; - private ApplicationService applicationService; - private SubDivisionService subDivisionService; - private AuditLogService auditLogService; - private SettingsService settingsService; - - @Value("${host.url}") - private String url; - - public TodoReminderService(JdbcDao jdbcDao, TodoReminderRepository repository, SettingsService settingsService, - EventService eventService, MailService mailService, UserService userService, - DivisionService divisionService, SubDivisionService subDivisionService, - ApplicationService applicationService, AuditLogService auditLogService) { - super(jdbcDao, repository); - this.eventService = eventService; - this.mailService = mailService; - this.userService = userService; - this.divisionService = divisionService; - this.auditLogService = auditLogService; - this.subDivisionService = subDivisionService; - this.applicationService = applicationService; - this.settingsService = settingsService; - this.reminderBefore = settingsService.getInt(SettingNames.SYS_REMINDER_BEFORE); - this.reminderInterval = settingsService.getInt(SettingNames.SYS_REMINDER_INTERVAL); - this.reminderLimit = settingsService.getInt(SettingNames.SYS_REMINDER_LIMIT); - this.reminderMaxValue = settingsService.getInt(SettingNames.SYS_REMINDER_LIMIT_MAX); - this.reminderEventWithin = settingsService.getInt(SettingNames.SYS_REMINDER_WITHIN); - } - - @Scheduled(cron = "0 0 6 * * ?") // Runs at 06:00 AM every day - public void generateApplicationReminder() throws UnsupportedEncodingException, ParseException { - logger.info("============= Generate Application Reminder Start ============="); - LocalDateTime range = LocalDateTime.now().minusYears(reminderEventWithin); - - logger.info("Fetch Event From: " + range.toString()); - - List eventList = eventService.getEventByWithinYear(Map.of( - "yearRange", range)); - - logger.info("Fetched Total Number of Event: " + eventList.size()); - - for (Event event : eventList) { - - logger.info("---------------------------------------------"); - logger.info("Checking Event: " + event.getName()); - Boolean isOldEvent = false; - LocalDate firstIssueDate = null; - Boolean hasApplicationRecord = eventService.hasApplicationRecord(Map.of("id", event.getId())); - - - LocalDate newEventFirstIssueDate = event.getStartDate().minusDays(event.getReminderThreshold()); - generateNewEventApplicationReminder(event, newEventFirstIssueDate); - if (hasApplicationRecord) {{ - if (event.getNextApplicationDate() == null) - continue; - isOldEvent = true; - - LocalDate oldEventFirstIssueDate = event.getNextApplicationDate().minusDays(event.getReminderThreshold()); - generateOldEventApplicationReminder(event, oldEventFirstIssueDate); - } - } - } - logger.info("============= Generate Application Reminder End ============="); - } - - public void generateOldEventApplicationReminder(Event event, LocalDate firstIssueDate) { - - logger.info("=> Checking Old Event Application Reminder"); - LocalDate now = LocalDate.now(); - Integer limit = event.getReminderLimit().intValue(); - Integer interval = event.getReminderInterval().intValue(); - - List reminderDateSchedule = new ArrayList(); - for (Integer i = 0; i < limit; i++) { - reminderDateSchedule.add(firstIssueDate.plusDays(i * interval)); - } - - logger.info("Reminder Dates: " + reminderDateSchedule.stream() - .map(date -> date.format(dateFormat)).collect(Collectors.joining(", "))); - - List> eventSubDivision = eventService - .getEventDivisionAllData(Map.of("id", event.getId())); - for (Map subDivision : eventSubDivision) { - Integer eventSubDivisionId = (Integer) subDivision.get("id"); - Integer subDivisionId = (Integer) subDivision.get("subDivisionId"); - Integer reminderCount = (Integer) subDivision.get("oldReminderCount"); - Boolean isSuppressed = (Boolean) subDivision.get("suppressedOldReminder"); - if (!isSuppressed) { - if (reminderCount < reminderDateSchedule.size()) { - LocalDate date = reminderDateSchedule.get(reminderCount); - - if (date.compareTo(now) <= 0) { - logger.info("*** Reminder Date Matched ***"); - - // update event_sub_division reminder count - jdbcDao.executeUpdate( - "UPDATE event_sub_division esd" - + " SET esd.oldReminderCount = esd.oldReminderCount + 1" - + " WHERE id = :eventSubDivisionId", - Map.of("eventSubDivisionId", eventSubDivisionId)); - - // Send email reminder - List userList = userService.listUserBySubDivision(subDivisionId); - for (User user : userList) { - logger.info("Send Email to user: " + user.getUsername() + " (" - + user.getEmail() - + ")"); - sendApplicationEmail(event.getId(), subDivisionId.longValue(), - user.getId(), - event, user, - true); - } - - // Update system reminder - String message = "Please note below event will be opened for application:\\n\\n" - + - " - Event Name: \\t\\t\\t " + event.getName() + "\\n" + - " - Application Deadline: \\t " - + event.getApplicationDeadline(); - - TodoReminder instance = new TodoReminder(); - instance.setEventId(event.getId()); - instance.setSubDivisionId(subDivisionId.longValue()); - instance.setTitle("Application Reminder (Old Event)"); - instance.setMessage(message); - instance.setReminderType("oldEventApplication"); - - // =====GET OLD AUDIT LOG=====// - String tableName = instance.getClass().getAnnotation(Table.class) - .name(); - Map oldValueObject = new HashMap(); - Map newValueObject = new HashMap(); - - if (instance != null && instance.getId() != null - && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - oldValueObject = logData; - } - // =====GET OLD AUDIT LOG=====// - instance = save(instance); - // =====GET NEW AUDIT LOG=====// - if (instance != null && instance.getId() != null - && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - logData.put("noted", this.getTodoRead(input)); - newValueObject = logData; - } - - try { - auditLogService.save( - tableName, - instance.getId(), - instance.getTitle(), - SecurityUtils.getUser().isPresent() - ? SecurityUtils.getUser().get() - .getId() - : null, - new Date(), - JsonUtils.toJsonString( - auditLogService.compareMaps( - newValueObject, - oldValueObject)), - JsonUtils.toJsonString( - auditLogService.compareMaps( - oldValueObject, - newValueObject))); - } catch (Exception e) { - logger.info("Saving Audit Log Exception:"); - logger.info(ExceptionUtils.getStackTrace(e)); - } - // =====GET NEW AUDIT LOG=====//\ - } - } - } - - } - } - - public void generateNewEventApplicationReminder(Event event, LocalDate firstIssueDate) { - logger.info("=> Checking New Event Application Reminder"); - - LocalDate now = LocalDate.now(); - Integer limit = event.getReminderLimit().intValue(); - Integer interval = event.getReminderInterval().intValue(); - - List reminderDateSchedule = new ArrayList(); - for (Integer i = 0; i < limit; i++) { - reminderDateSchedule.add(firstIssueDate.plusDays(i * interval)); - } - - logger.info("Reminder Dates: " + reminderDateSchedule.stream() - .map(date -> date.format(dateFormat)).collect(Collectors.joining(", "))); - - logger.info("Application Deadline: " + event.getApplicationDeadline().format(dateFormat)); - List> eventSubDivision = eventService - .getEventDivisionAllData(Map.of("id", event.getId())); - for (Map subDivision : eventSubDivision) { - Integer eventSubDivisionId = (Integer) subDivision.get("id"); - Integer subDivisionId = (Integer) subDivision.get("subDivisionId"); - Integer reminderCount = (Integer) subDivision.get("newReminderCount"); - Boolean isSuppressed = (Boolean) subDivision.get("suppressedOldReminder"); - if (!isSuppressed) { - if (reminderCount < reminderDateSchedule.size()) { - LocalDate date = reminderDateSchedule.get(reminderCount); - - if (date.compareTo(now) <= 0 - && now.compareTo(event.getApplicationDeadline()) <= 0) { - logger.info("*** Reminder Date Matched ***"); - - // update event_sub_division reminder count - jdbcDao.executeUpdate( - "UPDATE event_sub_division esd" - + " SET esd.newReminderCount = esd.newReminderCount + 1" - + " WHERE id = :eventSubDivisionId", - Map.of("eventSubDivisionId", eventSubDivisionId)); - - // Send email reminder - List userList = userService.listUserBySubDivision(subDivisionId); - for (User user : userList) { - logger.info("Send Email to user: " + user.getUsername() + " (" - + user.getEmail() - + ")"); - sendApplicationEmail(event.getId(), subDivisionId.longValue(), - user.getId(), - event, user, - false); - } - - // Update system reminder - String message = "Please note below event will be opened for application:\\n\\n" - + - " - Event Name: \\t\\t\\t " + event.getName() + "\\n" + - " - Application Deadline: \\t " - + event.getApplicationDeadline(); - - TodoReminder instance = new TodoReminder(); - instance.setEventId(event.getId()); - instance.setSubDivisionId(subDivisionId.longValue()); - instance.setTitle( - "Application Reminder (New Event)"); - instance.setMessage(message); - instance.setReminderType("newEventApplication"); - - // =====GET OLD AUDIT LOG=====// - String tableName = instance.getClass().getAnnotation(Table.class) - .name(); - Map oldValueObject = new HashMap(); - Map newValueObject = new HashMap(); - - if (instance != null && instance.getId() != null - && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - oldValueObject = logData; - } - // =====GET OLD AUDIT LOG=====// - instance = save(instance); - // =====GET NEW AUDIT LOG=====// - if (instance != null && instance.getId() != null - && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - logData.put("noted", this.getTodoRead(input)); - newValueObject = logData; - } - - try { - auditLogService.save( - tableName, - instance.getId(), - instance.getTitle(), - SecurityUtils.getUser().isPresent() - ? SecurityUtils.getUser().get() - .getId() - : null, - new Date(), - JsonUtils.toJsonString( - auditLogService.compareMaps( - newValueObject, - oldValueObject)), - JsonUtils.toJsonString( - auditLogService.compareMaps( - oldValueObject, - newValueObject))); - } catch (Exception e) { - logger.info("Saving Audit Log Exception:"); - logger.info(ExceptionUtils.getStackTrace(e)); - } - // =====GET NEW AUDIT LOG=====//\ - } - } - } - } - } - - @Scheduled(cron = "0 30 6 * * ?") // Runs at 06:30 AM every day - public void generateApplicationAnnouncement() throws UnsupportedEncodingException, ParseException { - logger.info("============= Generate Announcement Reminder Start ============="); - LocalDateTime range = LocalDateTime.now().minusYears(reminderEventWithin); - - logger.info("Fetch Event From: " + range.toString()); - - List eventList = eventService.getEventByWithinYear(Map.of( - "yearRange", range, "announcementDate", LocalDate.now())); - - logger.info("Fetched Total Number of Event: " + eventList.size()); - - for (Event event : eventList) { - logger.info("---------------------------------------------"); - logger.info("Event's award to be announced: " + event.getName()); - List applications = applicationService - .getApplicationByEventId(Map.of("eventId", event.getId())); - String applicationString = ""; - for (Application application : applications) { - // get application name list - logger.info("Send Email for Application: " + application.getName()); - if (applicationString.length() > 0) { - applicationString = applicationString + - "\\t\\t\\t\\t\\t\\t" + - application.getName() + "\\n"; - } else { - applicationString = application.getName() + "\\n"; - } - } - - for (Application application : applications) { - // send email in application level - List appSubDivisionIdList = applicationService - .getApplicationSubDivision(Map.of("id", application.getId())); - for (Integer subDivisionId : appSubDivisionIdList) { - List userList = userService.listUserBySubDivision(subDivisionId); - for (User user : userList) { - logger.info("Send Email to user: " + user.getUsername() + " (" - + user.getEmail() - + ")"); - sendAnnouncementEmail(event.getId(), subDivisionId.longValue(), - user.getId(), event, user); - } - String message = //"Result announcement details:\\n\\n" + - //" - Event Title: \\t\\t\\t" + event.getName() + "\\n" + - //" - Application : \\t\\t\\t" + applicationString + "\\n" + - " Announcement Date: \\t" + event.getAnnouncementDate(); - - TodoReminder instance = new TodoReminder(); - instance.setEventId(event.getId()); - instance.setSubDivisionId(subDivisionId.longValue()); - instance.setTitle("Result Announcement for " + event.getName()); - instance.setMessage(message); - instance.setReminderType("announcement"); - // =====GET OLD AUDIT LOG=====// - String tableName = instance.getClass().getAnnotation(Table.class) - .name(); - Map oldValueObject = new HashMap(); - Map newValueObject = new HashMap(); - - if (instance != null && instance.getId() != null - && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - oldValueObject = logData; - } - // =====GET OLD AUDIT LOG=====// - instance = save(instance); - // =====GET NEW AUDIT LOG=====// - if (instance != null && instance.getId() != null - && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - logData.put("noted", this.getTodoRead(input)); - newValueObject = logData; - } - - try { - auditLogService.save( - tableName, - instance.getId(), - instance.getTitle(), - SecurityUtils.getUser().isPresent() - ? SecurityUtils.getUser().get().getId() - : null, - new Date(), - JsonUtils.toJsonString(auditLogService.compareMaps( - newValueObject, oldValueObject)), - JsonUtils.toJsonString(auditLogService.compareMaps( - oldValueObject, newValueObject))); - } catch (Exception e) { - logger.info("Saving Audit Log Exception:"); - logger.info(ExceptionUtils.getStackTrace(e)); - } - // =====GET NEW AUDIT LOG=====// - } - } - - } - logger.info("============= Generate Announcement Reminder End ============="); - } - - public Map getAuditLogObject(Map req) { - StringBuilder sql = new StringBuilder("SELECT" - + " tr.id, " - + " tr.created, " - + " tr.createdBy AS createdById, " - + " u1.name AS createdBy, " - + " tr.version, " - + " tr.modified, " - + " tr.modifiedBy AS modifiedById, " - + " tr.deleted, " - + " u2.name AS modifiedBy, " - + " e.name, " - + " sd.name, " - + " tr.reminderType, " - + " tr.title, " - + " tr.message, " - + " tr.suppressedBy, " - + " tr.suppressedDate " - + " FROM todo_reminder tr " - + " LEFT JOIN `user` u1 ON u1.id = tr.createdBy " - + " LEFT JOIN `user` u2 ON u2.id = tr.modifiedBy " - + " JOIN event e ON e.id = tr.eventId " - + " JOIN sub_division sd ON sd.id = tr.subDivisionId " - + " WHERE tr.id = :id "); - - return jdbcDao.queryForMap(sql.toString(), req).get(); - } - - public void sendTestEmail(Map req) - throws UnsupportedEncodingException, ParseException { - - String receiver = (String) req.get("receiver"); - String templateName = (String) req.get("templateName"); - Locale locale = Locale.ENGLISH; - Boolean isAnnouncement = templateName.contains("announcement"); - - logger.info(templateName); - String templateContent = settingsService.getString(templateName); - Long tempId = (long) -1; - Map dummyAnnouncementData = Map.of( - "subject", "Reminder: Upcoming Event for Enrolment", - "receiver", "RECEIVER", - "eventName", "EVENT NAME", - "applicationDetail", "APPLICATION DETAIL", - "announcementDate", "ANNOUNCEMENT DATE", - "subDivision", "SUBDIVISION", - "division", "DIVISION", - "sender", "SENDER", - "arsLink", url + "/award"); - - Map dummyApplicationData = Map.of( - "subject", "Result Announcement for EVENT NAME", - "receiver", "RECEIVER", - "eventName", "EVENT NAME", - "applicationDeadLine", "APPLICATION DEAD LINE", - "subDivision", "SUBDIVISION", - "division", "DIVISION", - "sender", "SENDER", - "arsLink", url + "/application"); - - MailRequest temp = MailRequest.builder() - .subject(isAnnouncement ? dummyAnnouncementData.get("subject").toString() - : dummyApplicationData.get("subject").toString()) - // .template("mail/applicationAnnouncement") - .templateContent(templateContent) - .args(isAnnouncement ? dummyAnnouncementData : dummyApplicationData) - .addTo(new InternetAddress( - // "mabelng@emsd.gov.hk", "Mable Ng")) - // user.getEmail(), user.getFullname())) - receiver, "RECEIVER")) - - .build(); - - List temp2 = new ArrayList(); - temp2.add(temp); - mailService.sendARS(temp2, locale, tempId, tempId, tempId, - isAnnouncement ? "announcement" : "application"); - } - - public void sendApplicationEmail(Long eventId, Long subDivisionId, Long userId, Event event, User user, - Boolean isOldEvent) { - try { - Locale locale = Locale.ENGLISH; - SubDivision subDivision = subDivisionService.find(subDivisionId).get(); - Division division = divisionService.find(subDivision.getDivisionId()).get(); - String templateContent = isOldEvent - ? settingsService.getString(SettingNames.SYS_EMAIL_TEMPLATE_REMINDER_OLDEVENT) - : settingsService.getString(SettingNames.SYS_EMAIL_TEMPLATE_REMINDER_NEWEVENT); - - MailRequest temp = MailRequest.builder() - .subject("Reminder: Upcoming Event for Enrolment") - // .template("mail/applicationReminder") - .templateContent(templateContent) - .args(Map.of( - "receiver", user.getFullname(), - "eventName", event.getName(), - "applicationDeadLine", - isOldEvent ? event.getNextApplicationDate() - : event.getApplicationDeadline(), - "subDivision", subDivision.getName(), - "division", division.getName(), - "sender", "Electrical and Mechanical Services Department", - "arsLink", url + "/event/maintain/" + event.getId())) - .addTo(new InternetAddress( - // "mabelng@emsd.gov.hk", "Mabel Ng")) - user.getEmail(), user.getFullname())) - // "jason.lam@2fi-solutions.com.hk", "Jason Lam")) - - .build(); - List temp2 = new ArrayList(); - temp2.add(temp); - mailService.sendARS(temp2, locale, eventId, subDivisionId, userId, "application"); - } catch (Exception e) { - logger.info(ExceptionUtils.getStackTrace(e)); - } - } - - public void sendAnnouncementEmail(Long eventId, Long subDivisionId, Long userId, Event event, User user) { - - try { - Locale locale = Locale.ENGLISH; - List applications = applicationService - .getApplicationByEventId(Map.of("eventId", event.getId())); - SubDivision subDivision = subDivisionService.find(subDivisionId).get(); - Division division = divisionService.find(subDivision.getDivisionId()).get(); - String templateContent = settingsService - .getString(SettingNames.SYS_EMAIL_TEMPLATE_ANNOUNCEMENT); - - String applicationString = ""; - for (Application application : applications) { - applicationString = applicationString + "- " + application.getName() + "
"; - } - - MailRequest temp = MailRequest.builder() - .subject("Reminder: Result Announcement for " + event.getName()) - // .template("mail/applicationAnnouncement") - .templateContent(templateContent) - .args(Map.of( - "receiver", user.getFullname(), - "eventName", event.getName(), - "applicationDetail", applicationString, - "announcementDate", event.getAnnouncementDate(), - "subDivision", subDivision.getName(), - "division", division.getName(), - "sender", "Electrical and Mechanical Services Department", - "arsLink", url + "/event/maintain/" + event.getId())) - .addTo(new InternetAddress( - // "mabelng@emsd.gov.hk", "Mable Ng")) - user.getEmail(), user.getFullname())) - // "jason.lam@2fi-solutions.com.hk", "Jason Lam")) - - .build(); - - List temp2 = new ArrayList(); - temp2.add(temp); - mailService.sendARS(temp2, locale, eventId, subDivisionId, userId, "announcement"); - } catch (Exception e) { - logger.info(ExceptionUtils.getStackTrace(e)); - } - } - - public List> list(Map args) { - StringBuilder sql = new StringBuilder("SELECT" - + " DISTINCT tr.id, " - + " tr.eventId, " - + " tr.subDivisionId, " - + " tr.reminderType, " - + " tr.title, " - + " tr.message, " - + " tr.suppressedBy, " - + " trn.userId " - + " FROM `user` u " - + " LEFT JOIN sub_division sd ON u.subDivisionId = sd.id " - // + " LEFT JOIN division d ON sd.divisionId = d.id " - // + " LEFT JOIN sub_division sd2 ON sd2.divisionId = d.id " - + " LEFT JOIN todo_reminder tr ON tr.subDivisionId = sd.id " - + " LEFT JOIN todo_reminder_noted trn ON trn.todoReminderId = tr.id " - + " WHERE tr.deleted = FALSE " - + " AND u.id = :userId " - ); - if (args != null) { - if (args.containsKey("reminderType")) - sql.append(" AND tr.reminderType= :reminderType "); - else - sql.append(" AND tr.reminderType != \"announcement\" "); - } - - sql.append( - " AND IF(:read, trn.userId IS NOT NULL AND trn.userId = :userId , trn.userId IS NULL) "+ - " ORDER BY tr.id DESC" - ); - - return jdbcDao.queryForList(sql.toString(), args); - } - - public Integer userRead(Long id, Long userId) { - TodoReminder instance = this.find(id).get(); - - Map value = Map.of("todoReminderId", id, "userId", userId, "notedDate", - LocalDateTime.now()); - // =====GET OLD AUDIT LOG=====// - String tableName = instance.getClass().getAnnotation(Table.class).name(); - StringBuilder sql = new StringBuilder("SELECT * FROM " + tableName + " WHERE id = :id"); - Map oldValueObject = new HashMap(); - Map newValueObject = new HashMap(); - - if (instance != null && instance.getId() != null && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - oldValueObject = logData; - } - // =====GET OLD AUDIT LOG=====// - jdbcDao.executeUpdate( - "INSERT IGNORE INTO todo_reminder_noted (todoReminderId, userId, notedDate)" - + " VALUE (:todoReminderId, :userId, :notedDate)", - value); - // =====GET NEW AUDIT LOG=====// - if (instance != null && instance.getId() != null && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - logData.put("noted", this.getTodoRead(input).get("notedDate")); - newValueObject = logData; - } - auditLogService.save( - tableName, - instance.getId(), - instance.getTitle(), - SecurityUtils.getUser() != null ? SecurityUtils.getUser().get().getId() : null, - new Date(), - JsonUtils.toJsonString(auditLogService.compareMaps(newValueObject, oldValueObject)), - JsonUtils.toJsonString(auditLogService.compareMaps(oldValueObject, newValueObject))); - // =====GET NEW AUDIT LOG=====// - - return 1; - - } - - public Map getTodoRead(Map req) { - StringBuilder sql = new StringBuilder("SELECT" - + " trn.notedDate " - + " FROM todo_reminder_noted trn " - + " WHERE trn.todoReminderId =:id "); - - return jdbcDao.queryForMap(sql.toString(), req).orElse(null); - } - - public List getFailEmailRecord(Map req) { - StringBuilder sql = new StringBuilder("SELECT" - + " * " - + " FROM todo_reminder_email_log trel " - + " WHERE trel.resendSuccess=0 " - + " AND trel.success=0 "); - - return jdbcDao.queryForList(sql.toString(), req, TodoReminderEmailLog.class); - } - - public Long suppressTodo(Long id, Long userId) { - TodoReminder instance = find(id).get(); - instance.setSuppressedBy(userId); - instance.setSuppressedDate(LocalDateTime.now()); - - // =====GET OLD AUDIT LOG=====// - String tableName = instance.getClass().getAnnotation(Table.class).name(); - StringBuilder sql = new StringBuilder("SELECT * FROM " + tableName + " WHERE id = :id"); - Map oldValueObject = new HashMap(); - Map newValueObject = new HashMap(); - - if (instance != null && instance.getId() != null && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - oldValueObject = logData; - } - // =====GET OLD AUDIT LOG=====// - instance = save(instance); - - Map value = Map.of( - "eventId", instance.getEventId(), - "subDivisionId", instance.getSubDivisionId()); - - logger.info(instance.getReminderType()); - if (instance.getReminderType().equals("newEventApplication")) { - logger.info("here"); - jdbcDao.executeUpdate( - "UPDATE event_sub_division esd" - + " SET esd.suppressedNewReminder = TRUE" - + " WHERE eventId = :eventId " - + " AND subDivisionId = :subDivisionId", - value); - } else if (instance.getReminderType().equals("oldEventApplication")) { - logger.info("here2"); - jdbcDao.executeUpdate( - "UPDATE event_sub_division esd" - + " SET esd.suppressedOldReminder = TRUE" - + " WHERE eventId = :eventId " - + " AND subDivisionId = :subDivisionId", - value); - } - - Map value2 = Map.of("todoReminderId", id, "userId", userId, "notedDate", - LocalDateTime.now()); - - if (this.getTodoRead(Map.of("id", instance.getId())) == null) { - jdbcDao.executeUpdate( - "INSERT IGNORE INTO todo_reminder_noted (todoReminderId, userId, notedDate)" - + " VALUE (:todoReminderId, :userId, :notedDate)", - value2); - } - - // =====GET NEW AUDIT LOG=====// - if (instance != null && instance.getId() != null && instance.getId() > 0) { - Map input = Map.of("id", instance.getId()); - Map logData = getAuditLogObject(input); - logData.put("noted", this.getTodoRead(input).get("notedDate")); - newValueObject = logData; - } - auditLogService.save( - tableName, - instance.getId(), - instance.getTitle(), - SecurityUtils.getUser() != null ? SecurityUtils.getUser().get().getId() : null, - new Date(), - JsonUtils.toJsonString(auditLogService.compareMaps(newValueObject, oldValueObject)), - JsonUtils.toJsonString(auditLogService.compareMaps(oldValueObject, newValueObject))); - // =====GET NEW AUDIT LOG=====// - return instance.getId(); - } - -} \ No newline at end of file diff --git a/src/main/java/com/ffii/lioner/modules/lioner/web/TodoReminderController.java b/src/main/java/com/ffii/lioner/modules/lioner/web/TodoReminderController.java deleted file mode 100644 index 6cdd73d..0000000 --- a/src/main/java/com/ffii/lioner/modules/lioner/web/TodoReminderController.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.ffii.lioner.modules.lioner.web; - -import java.io.UnsupportedEncodingException; -import java.text.ParseException; -import java.time.LocalDate; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.web.bind.ServletRequestBindingException; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.ffii.lioner.modules.lioner.entity.TodoReminderEmailLog; -import com.ffii.lioner.modules.lioner.service.TodoReminderService; -import com.ffii.lioner.modules.common.LocalDateAdapter; -import com.ffii.lioner.modules.common.mail.pojo.MailRequest; -import com.ffii.lioner.modules.common.mail.service.MailService; -import com.ffii.lioner.modules.user.service.UserService; -import com.ffii.core.response.RecordsRes; -import com.ffii.core.utils.CriteriaArgsBuilder; -import com.ffii.core.utils.Params; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import jakarta.servlet.http.HttpServletRequest; - -@RestController -@RequestMapping("/todo") -public class TodoReminderController{ - - private final Log logger = LogFactory.getLog(getClass()); - private TodoReminderService todoReminderService; - private MailService mailService; - - public TodoReminderController(TodoReminderService todoReminderService, MailService mailService) { - this.todoReminderService = todoReminderService; - this.mailService = mailService; - } - - @GetMapping("/application/{id}/{read}") - public RecordsRes> listApplication(@PathVariable Long id, @PathVariable Boolean read) throws ServletRequestBindingException { - return new RecordsRes<>(todoReminderService.list( - Map.of("userId", id, - //"reminderType", "application", - "read", read - ))); - } - - @GetMapping("/announcement/{id}/{read}") - public RecordsRes> listAnnouncement(@PathVariable Long id, @PathVariable Boolean read) throws ServletRequestBindingException { - return new RecordsRes<>(todoReminderService.list( - Map.of( - "userId", id, - "reminderType", "announcement", - "read", read - ))); - } - - @PostMapping("/markRead/{id}/{userId}") - public Map markRead(@PathVariable Long id, @PathVariable Long userId) { - return Map.of( - Params.DATA, todoReminderService.userRead(id,userId) - ); - } - - @PostMapping("/markSuppress/{id}/{userId}") - public Map markSuppress(@PathVariable Long id, @PathVariable Long userId) { - return Map.of( - Params.DATA, todoReminderService.suppressTodo(id,userId) - ); - } - - @GetMapping("/test") - public void test(HttpServletRequest request) throws UnsupportedEncodingException, ParseException, ServletRequestBindingException { - todoReminderService.sendTestEmail( - CriteriaArgsBuilder.withRequest(request) - .addString("templateName") - .addString("receiver") - .build() - ); - } - - @GetMapping("/testReminder") - public void testReminder(HttpServletRequest request) throws UnsupportedEncodingException, ParseException, ServletRequestBindingException { - todoReminderService.generateApplicationReminder(); - } - - @GetMapping("/testAnnouncement") - public void testAnnouncement(HttpServletRequest request) throws UnsupportedEncodingException, ParseException, ServletRequestBindingException { - todoReminderService.generateApplicationAnnouncement(); - } - - @GetMapping("/resendFailEmail") - public void resendFailEmail() throws ParseException{ - List list = todoReminderService.getFailEmailRecord(null); - logger.info("============= Resend Failed Email Start ============="); - logger.info("Fetched Total Number of Email: " + list.size()); - - for (TodoReminderEmailLog todoReminderEmailLog : list) { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateAdapter()); - Gson gson = gsonBuilder.create(); - MailRequest mailRequestObj = gson.fromJson(todoReminderEmailLog.getContent(), MailRequest.class); - logger.info("---------------------------------------------"); - logger.info("Try Resend for userId: " + todoReminderEmailLog.getUserId()); - logger.info("Try Resend for eventId: " + todoReminderEmailLog.getEventId()); - mailService.resendARS(mailRequestObj, todoReminderEmailLog.getId()); - } - logger.info("============= Resend Failed Email End ============="); - } - - /* - - //TEST USE ONLY START// - @GetMapping("/email") - public Map testEmail() throws Exception{ - todoReminderService.sendApplicationEmail(); - return Map.of("success", true); - } - - @GetMapping("/announceEmail") - public Map testEmail2() throws Exception{ - todoReminderService.sendAnnouncementEmail(); - return Map.of("success", true); - } - //TEST USE ONLY END// - - */ - -} diff --git a/src/main/java/com/ffii/lioner/modules/user/service/UserService.java b/src/main/java/com/ffii/lioner/modules/user/service/UserService.java index 0dafce2..78bd538 100644 --- a/src/main/java/com/ffii/lioner/modules/user/service/UserService.java +++ b/src/main/java/com/ffii/lioner/modules/user/service/UserService.java @@ -85,8 +85,8 @@ public class UserService extends AbstractBaseEntityService params = new LinkedMultiValueMap<>(); - params.add("AuthenticationCode", "arspass"); - params.add("EMSDlotus", EMSDlotus); - params.add("cn", ""); - params.add("EMSDpersonno", ""); - params.add("EMSDemploystatus", ""); - params.add("EMSDformaddr", ""); - params.add("EMSDlastname", ""); - params.add("EMSDfirstname", ""); - params.add("EMSDknownas", ""); - params.add("EMSDgender", ""); - params.add("EMSDposition", ""); - params.add("EMSDtitle", ""); - params.add("EMSDorgunit", ""); - params.add("EMSDorgdesc", ""); - params.add("EMSDmangid", ""); - params.add("EMSDgrpemploy", ""); - params.add("EMSDsgrpemploy", ""); - params.add("EMSDrankcode", ""); - params.add("EMSDrankdesc", ""); - params.add("EMSDEMSDemail", ""); - params.add("EMSDapmail", ""); - params.add("EMSDofftel", ""); - params.add("EMSDcc", ""); - params.add("EMSDccresp", ""); - params.add("EMSDdivision", ""); - params.add("EMSDstream1", ""); - params.add("EMSDstream2", ""); - params.add("EMSDactdesc1", ""); - params.add("EMSDactrank1", ""); - params.add("EMSDactldesc1", ""); - params.add("EMSDactdesc2", ""); - params.add("EMSDactrank2", ""); - params.add("EMSDactldesc2", ""); - params.add("EMSDactdesc3", ""); - params.add("EMSDactrank3", ""); - params.add("EMSDactldesc3", ""); - params.add("EMSDupddate", ""); - params.add("EMSDactpid1", ""); - params.add("EMSDactpost1", ""); - params.add("EMSDactpid2", ""); - params.add("EMSDactpost2", ""); - params.add("EMSDactpid3", ""); - params.add("EMSDactpost3", ""); - params.add("EMSDnickname", ""); - params.add("EMSDtitledescen", ""); - params.add("EMSDtitledescch", ""); - params.add("EMSDotherdeptemail", ""); - params.add("EMSDotherdeptapmail", ""); - params.add("EMSDgoamail", ""); - params.add("EMSDdpac", ""); - params.add("EMSDarrayorgobjid", ""); - params.add("EMSDarrayorgengna", ""); - params.add("EMSDarrayorgchina", ""); - - UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiUrl); - for (String key : params.keySet()) { - for (String value : params.get(key)) { - builder.queryParam(key, value); - } - } - - HttpEntity> requestEntity = new HttpEntity<>(params, headers); - ResponseEntity response = restTemplate.exchange(builder.toUriString(), HttpMethod.POST, requestEntity, - String.class); - - if (response.getStatusCode().is2xxSuccessful()) { - return response.getBody(); - } else { - throw new RuntimeException("Failed to fetch data from the API"); - } - } - public boolean isNameTaken(String name, Long id) { StringBuilder sql = new StringBuilder("SELECT" + " Count(u.id) " diff --git a/src/main/java/com/ffii/lioner/modules/user/web/UserController.java b/src/main/java/com/ffii/lioner/modules/user/web/UserController.java index 20bec20..3250468 100644 --- a/src/main/java/com/ffii/lioner/modules/user/web/UserController.java +++ b/src/main/java/com/ffii/lioner/modules/user/web/UserController.java @@ -11,7 +11,6 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.NoSuchMessageException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -33,11 +32,16 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.ffii.lioner.modules.common.ErrorCodes; +import com.ffii.core.exception.NotFoundException; +import com.ffii.core.exception.UnprocessableEntityException; +import com.ffii.core.response.IdRes; +import com.ffii.core.response.RecordsRes; +import com.ffii.core.utils.CriteriaArgsBuilder; +import com.ffii.core.utils.Params; +import com.ffii.core.utils.PasswordUtils; import com.ffii.lioner.modules.common.PasswordRule; import com.ffii.lioner.modules.common.SecurityUtils; import com.ffii.lioner.modules.common.SettingNames; -import com.ffii.lioner.modules.common.TempConst; import com.ffii.lioner.modules.settings.service.SettingsService; import com.ffii.lioner.modules.user.entity.User; import com.ffii.lioner.modules.user.entity.UserPasswordHistory; @@ -49,14 +53,6 @@ import com.ffii.lioner.modules.user.req.UpdateUserReq; import com.ffii.lioner.modules.user.service.UserPasswordHistoryService; import com.ffii.lioner.modules.user.service.UserService; import com.ffii.lioner.modules.user.service.res.LoadUserRes; -import com.ffii.core.exception.BadRequestException; -import com.ffii.core.exception.NotFoundException; -import com.ffii.core.exception.UnprocessableEntityException; -import com.ffii.core.response.IdRes; -import com.ffii.core.response.RecordsRes; -import com.ffii.core.utils.CriteriaArgsBuilder; -import com.ffii.core.utils.Params; -import com.ffii.core.utils.PasswordUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; @@ -77,7 +73,6 @@ public class UserController { @Autowired private LdapTemplate ldapTemplate; - @Value("${emsd.webservice.required}") private Boolean ldapWebServiceRequired; public UserController( @@ -293,19 +288,6 @@ public class UserController { return new RecordsRes<>(temp); } - @GetMapping("/lotus") - public String getDataFromThirdPartyApi(HttpServletRequest request, @RequestParam String EMSDlotus) - throws Exception { - String xmlResponse = ""; - - if (ldapWebServiceRequired) { - xmlResponse = userService.fetchDataFromApi(EMSDlotus); - } else { - xmlResponse = "" + TempConst.LOTUS_TEMP_CONST; - } - return xmlResponse; - } - @GetMapping("/lotusCombo") public ResponseEntity lotusCombo(@RequestParam(defaultValue = "") String username) throws Exception { AtomicInteger tempId = new AtomicInteger(0); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5fef5d1..1726a72 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -11,6 +11,11 @@ server: tomcat: connection-timeout: 300000 spring: + datasource: + jdbc-url: jdbc:mysql://localhost:3306/lionerdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 + username: root + password: cFDp7988vc+$] + servlet: multipart: max-file-size: 500MB