Explorar el Código

improt bom fix

production
CANCERYS\kw093 hace 2 semanas
padre
commit
51bb08e2f2
Se han modificado 2 ficheros con 60 adiciones y 9 borrados
  1. +3
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt
  2. +57
    -9
      src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt

+ 3
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt Ver fichero

@@ -33,6 +33,9 @@ interface BomRepository : AbstractRepository<Bom, Long> {
fun findAllIdsByDeletedIsFalse(): List<Long>

fun findByCodeAndDeletedIsFalse(code: String): Bom?

fun findByCodeAndDescriptionIgnoreCaseAndDeletedIsFalse(code: String, description: String): Bom?

@Query("""
select b.item.id
from Bom b


+ 57
- 9
src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt Ver fichero

@@ -68,6 +68,10 @@ open class BomService(
private val settingsService: SettingsService,
@Value("\${bom.import.temp-dir:\${java.io.tmpdir}/fpsms-bom-import}") private val bomImportTempDir: String,
) {
companion object {
private const val BOM_WIP_DESCRIPTION = "WIP"
}

open fun uploadBomFiles(files: List<MultipartFile>): BomUploadResponse {
val batchId = UUID.randomUUID().toString()
val batchDir = Paths.get(bomImportTempDir, batchId).toAbsolutePath()
@@ -580,7 +584,8 @@ open class BomService(
private fun saveBomEntity(req: ImportBomRequest): Bom {
val item = itemsRepository.findByCodeAndDeletedFalse(req.code) ?: itemsRepository.findByNameAndDeletedFalse(req.name)
val uom = if (req.uomId != null) uomConversionRepository.findById(req.uomId!!).orElseThrow() else null
val bom = bomRepository.findByCodeAndDeletedIsFalse(req.code) ?: Bom()
val fgDescription = req.description.trim().ifEmpty { "FG" }
val bom = bomRepository.findByCodeAndDescriptionIgnoreCaseAndDeletedIsFalse(req.code, fgDescription) ?: Bom()
bom.apply {
this.isDark = req.isDark
this.isFloat = req.isFloat
@@ -1576,6 +1581,45 @@ open class BomService(
return null
}

/** Reads BOM 種類 (FG / WIP) from sheet without saving. */
private fun readBomDescriptionFromSheet(sheet: Sheet): String? {
for (r in 0..9) {
for (c in 0..9) {
val cell = sheet.getRow(r)?.getCell(c) ?: continue
if (cell.cellType != CellType.STRING) continue
if (cell.stringCellValue.trim() != "種類") continue
val valueRow = sheet.getRow(r + 1) ?: return null
val valueCell = valueRow.getCell(c) ?: return null
return when {
valueCell.cellType == CellType.STRING -> valueCell.stringCellValue.trim().takeIf { it.isNotEmpty() }
valueCell.cellType == CellType.FORMULA && valueCell.cachedFormulaResultType == CellType.STRING ->
valueCell.stringCellValue.trim().takeIf { it.isNotEmpty() }
else -> null
}
}
}
return null
}

private fun normalizeFgDescriptionForImport(description: String?): String =
description?.trim()?.takeIf { it.isNotEmpty() } ?: "FG"

/** Soft-delete FG (code + Excel 種類) and WIP (code + WIP) rows before re-import. */
private fun softDeleteExistingBomsForImport(code: String, fgDescription: String) {
val fgDesc = normalizeFgDescriptionForImport(fgDescription)
bomRepository.findByCodeAndDescriptionIgnoreCaseAndDeletedIsFalse(code, fgDesc)?.id?.let {
softDeleteBomAndRelated(it)
}
bomRepository.findByCodeAndDescriptionIgnoreCaseAndDeletedIsFalse(code, BOM_WIP_DESCRIPTION)?.id?.let {
softDeleteBomAndRelated(it)
}
}

private fun findFgBomIdForImport(code: String, fgDescription: String): Long? {
val fgDesc = normalizeFgDescriptionForImport(fgDescription)
return bomRepository.findByCodeAndDescriptionIgnoreCaseAndDeletedIsFalse(code, fgDesc)?.id
}

private fun softDeleteBomAndRelated(bomId: Long) {
val bom = bomRepository.findById(bomId).orElse(null) ?: return
bom.deleted = true
@@ -1633,12 +1677,11 @@ open class BomService(
?: workbook2.getSheet("食物成品")
?: workbook2.getSheetAt(0)
val code = readBomCodeFromSheet(sheet)
val fgDescription = readBomDescriptionFromSheet(sheet)
var oldBomId: Long? = null
code?.let { c ->
bomRepository.findByCodeAndDeletedIsFalse(c)?.id?.let { existingId ->
softDeleteBomAndRelated(existingId)
oldBomId = existingId
}
oldBomId = findFgBomIdForImport(c, fgDescription ?: "FG")
softDeleteExistingBomsForImport(c, fgDescription ?: "FG")
}
val bom = importExcelBomBasicInfo(sheet)
bom.isDrink = isDrink
@@ -1705,10 +1748,15 @@ open class BomService(
}
/** 方案 A:複製 FG BOM 為一筆相同 code、相同 item、description=WIP 的 BOM,並複製 materials 與 processes。 */
private fun createWipCopyFromFgBom(fgBom: Bom) {
val code = fgBom.code ?: return
val existingWip = bomRepository.findByCodeAndDescriptionIgnoreCaseAndDeletedIsFalse(code, BOM_WIP_DESCRIPTION)
if (existingWip != null) {
softDeleteBomAndRelated(existingWip.id!!)
}
val wipBom = Bom().apply {
code = fgBom.code
this.code = code
name = fgBom.name
description = "WIP"
description = BOM_WIP_DESCRIPTION
item = fgBom.item
outputQty = fgBom.outputQty
outputQtyUom = fgBom.outputQtyUom
@@ -2364,7 +2412,7 @@ open class BomService(
var ColorDepthValueOk = false
var FloatingValueOk = false
var ConcentrationValueOk = false
println("=== Debug sheet content for $fileName ===")
// println("=== Debug sheet content for $fileName ===")
for (r in 0..20) {
val row = sheet.getRow(r) ?: continue
for (c in 0..20) {
@@ -2383,7 +2431,7 @@ for (r in 0..20) {
else -> cell.cellType.toString()
}
if (value.isNotBlank() && value != "BLANK") {
println("($r, $c) = $value")
// println("($r, $c) = $value")
}
}
}


Cargando…
Cancelar
Guardar