diff --git a/src/queues/queues.service.ts b/src/queues/queues.service.ts index 605fbf31cbf6df9f22c5dd3688047d1f0afae752..55d21c85d2ca1748d577d155547be9fa806bf569 100644 --- a/src/queues/queues.service.ts +++ b/src/queues/queues.service.ts @@ -63,25 +63,31 @@ export class QueuesService { // ฟังก์ชันใหม่: _reverseDeduction() ที่ return ทั้ง leftover และ totalProduced // ============================================================================ // _reverseDeduction() แบบใหม่ ที่รองรับ grouping ตาม OrderID + // ฟังก์ชัน _reverseDeduction() ที่แยกกลุ่มโดยใช้ global key = `${orderId}|${day}|${itemType}-${itemID}` private async _reverseDeduction(newlyCreatedQueues: Queue[]) { - // สร้าง map เพื่อเก็บยอดผลิตและยอดที่ถูกใช้สำหรับแต่ละ global key - // globalKey = `${orderId}|${itemType}-${itemID}` + // Define type สำหรับ entry ในกลุ่ม type GroupEntry = { orderId: number | null; - key: string; + day: string; // YYYY-MM-DD + key: string; // itemKey: `${itemType}-${itemID}` totalProduced: number; totalUsed: number; }; + const groupMap = new Map<string, GroupEntry>(); - // 1. รวมยอดผลิตจากแต่ละ Queue (direct production) + // 1. รวมยอดผลิต (direct production) จากแต่ละ Queue for (const q of newlyCreatedQueues) { const orderId = q.order ? q.order.OrderID : null; + const day = q.startTime + ? q.startTime.toISOString().substring(0, 10) + : 'none'; const itemKey = `${q.itemType}-${q.itemID}`; - const globalKey = `${orderId}|${itemKey}`; + const globalKey = `${orderId}|${day}|${itemKey}`; const producedQty = q.producedQuantity || 0; const current = groupMap.get(globalKey) || { orderId, + day, key: itemKey, totalProduced: 0, totalUsed: 0, @@ -90,7 +96,7 @@ export class QueuesService { groupMap.set(globalKey, current); } - // 2. โหลด Recipe ทั้งหมด (เชื่อม ingredients) + // 2. โหลด Recipe ทั้งหมด (พร้อม ingredients) const recipes = await this.recipeRepository.find({ relations: ['ingredients', 'ingredients.material'], }); @@ -100,19 +106,24 @@ export class QueuesService { recipeMap.set(outKey, r); } - // 3. สำหรับแต่ละ Queue ถ้ามี Recipe → หักยอด input material (เฉพาะ Material) + // 3. สำหรับแต่ละ Queue ที่มี Recipe → หักยอด input material (เฉพาะ Material) for (const q of newlyCreatedQueues) { const outKey = `${q.itemType}-${q.itemID}`; const recipe = recipeMap.get(outKey); if (recipe && recipe.ingredients && recipe.ingredients.length > 0) { const producedQty = q.producedQuantity || 0; + const orderId = q.order ? q.order.OrderID : null; + // ใช้วันจาก q.startTime + const day = q.startTime + ? q.startTime.toISOString().substring(0, 10) + : 'none'; for (const ing of recipe.ingredients) { const ingKey = `MATERIAL-${ing.material.MaterialID}`; const usedQty = (ing.quantityNeed || 0) * producedQty; - const orderId = q.order ? q.order.OrderID : null; - const globalKey = `${orderId}|${ingKey}`; + const globalKey = `${orderId}|${day}|${ingKey}`; const current = groupMap.get(globalKey) || { orderId, + day, key: ingKey, totalProduced: 0, totalUsed: 0, @@ -126,6 +137,7 @@ export class QueuesService { // 4. คำนวณ leftover = totalProduced - totalUsed (ถ้าติดลบ ให้เป็น 0) const results = Array.from(groupMap.values()).map((entry) => ({ orderId: entry.orderId, + day: entry.day, key: entry.key, // ex: "MATERIAL-12" or "PRODUCT-2" leftover: entry.totalProduced - entry.totalUsed < 0 @@ -369,11 +381,14 @@ export class QueuesService { // --- STEP 2: Save Queues --- const savedQueues = await this.queueRepository.save(newQueues); - // --- STEP 3: Group Queues by OrderID + item (สร้าง ProductionTarget เดิม) --- + // --- STEP 3: Group Queues by OrderID + Day + Item (สร้าง ProductionTarget เดิม) --- const targetMap = new Map<string, ProductionTarget>(); - for (const q of savedQueues) { - const key = `${q.order?.OrderID || 'none'}|${q.itemType}-${q.itemID}`; + const orderId = q.order ? q.order.OrderID : 'none'; + const day = q.startTime + ? q.startTime.toISOString().substring(0, 10) + : 'none'; + const key = `${orderId}|${q.itemType}-${q.itemID}|${day}`; const producedQty = q.producedQuantity || 0; const existing = targetMap.get(key); @@ -404,7 +419,7 @@ export class QueuesService { itemType: q.itemType, order: q.order ?? null, page: q.page, - TargetProduced: producedQty, // temporary,จะอัปเดตใหม่ + TargetProduced: producedQty, // temporary, จะอัปเดตใหม่ ActualProduced: 0, startTime: q.startTime, endTime: q.finishTime, @@ -421,20 +436,24 @@ export class QueuesService { const targets = Array.from(targetMap.values()); await this.productionTargetRepository.save(targets); - // --- STEP 4: Reverse Deduction (แยกตาม Order) --- + // --- STEP 4: Reverse Deduction (แยกตาม OrderID และวัน) --- const deduction = await this._reverseDeduction(savedQueues); - // deduction จะได้ array ของ { orderId, key, leftover, totalProduced } + // deduction จะได้ array ของ { orderId, day, key, leftover, totalProduced } - // สร้าง map จาก deduction ด้วย global key = `${orderId}|${key}` + // สร้าง map จาก deduction ด้วย global key = `${orderId}|${key}|${day}` const leftoverMap = new Map<string, number>(); for (const entry of deduction) { - const globalKey = `${entry.orderId || 'none'}|${entry.key}`; + const globalKey = `${entry.orderId || 'none'}|${entry.key}|${entry.day}`; leftoverMap.set(globalKey, entry.leftover); } // --- STEP 5: Update ProductionTarget.TargetProduced ให้เป็น leftover --- for (const target of targets) { - const globalKey = `${target.order?.OrderID || 'none'}|${target.itemType}-${target.itemID}`; + const orderId = target.order ? target.order.OrderID : 'none'; + const day = target.startTime + ? target.startTime.toISOString().substring(0, 10) + : 'none'; + const globalKey = `${orderId}|${target.itemType}-${target.itemID}|${day}`; const leftover = leftoverMap.get(globalKey) ?? 0; target.TargetProduced = leftover; }