Просмотр исходного кода

[mail tempalte] add po mail template

master
cyril.tsui 3 дней назад
Родитель
Сommit
1ec389acfe
7 измененных файлов: 172 добавлений и 0 удалений
  1. +2
    -0
      src/main/java/com/ffii/fpsms/modules/common/mail/entity/MailTemplateRepository.kt
  2. +118
    -0
      src/main/java/com/ffii/fpsms/modules/common/mail/service/MailTemplateService.kt
  3. +19
    -0
      src/main/java/com/ffii/fpsms/modules/common/mail/web/MailTemplateController.kt
  4. +24
    -0
      src/main/java/com/ffii/fpsms/modules/common/mail/web/models/DownloadMailTemplateResponse.kt
  5. +3
    -0
      src/main/java/com/ffii/fpsms/modules/qc/entity/projection/QcResultInfo.kt
  6. +2
    -0
      src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotRepository.kt
  7. +4
    -0
      src/main/java/com/ffii/fpsms/modules/stock/service/InventoryLotService.kt

+ 2
- 0
src/main/java/com/ffii/fpsms/modules/common/mail/entity/MailTemplateRepository.kt Просмотреть файл

@@ -9,4 +9,6 @@ interface MailTemplateRepository : AbstractRepository<MailTemplate, Long> {
fun findAllByDeletedIsFalse(): List<MailTemplate>

fun findByIdAndDeletedIsFalse(id: Serializable): MailTemplate?

fun findByCodeAndDeletedIsFalse(code: String): MailTemplate?
}

+ 118
- 0
src/main/java/com/ffii/fpsms/modules/common/mail/service/MailTemplateService.kt Просмотреть файл

@@ -2,13 +2,29 @@ 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.DownloadMailTemplateResponse
import com.ffii.fpsms.modules.common.mail.web.models.MailTemplateRequest
import com.ffii.fpsms.modules.qc.service.QcResultService
import com.ffii.fpsms.modules.stock.entity.StockInLineRepository
import com.ffii.fpsms.modules.stock.service.InventoryLotService
import com.itextpdf.html2pdf.ConverterProperties
import com.itextpdf.html2pdf.HtmlConverter
import com.itextpdf.layout.font.FontProvider
import org.jsoup.Jsoup
import org.springframework.stereotype.Service
import java.io.ByteArrayOutputStream
import java.math.BigDecimal
import java.time.format.DateTimeFormatter
import kotlin.jvm.optionals.getOrNull

