From fe8176f31ea5c38304b2b579052de9a158060940 Mon Sep 17 00:00:00 2001 From: "jason.lam" Date: Tue, 13 May 2025 17:14:05 +0800 Subject: [PATCH] [rough schedule] update logic --- .../master/service/SchedulingService.kt | 91 ++++++++++++------- .../master/web/UomConversionController.kt | 46 +++++++++- 2 files changed, 100 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/SchedulingService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/SchedulingService.kt index 7058e7f..3618175 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/SchedulingService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/SchedulingService.kt @@ -36,31 +36,67 @@ open class SchedulingService( } //完成初步fg粗排後檢查調整 - for (i in 5 until 12) { + for (i in 0 until 12) { var accProductionCount = 0L; // Sort by totalDifference before processing val sortedEntries = roughScheduleOutput.entries.sortedBy { it.value } + //原排產 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() //分開日子算 + 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(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(); + + 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; } 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; accProductionCount += maxExtraProduction; + roughScheduleRecord.totalDifference += maxExtraProduction; //update close balance 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("========================================"); } @@ -98,37 +121,37 @@ open class SchedulingService( } 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 productionSchedule: Array = Array(12, { 0.0 }) //首日粗排產量 —> 取結果,或是fg本身生產上限,並不可小於0 productionSchedule[0] = Math.max( - Math.min( + ceil(Math.min( (stockDifference + fg.lastMonthAvgSalesCount), fg.fgProductionLimit - ), + )), 0.0 ) val closeBalance: Array = Array(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){ //最少庫存-closeBalance 有可能小於0,所以必須要確保輸出>=0 productionSchedule[i] = Math.max( - Math.min( + ceil(Math.min( (minStockCount - closeBalance[i-1] + fg.lastMonthAvgSalesCount), fg.fgProductionLimit - ), + )), 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 - for (i in 0 until 12) { + for (i in 5 until 12) { totalProductionCount = totalProductionCount + productionSchedule[i]; } diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/UomConversionController.kt b/src/main/java/com/ffii/fpsms/modules/master/web/UomConversionController.kt index 5860421..adb7d5b 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/web/UomConversionController.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/web/UomConversionController.kt @@ -43,7 +43,7 @@ class UomConversionController( val demoFGList = arrayListOf( FinishedGood( 1, - "豆腐花", + "豆腐花 - Tofu pudding", 3, 91.0, 31.0, @@ -51,7 +51,7 @@ class UomConversionController( ), FinishedGood( 2, - "中湯包", + "中湯包 - Chinese Soup", 4, 100.0, 72.5, @@ -59,12 +59,52 @@ class UomConversionController( ), FinishedGood( 3, - "苦瓜炒蛋", + "苦瓜炒蛋 - Fried Egg", 3, 700.0, 300.5, 22000.0 ), + FinishedGood( + 4, + "酸菜魚湯包 - Pickled fish soup", + 4, + 3000.0, + 600.5, + 22000.0 + ), + FinishedGood( + 5, + "咖哩雞球 - Curry chicken balls", + 5, + 3000.0, + 2150.5, + 22000.0 + ), + FinishedGood( + 6, + "水煮牛 - Spicy Beef", + 6, + 1000.0, + 2000.5, + 22000.0 + ), + FinishedGood( + 6, + "海鮮濃湯 - Sea Food Soup", + 6, + 0.0, + 3500.5, + 22000.0 + ), + FinishedGood( + 7, + "薯條 - Fries", + 7, + 0.0, + 3000.5, + 22000.0 + ), ); val result: HashMap = schedulingService.generateRoughScheduleByWeek(demoFGList)