|
@@ -1,15 +1,22 @@ |
|
|
package com.ffii.fpsms.modules.master.service |
|
|
package com.ffii.fpsms.modules.master.service |
|
|
|
|
|
|
|
|
|
|
|
import com.ffii.core.response.RecordsRes |
|
|
import com.ffii.core.support.AbstractBaseEntityService |
|
|
import com.ffii.core.support.AbstractBaseEntityService |
|
|
import com.ffii.core.support.JdbcDao |
|
|
import com.ffii.core.support.JdbcDao |
|
|
import com.ffii.fpsms.modules.master.entity.* |
|
|
import com.ffii.fpsms.modules.master.entity.* |
|
|
import com.ffii.fpsms.modules.master.web.models.MessageResponse |
|
|
|
|
|
|
|
|
import com.ffii.fpsms.modules.master.entity.projections.* |
|
|
|
|
|
import com.ffii.fpsms.modules.master.web.models.SearchProdScheduleRequest |
|
|
|
|
|
import org.springframework.data.domain.PageRequest |
|
|
import org.springframework.stereotype.Service |
|
|
import org.springframework.stereotype.Service |
|
|
|
|
|
import java.math.BigDecimal |
|
|
|
|
|
import java.math.RoundingMode |
|
|
import java.time.LocalDateTime |
|
|
import java.time.LocalDateTime |
|
|
import java.time.format.DateTimeFormatter |
|
|
import java.time.format.DateTimeFormatter |
|
|
import java.util.* |
|
|
import java.util.* |
|
|
|
|
|
import kotlin.NoSuchElementException |
|
|
import kotlin.collections.component1 |
|
|
import kotlin.collections.component1 |
|
|
import kotlin.collections.component2 |
|
|
import kotlin.collections.component2 |
|
|
|
|
|
import kotlin.jvm.optionals.getOrNull |
|
|
import kotlin.math.ceil |
|
|
import kotlin.math.ceil |
|
|
|
|
|
|
|
|
@Service |
|
|
@Service |
|
@@ -18,10 +25,214 @@ open class ProductionScheduleService( |
|
|
private val itemService: ItemsService, |
|
|
private val itemService: ItemsService, |
|
|
private val productionScheduleRepository: ProductionScheduleRepository, |
|
|
private val productionScheduleRepository: ProductionScheduleRepository, |
|
|
private val productionScheduleLineRepository: ProductionScheduleLineRepository, |
|
|
private val productionScheduleLineRepository: ProductionScheduleLineRepository, |
|
|
): AbstractBaseEntityService<ProductionSchedule, Long, ProductionScheduleRepository>(jdbcDao, productionScheduleRepository) { |
|
|
|
|
|
|
|
|
private val bomMaterialService: BomMaterialService, private val bomMaterialRepository: BomMaterialRepository, |
|
|
|
|
|
) : AbstractBaseEntityService<ProductionSchedule, Long, ProductionScheduleRepository>( |
|
|
|
|
|
jdbcDao, |
|
|
|
|
|
productionScheduleRepository |
|
|
|
|
|
) { |
|
|
// do mapping with projection |
|
|
// do mapping with projection |
|
|
open val formatter: DateTimeFormatter? = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") |
|
|
open val formatter: DateTimeFormatter? = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") |
|
|
|
|
|
|
|
|
|
|
|
open fun getLatestScheduleAt(type: String?): LocalDateTime { |
|
|
|
|
|
return productionScheduleRepository.getLatestRoughScheduleAt(type) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
open fun allProdSchedulesByPage(request: SearchProdScheduleRequest): RecordsRes<ProdScheduleInfo> { |
|
|
|
|
|
val pageable = PageRequest.of(request.pageNum ?: 0, request.pageSize ?: 10); |
|
|
|
|
|
|
|
|
|
|
|
val response = productionScheduleRepository.findProdScheduleInfoByPage( |
|
|
|
|
|
scheduleAt = request.scheduleAt, |
|
|
|
|
|
schedulePeriod = request.schedulePeriod, |
|
|
|
|
|
schedulePeriodTo = request.schedulePeriodTo, |
|
|
|
|
|
totalEstProdCount = request.totalEstProdCount, |
|
|
|
|
|
type = request.type, |
|
|
|
|
|
pageable = pageable |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
val records = response.content |
|
|
|
|
|
val total = response.totalElements |
|
|
|
|
|
return RecordsRes<ProdScheduleInfo>(records, total.toInt()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
open fun prodScheduleDetail(id: Long): ProdScheduleWithLine { |
|
|
|
|
|
val zero = BigDecimal.ZERO |
|
|
|
|
|
val prodSchedule = productionScheduleRepository.findById(id).getOrNull() ?: throw NoSuchElementException() |
|
|
|
|
|
val dayOfWeekValue = |
|
|
|
|
|
if (prodSchedule.scheduleAt.dayOfWeek.value >= 7) prodSchedule.scheduleAt.dayOfWeek.value - 7 else prodSchedule.scheduleAt.dayOfWeek.value |
|
|
|
|
|
val schedulePeriod = prodSchedule.scheduleAt.plusDays((7 - dayOfWeekValue).toLong()) |
|
|
|
|
|
val schedulePeriodTo = prodSchedule.scheduleAt.plusDays((7 + 6 - dayOfWeekValue).toLong()) |
|
|
|
|
|
val prodScheduleLines = prodSchedule.productionScheduleLines.filter { !it.deleted } |
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------- By FG ----------------------------------// |
|
|
|
|
|
// Production Schedule By Date |
|
|
|
|
|
val prodScheduleLineInfosByFg = prodScheduleLines.map { line -> |
|
|
|
|
|
val bomMaterials = line.item.id?.let { bomMaterialRepository.findAllByBomItemIdAndDeletedIsFalse(it) } |
|
|
|
|
|
?.map { bm -> |
|
|
|
|
|
val proportion = |
|
|
|
|
|
if (line.prodQty > 0 && bm.bom?.outputQty != null && (bm.bom?.outputQty ?: zero) > zero) { |
|
|
|
|
|
BigDecimal(line.prodQty).divide(bm.bom!!.outputQty, 2, RoundingMode.HALF_UP) |
|
|
|
|
|
} else { |
|
|
|
|
|
zero |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val demandQty = bm.qty?.times(proportion) ?: zero |
|
|
|
|
|
|
|
|
|
|
|
ProdScheduleLineBomMaterialInfoByFg( |
|
|
|
|
|
id = bm.id, |
|
|
|
|
|
code = bm.item?.code, |
|
|
|
|
|
name = bm.item?.name, |
|
|
|
|
|
type = bm.item?.type, |
|
|
|
|
|
availableQty = bm.item?.inventories?.sumOf { |
|
|
|
|
|
(it.onHandQty ?: zero) - (it.onHoldQty ?: zero) - (it.unavailableQty ?: zero) |
|
|
|
|
|
}, |
|
|
|
|
|
demandQty = demandQty, |
|
|
|
|
|
uomName = bm.uomName |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ProdScheduleLineInfoByFg( |
|
|
|
|
|
id = line.id, |
|
|
|
|
|
code = line.item.code, |
|
|
|
|
|
name = line.item.name, |
|
|
|
|
|
type = line.item.type, |
|
|
|
|
|
availableQty = line.item.inventories.sumOf { |
|
|
|
|
|
(it.onHandQty ?: zero) - (it.onHoldQty ?: zero) - (it.unavailableQty ?: zero) |
|
|
|
|
|
}, |
|
|
|
|
|
prodQty = BigDecimal(line.prodQty), |
|
|
|
|
|
lastMonthAvgSales = BigDecimal(line.lastMonthAvgSales), |
|
|
|
|
|
estCloseBal = BigDecimal(line.estCloseBal), |
|
|
|
|
|
priority = line.itemPriority, |
|
|
|
|
|
bomMaterials = bomMaterials, |
|
|
|
|
|
assignDate = line.assignDate, |
|
|
|
|
|
) |
|
|
|
|
|
}.filter { !it.bomMaterials.isNullOrEmpty() } |
|
|
|
|
|
|
|
|
|
|
|
// Sum of the Production Schedule |
|
|
|
|
|
val sumProdScheduleLineInfosByFg = prodScheduleLineInfosByFg |
|
|
|
|
|
.groupBy { it.code } |
|
|
|
|
|
.map { (code, infos) -> |
|
|
|
|
|
val sumBomMaterials = infos |
|
|
|
|
|
.flatMap { it.bomMaterials ?: mutableListOf() } |
|
|
|
|
|
.groupBy { it.code } |
|
|
|
|
|
.map { (code, bm) -> |
|
|
|
|
|
ProdScheduleLineBomMaterialInfoByFg( |
|
|
|
|
|
id = if (bm.isNotEmpty()) bm[0].id else null, |
|
|
|
|
|
code = if (bm.isNotEmpty()) bm[0].code else null, |
|
|
|
|
|
name = if (bm.isNotEmpty()) bm[0].name else null, |
|
|
|
|
|
type = if (bm.isNotEmpty()) bm[0].type else null, |
|
|
|
|
|
availableQty = bm.sumOf { it.availableQty ?: zero }, |
|
|
|
|
|
demandQty = bm.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
uomName = if (bm.isNotEmpty()) bm[0].uomName else null |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ProdScheduleLineInfoByFg( |
|
|
|
|
|
id = if (infos.isNotEmpty()) infos[0].assignDate else null, |
|
|
|
|
|
code = if (infos.isNotEmpty()) infos[0].code else null, |
|
|
|
|
|
name = if (infos.isNotEmpty()) infos[0].name else null, |
|
|
|
|
|
type = if (infos.isNotEmpty()) infos[0].type else null, |
|
|
|
|
|
availableQty = infos.sumOf { (it.availableQty ?: zero) }, |
|
|
|
|
|
prodQty = infos.sumOf { (it.prodQty ?: zero) }, |
|
|
|
|
|
lastMonthAvgSales = infos.sumOf { (it.lastMonthAvgSales ?: zero) }, |
|
|
|
|
|
estCloseBal = infos.sumOf { (it.estCloseBal ?: zero) }, |
|
|
|
|
|
priority = if (infos.isNotEmpty()) infos[0].priority else null, |
|
|
|
|
|
bomMaterials = sumBomMaterials, |
|
|
|
|
|
assignDate = null, |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Production Schedule By Date group by assign date |
|
|
|
|
|
val groupedProdScheduleLinesByFg = prodScheduleLineInfosByFg.groupBy { it.assignDate } |
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------- By BoM ----------------------------------// |
|
|
|
|
|
// Seven Days of Bom Materials |
|
|
|
|
|
val prodScheduleLinesInfoByBom7Days = prodScheduleLines.mapNotNull { line -> |
|
|
|
|
|
val bomMaterial = line.item.id?.let { bomMaterialRepository.findAllByBomItemIdAndDeletedIsFalse(it) } |
|
|
|
|
|
|
|
|
|
|
|
bomMaterial?.map { bm -> |
|
|
|
|
|
val proportion = |
|
|
|
|
|
if (line.prodQty > 0 && bm.bom?.outputQty != null && (bm.bom?.outputQty ?: zero) > zero) { |
|
|
|
|
|
BigDecimal(line.prodQty).divide(bm.bom!!.outputQty, 2, RoundingMode.HALF_UP) |
|
|
|
|
|
} else { |
|
|
|
|
|
zero |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val demandQty = bm.qty?.times(proportion) ?: zero |
|
|
|
|
|
|
|
|
|
|
|
ProdScheduleLineInfoByBomByDate( |
|
|
|
|
|
id = bm.item?.id, |
|
|
|
|
|
code = bm.item?.code, |
|
|
|
|
|
name = bm.item?.name, |
|
|
|
|
|
type = bm.item?.type, |
|
|
|
|
|
availableQty = bm.item?.inventories?.sumOf { |
|
|
|
|
|
(it.onHandQty ?: zero) - (it.onHoldQty ?: zero) - (it.unavailableQty ?: zero) |
|
|
|
|
|
} ?: zero, |
|
|
|
|
|
demandQty = demandQty, |
|
|
|
|
|
assignDate = line.assignDate, |
|
|
|
|
|
uomName = bm.uomName |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.flatten() |
|
|
|
|
|
|
|
|
|
|
|
// println(prodScheduleLinesInfoByBom7Days) |
|
|
|
|
|
|
|
|
|
|
|
// Production Schedule By Bom By Date |
|
|
|
|
|
val prodScheduleLinesInfoByBom = prodScheduleLinesInfoByBom7Days |
|
|
|
|
|
.groupBy { Pair(it.assignDate, it.code) } |
|
|
|
|
|
.map { (key, line) -> |
|
|
|
|
|
ProdScheduleLineInfoByBomByDate( |
|
|
|
|
|
id = if (line.isNotEmpty()) line[0].id else null, |
|
|
|
|
|
code = if (line.isNotEmpty()) line[0].code else null, |
|
|
|
|
|
name = if (line.isNotEmpty()) line[0].name else null, |
|
|
|
|
|
type = if (line.isNotEmpty()) line[0].type else null, |
|
|
|
|
|
availableQty = if (line.isNotEmpty()) line[0].availableQty else zero, |
|
|
|
|
|
demandQty = line.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
assignDate = key.first, |
|
|
|
|
|
uomName = if (line.isNotEmpty()) line[0].uomName else null, |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val groupedProdScheduleLinesByBom = prodScheduleLinesInfoByBom.groupBy { it.assignDate } |
|
|
|
|
|
|
|
|
|
|
|
// Sum of the Production Schedule By Bom |
|
|
|
|
|
val sumProdScheduleLinesInfoByBom = prodScheduleLinesInfoByBom7Days |
|
|
|
|
|
.groupBy { it.code } |
|
|
|
|
|
.map { (_, line) -> |
|
|
|
|
|
ProdScheduleLineInfoByBom( |
|
|
|
|
|
id = if (line.isNotEmpty()) line[0].id else null, |
|
|
|
|
|
code = if (line.isNotEmpty()) line[0].code else null, |
|
|
|
|
|
name = if (line.isNotEmpty()) line[0].name else null, |
|
|
|
|
|
type = if (line.isNotEmpty()) line[0].type else null, |
|
|
|
|
|
availableQty = if (line.isNotEmpty()) line[0].availableQty else null, |
|
|
|
|
|
totalDemandQty = line.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
demandQty1 = line.filter { it.assignDate == 1L }.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
demandQty2 = line.filter { it.assignDate == 2L }.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
demandQty3 = line.filter { it.assignDate == 3L }.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
demandQty4 = line.filter { it.assignDate == 4L }.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
demandQty5 = line.filter { it.assignDate == 5L }.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
demandQty6 = line.filter { it.assignDate == 6L }.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
demandQty7 = line.filter { it.assignDate == 7L }.sumOf { it.demandQty ?: zero }, |
|
|
|
|
|
uomName = if (line.isNotEmpty()) line[0].uomName else null, |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------- Response ----------------------------------// |
|
|
|
|
|
return ProdScheduleWithLine( |
|
|
|
|
|
id = prodSchedule.id, |
|
|
|
|
|
scheduleAt = prodSchedule.scheduleAt, |
|
|
|
|
|
schedulePeriod = schedulePeriod, |
|
|
|
|
|
schedulePeriodTo = schedulePeriodTo, |
|
|
|
|
|
totalEstProdCount = BigDecimal(prodSchedule.totalEstProdCount), |
|
|
|
|
|
totalFGType = prodSchedule.totalFGType, |
|
|
|
|
|
type = prodSchedule.type, |
|
|
|
|
|
prodScheduleLinesByFg = sumProdScheduleLineInfosByFg, |
|
|
|
|
|
prodScheduleLinesByFgByDate = groupedProdScheduleLinesByFg, |
|
|
|
|
|
prodScheduleLinesByBom = sumProdScheduleLinesInfoByBom, |
|
|
|
|
|
prodScheduleLinesByBomByDate = groupedProdScheduleLinesByBom |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
//====================細排相關 START====================// |
|
|
//====================細排相關 START====================// |
|
|
|
|
|
|
|
|
open fun getDailyProductionCount(assignDate: Int, selectedDate: LocalDateTime): Int { |
|
|
open fun getDailyProductionCount(assignDate: Int, selectedDate: LocalDateTime): Int { |
|
@@ -33,14 +244,14 @@ open class ProductionScheduleService( |
|
|
|
|
|
|
|
|
val sql = StringBuilder( |
|
|
val sql = StringBuilder( |
|
|
" SELECT " |
|
|
" SELECT " |
|
|
+ " SUM(psl.prodQty) AS dailyProdCount " |
|
|
|
|
|
+ " FROM production_schedule ps " |
|
|
|
|
|
+ " LEFT JOIN production_schedule_line psl ON psl.prodScheduleId = ps.id " |
|
|
|
|
|
+ " WHERE ps.deleted = FALSE " |
|
|
|
|
|
+ " AND psl.deleted = FALSE " |
|
|
|
|
|
+ " AND DATE(ps.scheduleAt) LIKE DATE(:selectedDate) " |
|
|
|
|
|
+ " AND psl.assignDate = :assignDate " |
|
|
|
|
|
+ " GROUP BY ps.id " |
|
|
|
|
|
|
|
|
+ " SUM(psl.prodQty) AS dailyProdCount " |
|
|
|
|
|
+ " FROM production_schedule ps " |
|
|
|
|
|
+ " LEFT JOIN production_schedule_line psl ON psl.prodScheduleId = ps.id " |
|
|
|
|
|
+ " WHERE ps.deleted = FALSE " |
|
|
|
|
|
+ " AND psl.deleted = FALSE " |
|
|
|
|
|
+ " AND DATE(ps.scheduleAt) LIKE DATE(:selectedDate) " |
|
|
|
|
|
+ " AND psl.assignDate = :assignDate " |
|
|
|
|
|
+ " GROUP BY ps.id " |
|
|
); |
|
|
); |
|
|
return jdbcDao.queryForInt(sql.toString(), args); |
|
|
return jdbcDao.queryForInt(sql.toString(), args); |
|
|
} |
|
|
} |
|
@@ -64,11 +275,12 @@ open class ProductionScheduleService( |
|
|
val productionPriorityMap: HashMap<ProductionScheduleRecord, Double> = HashMap(); |
|
|
val productionPriorityMap: HashMap<ProductionScheduleRecord, Double> = HashMap(); |
|
|
|
|
|
|
|
|
//TODO: update to use SQL get shop order record for detailed scheduling (real prodQty and openBal) |
|
|
//TODO: update to use SQL get shop order record for detailed scheduling (real prodQty and openBal) |
|
|
for (record in scheduledList){ |
|
|
|
|
|
println("Object - " + record.toString() ); |
|
|
|
|
|
val tempRecord= record; |
|
|
|
|
|
tempRecord.prodQty = tempRecord.prodQty *2; |
|
|
|
|
|
val difference = -(tempRecord.targetMinStock + tempRecord.prodQty - tempRecord.estCloseBal) /*TODO: this should be real close bal*/; |
|
|
|
|
|
|
|
|
for (record in scheduledList) { |
|
|
|
|
|
println("Object - " + record.toString()); |
|
|
|
|
|
val tempRecord = record; |
|
|
|
|
|
tempRecord.prodQty = tempRecord.prodQty * 2; |
|
|
|
|
|
val difference = |
|
|
|
|
|
-(tempRecord.targetMinStock + tempRecord.prodQty - tempRecord.estCloseBal) /*TODO: this should be real close bal*/; |
|
|
productionPriorityMap.put(tempRecord, difference) |
|
|
productionPriorityMap.put(tempRecord, difference) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -80,17 +292,16 @@ open class ProductionScheduleService( |
|
|
|
|
|
|
|
|
for ((updatedScheduleRecord, totalDifference) in sortedEntries) { |
|
|
for ((updatedScheduleRecord, totalDifference) in sortedEntries) { |
|
|
//match id with rough schedule record to create new record |
|
|
//match id with rough schedule record to create new record |
|
|
val targetRecord = scheduledList.find { it.itemId == updatedScheduleRecord.itemId } |
|
|
|
|
|
|
|
|
val targetRecord = scheduledList.find { it.item.id == updatedScheduleRecord.item.id } |
|
|
val prodDifference = updatedScheduleRecord.prodQty - (targetRecord?.prodQty ?: 0.0) |
|
|
val prodDifference = updatedScheduleRecord.prodQty - (targetRecord?.prodQty ?: 0.0) |
|
|
|
|
|
|
|
|
if(idleProductionCount - prodDifference >= 0){ |
|
|
|
|
|
|
|
|
if (idleProductionCount - prodDifference >= 0) { |
|
|
//have enough quoter for adjustment |
|
|
//have enough quoter for adjustment |
|
|
idleProductionCount -= prodDifference; |
|
|
idleProductionCount -= prodDifference; |
|
|
detailedScheduleOutputList.add(updatedScheduleRecord) |
|
|
detailedScheduleOutputList.add(updatedScheduleRecord) |
|
|
accProdCount += updatedScheduleRecord.prodQty |
|
|
accProdCount += updatedScheduleRecord.prodQty |
|
|
fgCount++ |
|
|
fgCount++ |
|
|
} |
|
|
|
|
|
else{ |
|
|
|
|
|
|
|
|
} else { |
|
|
println("[INFO] item " + updatedScheduleRecord.name + " have bee skipped"); |
|
|
println("[INFO] item " + updatedScheduleRecord.name + " have bee skipped"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -108,7 +319,11 @@ open class ProductionScheduleService( |
|
|
saveDetailedScheduleOutput(sortedOutputList, accProdCount, fgCount) |
|
|
saveDetailedScheduleOutput(sortedOutputList, accProdCount, fgCount) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
open fun saveDetailedScheduleOutput(sortedEntries: List<ProductionScheduleRecord>, accProdCount: Double, fgCount: Long) { |
|
|
|
|
|
|
|
|
open fun saveDetailedScheduleOutput( |
|
|
|
|
|
sortedEntries: List<ProductionScheduleRecord>, |
|
|
|
|
|
accProdCount: Double, |
|
|
|
|
|
fgCount: Long |
|
|
|
|
|
) { |
|
|
val tempObj = ProductionSchedule() |
|
|
val tempObj = ProductionSchedule() |
|
|
tempObj.id = -1; |
|
|
tempObj.id = -1; |
|
|
tempObj.scheduleAt = LocalDateTime.now() |
|
|
tempObj.scheduleAt = LocalDateTime.now() |
|
@@ -117,7 +332,7 @@ open class ProductionScheduleService( |
|
|
tempObj.id = saveProductionScheduleToDatabase(tempObj); |
|
|
tempObj.id = saveProductionScheduleToDatabase(tempObj); |
|
|
tempObj.type = "detailed" |
|
|
tempObj.type = "detailed" |
|
|
|
|
|
|
|
|
for ( detailedScheduleRecord in sortedEntries) { |
|
|
|
|
|
|
|
|
for (detailedScheduleRecord in sortedEntries) { |
|
|
saveDetailedScheduleLineToDatabase(tempObj.id ?: -1, detailedScheduleRecord) |
|
|
saveDetailedScheduleLineToDatabase(tempObj.id ?: -1, detailedScheduleRecord) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -125,10 +340,12 @@ open class ProductionScheduleService( |
|
|
|
|
|
|
|
|
private fun saveDetailedScheduleLineToDatabase(parentId: Long, detailedScheduleObj: ProductionScheduleRecord) { |
|
|
private fun saveDetailedScheduleLineToDatabase(parentId: Long, detailedScheduleObj: ProductionScheduleRecord) { |
|
|
try { |
|
|
try { |
|
|
|
|
|
val prodSchedule = productionScheduleRepository.findById(parentId).get() |
|
|
var savedItem = ProductionScheduleLine() |
|
|
var savedItem = ProductionScheduleLine() |
|
|
savedItem.id = -1; |
|
|
savedItem.id = -1; |
|
|
savedItem.prodScheduleId = parentId; |
|
|
|
|
|
savedItem.itemId = detailedScheduleObj.itemId ?: -1; |
|
|
|
|
|
|
|
|
// savedItem.prodScheduleId = parentId; |
|
|
|
|
|
savedItem.productionSchedule = prodSchedule; |
|
|
|
|
|
savedItem.item.id = detailedScheduleObj.item.id ?: -1; |
|
|
savedItem.lastMonthAvgSales = detailedScheduleObj.lastMonthAvgSales ?: 0.0; |
|
|
savedItem.lastMonthAvgSales = detailedScheduleObj.lastMonthAvgSales ?: 0.0; |
|
|
savedItem.refScheduleId = detailedScheduleObj.id; |
|
|
savedItem.refScheduleId = detailedScheduleObj.id; |
|
|
savedItem.approverId = null; |
|
|
savedItem.approverId = null; |
|
@@ -155,8 +372,8 @@ open class ProductionScheduleService( |
|
|
open var targetMinStock: Double = 0.0; |
|
|
open var targetMinStock: Double = 0.0; |
|
|
|
|
|
|
|
|
override fun toString(): String { |
|
|
override fun toString(): String { |
|
|
return "ProductionScheduleLine(prodScheduleId=$prodScheduleId," + |
|
|
|
|
|
" itemId=$itemId, lastMonthAvgSales=$lastMonthAvgSales," + |
|
|
|
|
|
|
|
|
return "ProductionScheduleLine(prodScheduleId=${productionSchedule.id}," + |
|
|
|
|
|
" itemId=${item.id}, lastMonthAvgSales=$lastMonthAvgSales," + |
|
|
" prodQty=$prodQty, estCloseBal=$estCloseBal, type='$type'," + |
|
|
" prodQty=$prodQty, estCloseBal=$estCloseBal, type='$type'," + |
|
|
" approverId=$approverId, refScheduleId=$refScheduleId," + |
|
|
" approverId=$approverId, refScheduleId=$refScheduleId," + |
|
|
" assignDate=$assignDate, itemPriority=$itemPriority)" + |
|
|
" assignDate=$assignDate, itemPriority=$itemPriority)" + |
|
@@ -190,22 +407,24 @@ open class ProductionScheduleService( |
|
|
+ " AND psl.deleted = FALSE " |
|
|
+ " AND psl.deleted = FALSE " |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
if(args.containsKey("selectedDate")){ |
|
|
|
|
|
|
|
|
if (args.containsKey("selectedDate")) { |
|
|
sql.append(" AND DATE(ps.scheduleAt) LIKE DATE(:selectedDate) "); |
|
|
sql.append(" AND DATE(ps.scheduleAt) LIKE DATE(:selectedDate) "); |
|
|
} |
|
|
} |
|
|
if(args.containsKey("name")){ |
|
|
|
|
|
|
|
|
if (args.containsKey("name")) { |
|
|
sql.append(" AND i.name LIKE :name "); |
|
|
sql.append(" AND i.name LIKE :name "); |
|
|
} |
|
|
} |
|
|
if(args.containsKey("assignDate")){ |
|
|
|
|
|
|
|
|
if (args.containsKey("assignDate")) { |
|
|
sql.append(" AND psl.assignDate = :assignDate "); |
|
|
sql.append(" AND psl.assignDate = :assignDate "); |
|
|
} |
|
|
} |
|
|
if(args.containsKey("id")){ |
|
|
|
|
|
|
|
|
if (args.containsKey("id")) { |
|
|
sql.append(" AND i.id = :id "); |
|
|
sql.append(" AND i.id = :id "); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
sql.append(" ORDER BY psl.assignDate, psl.itemPriority ASC "); |
|
|
sql.append(" ORDER BY psl.assignDate, psl.itemPriority ASC "); |
|
|
|
|
|
|
|
|
val resultList = jdbcDao.queryForList(sql.toString(), args, ); |
|
|
|
|
|
|
|
|
print(sql) |
|
|
|
|
|
val resultList = jdbcDao.queryForList(sql.toString(), args); |
|
|
|
|
|
print(resultList) |
|
|
|
|
|
|
|
|
//TODO: From Global config |
|
|
//TODO: From Global config |
|
|
val DARK_MAX_VALUE = 1; |
|
|
val DARK_MAX_VALUE = 1; |
|
@@ -214,13 +433,13 @@ open class ProductionScheduleService( |
|
|
val DARK_WEIGHTING = 0.34; |
|
|
val DARK_WEIGHTING = 0.34; |
|
|
val FLOAT_WEIGHTING = 0.33; |
|
|
val FLOAT_WEIGHTING = 0.33; |
|
|
val DENSE_WEIGHTING = 0.33; |
|
|
val DENSE_WEIGHTING = 0.33; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Convert the list of maps to a list of ProductionScheduleRecord |
|
|
// Convert the list of maps to a list of ProductionScheduleRecord |
|
|
return resultList.map { row -> |
|
|
return resultList.map { row -> |
|
|
ProductionScheduleRecord().apply { |
|
|
ProductionScheduleRecord().apply { |
|
|
this.id = row["id"].toString().toLong() |
|
|
this.id = row["id"].toString().toLong() |
|
|
this.itemPriority = row["itemPriority"].toString().toLong() |
|
|
this.itemPriority = row["itemPriority"].toString().toLong() |
|
|
this.itemId = row["itemId"].toString().toLong() |
|
|
|
|
|
|
|
|
this.item.id = row["itemId"].toString().toLong() |
|
|
this.name = row["name"] as String |
|
|
this.name = row["name"] as String |
|
|
this.lastMonthAvgSales = row["lastMonthAvgSales"].toString().toDouble() |
|
|
this.lastMonthAvgSales = row["lastMonthAvgSales"].toString().toDouble() |
|
|
this.targetMinStock = row["targetMinStock"].toString().toDouble() // Ensure correct type |
|
|
this.targetMinStock = row["targetMinStock"].toString().toDouble() // Ensure correct type |
|
@@ -239,20 +458,20 @@ open class ProductionScheduleService( |
|
|
|
|
|
|
|
|
this.weightingRef = |
|
|
this.weightingRef = |
|
|
if (isDarkValue > 0) { |
|
|
if (isDarkValue > 0) { |
|
|
(DARK_MAX_VALUE+1 - isDarkValue) / DARK_MAX_VALUE.toDouble() * DARK_WEIGHTING |
|
|
|
|
|
} else { |
|
|
|
|
|
0.0 |
|
|
|
|
|
} + |
|
|
|
|
|
if (isDenseValue > 0) { |
|
|
|
|
|
(DENSE_MAX_VALUE+1 - isDenseValue) / DENSE_MAX_VALUE.toDouble() * DENSE_WEIGHTING |
|
|
|
|
|
|
|
|
(DARK_MAX_VALUE + 1 - isDarkValue) / DARK_MAX_VALUE.toDouble() * DARK_WEIGHTING |
|
|
} else { |
|
|
} else { |
|
|
0.0 |
|
|
0.0 |
|
|
} + |
|
|
} + |
|
|
if (isFloatValue > 0) { |
|
|
|
|
|
(FLOAT_MAX_VALUE+1 - isFloatValue) / FLOAT_MAX_VALUE.toDouble() * FLOAT_WEIGHTING |
|
|
|
|
|
} else { |
|
|
|
|
|
0.0 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (isDenseValue > 0) { |
|
|
|
|
|
(DENSE_MAX_VALUE + 1 - isDenseValue) / DENSE_MAX_VALUE.toDouble() * DENSE_WEIGHTING |
|
|
|
|
|
} else { |
|
|
|
|
|
0.0 |
|
|
|
|
|
} + |
|
|
|
|
|
if (isFloatValue > 0) { |
|
|
|
|
|
(FLOAT_MAX_VALUE + 1 - isFloatValue) / FLOAT_MAX_VALUE.toDouble() * FLOAT_WEIGHTING |
|
|
|
|
|
} else { |
|
|
|
|
|
0.0 |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -277,11 +496,11 @@ open class ProductionScheduleService( |
|
|
return finishedGoodList |
|
|
return finishedGoodList |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
open fun generateRoughScheduleByWeek(fgList : ArrayList<FinishedGood>): HashMap<RoughScheduleObj, Double> { |
|
|
|
|
|
|
|
|
open fun generateRoughScheduleByWeek(fgList: ArrayList<FinishedGood>): HashMap<RoughScheduleObj, Double> { |
|
|
val roughScheduleOutput: HashMap<RoughScheduleObj, Double> = HashMap(); |
|
|
val roughScheduleOutput: HashMap<RoughScheduleObj, Double> = HashMap(); |
|
|
|
|
|
|
|
|
var itemCount = 1 |
|
|
var itemCount = 1 |
|
|
for(fg:FinishedGood in fgList) { |
|
|
|
|
|
|
|
|
for (fg: FinishedGood in fgList) { |
|
|
val roughScheduleRecord: RoughScheduleObj = roughScheduleByItem(fg); |
|
|
val roughScheduleRecord: RoughScheduleObj = roughScheduleByItem(fg); |
|
|
itemCount++ |
|
|
itemCount++ |
|
|
roughScheduleOutput.put(roughScheduleRecord, roughScheduleRecord.totalDifference); |
|
|
roughScheduleOutput.put(roughScheduleRecord, roughScheduleRecord.totalDifference); |
|
@@ -307,17 +526,19 @@ open class ProductionScheduleService( |
|
|
roughScheduleRecord.totalDifference += roughScheduleRecord.productionSchedule[i] |
|
|
roughScheduleRecord.totalDifference += roughScheduleRecord.productionSchedule[i] |
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
else{//超過每日產量 |
|
|
|
|
|
var maxExtraProduction = Math.max((22000L - accProductionCount),0L); |
|
|
|
|
|
roughScheduleRecord.totalForgoneCount = roughScheduleRecord.totalForgoneCount + roughScheduleRecord.productionSchedule[i] - maxExtraProduction; |
|
|
|
|
|
|
|
|
} else {//超過每日產量 |
|
|
|
|
|
var maxExtraProduction = Math.max((22000L - accProductionCount), 0L); |
|
|
|
|
|
roughScheduleRecord.totalForgoneCount = |
|
|
|
|
|
roughScheduleRecord.totalForgoneCount + roughScheduleRecord.productionSchedule[i] - maxExtraProduction; |
|
|
roughScheduleRecord.productionSchedule[i] = maxExtraProduction.toDouble(); |
|
|
roughScheduleRecord.productionSchedule[i] = maxExtraProduction.toDouble(); |
|
|
accProductionCount += maxExtraProduction; |
|
|
accProductionCount += maxExtraProduction; |
|
|
|
|
|
|
|
|
//update close balance |
|
|
//update close balance |
|
|
roughScheduleRecord.closeBalance[i] = roughScheduleRecord.closeBalance[i] - roughScheduleRecord.productionSchedule[i] + maxExtraProduction.toDouble(); |
|
|
|
|
|
for (j in i+1 until 12){ |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] = roughScheduleRecord.closeBalance[j] - roughScheduleRecord.productionSchedule[i] + maxExtraProduction.toDouble(); |
|
|
|
|
|
|
|
|
roughScheduleRecord.closeBalance[i] = |
|
|
|
|
|
roughScheduleRecord.closeBalance[i] - roughScheduleRecord.productionSchedule[i] + maxExtraProduction.toDouble(); |
|
|
|
|
|
for (j in i + 1 until 12) { |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] = |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] - roughScheduleRecord.productionSchedule[i] + maxExtraProduction.toDouble(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Update totalDifference in roughScheduleRecord |
|
|
// Update totalDifference in roughScheduleRecord |
|
@@ -328,12 +549,13 @@ open class ProductionScheduleService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//解決拖欠的數量 |
|
|
//解決拖欠的數量 |
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries){ |
|
|
|
|
|
|
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries) { |
|
|
if (accProductionCount + ceil(roughScheduleRecord.productionSchedule[i]).toLong() <= 22000) { //沒有超過每日產量 |
|
|
if (accProductionCount + ceil(roughScheduleRecord.productionSchedule[i]).toLong() <= 22000) { //沒有超過每日產量 |
|
|
if(roughScheduleRecord.totalForgoneCount > 0.0){ |
|
|
|
|
|
if(accProductionCount + ceil(roughScheduleRecord.totalForgoneCount).toLong() <=22000){ |
|
|
|
|
|
|
|
|
if (roughScheduleRecord.totalForgoneCount > 0.0) { |
|
|
|
|
|
if (accProductionCount + ceil(roughScheduleRecord.totalForgoneCount).toLong() <= 22000) { |
|
|
//可以全做 |
|
|
//可以全做 |
|
|
roughScheduleRecord.productionSchedule[i] = roughScheduleRecord.productionSchedule[i] + ceil(roughScheduleRecord.totalForgoneCount).toLong(); |
|
|
|
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] = |
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] + ceil(roughScheduleRecord.totalForgoneCount).toLong(); |
|
|
|
|
|
|
|
|
accProductionCount += ceil(roughScheduleRecord.totalForgoneCount).toLong(); |
|
|
accProductionCount += ceil(roughScheduleRecord.totalForgoneCount).toLong(); |
|
|
|
|
|
|
|
@@ -341,23 +563,26 @@ open class ProductionScheduleService( |
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
|
|
|
|
|
|
//update close balance |
|
|
//update close balance |
|
|
for (j in i until 12){ |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] = roughScheduleRecord.closeBalance[j] + roughScheduleRecord.totalForgoneCount; |
|
|
|
|
|
|
|
|
for (j in i until 12) { |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] = |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] + roughScheduleRecord.totalForgoneCount; |
|
|
} |
|
|
} |
|
|
roughScheduleRecord.totalForgoneCount = 0.0; |
|
|
roughScheduleRecord.totalForgoneCount = 0.0; |
|
|
} |
|
|
|
|
|
else{ |
|
|
|
|
|
|
|
|
} else { |
|
|
//只能做部分 |
|
|
//只能做部分 |
|
|
var maxExtraProduction = Math.max((22000L - accProductionCount), 0L); |
|
|
var maxExtraProduction = Math.max((22000L - accProductionCount), 0L); |
|
|
roughScheduleRecord.totalForgoneCount = Math.max((roughScheduleRecord.totalForgoneCount - maxExtraProduction), 0.0); |
|
|
|
|
|
|
|
|
roughScheduleRecord.totalForgoneCount = |
|
|
|
|
|
Math.max((roughScheduleRecord.totalForgoneCount - maxExtraProduction), 0.0); |
|
|
|
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] = roughScheduleRecord.productionSchedule[i] + maxExtraProduction; |
|
|
|
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] = |
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] + maxExtraProduction; |
|
|
accProductionCount += maxExtraProduction; |
|
|
accProductionCount += maxExtraProduction; |
|
|
roughScheduleRecord.totalDifference += maxExtraProduction; |
|
|
roughScheduleRecord.totalDifference += maxExtraProduction; |
|
|
|
|
|
|
|
|
//update close balance |
|
|
//update close balance |
|
|
for (j in i until 12){ |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] = roughScheduleRecord.closeBalance[j] + maxExtraProduction; |
|
|
|
|
|
|
|
|
for (j in i until 12) { |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] = |
|
|
|
|
|
roughScheduleRecord.closeBalance[j] + maxExtraProduction; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -366,7 +591,7 @@ open class ProductionScheduleService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//debug use |
|
|
//debug use |
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries){ |
|
|
|
|
|
|
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries) { |
|
|
println("[RUN" + i + "][index:" + totalDifference + "] - " + roughScheduleRecord.fgDetail?.name + " - " + roughScheduleRecord.productionSchedule[i]); |
|
|
println("[RUN" + i + "][index:" + totalDifference + "] - " + roughScheduleRecord.fgDetail?.name + " - " + roughScheduleRecord.productionSchedule[i]); |
|
|
} |
|
|
} |
|
|
println("Total Production Count $accProductionCount"); |
|
|
println("Total Production Count $accProductionCount"); |
|
@@ -377,33 +602,38 @@ open class ProductionScheduleService( |
|
|
return roughScheduleOutput |
|
|
return roughScheduleOutput |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
open fun roughScheduleByItem(fg: FinishedGood): RoughScheduleObj{ |
|
|
|
|
|
|
|
|
open fun roughScheduleByItem(fg: FinishedGood): RoughScheduleObj { |
|
|
val minStockCount: Double = fg.lastMonthAvgSalesCount * 2 //TODO: change to multiple by user config setting |
|
|
val minStockCount: Double = fg.lastMonthAvgSalesCount * 2 //TODO: change to multiple by user config setting |
|
|
val stockDifference: Double = minStockCount - fg.openBalance |
|
|
val stockDifference: Double = minStockCount - fg.openBalance |
|
|
val productionSchedule: Array<Double> = Array<Double>(12, { 0.0 }) |
|
|
val productionSchedule: Array<Double> = Array<Double>(12, { 0.0 }) |
|
|
|
|
|
|
|
|
//首日粗排產量 —> 取結果,或是fg本身生產上限,並不可小於0 |
|
|
//首日粗排產量 —> 取結果,或是fg本身生產上限,並不可小於0 |
|
|
productionSchedule[0] = Math.max( |
|
|
productionSchedule[0] = Math.max( |
|
|
ceil(Math.min( |
|
|
|
|
|
(stockDifference + fg.lastMonthAvgSalesCount), |
|
|
|
|
|
fg.fgProductionLimit |
|
|
|
|
|
)), |
|
|
|
|
|
|
|
|
ceil( |
|
|
|
|
|
Math.min( |
|
|
|
|
|
(stockDifference + fg.lastMonthAvgSalesCount), |
|
|
|
|
|
fg.fgProductionLimit |
|
|
|
|
|
) |
|
|
|
|
|
), |
|
|
0.0 |
|
|
0.0 |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
val closeBalance: Array<Double> = Array<Double>(12, { 0.0 }) |
|
|
val closeBalance: Array<Double> = Array<Double>(12, { 0.0 }) |
|
|
closeBalance[0] = /*Math.floor(*/fg.openBalance + productionSchedule[0] - fg.lastMonthAvgSalesCount/*)*/; |
|
|
closeBalance[0] = /*Math.floor(*/fg.openBalance + productionSchedule[0] - fg.lastMonthAvgSalesCount/*)*/; |
|
|
|
|
|
|
|
|
for (i in 1 until 12){ |
|
|
|
|
|
|
|
|
for (i in 1 until 12) { |
|
|
//最少庫存-closeBalance 有可能小於0,所以必須要確保輸出>=0 |
|
|
//最少庫存-closeBalance 有可能小於0,所以必須要確保輸出>=0 |
|
|
productionSchedule[i] = Math.max( |
|
|
|
|
|
ceil(Math.min( |
|
|
|
|
|
(minStockCount - closeBalance[i-1] + fg.lastMonthAvgSalesCount), |
|
|
|
|
|
fg.fgProductionLimit |
|
|
|
|
|
)), |
|
|
|
|
|
|
|
|
productionSchedule[i] = Math.max( |
|
|
|
|
|
ceil( |
|
|
|
|
|
Math.min( |
|
|
|
|
|
(minStockCount - closeBalance[i - 1] + fg.lastMonthAvgSalesCount), |
|
|
|
|
|
fg.fgProductionLimit |
|
|
|
|
|
) |
|
|
|
|
|
), |
|
|
0.0 |
|
|
0.0 |
|
|
) |
|
|
) |
|
|
closeBalance[i] = /*Math.floor(*/closeBalance[i-1] + productionSchedule[i] - fg.lastMonthAvgSalesCount/*)*/; |
|
|
|
|
|
|
|
|
closeBalance[i] = /*Math.floor(*/ |
|
|
|
|
|
closeBalance[i - 1] + productionSchedule[i] - fg.lastMonthAvgSalesCount/*)*/; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var totalProductionCount: Double = 0.0 |
|
|
var totalProductionCount: Double = 0.0 |
|
@@ -425,7 +655,11 @@ open class ProductionScheduleService( |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
open fun saveRoughScheduleOutput(sortedEntries: List<Map.Entry<RoughScheduleObj, Double>>, accProdCount: Double, fgCount: Long) { |
|
|
|
|
|
|
|
|
open fun saveRoughScheduleOutput( |
|
|
|
|
|
sortedEntries: List<Map.Entry<RoughScheduleObj, Double>>, |
|
|
|
|
|
accProdCount: Double, |
|
|
|
|
|
fgCount: Long |
|
|
|
|
|
) { |
|
|
val tempObj = ProductionSchedule() |
|
|
val tempObj = ProductionSchedule() |
|
|
tempObj.id = -1; |
|
|
tempObj.id = -1; |
|
|
tempObj.scheduleAt = LocalDateTime.now() |
|
|
tempObj.scheduleAt = LocalDateTime.now() |
|
@@ -439,7 +673,7 @@ open class ProductionScheduleService( |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private fun saveProductionScheduleToDatabase(newRecord: ProductionSchedule): Long?{ |
|
|
|
|
|
|
|
|
private fun saveProductionScheduleToDatabase(newRecord: ProductionSchedule): Long? { |
|
|
try { |
|
|
try { |
|
|
val savedItem = productionScheduleRepository.saveAndFlush(newRecord) |
|
|
val savedItem = productionScheduleRepository.saveAndFlush(newRecord) |
|
|
return savedItem.id |
|
|
return savedItem.id |
|
@@ -449,19 +683,21 @@ open class ProductionScheduleService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private fun saveRoughScheduleLineToDatabase(parentId: Long, roughScheduleObj: RoughScheduleObj) { |
|
|
private fun saveRoughScheduleLineToDatabase(parentId: Long, roughScheduleObj: RoughScheduleObj) { |
|
|
for (i in 5 until 12){ |
|
|
|
|
|
|
|
|
for (i in 5 until 12) { |
|
|
try { |
|
|
try { |
|
|
|
|
|
val prodSchedule = productionScheduleRepository.findById(parentId).get() |
|
|
var savedItem = ProductionScheduleLine() |
|
|
var savedItem = ProductionScheduleLine() |
|
|
savedItem.id = -1; |
|
|
savedItem.id = -1; |
|
|
savedItem.prodScheduleId = parentId; |
|
|
|
|
|
savedItem.itemId = roughScheduleObj.fgDetail?.id ?: -1; |
|
|
|
|
|
|
|
|
// savedItem.prodScheduleId = parentId; |
|
|
|
|
|
savedItem.productionSchedule = prodSchedule; |
|
|
|
|
|
savedItem.item.id = roughScheduleObj.fgDetail?.id ?: -1; |
|
|
savedItem.lastMonthAvgSales = roughScheduleObj.fgDetail?.lastMonthAvgSalesCount ?: 0.0; |
|
|
savedItem.lastMonthAvgSales = roughScheduleObj.fgDetail?.lastMonthAvgSalesCount ?: 0.0; |
|
|
savedItem.refScheduleId = null; |
|
|
savedItem.refScheduleId = null; |
|
|
savedItem.approverId = null; |
|
|
savedItem.approverId = null; |
|
|
savedItem.estCloseBal = roughScheduleObj.closeBalance[i] |
|
|
savedItem.estCloseBal = roughScheduleObj.closeBalance[i] |
|
|
savedItem.prodQty = roughScheduleObj.productionSchedule[i] |
|
|
savedItem.prodQty = roughScheduleObj.productionSchedule[i] |
|
|
savedItem.type = "rough" |
|
|
savedItem.type = "rough" |
|
|
savedItem.assignDate = i-4L; |
|
|
|
|
|
|
|
|
savedItem.assignDate = i - 4L; |
|
|
savedItem.itemPriority = roughScheduleObj.itemPriority[i] |
|
|
savedItem.itemPriority = roughScheduleObj.itemPriority[i] |
|
|
productionScheduleLineRepository.saveAndFlush(savedItem) |
|
|
productionScheduleLineRepository.saveAndFlush(savedItem) |
|
|
|
|
|
|
|
@@ -530,5 +766,4 @@ open class ProductionScheduleService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |