|
@@ -1,18 +1,32 @@ |
|
|
package com.ffii.fpsms.modules.master.service |
|
|
package com.ffii.fpsms.modules.master.service |
|
|
|
|
|
|
|
|
import com.ffii.fpsms.modules.master.entity.Bom |
|
|
|
|
|
import com.ffii.fpsms.modules.master.entity.BomRepository |
|
|
|
|
|
|
|
|
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.SaveBomRequest |
|
|
import com.ffii.fpsms.modules.master.web.models.SaveBomResponse |
|
|
import com.ffii.fpsms.modules.master.web.models.SaveBomResponse |
|
|
|
|
|
import org.apache.poi.ss.usermodel.CellType |
|
|
|
|
|
import org.apache.poi.ss.usermodel.Sheet |
|
|
|
|
|
import org.apache.poi.ss.usermodel.Workbook |
|
|
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook |
|
|
|
|
|
import org.springframework.core.io.ClassPathResource |
|
|
|
|
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver |
|
|
import org.springframework.stereotype.Service |
|
|
import org.springframework.stereotype.Service |
|
|
import kotlin.jvm.optionals.getOrNull |
|
|
|
|
|
|
|
|
import java.io.File |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Service |
|
|
@Service |
|
|
open class BomService( |
|
|
open class BomService( |
|
|
val bomRepository: BomRepository, |
|
|
val bomRepository: BomRepository, |
|
|
|
|
|
val bomMaterialRepository: BomMaterialRepository, |
|
|
val itemsService: ItemsService, |
|
|
val itemsService: ItemsService, |
|
|
val uomConversionService: UomConversionService |
|
|
|
|
|
|
|
|
val itemsRepository: ItemsRepository, |
|
|
|
|
|
val uomConversionService: UomConversionService, |
|
|
|
|
|
val uomConversionRepository: UomConversionRepository |
|
|
) { |
|
|
) { |
|
|
|
|
|
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> { |
|
|
open fun findAll(): List<Bom> { |
|
|
return bomRepository.findAll() |
|
|
return bomRepository.findAll() |
|
@@ -65,4 +79,209 @@ open class BomService( |
|
|
|
|
|
|
|
|
return response |
|
|
return response |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//////// -------------------------------- for excel import ------------------------------- ///////// |
|
|
|
|
|
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 { |
|
|
|
|
|
this.isDark = req.isDark |
|
|
|
|
|
this.isFloat = req.isFloat |
|
|
|
|
|
this.isDense = req.isDense |
|
|
|
|
|
this.code = req.code |
|
|
|
|
|
this.name = req.name |
|
|
|
|
|
this.description = req.description |
|
|
|
|
|
this.item = item |
|
|
|
|
|
this.outputQty = req.outputQty |
|
|
|
|
|
this.outputQtyUom = req.outputQtyUom |
|
|
|
|
|
this.yield = req.yield |
|
|
|
|
|
this.uom = uom |
|
|
|
|
|
// this.excelUom = req.excelUom |
|
|
|
|
|
} |
|
|
|
|
|
val savedBom = bomRepository.saveAndFlush(bom) |
|
|
|
|
|
// println("saved: ${savedBom.id}") |
|
|
|
|
|
return savedBom |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun saveBomMaterial(req: ImportBomMatRequest): BomMaterial { |
|
|
|
|
|
val bomMaterial = BomMaterial().apply { |
|
|
|
|
|
this.item = req.item |
|
|
|
|
|
this.itemName = req.item!!.name |
|
|
|
|
|
this.isConsumable = req.isConsumable |
|
|
|
|
|
this.qty = req.qty |
|
|
|
|
|
this.uomName = req.uomName |
|
|
|
|
|
this.bom = req.bom |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
return bomMaterialRepository.saveAndFlush(bomMaterial) |
|
|
|
|
|
} |
|
|
|
|
|
fun importExcelBomMaterial(bom: Bom, sheet: Sheet) { |
|
|
|
|
|
var request = ImportBomMatRequest( |
|
|
|
|
|
bom = bom |
|
|
|
|
|
) |
|
|
|
|
|
var startRowIndex = 10 |
|
|
|
|
|
val endRowIndex = 30 |
|
|
|
|
|
var startColumnIndex = 0 |
|
|
|
|
|
val endColumnIndex = 9 |
|
|
|
|
|
while (startRowIndex < endRowIndex) { |
|
|
|
|
|
val tempRow = sheet.getRow(startRowIndex) |
|
|
|
|
|
val tempCell = tempRow.getCell(startColumnIndex) |
|
|
|
|
|
if (tempCell != null && tempCell.cellType == CellType.STRING && tempCell.stringCellValue.trim() == "材料編號") { |
|
|
|
|
|
println("last: $startRowIndex") |
|
|
|
|
|
startRowIndex++ |
|
|
|
|
|
break |
|
|
|
|
|
} |
|
|
|
|
|
startRowIndex++ |
|
|
|
|
|
} |
|
|
|
|
|
while (startRowIndex != endRowIndex || startColumnIndex != endColumnIndex) { |
|
|
|
|
|
val tempRow = sheet.getRow(startRowIndex) |
|
|
|
|
|
val tempCell = tempRow.getCell(startColumnIndex) |
|
|
|
|
|
if (tempCell == null || tempCell.cellType == CellType.BLANK) { |
|
|
|
|
|
break |
|
|
|
|
|
} else { |
|
|
|
|
|
try { |
|
|
|
|
|
when (startColumnIndex) { |
|
|
|
|
|
0 -> { |
|
|
|
|
|
// println("start") |
|
|
|
|
|
val nameRow = sheet.getRow(startRowIndex) |
|
|
|
|
|
val nameCell = nameRow.getCell(1) |
|
|
|
|
|
val item = itemsRepository.findByCodeAndDeletedFalse(tempCell.stringCellValue.trim()) |
|
|
|
|
|
?: itemsRepository.findByNameAndDeletedFalse(nameCell.stringCellValue.trim()) |
|
|
|
|
|
// println(item) |
|
|
|
|
|
request.apply { |
|
|
|
|
|
this.item = item |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
2 -> { |
|
|
|
|
|
request.apply { |
|
|
|
|
|
this.qty = tempCell.numericCellValue.toBigDecimal() |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
3 -> { |
|
|
|
|
|
request.apply { |
|
|
|
|
|
this.uomName = tempCell.stringCellValue.trim() |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} catch(e: Error) { |
|
|
|
|
|
println(startColumnIndex) |
|
|
|
|
|
println(startRowIndex) |
|
|
|
|
|
println(tempCell.stringCellValue.trim()) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (startColumnIndex < endColumnIndex) { |
|
|
|
|
|
startColumnIndex++ |
|
|
|
|
|
} else if (startRowIndex < endRowIndex) { |
|
|
|
|
|
startRowIndex++ |
|
|
|
|
|
// do save |
|
|
|
|
|
saveBomMaterial(request) |
|
|
|
|
|
startColumnIndex = 0 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun importExcelBomBasicInfo(sheet: Sheet): Bom { |
|
|
|
|
|
var request = ImportBomRequest( |
|
|
|
|
|
code = "", |
|
|
|
|
|
name = "", |
|
|
|
|
|
description = "", |
|
|
|
|
|
) |
|
|
|
|
|
var startRowIndex = 0 |
|
|
|
|
|
val endRowIndex = 15 |
|
|
|
|
|
var startColumnIndex = 0 |
|
|
|
|
|
val endColumnIndex = 15 |
|
|
|
|
|
while (startRowIndex != endRowIndex || startColumnIndex != endColumnIndex) { |
|
|
|
|
|
val tempRow = sheet.getRow(startRowIndex) |
|
|
|
|
|
val tempCell = tempRow.getCell(startColumnIndex) |
|
|
|
|
|
if (tempCell != null && tempCell.cellType == CellType.STRING) { |
|
|
|
|
|
val tempCellVal = tempCell.stringCellValue.trim() |
|
|
|
|
|
// --------------------- assigning value that is under a header to request ------------------------ // |
|
|
|
|
|
val topTargetValueRow = sheet.getRow(startRowIndex + 1) |
|
|
|
|
|
val topTargetValueCell = topTargetValueRow.getCell(startColumnIndex) |
|
|
|
|
|
when (tempCellVal) { |
|
|
|
|
|
"編號" -> { |
|
|
|
|
|
println(topTargetValueCell.stringCellValue.trim()) |
|
|
|
|
|
request.apply { |
|
|
|
|
|
code = topTargetValueCell.stringCellValue.trim() |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
"產品名稱" -> request.apply { |
|
|
|
|
|
name = topTargetValueCell.stringCellValue.trim() |
|
|
|
|
|
} |
|
|
|
|
|
"種類" -> request.apply { |
|
|
|
|
|
description = topTargetValueCell.stringCellValue.trim() |
|
|
|
|
|
} |
|
|
|
|
|
"份量 (Qty)" -> request.apply { |
|
|
|
|
|
outputQty = topTargetValueCell.numericCellValue.toBigDecimal() |
|
|
|
|
|
} |
|
|
|
|
|
"單位" -> request.apply { |
|
|
|
|
|
outputQtyUom = topTargetValueCell.stringCellValue.trim() |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// ----------------------------------------------------------------------------------------------- // |
|
|
|
|
|
// --------------------- assigning value that is next to a header to request ------------------------ // |
|
|
|
|
|
fun calculateColourScore(value: String): Int { |
|
|
|
|
|
var score = -1 |
|
|
|
|
|
when (value) { |
|
|
|
|
|
"淺" -> score = 0 |
|
|
|
|
|
"深" -> score = 1 |
|
|
|
|
|
} |
|
|
|
|
|
return score |
|
|
|
|
|
} |
|
|
|
|
|
fun calculateFloatScore(value: String): Int { |
|
|
|
|
|
var score = -1 |
|
|
|
|
|
when (value) { |
|
|
|
|
|
"沉" -> score = 0 |
|
|
|
|
|
"浮" -> score = 1 |
|
|
|
|
|
} |
|
|
|
|
|
return score |
|
|
|
|
|
} |
|
|
|
|
|
val leftTargetValueRow = sheet.getRow(startRowIndex) |
|
|
|
|
|
val leftTargetValueCell = leftTargetValueRow.getCell(startColumnIndex + 1) |
|
|
|
|
|
if (tempCellVal == "顔色深淺度") println("顔色深淺度") |
|
|
|
|
|
when (tempCellVal) { |
|
|
|
|
|
"顔色深淺度" -> request.apply { |
|
|
|
|
|
isDark = calculateColourScore(leftTargetValueCell.stringCellValue.trim()) |
|
|
|
|
|
} |
|
|
|
|
|
"浮沉" -> request.apply { |
|
|
|
|
|
isFloat = calculateFloatScore(leftTargetValueCell.stringCellValue.trim()) |
|
|
|
|
|
} |
|
|
|
|
|
"濃淡程度" -> request.apply { |
|
|
|
|
|
isDense = if (leftTargetValueCell.cellType == CellType.NUMERIC) leftTargetValueCell.numericCellValue.toInt() else 0 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (startRowIndex < endRowIndex) { |
|
|
|
|
|
startRowIndex++ |
|
|
|
|
|
} else if (startColumnIndex < endColumnIndex) { |
|
|
|
|
|
startColumnIndex++ |
|
|
|
|
|
startRowIndex = 0 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return saveBomEntity(request) |
|
|
|
|
|
} |
|
|
|
|
|
open fun importBOM() { |
|
|
|
|
|
// val folderPath = "bomImport" |
|
|
|
|
|
// val folder = File(folderPath) |
|
|
|
|
|
val resolver = PathMatchingResourcePatternResolver() |
|
|
|
|
|
val excels = resolver.getResources("bomImport/*.xlsx") |
|
|
|
|
|
|
|
|
|
|
|
for (resource in excels) { |
|
|
|
|
|
//get sheet |
|
|
|
|
|
println(resource.filename) |
|
|
|
|
|
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) |
|
|
|
|
|
// break |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |