findOrFail($data['work_center_id']); $eventType = $data['event_type']; $quantity = (float) ($data['quantity'] ?? 0); $goodQuantity = (float) ($data['good_quantity'] ?? 0); $scrapQuantity = (float) ($data['scrap_quantity'] ?? 0); if ($eventType === 'complete') { $goodQuantity = $quantity > 0 ? $quantity : $goodQuantity; } elseif ($eventType === 'scrap') { $scrapQuantity = $quantity > 0 ? $quantity : $scrapQuantity; } $event = ProductionEvent::create([ 'business_id' => $businessId, 'work_center_id' => $workCenter->id, 'ie_work_order_id' => $data['ie_work_order_id'] ?? null, 'event_type' => $eventType, 'quantity' => $quantity, 'good_quantity' => $goodQuantity, 'scrap_quantity' => $scrapQuantity, 'recorded_at' => $data['recorded_at'] ?? now(), 'recorded_by' => $data['recorded_by'] ?? auth()->id(), 'lot_no' => $data['lot_no'] ?? null, 'serial_no' => $data['serial_no'] ?? null, ]); $this->syncWorkOrderProgress($event); return $event; } public function syncWorkOrderProgress(ProductionEvent $event): void { if (! $event->ie_work_order_id) { return; } $workOrder = ManufacturingWorkOrder::where('business_id', $event->business_id) ->find($event->ie_work_order_id); if (! $workOrder) { return; } if ($event->event_type === 'start') { $updates = ['status' => 'in_progress']; if (empty($workOrder->actual_start_date)) { $updates['actual_start_date'] = now()->toDateString(); } $workOrder->update($updates); return; } if (! in_array($event->event_type, ['complete', 'scrap'], true)) { return; } $completedQty = ProductionEvent::forBusiness($event->business_id) ->where('ie_work_order_id', $workOrder->id) ->where('event_type', 'complete') ->sum('good_quantity'); $updates = ['completed_quantity' => $completedQty]; if ($completedQty >= (float) $workOrder->planned_quantity && (float) $workOrder->planned_quantity > 0) { $updates['actual_end_date'] = now()->toDateString(); $updates['status'] = 'completed'; } $workOrder->update($updates); } public function isWorkCenterRunning(int $businessId, int $workCenterId): bool { $lastEvent = ProductionEvent::forBusiness($businessId) ->where('work_center_id', $workCenterId) ->orderByDesc('recorded_at') ->orderByDesc('id') ->first(); return $lastEvent && $lastEvent->event_type === 'start'; } }