| @@ -0,0 +1,40 @@ | |||
| package com.ffii.fpsms.modules.common.mail.entity | |||
| import com.ffii.core.entity.BaseEntity | |||
| import jakarta.persistence.* | |||
| import jakarta.validation.constraints.NotNull | |||
| import jakarta.validation.constraints.Size | |||
| import java.time.LocalDateTime | |||
| @Entity | |||
| @Table(name = "mail_send_log") | |||
| open class MailSendLog : BaseEntity<Long>() { | |||
| @NotNull | |||
| @ManyToOne | |||
| @JoinColumn(name = "tempId", nullable = false) | |||
| open var temp: MailSendLog? = null | |||
| @Size(max = 255) | |||
| @NotNull | |||
| @Column(name = "tempDesc", nullable = false) | |||
| open var tempDesc: String? = null | |||
| @Size(max = 255) | |||
| @Column(name = "senderMail") | |||
| open var senderMail: String? = null | |||
| @Column(name = "subject") | |||
| open var subject: String? = null | |||
| @Lob | |||
| @Column(name = "content") | |||
| open var content: String? = null | |||
| @Column(name = "sendDate") | |||
| open var sendDate: LocalDateTime? = null | |||
| @Lob | |||
| @Column(name = "errorMessage") | |||
| open var errorMessage: String? = null | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| package com.ffii.fpsms.modules.common.mail.entity | |||
| import com.ffii.core.entity.BaseEntity | |||
| import jakarta.persistence.* | |||
| import jakarta.validation.constraints.NotNull | |||
| import jakarta.validation.constraints.Size | |||
| @Entity | |||
| @Table(name = "mail_send_log_line") | |||
| open class MailSendLogLine : BaseEntity<Long>() { | |||
| @NotNull | |||
| @ManyToOne | |||
| @JoinColumn(name = "sendMailLogId", nullable = false) | |||
| open var sendMailLog: MailSendLog? = null | |||
| @Size(max = 255) | |||
| @Column(name = "toMail") | |||
| open var toMail: String? = null | |||
| @Lob | |||
| @Column(name = "errorMessage") | |||
| open var errorMessage: String? = null | |||
| } | |||
| @@ -0,0 +1,8 @@ | |||
| package com.ffii.fpsms.modules.common.mail.entity | |||
| import com.ffii.core.support.AbstractRepository | |||
| import org.springframework.stereotype.Repository | |||
| @Repository | |||
| interface MailSendLogLineRepository : AbstractRepository<MailSendLogLine, Long> { | |||
| } | |||
| @@ -0,0 +1,8 @@ | |||
| package com.ffii.fpsms.modules.common.mail.entity | |||
| import com.ffii.core.support.AbstractRepository | |||
| import org.springframework.stereotype.Repository | |||
| @Repository | |||
| interface MailSendLogRepository : AbstractRepository<MailSendLog, Long> { | |||
| } | |||
| @@ -0,0 +1,48 @@ | |||
| package com.ffii.fpsms.modules.common.mail.entity | |||
| import com.ffii.core.entity.BaseEntity | |||
| import jakarta.persistence.* | |||
| import jakarta.validation.constraints.NotNull | |||
| import jakarta.validation.constraints.Size | |||
| @Entity | |||
| @Table(name = "mail_template") | |||
| open class MailTemplate : BaseEntity<Long>() { | |||
| @Column(name = "`to`") | |||
| open var to: String? = null | |||
| @Column(name = "cc") | |||
| open var cc: String? = null | |||
| @Size(max = 255) | |||
| @NotNull | |||
| @Column(name = "code", nullable = false) | |||
| open var code: String? = null | |||
| @Size(max = 255) | |||
| @NotNull | |||
| @Column(name = "description", nullable = false) | |||
| open var description: String? = null | |||
| @Size(max = 30) | |||
| @Column(name = "type", length = 30) | |||
| open var type: String? = null | |||
| @Size(max = 255) | |||
| @Column(name = "params") | |||
| open var params: String? = null | |||
| @Column(name = "subjectCht") | |||
| open var subjectCht: String? = null | |||
| @Column(name = "subjectEng") | |||
| open var subjectEng: String? = null | |||
| @Lob | |||
| @Column(name = "contentCht") | |||
| open var contentCht: String? = null | |||
| @Lob | |||
| @Column(name = "contentEng") | |||
| open var contentEng: String? = null | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| package com.ffii.fpsms.modules.common.mail.entity | |||
| import com.ffii.core.support.AbstractRepository | |||
| import org.springframework.stereotype.Repository | |||
| import java.io.Serializable | |||
| @Repository | |||
| interface MailTemplateRepository : AbstractRepository<MailTemplate, Long> { | |||
| fun findAllByDeletedIsFalse(): List<MailTemplate> | |||
| fun findByIdAndDeletedIsFalse(id: Serializable): MailTemplate? | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| package com.ffii.fpsms.modules.common.mail.enums | |||
| enum class MailTemplateType(val value: String) { | |||
| PURCHASE_ORDER("po"), | |||
| } | |||
| @@ -23,43 +23,20 @@ open class MailReminderService( | |||
| val settingsService: SettingsService, | |||
| ) { | |||
| protected val logger: Log = LogFactory.getLog(javaClass) | |||
| private val FULLTIME = "FT" | |||
| private val PARTTIME = "PT" | |||
| private val dateFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") | |||
| private fun isSettingsConfigValid(): Boolean { | |||
| try { | |||
| val username = settingsService.findByName(SettingNames.MAIL_SMTP_USERNAME).orElseThrow().value | |||
| val pw = settingsService.findByName(SettingNames.MAIL_SMTP_USERNAME).orElseThrow().value | |||
| val pw = settingsService.findByName(SettingNames.MAIL_SMTP_PASSWORD).orElseThrow().value | |||
| return !username.isNullOrEmpty() && !pw.isNullOrEmpty() | |||
| } catch (e: Error) { | |||
| return false | |||
| } | |||
| } | |||
| private fun createHTMLTable(naughtyList: MutableList<TableRow>): String { | |||
| val tableStarter = StringBuilder(" <table width='100%' border='1' align='center'> ") | |||
| val header = StringBuilder( | |||
| " <tr> " | |||
| + " <th>StaffId</th> " | |||
| + " <th>Name</th> " | |||
| + " <th>Missing Dates</th> " | |||
| + " </tr> " | |||
| ) | |||
| tableStarter.append(header) | |||
| for (per in naughtyList) { | |||
| tableStarter.append( | |||
| " <tr> " | |||
| + " <td>${per.staffId}</td>" | |||
| + " <td>${per.name}</td>" | |||
| + " <td>${per.missingDates.joinToString(", ")}</td>" | |||
| + " </tr> " | |||
| ) | |||
| } | |||
| val footer = StringBuilder(" </table> ") | |||
| return tableStarter.toString() | |||
| } | |||
| open fun createEmailRequest(content: String, emailTo: List<String>) { | |||
| if (!isSettingsConfigValid()) return; | |||
| // val subject = settingsService.findByName(SettingNames.TIMESHEET_MAIL_SUBJECT).orElseThrow().value | |||
| // val template = settingsService.findByName(SettingNames.TIMESHEET_MAIL_TEMPLATE).orElseThrow().value | |||
| // val cc = settingsService.findByName(SettingNames.TIMESHEET_MAIL_CC).orElseThrow().value.split(",") | |||
| @@ -5,7 +5,7 @@ import com.ffii.core.utils.LocaleUtils | |||
| import com.ffii.fpsms.modules.common.ErrorCodes | |||
| import com.ffii.fpsms.modules.common.SettingNames | |||
| import com.ffii.fpsms.modules.common.mail.pojo.MailRequest | |||
| import com.ffii.fpsms.modules.common.mail.web.models.MailSave | |||
| import com.ffii.fpsms.modules.common.mail.web.models.MailSaveRequest | |||
| import com.ffii.fpsms.modules.settings.entity.Settings | |||
| import com.ffii.fpsms.modules.settings.entity.SettingsRepository | |||
| import com.ffii.fpsms.modules.settings.service.SettingsService | |||
| @@ -32,6 +32,7 @@ open class MailService( | |||
| private val settingsService: SettingsService, | |||
| private val passwordEncoder: PasswordEncoder, | |||
| private val settingsRepository: SettingsRepository, | |||
| private val mailTemplateService: MailTemplateService, | |||
| ) { | |||
| protected val logger: Log = LogFactory.getLog(javaClass) | |||
| @@ -171,45 +172,22 @@ open class MailService( | |||
| asyncSend(mutableListOf(mailRequest)) | |||
| } | |||
| open fun saveMail(mailSave: MailSave): List<Settings> { | |||
| open fun saveMail(request: MailSaveRequest): List<Settings> { | |||
| // ------------------ save mail settings ------------------ // | |||
| val settings = mutableListOf<Settings>() | |||
| mailSave.settings.forEach { setting -> | |||
| request.settings.forEach { setting -> | |||
| val tempSetting = settingsRepository.findById(setting.id).orElseThrow() | |||
| settings += tempSetting.apply { | |||
| value = setting.value | |||
| } | |||
| } | |||
| // ------------------ save timesheet mail details ------------------ // | |||
| // val mailCc = settingsRepository.findByName("TIMESHEET.mail.cc").orElseThrow() | |||
| // | |||
| // settings += mailCc.apply { | |||
| // value = mailSave.template.cc | |||
| // } | |||
| // | |||
| // val mailBcc = settingsRepository.findByName("TIMESHEET.mail.bcc").orElseThrow() | |||
| // | |||
| // settings += mailBcc.apply { | |||
| // value = mailSave.template.bcc | |||
| // } | |||
| // | |||
| // val mailSubject = settingsRepository.findByName("TIMESHEET.mail.subject").orElseThrow() | |||
| // | |||
| // settings += mailSubject.apply { | |||
| // value = mailSave.template.subject | |||
| // } | |||
| // | |||
| // val mailTemplate = settingsRepository.findByName("TIMESHEET.mail.template").orElseThrow() | |||
| // | |||
| // settings += mailTemplate.apply { | |||
| // value = mailSave.template.template | |||
| // } | |||
| // ------------------ save all ------------------ // | |||
| settingsRepository.saveAll(settings) | |||
| // ------------------ save mail templates' details ------------------ // | |||
| mailTemplateService.saveMailTemplates(request.templates) | |||
| return settings | |||
| } | |||
| } | |||
| @@ -0,0 +1,62 @@ | |||
| package com.ffii.fpsms.modules.common.mail.service | |||
| import com.ffii.fpsms.modules.common.mail.entity.MailTemplate | |||
| import com.ffii.fpsms.modules.common.mail.entity.MailTemplateRepository | |||
| import com.ffii.fpsms.modules.common.mail.web.models.MailTemplateRequest | |||
| import org.springframework.stereotype.Service | |||
| @Service | |||
| open class MailTemplateService( | |||
| private val mailTemplateRepository: MailTemplateRepository, | |||
| ) { | |||
| fun allMailTemplates(): List<MailTemplate> { | |||
| return mailTemplateRepository.findAllByDeletedIsFalse(); | |||
| } | |||
| fun findById(id: Long): MailTemplate? { | |||
| return mailTemplateRepository.findByIdAndDeletedIsFalse(id); | |||
| } | |||
| fun saveMailTemplate(request: MailTemplateRequest): MailTemplate { | |||
| val mailTemplate = request.id?.let { findById(it) } ?: MailTemplate() | |||
| mailTemplate.apply { | |||
| to = request.to | |||
| cc = request.cc | |||
| code = request.code | |||
| description = request.description | |||
| type = request.type | |||
| params = request.params | |||
| subjectCht = request.subjectCht | |||
| subjectEng = request.subjectEng | |||
| contentCht = request.contentCht | |||
| contentEng = request.contentEng | |||
| } | |||
| val response = mailTemplateRepository.saveAndFlush(mailTemplate) | |||
| return response | |||
| } | |||
| fun saveMailTemplates(requests: List<MailTemplateRequest>) { | |||
| val mailTemplates: List<MailTemplate> = mutableListOf() | |||
| requests.forEach { request -> | |||
| val mailTemplate = request.id?.let { findById(it) } ?: MailTemplate() | |||
| mailTemplate.apply { | |||
| to = request.to | |||
| cc = request.cc | |||
| code = request.code | |||
| description = request.description | |||
| type = request.type | |||
| params = request.params | |||
| subjectCht = request.subjectCht | |||
| subjectEng = request.subjectEng | |||
| contentCht = request.contentCht | |||
| contentEng = request.contentEng | |||
| }.let { mailTemplates.plus(it) } | |||
| } | |||
| mailTemplateRepository.saveAll(mailTemplates) | |||
| } | |||
| } | |||
| @@ -1,8 +1,10 @@ | |||
| package com.ffii.fpsms.modules.common.mail.web | |||
| import com.ffii.fpsms.modules.common.mail.entity.MailTemplate | |||
| import com.ffii.fpsms.modules.common.mail.service.MailReminderService | |||
| import com.ffii.fpsms.modules.common.mail.service.MailService | |||
| import com.ffii.fpsms.modules.common.mail.web.models.MailSave | |||
| import com.ffii.fpsms.modules.common.mail.service.MailTemplateService | |||
| import com.ffii.fpsms.modules.common.mail.web.models.MailSaveRequest | |||
| import com.ffii.fpsms.modules.common.mail.web.models.Setting | |||
| import com.ffii.fpsms.modules.settings.entity.Settings | |||
| import com.ffii.fpsms.modules.settings.service.SettingsService | |||
| @@ -16,7 +18,7 @@ import java.util.Date | |||
| class MailController( | |||
| private val settingsService: SettingsService, | |||
| private val mailService: MailService, | |||
| private val mailReminderService: MailReminderService, | |||
| private val mailReminderService: MailReminderService | |||
| ) { | |||
| @GetMapping("/setting") | |||
| fun mailSetting(): List<Settings> { | |||
| @@ -29,7 +31,7 @@ class MailController( | |||
| } | |||
| @PostMapping("/save") | |||
| fun saveMail(@Valid @RequestBody mailSave: MailSave): List<Settings> { | |||
| fun saveMail(@Valid @RequestBody mailSave: MailSaveRequest): List<Settings> { | |||
| return mailService.saveMail(mailSave) | |||
| } | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| package com.ffii.fpsms.modules.common.mail.web | |||
| import com.ffii.fpsms.modules.common.mail.entity.MailTemplate | |||
| import com.ffii.fpsms.modules.common.mail.web.models.MailTemplateRequest | |||
| import com.ffii.fpsms.modules.common.mail.service.MailTemplateService | |||
| import org.springframework.web.bind.annotation.GetMapping | |||
| import org.springframework.web.bind.annotation.PostMapping | |||
| import org.springframework.web.bind.annotation.RequestMapping | |||
| import org.springframework.web.bind.annotation.RestController | |||
| @RequestMapping("/mailTemplates") | |||
| @RestController | |||
| class MailTemplateController( | |||
| private val mailTemplateService: MailTemplateService, | |||
| ) { | |||
| @GetMapping | |||
| fun allMailTemplates(): List<MailTemplate> { | |||
| return mailTemplateService.allMailTemplates(); | |||
| } | |||
| @PostMapping("/save") | |||
| fun saveMailTemplate(request: MailTemplateRequest): MailTemplate { | |||
| return mailTemplateService.saveMailTemplate(request); | |||
| } | |||
| } | |||
| @@ -15,7 +15,8 @@ data class Template ( | |||
| val template: String?, | |||
| ) | |||
| data class MailSave ( | |||
| data class MailSaveRequest ( | |||
| val settings: List<Setting>, | |||
| val templates: List<MailTemplateRequest>, | |||
| // val template: Template | |||
| ) | |||
| @@ -0,0 +1,19 @@ | |||
| package com.ffii.fpsms.modules.common.mail.web.models | |||
| import jakarta.validation.constraints.NotNull | |||
| data class MailTemplateRequest( | |||
| val id: Long?, | |||
| val to: String?, | |||
| val cc: String?, | |||
| @field:NotNull(message = "code cannot be null") | |||
| val code: String, | |||
| @field:NotNull(message = "description cannot be null") | |||
| val description: String?, | |||
| val type: String?, | |||
| val params: String?, | |||
| val subjectCht: String?, | |||
| val subjectEng: String?, | |||
| val contentCht: String?, | |||
| val contentEng: String?, | |||
| ) | |||
| @@ -0,0 +1,24 @@ | |||
| -- liquibase formatted sql | |||
| -- changeset cyril:create mail template | |||
| CREATE TABLE `mail_template` | |||
| ( | |||
| `id` INT NOT NULL AUTO_INCREMENT, | |||
| `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `createdBy` VARCHAR(30) NULL DEFAULT NULL, | |||
| `version` INT NOT NULL DEFAULT '0', | |||
| `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, | |||
| `deleted` TINYINT(1) NOT NULL DEFAULT '0', | |||
| `to` VARCHAR(255) NULL, | |||
| `cc` VARCHAR(255) NULL, | |||
| `code` VARCHAR(255) NOT NULL, | |||
| `description` VARCHAR(255) NOT NULL, | |||
| `type` VARCHAR(30) NULL, | |||
| `params` VARCHAR(255) NULL, | |||
| `subjectCht` VARCHAR(255) NULL, | |||
| `subjectEng` VARCHAR(255) NULL, | |||
| `contentCht` TEXT NULL, | |||
| `contentEng` TEXT NULL, | |||
| CONSTRAINT pk_mail_template PRIMARY KEY (id) | |||
| ); | |||
| @@ -0,0 +1,38 @@ | |||
| -- liquibase formatted sql | |||
| -- changeset cyril:create send mail log | |||
| CREATE TABLE `mail_send_log` | |||
| ( | |||
| `id` INT NOT NULL AUTO_INCREMENT, | |||
| `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `createdBy` VARCHAR(30) NULL DEFAULT NULL, | |||
| `version` INT NOT NULL DEFAULT '0', | |||
| `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, | |||
| `deleted` TINYINT(1) NOT NULL DEFAULT '0', | |||
| `tempId` INT NOT NULL, | |||
| `tempDesc` VARCHAR(255) NOT NULL, | |||
| `senderMail` VARCHAR(255) NULL, | |||
| `subject` VARCHAR(255) NULL, | |||
| `content` TEXT NULL, | |||
| `sendDate` DATETIME NULL, | |||
| `errorMessage` TEXT NULL, | |||
| CONSTRAINT pk_mail_send_log PRIMARY KEY (id), | |||
| CONSTRAINT `FK_MAIL_SEND_LOG_ON_TEMPID` FOREIGN KEY (`tempId`) REFERENCES `mail_send_log` (`id`) | |||
| ); | |||
| CREATE TABLE `mail_send_log_line` | |||
| ( | |||
| `id` INT NOT NULL AUTO_INCREMENT, | |||
| `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `createdBy` VARCHAR(30) NULL DEFAULT NULL, | |||
| `version` INT NOT NULL DEFAULT '0', | |||
| `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, | |||
| `deleted` TINYINT(1) NOT NULL DEFAULT '0', | |||
| `sendMailLogId` INT NOT NULL, | |||
| `toMail` VARCHAR(255) NULL, | |||
| `errorMessage` TEXT NULL, | |||
| CONSTRAINT pk_mail_send_log_line PRIMARY KEY (id), | |||
| CONSTRAINT `FK_MAIL_SEND_LOG_LINE_ON_SENDMAILLOGID` FOREIGN KEY (`sendMailLogId`) REFERENCES `mail_send_log` (`id`) | |||
| ); | |||