@Service
open class MailTemplateService(
private val mailTemplateRepository: MailTemplateRepository,
private val stockInLineRepository: StockInLineRepository,
private val inventoryLotService: InventoryLotService,
private val qcResultService: QcResultService
) {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
fun allMailTemplates(): List<MailTemplate> {
return mailTemplateRepository.findAllByDeletedIsFalse();
}
@@ -17,6 +33,10 @@ open class MailTemplateService(
return mailTemplateRepository.findByIdAndDeletedIsFalse(id);
}

fun findByCode(code: String): MailTemplate? {
return mailTemplateRepository.findByCodeAndDeletedIsFalse(code);
}

fun saveMailTemplate(request: MailTemplateRequest): MailTemplate {
val mailTemplate = request.id?.let { findById(it) } ?: MailTemplate()

@@ -59,4 +79,102 @@ open class MailTemplateService(

mailTemplateRepository.saveAll(mailTemplates)
}

fun getMailTemplateForStockInLine(stockInLineId: Long): DownloadMailTemplateResponse {
val emailTemplate = findByCode("RM-01") ?: throw NoSuchElementException("No RP-01 Email Template")
val stockInLine = stockInLineRepository.findById(stockInLineId).getOrNull() ?: throw NoSuchElementException("Cant find this stock in line.")

// Value
val zero = BigDecimal.ZERO
val po = stockInLine.purchaseOrder
val pol = stockInLine.purchaseOrderLine
val item = stockInLine.item
val supplierName = po?.supplier?.name ?: "N/A"
val supplierEmail = if((po?.supplier?.contactEmail).isNullOrEmpty()) "N/A" else po?.supplier?.contactEmail
val dnDate = formatter.format(stockInLine.dnDate) ?: "N/A"
val poNo = po?.code ?: "N/A"
val supplierId = po?.supplier?.code ?: "N/A" // Id?
val itemNo = item?.code ?: "N/A"
val itemQty = (pol?.qty ?: zero).toString()
val uom = pol?.uom?.udfudesc ?: "N/A"
val planDnDate = po?.estimatedArrivalDate?.let { formatter.format(it) } ?: "N/A"
val unitPrice = (pol?.up ?: zero).toString()
val receivedCompany = po?.shop?.name ?: "N/A"
val lotNo = stockInLine.productLotNo ?: "N/A"
var qcDate = "N/A"
val qcResult = qcResultService.getAllQcResultInfoByStockInLineId(stockInLineId).let { qcResults ->
val filteredResult = qcResults
.groupBy { Pair(it.stockInLineId, it.qcItemId) }
.mapValues { (_, group) ->
group.maxByOrNull { it.recordDate }
}
.values
.filterNotNull()
.filter { !it.qcPassed }
if (filteredResult.isNotEmpty()) {
qcDate = formatter.format(filteredResult.maxOf { it.recordDate })

val tempDoc = Jsoup.parse("")
val element = tempDoc.appendElement("ul")
for (result in filteredResult) {
element.appendElement("li")
.text("${result.name} - ${result.description}")
}
tempDoc.outerHtml()
} else {
"N/A"
}
} ?: "N/A"
val acceptedQty = (stockInLine.acceptedQty ?: zero).minus(stockInLine.demandQty ?: zero).toString()
val rejectedQty = (stockInLine.demandQty ?: zero).toString() // reject?
val nonDelieveredQty = (zero).toString()

// HTML
val to = supplierEmail
val toHtmlStr = Jsoup.parse("").appendElement("p").text("To: $to").outerHtml()

val subject = (emailTemplate.subjectCht ?: "N/A")
// .replace("{supplierName}", supplierName)
.replace("{poNo}", poNo)
.replace("{itemNo}", itemNo)
val subjectHtmlStr = Jsoup.parse("").appendElement("p").text("Subject: $subject").outerHtml()

val content = (emailTemplate.contentCht ?: "N/A")
.replace("{supplierName}", supplierName)
.replace("{dnDate}", dnDate)
.replace("{poNo}", poNo)
.replace("{supplierId}", supplierId)
.replace("{itemNo}", itemNo)
.replace("{itemQty}", itemQty)
.replace("{uom}", uom)
.replace("{planDnDate}", planDnDate)
.replace("{unitPrice}", unitPrice)
.replace("{receivedCompany}", receivedCompany)
.replace("{lotNo}", lotNo)
.replace("{qcResult}", qcResult)
.replace("{acceptedQty}", acceptedQty)
.replace("{nonDelieveredQty}", nonDelieveredQty)
.replace("{rejectedQty}", rejectedQty)
.replace("{qcDate}", qcDate)
val contentHtmlStr = Jsoup.parse("").appendElement("p").append("Content: $content").outerHtml()

// Result
val resultHtmlStr = toHtmlStr + subjectHtmlStr + contentHtmlStr
// println(resultHtmlStr)

val resultPdf = ByteArrayOutputStream()
val fp = FontProvider();
fp.addStandardPdfFonts()
fp.addFont("/fonts/msjh_0.ttf")
val converterProperties = ConverterProperties()
converterProperties.apply {
fontProvider = fp
}
HtmlConverter.convertToPdf(resultHtmlStr, resultPdf, converterProperties)

return DownloadMailTemplateResponse(
file = resultPdf.toByteArray(),
fileName = subject ?: "N/A"
);
}
}

+ 19
- 0
src/main/java/com/ffii/fpsms/modules/common/mail/web/MailTemplateController.kt Просмотреть файл

@@ -3,10 +3,15 @@ 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.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
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 java.net.URLEncoder

@RequestMapping("/mailTemplates")
@RestController
@@ -22,4 +27,18 @@ class MailTemplateController(
fun saveMailTemplate(request: MailTemplateRequest): MailTemplate {
return mailTemplateService.saveMailTemplate(request);
}

@GetMapping("/getMailTemplateForStockInLine/{stockInLineId}")
fun getMailTemplateForStockInLine(@PathVariable stockInLineId: Long): ResponseEntity<ByteArray> {
val response = mailTemplateService.getMailTemplateForStockInLine(stockInLineId)
val headers = HttpHeaders().apply {
contentType = MediaType.APPLICATION_PDF
// add("Content-Disposition", "attachment; filename=${response.fileName}")
add("filename", "${response.fileName}.pdf")
}

return ResponseEntity.ok()
.headers(headers)
.body(response.file)
}
}

+ 24
- 0
src/main/java/com/ffii/fpsms/modules/common/mail/web/models/DownloadMailTemplateResponse.kt Просмотреть файл

@@ -0,0 +1,24 @@
package com.ffii.fpsms.modules.common.mail.web.models

data class DownloadMailTemplateResponse(
val file: ByteArray,
val fileName: String,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as DownloadMailTemplateResponse

if (!file.contentEquals(other.file)) return false
if (fileName != other.fileName) return false

return true
}

override fun hashCode(): Int {
var result = file.contentHashCode()
result = 31 * result + fileName.hashCode()
return result
}
}

+ 3
- 0
src/main/java/com/ffii/fpsms/modules/qc/entity/projection/QcResultInfo.kt Просмотреть файл

@@ -1,6 +1,7 @@
package com.ffii.fpsms.modules.qc.entity.projection

import org.springframework.beans.factory.annotation.Value
import java.time.LocalDateTime

interface QcResultInfo {
val id: Long
@@ -19,4 +20,6 @@ interface QcResultInfo {
val stockOutLineId: Long?
val failQty: Double?
val qcPassed: Boolean
@get:Value("#{target.modified}")
val recordDate: LocalDateTime
}

+ 2
- 0
src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotRepository.kt Просмотреть файл

@@ -2,7 +2,9 @@ package com.ffii.fpsms.modules.stock.entity

import com.ffii.core.support.AbstractRepository
import org.springframework.stereotype.Repository
import java.io.Serializable

@Repository
interface InventoryLotRepository: AbstractRepository<InventoryLot, Long> {
fun findByStockInLineIdAndDeletedFalse(stockInLineId: Serializable): InventoryLot?
}

+ 4
- 0
src/main/java/com/ffii/fpsms/modules/stock/service/InventoryLotService.kt Просмотреть файл

@@ -20,6 +20,10 @@ open class InventoryLotService(
private val inventoryLotRepository: InventoryLotRepository,
): AbstractBaseEntityService<InventoryLot, Long, InventoryLotRepository>(jdbcDao, inventoryLotRepository) {

open fun findByStockInLineId(stockInLineId: Long): InventoryLot? {
return inventoryLotRepository.findByStockInLineIdAndDeletedFalse(stockInLineId)
}

@Throws(IOException::class)
@Transactional
open fun createOrUpdate(request: SaveInventoryRequest): MessageResponse {


Загрузка…
Отмена
Сохранить