@@ -0,0 +1,42 @@ | |||||
package com.ffii.core.utils; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.context.i18n.LocaleContextHolder; | |||||
import java.util.Locale; | |||||
/** this utils follow "-" standard ("zh-TW", no "zh_TW") */ | |||||
public abstract class LocaleUtils { | |||||
public static Locale getLocale() { | |||||
return LocaleContextHolder.getLocale(); | |||||
} | |||||
public static String getLocaleStr() { | |||||
return toLocaleStr(LocaleContextHolder.getLocale()); | |||||
} | |||||
public static String toLocaleStr(Locale locale) { | |||||
String language = locale.getLanguage(); | |||||
String country = locale.getCountry(); | |||||
if (StringUtils.isNotBlank(country)) { | |||||
return language + "-" + country; | |||||
} else { | |||||
return language; | |||||
} | |||||
} | |||||
/** | |||||
* @param localeStr | |||||
* e.g. zh-TW | |||||
*/ | |||||
public static Locale from(String localeStr) { | |||||
String[] localeArr = localeStr.split("-"); | |||||
if (localeArr.length == 1) { | |||||
return new Locale(localeArr[0]); | |||||
} else { | |||||
return new Locale(localeArr[0], localeArr[1]); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,38 @@ | |||||
package com.ffii.fpsms.modules.common | |||||
import com.ffii.fpsms.modules.settings.service.SettingsService | |||||
import org.apache.commons.lang3.StringUtils | |||||
open class MailSMTP(settingsService: SettingsService) { | |||||
open var host: String? = null | |||||
open var port: Int? = null | |||||
open var username: String? = null | |||||
open var password: String? = null | |||||
open var auth: Boolean? = null | |||||
init { | |||||
this.host = settingsService.getString(SettingNames.MAIL_SMTP_HOST) | |||||
this.port = settingsService.getInt(SettingNames.MAIL_SMTP_PORT) | |||||
this.username = settingsService.getString(SettingNames.MAIL_SMTP_USERNAME) | |||||
this.password = settingsService.getString(SettingNames.MAIL_SMTP_PASSWORD) | |||||
this.auth = settingsService.getBoolean(SettingNames.MAIL_SMTP_AUTH) | |||||
} | |||||
final override fun equals(other: Any?): Boolean { | |||||
if (other == null || other !is MailSMTP) return false | |||||
val o = other as MailSMTP | |||||
if (StringUtils.equals( | |||||
this.host, | |||||
o.host | |||||
) && this.port == o.port && | |||||
StringUtils.equals(this.username, o.username) && | |||||
StringUtils.equals(this.password, o.password) | |||||
) { | |||||
return true | |||||
} | |||||
return false | |||||
} | |||||
} |
@@ -38,6 +38,8 @@ public abstract class SettingNames { | |||||
public static final String MAIL_SMTP_RECIPIENTS = "MAIL.smtp.recipients"; | public static final String MAIL_SMTP_RECIPIENTS = "MAIL.smtp.recipients"; | ||||
public static final String MAIL_SMTP_AUTH = "MAIL.smtp.auth"; | |||||
public static final String JS_VERSION = "JS.version"; | public static final String JS_VERSION = "JS.version"; | ||||
public static final String REPORT_DAILYMAINT_RECIPIENTS_MECH = "REPORT.dailyMaint.recipients.mech"; | public static final String REPORT_DAILYMAINT_RECIPIENTS_MECH = "REPORT.dailyMaint.recipients.mech"; | ||||
@@ -0,0 +1,246 @@ | |||||
package com.ffii.fpsms.modules.common.mail.pojo | |||||
import jakarta.mail.internet.InternetAddress | |||||
open class MailRequest() { | |||||
val PRIORITY_HIGHEST: Int = 1 | |||||
val PRIORITY_HIGH: Int = 2 | |||||
val PRIORITY_NORMAL: Int = 3 | |||||
val PRIORITY_LOW: Int = 4 | |||||
val PRIORITY_LOWEST: Int = 5 | |||||
open var from: InternetAddress? = null | |||||
open var to: List<InternetAddress> = mutableListOf() | |||||
open var subject: String? = null | |||||
open var template: String? = null | |||||
open var templateContent: String? = null | |||||
open var args: Map<String, Any?> = mapOf() | |||||
open var priority: Int? = null | |||||
open var replyTo: InternetAddress? = null | |||||
open var cc: List<InternetAddress> = mutableListOf() | |||||
open var bcc: List<InternetAddress> = mutableListOf() | |||||
open var attachments: Map<String, ByteArray> = mapOf() | |||||
open fun builder(): Builder { | |||||
return Builder() | |||||
} | |||||
open fun addAttachment(attachmentFilename: String, byteArray: ByteArray) { | |||||
this.attachments += Pair(attachmentFilename, byteArray) | |||||
} | |||||
open fun addTo(to: InternetAddress) { | |||||
this.to += to | |||||
} | |||||
open fun addCc(cc: InternetAddress) { | |||||
this.cc += cc | |||||
} | |||||
open fun addBcc(bcc: InternetAddress) { | |||||
this.bcc += bcc | |||||
} | |||||
open class Builder() { | |||||
open var mailRequest:MailRequest = MailRequest() | |||||
init { | |||||
this.mailRequest = MailRequest() | |||||
} | |||||
open fun build(): MailRequest { | |||||
return this.mailRequest | |||||
} | |||||
open fun addAttachment(attachmentFilename: String, byteArray: ByteArray): Builder { | |||||
mailRequest.addAttachment(attachmentFilename, byteArray) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addToInternetAddress") | |||||
open fun addTo(to: InternetAddress): Builder { | |||||
mailRequest.addTo(to) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addToString") | |||||
open fun addTo(to: String): Builder { | |||||
mailRequest.addTo(InternetAddress(to)) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addToList") | |||||
open fun addTo(to: List<String>): Builder { | |||||
to.forEach { | |||||
if (it.isNotEmpty()) { | |||||
mailRequest.addTo(InternetAddress(it)) | |||||
} | |||||
} | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addCcInternetAddress") | |||||
open fun addCc(cc: InternetAddress): Builder { | |||||
mailRequest.addCc(cc) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addCcString") | |||||
open fun addCc(cc: String): Builder { | |||||
mailRequest.addCc(InternetAddress(cc)) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addCcStringList") | |||||
open fun addCc(cc: List<String>): Builder { | |||||
cc.forEach { | |||||
if (it.isNotEmpty()) { | |||||
mailRequest.addCc(InternetAddress(it)) | |||||
} | |||||
} | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addBccInternetAddress") | |||||
open fun addBcc(bcc: InternetAddress): Builder { | |||||
mailRequest.addBcc(bcc) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addBccString") | |||||
open fun addBcc(bcc: String): Builder { | |||||
mailRequest.addBcc(InternetAddress(bcc)) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("addBccStringList") | |||||
open fun addBcc(bcc: List<String>): Builder { | |||||
bcc.forEach { | |||||
if (it.isNotEmpty()) { | |||||
mailRequest.addBcc(InternetAddress(it)) | |||||
} | |||||
} | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("fromInternetAddress") | |||||
open fun from(from: InternetAddress): Builder { | |||||
mailRequest.from = from | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("fromString") | |||||
open fun from(from: String): Builder { | |||||
mailRequest.from = InternetAddress(from) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("toListInternetAddress") | |||||
open fun to(to: List<InternetAddress>): Builder { | |||||
mailRequest.to = to | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("toListString") | |||||
open fun to(to: List<String>): Builder { | |||||
mailRequest.to = to.map { InternetAddress(it) } | |||||
return this | |||||
} | |||||
open fun subject(subject: String?): Builder { | |||||
mailRequest.subject = subject | |||||
return this | |||||
} | |||||
open fun template(template: String?): Builder { | |||||
mailRequest.template = template | |||||
return this | |||||
} | |||||
open fun templateContent(templateContent: String?): Builder { | |||||
mailRequest.templateContent = templateContent | |||||
return this | |||||
} | |||||
open fun args(args: Map<String, Any?>): Builder { | |||||
mailRequest.args = args | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("replyToInternetAddress") | |||||
open fun replyTo(replyTo: InternetAddress?): Builder { | |||||
mailRequest.replyTo = replyTo | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("replyToString") | |||||
open fun replyTo(replyTo: String?): Builder { | |||||
mailRequest.replyTo = InternetAddress(replyTo) | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("ccListInternetAddress") | |||||
open fun cc(cc: List<InternetAddress>): Builder { | |||||
mailRequest.cc = cc | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("ccListString") | |||||
open fun cc(cc: List<String>): Builder { | |||||
mailRequest.cc = cc.map { InternetAddress(it) } | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("bccListInternetAddress") | |||||
open fun bcc(bcc: List<InternetAddress>): Builder { | |||||
mailRequest.bcc = bcc | |||||
return this | |||||
} | |||||
@Suppress("INAPPLICABLE_JVM_NAME") | |||||
@JvmName("bccListString") | |||||
open fun bcc(bcc: List<String>): Builder { | |||||
mailRequest.bcc = bcc.map { InternetAddress(it) } | |||||
return this | |||||
} | |||||
open fun attachments(attachments: Map<String, ByteArray>): Builder { | |||||
mailRequest.attachments = attachments | |||||
return this | |||||
} | |||||
open fun priority(priority: Int?): Builder { | |||||
mailRequest.priority = priority | |||||
return this | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,88 @@ | |||||
package com.ffii.fpsms.modules.common.mail.service | |||||
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.WorkHourRecords | |||||
import com.ffii.fpsms.modules.settings.service.SettingsService | |||||
import com.ffii.fpsms.modules.user.service.UserService | |||||
import jakarta.mail.internet.InternetAddress | |||||
import org.apache.commons.logging.Log | |||||
import org.apache.commons.logging.LogFactory | |||||
import org.springframework.scheduling.annotation.Scheduled | |||||
import org.springframework.stereotype.Service | |||||
import java.time.DayOfWeek | |||||
import java.time.LocalDate | |||||
import java.time.YearMonth | |||||
import java.time.format.DateTimeFormatter | |||||
data class TableRow( | |||||
val staffId: String, | |||||
val name: String, | |||||
val missingDates: MutableList<LocalDate>, | |||||
) | |||||
@Service | |||||
open class MailReminderService( | |||||
val mailService: MailService, | |||||
val userService: UserService, | |||||
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 | |||||
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() | |||||
} | |||||
private fun createEmailRequest(content: String, emailTo: List<String>) { | |||||
// 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(",") | |||||
// val bcc = settingsService.findByName(SettingNames.TIMESHEET_MAIL_BCC).orElseThrow().value.split(",") | |||||
val mailRequest = MailRequest.Builder() | |||||
// .subject(subject) | |||||
// .templateContent(template) | |||||
.args( | |||||
mapOf( | |||||
Pair("date", content), | |||||
) | |||||
) | |||||
.addTo(emailTo) | |||||
// .addCc(cc) | |||||
// .addBcc(bcc) | |||||
.build() | |||||
val mailRequestList = mutableListOf<MailRequest>() | |||||
mailRequestList += mailRequest | |||||
mailService.send(mailRequestList) | |||||
} | |||||
} |
@@ -0,0 +1,47 @@ | |||||
package com.ffii.fpsms.modules.common.mail.service | |||||
import com.ffii.fpsms.modules.common.MailSMTP | |||||
import com.ffii.fpsms.modules.settings.service.SettingsService | |||||
import org.springframework.mail.javamail.JavaMailSender | |||||
import org.springframework.mail.javamail.JavaMailSenderImpl | |||||
import org.springframework.stereotype.Service | |||||
import java.util.* | |||||
@Service | |||||
open class MailSenderService(private val settingsService: SettingsService) { | |||||
private var sender: JavaMailSender? = null | |||||
private var mailConfigCachs: MailSMTP? = null | |||||
open fun get(): JavaMailSender { | |||||
val config = MailSMTP(settingsService) | |||||
if (this.sender == null || (mailConfigCachs == null) || !config.equals(this.mailConfigCachs)) { | |||||
this.mailConfigCachs = config | |||||
val sender = JavaMailSenderImpl() | |||||
val props = Properties() | |||||
val auth = config.auth ?: false | |||||
if (auth) { | |||||
props["mail.smtp.timeout"] = "20000" | |||||
props["mail.smtp.connectiontimeout"] = "10000" | |||||
} | |||||
props["mail.smtp.auth"] = auth | |||||
// The below setting needs to be included when the SMTP has TLS Version | |||||
// props["mail.smtp.starttls.enable"] = "true" | |||||
// props["mail.smtp.ssl.protocols"] = "TLSv1.2" | |||||
sender.host = config.host | |||||
sender.port = config.port!! | |||||
if (auth) { | |||||
sender.username = config.username | |||||
sender.password = config.password | |||||
} | |||||
sender.javaMailProperties = props | |||||
this.sender = sender | |||||
} | |||||
return this.sender ?: JavaMailSenderImpl() | |||||
} | |||||
} |
@@ -0,0 +1,215 @@ | |||||
package com.ffii.fpsms.modules.common.mail.service | |||||
import com.ffii.core.exception.InternalServerErrorException | |||||
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.settings.entity.Settings | |||||
import com.ffii.fpsms.modules.settings.entity.SettingsRepository | |||||
import com.ffii.fpsms.modules.settings.service.SettingsService | |||||
import freemarker.cache.StringTemplateLoader | |||||
import freemarker.template.* | |||||
import jakarta.mail.MessagingException | |||||
import jakarta.mail.internet.InternetAddress | |||||
import org.apache.commons.logging.Log | |||||
import org.apache.commons.logging.LogFactory | |||||
import org.springframework.core.io.ByteArrayResource | |||||
import org.springframework.mail.javamail.MimeMessageHelper | |||||
import org.springframework.scheduling.annotation.Async | |||||
import org.springframework.security.crypto.password.PasswordEncoder | |||||
import org.springframework.stereotype.Service | |||||
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils | |||||
import java.io.IOException | |||||
import java.text.ParseException | |||||
import java.util.* | |||||
@Service | |||||
open class MailService( | |||||
private val mailSenderService: MailSenderService, | |||||
private val freemarkerConfig: Configuration, | |||||
private val settingsService: SettingsService, | |||||
private val passwordEncoder: PasswordEncoder, | |||||
private val settingsRepository: SettingsRepository, | |||||
) { | |||||
protected val logger: Log = LogFactory.getLog(javaClass) | |||||
@Throws( | |||||
MessagingException::class, | |||||
TemplateNotFoundException::class, | |||||
MalformedTemplateNameException::class, | |||||
ParseException::class, | |||||
IOException::class, | |||||
TemplateException::class | |||||
) | |||||
open fun doSend(mailRequests: List<MailRequest>, locale: Locale) { | |||||
val sender = mailSenderService.get() | |||||
for (mailRequest in mailRequests) { | |||||
val mimeMessage = sender.createMimeMessage() | |||||
val helper = MimeMessageHelper(mimeMessage, true, "UTF-8") | |||||
mailRequest.subject?.let { helper.setSubject(it) } | |||||
var template: Template? = null | |||||
if (mailRequest.template != null) { | |||||
template = try { | |||||
freemarkerConfig | |||||
.getTemplate((mailRequest.template + "_" + LocaleUtils.toLocaleStr(locale)) + ".ftl") | |||||
} catch (e: TemplateNotFoundException) { | |||||
freemarkerConfig.getTemplate(mailRequest.template + ".ftl") | |||||
} | |||||
} else { | |||||
// Create a FreeMarker configuration | |||||
val configuration = Configuration(Configuration.VERSION_2_3_32) | |||||
// Create a template loader and add the template content | |||||
val templateLoader = StringTemplateLoader() | |||||
templateLoader.putTemplate("myTemplate", mailRequest.templateContent) | |||||
configuration.templateLoader = templateLoader | |||||
try { | |||||
// Get the template by name | |||||
template = configuration.getTemplate("myTemplate") | |||||
} catch (e: IOException) { | |||||
// Handle any IO exceptions | |||||
} | |||||
} | |||||
helper.setText( | |||||
FreeMarkerTemplateUtils.processTemplateIntoString(template!!, mailRequest.args), | |||||
true | |||||
) | |||||
val from: InternetAddress?; | |||||
if (mailRequest.from != null) { | |||||
helper.setFrom(mailRequest.from!!) | |||||
from = mailRequest.from | |||||
} else { | |||||
helper.setFrom(settingsService.getString(SettingNames.MAIL_SMTP_USERNAME)) | |||||
from = InternetAddress(settingsService.getString(SettingNames.MAIL_SMTP_USERNAME)) | |||||
} | |||||
if (mailRequest.priority != null) helper.setPriority(mailRequest.priority!!) | |||||
if (mailRequest.replyTo != null) helper.setReplyTo(mailRequest.replyTo!!) | |||||
if (mailRequest.to.isNotEmpty()) helper.setTo( | |||||
mailRequest.to.toTypedArray() | |||||
) | |||||
if (mailRequest.cc.isNotEmpty()) helper.setCc( | |||||
mailRequest.cc.toTypedArray() | |||||
) | |||||
if (mailRequest.bcc.isNotEmpty()) helper.setBcc( | |||||
mailRequest.bcc.toTypedArray() | |||||
) | |||||
if (mailRequest.attachments.isNotEmpty()) { | |||||
for ((key, value) in mailRequest.attachments.entries) { | |||||
helper.addAttachment(key, ByteArrayResource(value)) | |||||
} | |||||
} | |||||
if (from != null) { | |||||
sender.send(mimeMessage) | |||||
} | |||||
} | |||||
} | |||||
@Throws(ParseException::class) | |||||
fun send(mailRequests: List<MailRequest>, locale: Locale) { | |||||
try { | |||||
doSend(mailRequests, locale) | |||||
} catch (e: MessagingException) { | |||||
throw InternalServerErrorException(ErrorCodes.SEND_EMAIL_ERROR, e) | |||||
} catch (e: IOException) { | |||||
throw InternalServerErrorException(ErrorCodes.SEND_EMAIL_ERROR, e) | |||||
} catch (e: TemplateException) { | |||||
throw InternalServerErrorException(ErrorCodes.SEND_EMAIL_ERROR, e) | |||||
} | |||||
} | |||||
@Throws(ParseException::class) | |||||
fun send(mailRequests: List<MailRequest>) { | |||||
send(mailRequests, LocaleUtils.getLocale()) | |||||
} | |||||
@Throws(ParseException::class) | |||||
fun send(mailRequest: MailRequest, locale: Locale) { | |||||
send(mutableListOf(mailRequest), locale) | |||||
} | |||||
@Async | |||||
@Throws(ParseException::class) | |||||
open fun asyncSend(mailRequests: List<MailRequest>, locale: Locale) { | |||||
try { | |||||
doSend(mailRequests, locale) | |||||
} catch (e: MessagingException) { | |||||
logger.error("send email error", e) | |||||
} catch (e: IOException) { | |||||
logger.error("send email error", e) | |||||
} catch (e: TemplateException) { | |||||
logger.error("send email error", e) | |||||
} | |||||
} | |||||
@Async | |||||
@Throws(ParseException::class) | |||||
open fun asyncSend(mailRequest: MailRequest, locale: Locale) { | |||||
asyncSend(mutableListOf(mailRequest), locale) | |||||
} | |||||
@Async | |||||
@Throws(ParseException::class) | |||||
open fun asyncSend(mailRequests: List<MailRequest>) { | |||||
asyncSend(mailRequests, LocaleUtils.getLocale()) | |||||
} | |||||
@Async | |||||
@Throws(ParseException::class) | |||||
open fun asyncSend(mailRequest: MailRequest) { | |||||
asyncSend(mutableListOf(mailRequest)) | |||||
} | |||||
open fun saveMail(mailSave: MailSave): List<Settings> { | |||||
// ------------------ save mail settings ------------------ // | |||||
val settings = mutableListOf<Settings>() | |||||
mailSave.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) | |||||
return settings | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
package com.ffii.fpsms.modules.common.mail.web | |||||
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.settings.entity.Settings | |||||
import com.ffii.fpsms.modules.settings.service.SettingsService | |||||
import jakarta.validation.Valid | |||||
import org.springframework.web.bind.annotation.* | |||||
@RestController | |||||
@RequestMapping("/mails") | |||||
class MailController( | |||||
private val settingsService: SettingsService, | |||||
private val mailService: MailService, | |||||
private val mailReminderService: MailReminderService, | |||||
) { | |||||
@GetMapping("/setting") | |||||
fun mailSetting(): List<Settings> { | |||||
return settingsService.findAllByCategory("MAIL") | |||||
} | |||||
@PostMapping("/save") | |||||
fun saveMail(@Valid @RequestBody mailSave: MailSave): List<Settings> { | |||||
return mailService.saveMail(mailSave) | |||||
} | |||||
} |
@@ -0,0 +1,21 @@ | |||||
package com.ffii.fpsms.modules.common.mail.web.models | |||||
data class Setting ( | |||||
val id: Long, | |||||
val name: String, | |||||
val value: String, | |||||
val category: String, | |||||
val type: String, | |||||
) | |||||
data class Template ( | |||||
val cc: String?, | |||||
val bcc: String?, | |||||
val subject: String, | |||||
val template: String?, | |||||
) | |||||
data class MailSave ( | |||||
val settings: List<Setting>, | |||||
val template: Template | |||||
) |
@@ -0,0 +1,9 @@ | |||||
package com.ffii.fpsms.modules.common.mail.web.models | |||||
import java.time.LocalDate | |||||
data class WorkHourRecords( | |||||
val staffId: Long, | |||||
val recordDate: LocalDate, | |||||
val hours: Double, | |||||
) |
@@ -1,5 +1,6 @@ | |||||
package com.ffii.fpsms.modules.settings.entity; | package com.ffii.fpsms.modules.settings.entity; | ||||
import java.util.List; | |||||
import java.util.Optional; | import java.util.Optional; | ||||
import org.springframework.data.repository.query.Param; | import org.springframework.data.repository.query.Param; | ||||
@@ -9,4 +10,6 @@ import com.ffii.core.support.AbstractRepository; | |||||
public interface SettingsRepository extends AbstractRepository<Settings, Long> { | public interface SettingsRepository extends AbstractRepository<Settings, Long> { | ||||
Optional<Settings> findByName(@Param("name") String name); | Optional<Settings> findByName(@Param("name") String name); | ||||
List<Settings> findAllByCategory(@Param("category") String category); | |||||
} | } |
@@ -5,6 +5,7 @@ import java.time.LocalDateTime; | |||||
import java.time.LocalTime; | import java.time.LocalTime; | ||||
import java.time.format.DateTimeFormatter; | import java.time.format.DateTimeFormatter; | ||||
import java.time.format.DateTimeParseException; | import java.time.format.DateTimeParseException; | ||||
import java.util.List; | |||||
import java.util.Optional; | import java.util.Optional; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
@@ -29,6 +30,10 @@ public class SettingsService extends AbstractIdEntityService<Settings, Long, Set | |||||
return this.repository.findByName(name); | return this.repository.findByName(name); | ||||
} | } | ||||
public List<Settings> findAllByCategory(String category) { | |||||
return this.repository.findAllByCategory(category); | |||||
} | |||||
public boolean validateType(String type, String value) { | public boolean validateType(String type, String value) { | ||||
if (StringUtils.isBlank(type)) return true; | if (StringUtils.isBlank(type)) return true; | ||||
@@ -0,0 +1,13 @@ | |||||
-- liquibase formatted sql | |||||
-- changeset cyril:settings | |||||
INSERT INTO settings (id,name,value,category,`type`) | |||||
VALUES (7,'MAIL.smtp.host','smtp.office365.com','MAIL','string'); | |||||
INSERT INTO settings (id,name,value,category,`type`) | |||||
VALUES (8,'MAIL.smtp.port','587','MAIL','integer'); | |||||
INSERT INTO settings (id,name,value,category,`type`) | |||||
VALUES (9,'MAIL.smtp.username','','MAIL','string'); | |||||
INSERT INTO settings (id,name,value,category,`type`) | |||||
VALUES (10,'MAIL.smtp.password','','MAIL','string'); | |||||
INSERT INTO settings (id,name,value,category,`type`) | |||||
VALUES (11,'MAIL.smtp.auth','false','MAIL','boolean'); |