From 3d7168ad28ea3572391d0da723718b1070b28579 Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Fri, 19 Dec 2025 14:57:46 +0800 Subject: [PATCH] upate import bom function --- .../modules/master/service/BomService.kt | 136 +++++++++++++++--- 1 file changed, 116 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt index 7aad3c4..a590d84 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt @@ -16,6 +16,8 @@ import java.nio.file.Path import java.nio.file.Paths import java.nio.file.Files; import java.nio.file.StandardCopyOption +import com.ffii.fpsms.modules.master.entity.EquipmentDetailRepository + @Service open class BomService( @@ -29,6 +31,7 @@ open class BomService( private val uomConversionRepository: UomConversionRepository, private val equipmentRepository: EquipmentRepository, private val processRepository: ProcessRepository, + private val equipmentDetailRepository: EquipmentDetailRepository, ) { open fun findAll(): List { return bomRepository.findAll() @@ -97,6 +100,8 @@ open class BomService( this.isDense = req.isDense this.code = req.code this.scrapRate = req.scrapRate + this.timeSequence = req.timeSequence + this.complexity = req.complexity this.allergicSubstances = req.allergicSubstances this.name = req.name this.description = req.description @@ -263,7 +268,7 @@ open class BomService( description = "", ) var startRowIndex = 0 - val endRowIndex = 8 + val endRowIndex = 10 var startColumnIndex = 0 val endColumnIndex = 9 while (startRowIndex != endRowIndex || startColumnIndex != endColumnIndex) { @@ -328,6 +333,7 @@ open class BomService( } when { + //use fix row column by index not by search value contain later tempCellVal.contains("深淺") -> request.isDark = calculateColourScore(getCellValueAsString(leftTargetValueCell)) tempCellVal.contains("浮沉") -> request.isFloat = calculateFloatScore(getCellValueAsString(leftTargetValueCell)) tempCellVal.contains("過敏原 (如有)") -> request.allergicSubstances = calculateAllergicSubstancesScore(getCellValueAsString(leftTargetValueCell)) @@ -337,8 +343,15 @@ open class BomService( tempCellVal.contains("損耗率") -> request.scrapRate = if (leftTargetValueCell?.cellType == CellType.NUMERIC) leftTargetValueCell.numericCellValue.toInt() else 0 + tempCellVal.contains("生產先後次序") -> request.timeSequence = if (leftTargetValueCell?.cellType == CellType.NUMERIC) + leftTargetValueCell.numericCellValue.toInt() + else 0 + tempCellVal.contains("複雜度") -> request.complexity = if (leftTargetValueCell?.cellType == CellType.NUMERIC) + leftTargetValueCell.numericCellValue.toInt() + else 0 } } + if (startRowIndex < endRowIndex) { startRowIndex++ } else if (startColumnIndex < endColumnIndex) { @@ -349,19 +362,61 @@ open class BomService( return saveBomEntity(request) } - private fun bomGetOrCreateEquipment(name: String): Equipment { - var equipment = equipmentRepository.findByNameAndDeletedIsFalse(name) - ?: equipmentRepository.findByCodeAndDeletedIsFalse(name) + private fun generateNextTMPEquipmentCode(): String { + // 查询所有未删除的 EquipmentDetail + val allEquipmentDetails = equipmentDetailRepository.findAllByDeletedFalse() + + // 过滤出以 "TMP" 开头的 equipmentCode,并提取数字部分 + val tmpNumbers = allEquipmentDetails + .mapNotNull { it.equipmentCode } + .filter { it.startsWith("TMP") } + .mapNotNull { code -> + // 提取 TMP 后面的数字部分(例如:TMP01 -> 1, TMP02 -> 2) + val numberPart = code.substring(3).trim() + numberPart.toIntOrNull() + } + + // 找到最大编号,如果没有则从 0 开始 + val maxNumber = tmpNumbers.maxOrNull() ?: 0 + + // 递增并格式化为两位数(TMP01, TMP02, ...) + val nextNumber = maxNumber + 1 + return "TMP${nextNumber.toString().padStart(2, '0')}" + } + private fun bomGetOrCreateEquipment(equipmentName: String): Equipment { + var equipment = equipmentRepository.findByNameAndDeletedIsFalse(equipmentName) + ?: equipmentRepository.findByCodeAndDeletedIsFalse(equipmentName) + + var equipment_detail = equipmentDetailRepository.findByNameAndDeletedIsFalse(equipmentName) if (equipment == null) { + // 解析 XXX-YYY 格式 + val parts = equipmentName.split("-") + val firstPart = if (parts.size > 0) parts[0] else equipmentName // XXX + val secondPart = if (parts.size > 1) parts[1] else "" // YYY + + // 创建 equipment equipment = Equipment().apply { - this.name = name - this.code = name - this.description = name + this.name = equipmentName // 完整值 XXX-YYY + this.code = secondPart + this.description = firstPart // XXX 写入 description } equipment = equipmentRepository.saveAndFlush(equipment) + + // 创建 equipment_detail + if (equipment_detail == null) { + val nextEquipmentCode = generateNextTMPEquipmentCode() + equipment_detail = EquipmentDetail().apply { + this.name = "1號" // 默认值 + this.description = equipmentName // equipmentName (完整值 XXX-YYY) + this.code = "${this.description}-$name" + this.equipmentCode=nextEquipmentCode + } + equipment_detail = equipmentDetailRepository.saveAndFlush(equipment_detail) + } } return equipment!! } + private fun bomGetOrCreateProcess(name: String): Process { var process = processRepository.findByNameAndDeletedIsFalse(name) ?: processRepository.findByCodeAndDeletedIsFalse(name) @@ -403,7 +458,7 @@ open class BomService( } private fun importExcelBomProcess(bom: Bom, sheet: Sheet) { var startRowIndex = 30 - val endRowIndex = 70 + var endRowIndex = 70 var startColumnIndex = 0 val endColumnIndex = 11 while (startRowIndex < endRowIndex) { @@ -416,6 +471,17 @@ open class BomService( } startRowIndex++ } + var searchRowIndex = startRowIndex + val maxSearchRow = 50 + while (searchRowIndex < maxSearchRow) { + val tempRow = sheet.getRow(searchRowIndex) + val tempCell = tempRow?.getCell(0) + if (tempCell == null || tempCell.cellType == CellType.BLANK) { + endRowIndex = searchRowIndex + break + } + searchRowIndex++ + } var bomProcessRequest = ImportBomProcessRequest( bom = bom ) @@ -439,25 +505,26 @@ open class BomService( // println("seqNo: ${tempCell.numericCellValue.toLong()}") // println("bomProcessRequest: $bomProcessRequest") } + 1 -> { - val equipmentName = tempCell.stringCellValue.trim() - if (equipmentName != "不適用") { - val equipment = bomGetOrCreateEquipment(equipmentName) -// println("equipment created") - bomProcessRequest.equipment = equipment - } - } - 2 -> { val processName = tempCell.stringCellValue.trim() val process = bomGetOrCreateProcess(processName) bomProcessRequest.process = process // println("process created") } - 3 -> { + 2 -> { val description = tempCell.stringCellValue.trim() bomProcessRequest.description = description } - 6 -> { //duration + 3 -> { + val equipmentName = tempCell.stringCellValue.trim() + if (equipmentName != "不適用") { + val equipment = bomGetOrCreateEquipment(equipmentName) +// println("equipment created") + bomProcessRequest.equipment = equipment + } + } + 5 -> { //duration when (tempCell.cellType) { CellType.NUMERIC -> { bomProcessRequest.durationInMinute = tempCell.numericCellValue.toInt() @@ -471,6 +538,35 @@ open class BomService( } } + /* + 5 -> { //processOutputQty + val processOutputQty = tempCell.stringCellValue.trim() + bomProcessRequest.processOutputQty = processOutputQty + + } + 6 -> { //processOutputUnit + val processOutputUnit = tempCell.stringCellValue.trim() + bomProcessRequest.processOutputUnit = processOutputUnit + + } + 7 -> { //byProductName + val byProductQty = tempCell.stringCellValue.trim() + bomProcessRequest.byProductQty = byProductQty + } + 8 -> { //byProductQty + val byProductUnit = tempCell.stringCellValue.trim() + bomProcessRequest.byProductUnit = byProductUnit + } + + 9 -> { //byProductUnit + val byProductUnit = tempCell.stringCellValue.trim() + bomProcessRequest.byProductUnit = byProductUnit + } + */ + 9 -> { //scrapRate + // val scrapRate = tempCell.stringCellValue.trim() + // bomProcessRequest.scrapRate = scrapRate + } 10 -> { //prepTimeInMinute when (tempCell.cellType) { CellType.NUMERIC -> { @@ -537,8 +633,8 @@ open class BomService( val resolver = PathMatchingResourcePatternResolver() // val excels = resolver.getResources("bomImport/*.xlsx") //val excels = resolver.getResources("file:C:/Users/Kelvin YAU/Downloads/bom/*.xlsx") - val excels = resolver.getResources("file:C:/Users/Kelvin YAU/Downloads/bom/*.xlsx") - //val excels = resolver.getResources("file:C:/Users/kw093/Downloads/bom/bom/*.xlsx") + //val excels = resolver.getResources("file:C:/Users/Kelvin YAU/Downloads/bom/*.xlsx") + val excels = resolver.getResources("file:C:/Users/kw093/Downloads/bom/bom/*.xlsx") // val excels = resolver.getResources("file:C:/Users/2Fi/Desktop/Third Wave of BOM Excel/*.xlsx") println("size: ${excels.size}") val logExcel = ClassPathResource("excelTemplate/bom_excel_issue_log.xlsx")