diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt index 4360004..d8ecfb5 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt @@ -80,4 +80,7 @@ open class Bom : BaseEntity() { @Column(name = "m18LastModifyDate") open var m18LastModifyDate: LocalDateTime? = null + + @Column(name = "baseScore", precision = 14, scale = 2) + open var baseScore: BigDecimal? = null } \ No newline at end of file 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 db74f18..81579fa 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 @@ -17,6 +17,9 @@ import java.nio.file.Paths import java.nio.file.Files; import java.nio.file.StandardCopyOption import com.ffii.fpsms.modules.master.entity.EquipmentDetailRepository +import com.ffii.fpsms.modules.settings.entity.BomWeightingScoreRepository +import java.math.BigDecimal +import java.math.RoundingMode @Service @@ -32,6 +35,7 @@ open class BomService( private val equipmentRepository: EquipmentRepository, private val processRepository: ProcessRepository, private val equipmentDetailRepository: EquipmentDetailRepository, + private val bomWeightingScoreRepository: BomWeightingScoreRepository, ) { open fun findAll(): List { return bomRepository.findAll() @@ -112,6 +116,7 @@ open class BomService( this.uom = uom // this.excelUom = req.excelUom } + bom.baseScore = calculateBaseScore(bom) val savedBom = bomRepository.saveAndFlush(bom) // println("saved: ${savedBom.id}") return savedBom @@ -337,8 +342,12 @@ 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.isDark = if (leftTargetValueCell?.cellType == CellType.NUMERIC) + leftTargetValueCell.numericCellValue.toInt() + else 0 + tempCellVal.contains("浮沉") -> request.isFloat = if (leftTargetValueCell?.cellType == CellType.NUMERIC) + leftTargetValueCell.numericCellValue.toInt() + else 0 tempCellVal.contains("過敏原 (如有)") -> request.allergicSubstances = calculateAllergicSubstancesScore(getCellValueAsString(leftTargetValueCell)) tempCellVal.contains("濃淡") -> request.isDense = if (leftTargetValueCell?.cellType == CellType.NUMERIC) leftTargetValueCell.numericCellValue.toInt() @@ -622,6 +631,50 @@ open class BomService( } } } + + /** + * Calculates baseScore from BOM basic info using bom_weighting_score (code = BOM column name). + * For isDark, isFloat, isDense, allergicSubstances, timeSequence, complexity: (extractedScore / range) * weighting * 100. + * For equipmentConflict: weighting * 100 only. + */ + private fun calculateBaseScore(bom: Bom): BigDecimal { + val scale = 2 + val roundingMode = RoundingMode.HALF_UP + var sum = BigDecimal.ZERO.setScale(scale, roundingMode) + + // Score columns: contribution = (extractedScore / range) * weighting * 100 + val scoreColumns = listOf( + "isDark" to (bom.isDark?.toBigDecimal() ?: BigDecimal.ZERO), + "isFloat" to (bom.isFloat?.toBigDecimal() ?: BigDecimal.ZERO), + "isDense" to (bom.isDense?.toBigDecimal() ?: BigDecimal.ZERO), + "allergicSubstances" to (bom.allergicSubstances?.toBigDecimal() ?: BigDecimal.ZERO), + "timeSequence" to (bom.timeSequence?.toBigDecimal() ?: BigDecimal.ZERO), + "complexity" to (bom.complexity?.toBigDecimal() ?: BigDecimal.ZERO), + ) + for ((code, extractedScore) in scoreColumns) { + val row = bomWeightingScoreRepository.findByCodeAndDeletedFalse(code) ?: continue + val range = (row.range ?: 1).toBigDecimal() + val weighting = row.weighting ?: continue + if (range.compareTo(BigDecimal.ZERO) == 0) continue + val contribution = extractedScore + .divide(range, scale, roundingMode) + .multiply(weighting) + .multiply(BigDecimal(100)) + .setScale(scale, roundingMode) + sum = sum.add(contribution) + } + + // equipmentConflict: contribution = weighting * 100 only + val equipmentConflictRow = bomWeightingScoreRepository.findByCodeAndDeletedFalse("equipmentConflict") + if (equipmentConflictRow?.weighting != null) { + val contribution = equipmentConflictRow.weighting!! + .multiply(BigDecimal(100)) + .setScale(scale, roundingMode) + sum = sum.add(contribution) + } + + return sum.setScale(scale, roundingMode) + } open fun exportProblematicBOM() { val resolver = PathMatchingResourcePatternResolver() val successExcel = resolver.getResources("file:C:/Users/2Fi/Desktop/fail/*.xlsx") diff --git a/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScore.kt b/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScore.kt index f82fcc9..4de712c 100644 --- a/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScore.kt +++ b/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScore.kt @@ -10,9 +10,12 @@ import java.math.BigDecimal @Entity open class BomWeightingScore: BaseEntity() { @Column - open var name: String? = null + open var code: String? = null @Column + open var name: String? = null + + @Column(name = "`range`") open var range: Int? = null @Column diff --git a/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScoreRepository.kt b/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScoreRepository.kt index 70f17cf..5538e2b 100644 --- a/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScoreRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/settings/entity/BomWeightingScoreRepository.kt @@ -3,4 +3,5 @@ package com.ffii.fpsms.modules.settings.entity import com.ffii.core.support.AbstractRepository interface BomWeightingScoreRepository: AbstractRepository { + fun findByCodeAndDeletedFalse(code: String): BomWeightingScore? } \ No newline at end of file diff --git a/src/main/resources/db/changelog/changes/20260202_KelvinY/01_add_baseScore_to_bom.sql b/src/main/resources/db/changelog/changes/20260202_KelvinY/01_add_baseScore_to_bom.sql new file mode 100644 index 0000000..64b6cfb --- /dev/null +++ b/src/main/resources/db/changelog/changes/20260202_KelvinY/01_add_baseScore_to_bom.sql @@ -0,0 +1,5 @@ +-- liquibase formatted sql +-- changeset KelvinY:add_baseScore_to_bom + +ALTER TABLE `fpsmsdb`.`bom` + ADD COLUMN `baseScore` DECIMAL(14, 2) NULL DEFAULT NULL AFTER `complexity`; \ No newline at end of file