|
|
@@ -1,10 +1,7 @@ |
|
|
|
package com.ffii.fpsms.modules.master.service |
|
|
|
|
|
|
|
import com.ffii.fpsms.modules.master.entity.* |
|
|
|
import com.ffii.fpsms.modules.master.web.models.ImportBomMatRequest |
|
|
|
import com.ffii.fpsms.modules.master.web.models.ImportBomRequest |
|
|
|
import com.ffii.fpsms.modules.master.web.models.SaveBomRequest |
|
|
|
import com.ffii.fpsms.modules.master.web.models.SaveBomResponse |
|
|
|
import com.ffii.fpsms.modules.master.web.models.* |
|
|
|
import org.apache.poi.ss.usermodel.CellType |
|
|
|
import org.apache.poi.ss.usermodel.Sheet |
|
|
|
import org.apache.poi.ss.usermodel.Workbook |
|
|
@@ -17,17 +14,17 @@ import java.io.File |
|
|
|
|
|
|
|
@Service |
|
|
|
open class BomService( |
|
|
|
val bomRepository: BomRepository, |
|
|
|
val bomMaterialRepository: BomMaterialRepository, |
|
|
|
val itemsService: ItemsService, |
|
|
|
val itemsRepository: ItemsRepository, |
|
|
|
val uomConversionService: UomConversionService, |
|
|
|
val uomConversionRepository: UomConversionRepository |
|
|
|
private val bomRepository: BomRepository, |
|
|
|
private val bomMaterialRepository: BomMaterialRepository, |
|
|
|
private val bomProcessRepository: BomProcessRepository, |
|
|
|
private val bomProcessMaterialRepository: BomProcessMaterialRepository, |
|
|
|
private val itemsService: ItemsService, |
|
|
|
private val itemsRepository: ItemsRepository, |
|
|
|
private val uomConversionService: UomConversionService, |
|
|
|
private val uomConversionRepository: UomConversionRepository, |
|
|
|
private val equipmentRepository: EquipmentRepository, |
|
|
|
private val processRepository: ProcessRepository, |
|
|
|
) { |
|
|
|
private val COMPLETION_PROJECT = "templates/report/AR05_Project Completion Report.xlsx" |
|
|
|
private val EXCEL_PATH = "bomImport/006 PP1080 咖喱汁 Pings BOM Template v3.xlsx" |
|
|
|
// private val EXCEL_PATH = "C:\\Users\\2Fi\\Documents\\MTMS\\Ping's Production MTMS Project Folder\\模組2_生產規劃 (Production Planning)\\PP1080 咖哩汁 Bom\\006 PP1080 咖喱汁 Pings BOM Template v3.xlsx" |
|
|
|
|
|
|
|
open fun findAll(): List<Bom> { |
|
|
|
return bomRepository.findAll() |
|
|
|
} |
|
|
@@ -81,7 +78,7 @@ open class BomService( |
|
|
|
} |
|
|
|
|
|
|
|
//////// -------------------------------- for excel import ------------------------------- ///////// |
|
|
|
fun saveBomEntity(req: ImportBomRequest): Bom { |
|
|
|
private fun saveBomEntity(req: ImportBomRequest): Bom { |
|
|
|
val item = if (req.itemId != null) itemsRepository.findById(req.itemId).orElseThrow() else null |
|
|
|
val uom = if (req.uomId != null) uomConversionRepository.findById(req.uomId).orElseThrow() else null |
|
|
|
val bom = Bom().apply { |
|
|
@@ -115,14 +112,35 @@ open class BomService( |
|
|
|
} |
|
|
|
return bomMaterialRepository.saveAndFlush(bomMaterial) |
|
|
|
} |
|
|
|
fun importExcelBomMaterial(bom: Bom, sheet: Sheet) { |
|
|
|
var request = ImportBomMatRequest( |
|
|
|
fun saveBomProcess(req: ImportBomProcessRequest): BomProcess { |
|
|
|
val bomProcess = BomProcess().apply { |
|
|
|
this.process = req.process |
|
|
|
this.equipment = req.equipment |
|
|
|
this.description = req.description |
|
|
|
this.seqNo = req.seqNo |
|
|
|
this.duration = req.duration |
|
|
|
this.prepTimeInMinute = req.prepTimeInMinute |
|
|
|
this.postProdTimeInMinute = req.postProdTimeInMinute |
|
|
|
this.bom = req.bom |
|
|
|
} |
|
|
|
return bomProcessRepository.saveAndFlush(bomProcess) |
|
|
|
} |
|
|
|
fun saveBomProcessMaterial(req: ImportBomProcessMaterialRequest): BomProcessMaterial { |
|
|
|
val bomProcessMaterial = BomProcessMaterial().apply { |
|
|
|
this.bomProcess = req.bomProcess |
|
|
|
this.bomMaterial = req.bomMaterial |
|
|
|
} |
|
|
|
return bomProcessMaterialRepository.saveAndFlush(bomProcessMaterial) |
|
|
|
} |
|
|
|
private fun importExcelBomMaterial(bom: Bom, sheet: Sheet) { |
|
|
|
var bomMatRequest = ImportBomMatRequest( |
|
|
|
bom = bom |
|
|
|
) |
|
|
|
var bomProcessMatRequest = ImportBomProcessMaterialRequest() |
|
|
|
var startRowIndex = 10 |
|
|
|
val endRowIndex = 30 |
|
|
|
var startColumnIndex = 0 |
|
|
|
val endColumnIndex = 9 |
|
|
|
val endColumnIndex = 10 |
|
|
|
while (startRowIndex < endRowIndex) { |
|
|
|
val tempRow = sheet.getRow(startRowIndex) |
|
|
|
val tempCell = tempRow.getCell(startColumnIndex) |
|
|
@@ -142,31 +160,41 @@ open class BomService( |
|
|
|
try { |
|
|
|
when (startColumnIndex) { |
|
|
|
0 -> { |
|
|
|
// println("start") |
|
|
|
// println("rowIndex: $startRowIndex") |
|
|
|
val nameRow = sheet.getRow(startRowIndex) |
|
|
|
val nameCell = nameRow.getCell(1) |
|
|
|
println(tempCell.stringCellValue.trim()) |
|
|
|
val item = itemsRepository.findByCodeAndDeletedFalse(tempCell.stringCellValue.trim()) |
|
|
|
?: itemsRepository.findByNameAndDeletedFalse(nameCell.stringCellValue.trim()) |
|
|
|
// println("getting item.....:") |
|
|
|
// println(item) |
|
|
|
request.apply { |
|
|
|
bomMatRequest.apply { |
|
|
|
this.item = item |
|
|
|
} |
|
|
|
} |
|
|
|
2 -> { |
|
|
|
request.apply { |
|
|
|
bomMatRequest.apply { |
|
|
|
this.qty = tempCell.numericCellValue.toBigDecimal() |
|
|
|
} |
|
|
|
} |
|
|
|
3 -> { |
|
|
|
request.apply { |
|
|
|
bomMatRequest.apply { |
|
|
|
this.uomName = tempCell.stringCellValue.trim() |
|
|
|
} |
|
|
|
} |
|
|
|
10 -> { |
|
|
|
val bomProcess = bomProcessRepository.findBySeqNoAndBomIdAndDeletedIsFalse( |
|
|
|
seqNo = tempCell.numericCellValue.toInt(), |
|
|
|
bomId = bom.id!! |
|
|
|
)!! // if null = bugged |
|
|
|
bomProcessMatRequest.apply { |
|
|
|
this.bomProcess = bomProcess |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} catch(e: Error) { |
|
|
|
println(startColumnIndex) |
|
|
|
println(startRowIndex) |
|
|
|
println(tempCell.stringCellValue.trim()) |
|
|
|
println("DEBUG ERROR:") |
|
|
|
println(e) |
|
|
|
} |
|
|
|
} |
|
|
|
if (startColumnIndex < endColumnIndex) { |
|
|
@@ -174,11 +202,14 @@ open class BomService( |
|
|
|
} else if (startRowIndex < endRowIndex) { |
|
|
|
startRowIndex++ |
|
|
|
// do save |
|
|
|
saveBomMaterial(request) |
|
|
|
val bomMaterial = saveBomMaterial(bomMatRequest) |
|
|
|
bomProcessMatRequest.apply { |
|
|
|
this.bomMaterial = bomMaterial |
|
|
|
} |
|
|
|
val bomProcessMaterial = saveBomProcessMaterial(bomProcessMatRequest) |
|
|
|
startColumnIndex = 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
fun importExcelBomBasicInfo(sheet: Sheet): Bom { |
|
|
@@ -239,7 +270,6 @@ open class BomService( |
|
|
|
} |
|
|
|
val leftTargetValueRow = sheet.getRow(startRowIndex) |
|
|
|
val leftTargetValueCell = leftTargetValueRow.getCell(startColumnIndex + 1) |
|
|
|
if (tempCellVal == "顔色深淺度") println("顔色深淺度") |
|
|
|
when (tempCellVal) { |
|
|
|
"顔色深淺度" -> request.apply { |
|
|
|
isDark = calculateColourScore(leftTargetValueCell.stringCellValue.trim()) |
|
|
@@ -261,6 +291,162 @@ open class BomService( |
|
|
|
} |
|
|
|
return saveBomEntity(request) |
|
|
|
} |
|
|
|
|
|
|
|
private fun bomGetOrCreateEquipment(name: String): Equipment { |
|
|
|
var equipment = equipmentRepository.findByNameAndDeletedIsFalse(name) |
|
|
|
?: equipmentRepository.findByCodeAndDeletedIsFalse(name) |
|
|
|
if (equipment == null) { |
|
|
|
equipment = Equipment().apply { |
|
|
|
this.name = name |
|
|
|
this.code = name |
|
|
|
this.description = name |
|
|
|
} |
|
|
|
equipment = equipmentRepository.saveAndFlush(equipment) |
|
|
|
} |
|
|
|
return equipment!! |
|
|
|
} |
|
|
|
private fun bomGetOrCreateProcess(name: String): Process { |
|
|
|
var process = processRepository.findByNameAndDeletedIsFalse(name) |
|
|
|
?: processRepository.findByCodeAndDeletedIsFalse(name) |
|
|
|
if (process == null) { |
|
|
|
process = Process().apply { |
|
|
|
this.name = name |
|
|
|
this.code = name |
|
|
|
this.description = name |
|
|
|
} |
|
|
|
process = processRepository.saveAndFlush(process) |
|
|
|
} |
|
|
|
return process!! |
|
|
|
} |
|
|
|
|
|
|
|
private fun extractDurationStringToMinutes(str: String): Int { |
|
|
|
val regex = """(\d+)(\D+)""".toRegex() |
|
|
|
val matchResult = regex.find(str) |
|
|
|
|
|
|
|
val (number, unit) = matchResult?.let { |
|
|
|
val number = it.groupValues[1].toInt() |
|
|
|
val unit = it.groupValues[2] |
|
|
|
Pair(number, unit) |
|
|
|
}!! |
|
|
|
var multiplier = 1 |
|
|
|
when { |
|
|
|
unit.contains("min") -> { |
|
|
|
multiplier = 1 |
|
|
|
} |
|
|
|
unit.contains("hr") -> { |
|
|
|
multiplier = 60 |
|
|
|
} |
|
|
|
} |
|
|
|
return number * multiplier |
|
|
|
} |
|
|
|
private fun importExcelBomProcess(bom: Bom, sheet: Sheet) { |
|
|
|
var bomProcessRequest = ImportBomProcessRequest( |
|
|
|
bom = bom |
|
|
|
) |
|
|
|
var startRowIndex = 30 |
|
|
|
val endRowIndex = 70 |
|
|
|
var startColumnIndex = 0 |
|
|
|
val endColumnIndex = 11 |
|
|
|
while (startRowIndex < endRowIndex) { |
|
|
|
println("") |
|
|
|
val tempRow = sheet.getRow(startRowIndex) |
|
|
|
val tempCell = tempRow.getCell(startColumnIndex) |
|
|
|
if (tempCell != null && tempCell.cellType == CellType.STRING && tempCell.stringCellValue.trim() == "工序") { |
|
|
|
startRowIndex += 2 // skip column header |
|
|
|
println("last: $startRowIndex") |
|
|
|
break |
|
|
|
} |
|
|
|
startRowIndex++ |
|
|
|
} |
|
|
|
while (startRowIndex != endRowIndex || startColumnIndex != endColumnIndex) { |
|
|
|
val tempRow = sheet.getRow(startRowIndex) |
|
|
|
val tempCell = tempRow.getCell(startColumnIndex) |
|
|
|
val checkCell = tempRow.getCell(0) |
|
|
|
if (startColumnIndex == 0 && (tempCell == null || tempCell.cellType == CellType.BLANK)) { |
|
|
|
println("hi") |
|
|
|
break |
|
|
|
} else { |
|
|
|
println(tempCell.cellType) |
|
|
|
println(tempCell.toString()) |
|
|
|
try { |
|
|
|
when (startColumnIndex) { |
|
|
|
0 -> { |
|
|
|
println(tempCell.cellType) |
|
|
|
bomProcessRequest.apply { |
|
|
|
this.seqNo = tempCell.numericCellValue.toLong() |
|
|
|
} |
|
|
|
} |
|
|
|
1 -> { |
|
|
|
val equipmentName = tempCell.stringCellValue.trim() |
|
|
|
if (equipmentName != "不適用") {0 |
|
|
|
val equipment = bomGetOrCreateEquipment(equipmentName) |
|
|
|
bomProcessRequest.apply { |
|
|
|
this.equipment = equipment |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
2 -> { |
|
|
|
val processName = tempCell.stringCellValue.trim() |
|
|
|
val process = bomGetOrCreateProcess(processName) |
|
|
|
bomProcessRequest.apply { |
|
|
|
this.process = process |
|
|
|
} |
|
|
|
} |
|
|
|
3 -> { |
|
|
|
val description = tempCell.stringCellValue.trim() |
|
|
|
bomProcessRequest.apply { |
|
|
|
this.description = description |
|
|
|
} |
|
|
|
} |
|
|
|
6 -> { //duration |
|
|
|
val durationString = tempCell.stringCellValue.trim() |
|
|
|
bomProcessRequest.apply { |
|
|
|
this.duration = extractDurationStringToMinutes(durationString) |
|
|
|
} |
|
|
|
} |
|
|
|
10 -> { //prepTimeInMinute |
|
|
|
if (tempCell.cellType != CellType.BLANK) { |
|
|
|
val prepTimeInMinute = tempCell.stringCellValue.trim() |
|
|
|
bomProcessRequest.apply { |
|
|
|
this.prepTimeInMinute = extractDurationStringToMinutes(prepTimeInMinute) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
11 -> { //prepTimeInMinute |
|
|
|
if (tempCell.cellType != CellType.BLANK) { |
|
|
|
val prepTimeInMinute = tempCell.stringCellValue.trim() |
|
|
|
bomProcessRequest.apply { |
|
|
|
this.prepTimeInMinute = extractDurationStringToMinutes(prepTimeInMinute) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e: Error) { |
|
|
|
throw e |
|
|
|
} |
|
|
|
} |
|
|
|
println("startRowIndex: $startRowIndex") |
|
|
|
println("endRowIndex: $endRowIndex") |
|
|
|
println(startRowIndex < endRowIndex) |
|
|
|
|
|
|
|
println("startColumnIndex: $startColumnIndex") |
|
|
|
println("endColumnIndex: $endColumnIndex") |
|
|
|
println(startColumnIndex < endColumnIndex) |
|
|
|
// moving the loop |
|
|
|
if (startColumnIndex < endColumnIndex) { |
|
|
|
println("1st") |
|
|
|
startColumnIndex++ |
|
|
|
} else if (startRowIndex < endRowIndex) { |
|
|
|
println("2nd") |
|
|
|
// when doesn't meet first condition, falls to this and go new row |
|
|
|
startRowIndex++ |
|
|
|
// do save |
|
|
|
saveBomProcess(bomProcessRequest) |
|
|
|
startColumnIndex = 0 |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
open fun importBOM() { |
|
|
|
// val folderPath = "bomImport" |
|
|
|
// val folder = File(folderPath) |
|
|
@@ -273,14 +459,12 @@ open class BomService( |
|
|
|
val templateInputStream = resource.inputStream |
|
|
|
val workbook: Workbook = XSSFWorkbook(templateInputStream) |
|
|
|
val sheet: Sheet = workbook.getSheetAt(0) |
|
|
|
// val rowIndex = 1 |
|
|
|
// val columnIndex = 0 |
|
|
|
// val tempRow = sheet.getRow(rowIndex) |
|
|
|
// val tempCell = tempRow.getCell(columnIndex) |
|
|
|
// println(tempCell.cellType) |
|
|
|
// println(tempCell.toString()) |
|
|
|
val bom = importExcelBomBasicInfo(sheet) // updating bom table |
|
|
|
val bomMaterial = importExcelBomMaterial(bom, sheet) |
|
|
|
// import bom process / create new process |
|
|
|
importExcelBomProcess(bom, sheet) |
|
|
|
// import bom material |
|
|
|
importExcelBomMaterial(bom, sheet) |
|
|
|
|
|
|
|
// break |
|
|
|
} |
|
|
|
} |