|
@@ -36,31 +36,67 @@ open class SchedulingService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//完成初步fg粗排後檢查調整 |
|
|
//完成初步fg粗排後檢查調整 |
|
|
for (i in 5 until 12) { |
|
|
|
|
|
|
|
|
for (i in 0 until 12) { |
|
|
var accProductionCount = 0L; |
|
|
var accProductionCount = 0L; |
|
|
|
|
|
|
|
|
// Sort by totalDifference before processing |
|
|
// Sort by totalDifference before processing |
|
|
val sortedEntries = roughScheduleOutput.entries.sortedBy { it.value } |
|
|
val sortedEntries = roughScheduleOutput.entries.sortedBy { it.value } |
|
|
|
|
|
|
|
|
|
|
|
//原排產 |
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries) { |
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries) { |
|
|
kotlin.io.println("[RUN" + i + "][index:" + totalDifference + "] - " + roughScheduleRecord.fgDetail?.name); |
|
|
|
|
|
|
|
|
|
|
|
if (accProductionCount + ceil(totalDifference).toLong() < 22000) { //沒有超過每日產量 |
|
|
|
|
|
|
|
|
if (accProductionCount + ceil(roughScheduleRecord.productionSchedule[i]).toLong() <= 22000) { //沒有超過每日產量 |
|
|
accProductionCount += ceil(roughScheduleRecord.productionSchedule[i]).toLong() //分開日子算 |
|
|
accProductionCount += ceil(roughScheduleRecord.productionSchedule[i]).toLong() //分開日子算 |
|
|
|
|
|
|
|
|
|
|
|
roughScheduleRecord.totalDifference += roughScheduleRecord.productionSchedule[i] |
|
|
|
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
else{//超過每日產量 |
|
|
|
|
|
var maxExtraProduction = Math.max((22000L - accProductionCount),0L); |
|
|
|
|
|
roughScheduleRecord.totalForgoneCount = roughScheduleRecord.totalForgoneCount + roughScheduleRecord.productionSchedule[i] - maxExtraProduction; |
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] = maxExtraProduction.toDouble(); |
|
|
|
|
|
accProductionCount += maxExtraProduction; |
|
|
|
|
|
|
|
|
|
|
|
//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(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Update totalDifference in roughScheduleRecord |
|
|
|
|
|
roughScheduleRecord.totalDifference += (roughScheduleRecord.productionSchedule[i] - maxExtraProduction.toDouble()); |
|
|
|
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//解決拖欠的數量 |
|
|
|
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries){ |
|
|
|
|
|
if (accProductionCount + ceil(roughScheduleRecord.productionSchedule[i]).toLong() <= 22000) { //沒有超過每日產量 |
|
|
if(roughScheduleRecord.totalForgoneCount > 0.0){ |
|
|
if(roughScheduleRecord.totalForgoneCount > 0.0){ |
|
|
//優先解決拖欠的數量 |
|
|
|
|
|
if(accProductionCount + ceil(roughScheduleRecord.totalForgoneCount).toLong() <22000){ |
|
|
|
|
|
|
|
|
if(accProductionCount + ceil(roughScheduleRecord.totalForgoneCount).toLong() <=22000){ |
|
|
//可以全做 |
|
|
//可以全做 |
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] = roughScheduleRecord.productionSchedule[i] + ceil(roughScheduleRecord.totalForgoneCount).toLong(); |
|
|
|
|
|
|
|
|
accProductionCount += ceil(roughScheduleRecord.totalForgoneCount).toLong(); |
|
|
accProductionCount += ceil(roughScheduleRecord.totalForgoneCount).toLong(); |
|
|
|
|
|
|
|
|
|
|
|
roughScheduleRecord.totalDifference += roughScheduleRecord.totalForgoneCount; |
|
|
|
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
|
|
|
|
|
|
|
|
|
//update close balance |
|
|
|
|
|
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 = 22000L - accProductionCount; |
|
|
|
|
|
roughScheduleRecord.totalForgoneCount = roughScheduleRecord.totalForgoneCount - maxExtraProduction; |
|
|
|
|
|
|
|
|
var maxExtraProduction = Math.max((22000L - accProductionCount), 0L); |
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
//update close balance |
|
|
//update close balance |
|
|
for (j in i until 12){ |
|
|
for (j in i until 12){ |
|
@@ -69,27 +105,14 @@ open class SchedulingService( |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
roughScheduleRecord.totalDifference += roughScheduleRecord.productionSchedule[i] |
|
|
|
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
|
|
|
} |
|
|
|
|
|
else{//超過每日產量 |
|
|
|
|
|
var maxExtraProduction = 22000L - accProductionCount; |
|
|
|
|
|
roughScheduleRecord.totalForgoneCount = roughScheduleRecord.totalForgoneCount + roughScheduleRecord.productionSchedule[i] - maxExtraProduction; |
|
|
|
|
|
roughScheduleRecord.productionSchedule[i] = maxExtraProduction.toDouble(); |
|
|
|
|
|
accProductionCount += maxExtraProduction; |
|
|
|
|
|
|
|
|
|
|
|
//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(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Update totalDifference in roughScheduleRecord |
|
|
|
|
|
roughScheduleRecord.totalDifference += roughScheduleRecord.productionSchedule[i] + maxExtraProduction.toDouble(); |
|
|
|
|
|
roughScheduleOutput[roughScheduleRecord] = roughScheduleRecord.totalDifference |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//debug use |
|
|
|
|
|
for ((roughScheduleRecord, totalDifference) in sortedEntries){ |
|
|
|
|
|
kotlin.io.println("[RUN" + i + "][index:" + totalDifference + "] - " + roughScheduleRecord.fgDetail?.name + " - " + roughScheduleRecord.productionSchedule[i]); |
|
|
} |
|
|
} |
|
|
|
|
|
kotlin.io.println("Total Production Count $accProductionCount"); |
|
|
kotlin.io.println("========================================"); |
|
|
kotlin.io.println("========================================"); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
@@ -98,37 +121,37 @@ open class SchedulingService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
open fun roughScheduleByItem(fg: FinishedGood): RoughScheduleObj{ |
|
|
open fun roughScheduleByItem(fg: FinishedGood): RoughScheduleObj{ |
|
|
val minStockCount: Double = fg.lastMonthAvgSalesCount * 1.5 |
|
|
|
|
|
|
|
|
val minStockCount: Double = fg.lastMonthAvgSalesCount * 2 |
|
|
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( |
|
|
Math.min( |
|
|
|
|
|
|
|
|
ceil(Math.min( |
|
|
(stockDifference + fg.lastMonthAvgSalesCount), |
|
|
(stockDifference + fg.lastMonthAvgSalesCount), |
|
|
fg.fgProductionLimit |
|
|
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] = 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( |
|
|
productionSchedule[i] = Math.max( |
|
|
Math.min( |
|
|
|
|
|
|
|
|
ceil(Math.min( |
|
|
(minStockCount - closeBalance[i-1] + fg.lastMonthAvgSalesCount), |
|
|
(minStockCount - closeBalance[i-1] + fg.lastMonthAvgSalesCount), |
|
|
fg.fgProductionLimit |
|
|
fg.fgProductionLimit |
|
|
), |
|
|
|
|
|
|
|
|
)), |
|
|
0.0 |
|
|
0.0 |
|
|
) |
|
|
) |
|
|
closeBalance[i] = 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 |
|
|
|
|
|
|
|
|
for (i in 0 until 12) { |
|
|
|
|
|
|
|
|
for (i in 5 until 12) { |
|
|
totalProductionCount = totalProductionCount + productionSchedule[i]; |
|
|
totalProductionCount = totalProductionCount + productionSchedule[i]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|