where('profit_center_id', $profitCenterId) ->with('deliverySchedule') ->first(); if (! $assignment?->deliverySchedule) { return null; } $supplier = Supplier::find($supplierId); $pc = ProfitCenter::find($profitCenterId); if (! $supplier || ! $pc) { return null; } $leadDays = 0; $startDay = $orderDateTime->copy()->startOfDay(); if ($supplier->hasDeliveryConstraint) { $cutOffHour = (int) $supplier->orderCutOffTime; $leadDays = (int) ($supplier->deliveryLeadTime / 24); // Ha a leadási határidő UTÁN vagyunk, holnap az első számítandó munkanap if ($orderDateTime->hour >= $cutOffHour) { $startDay->addDay(); } } return $this->findNextDeliveryDay($startDay, $supplier, $pc, $leadDays); } /** * Munkanapokban számol előre ($leadDays darabot), majd az első olyan napot adja vissza, * amelyik szállítási nap is. */ private function findNextDeliveryDay( Carbon $candidate, Supplier $supplier, ProfitCenter $pc, int $leadDays, ): ?Carbon { $workingDaysCounted = 0; // Max. 365 nap iteráció (végtelen ciklus-védelem) for ($i = 0; $i < 365; $i++) { if ($this->workCalendarService->isWorkDay($candidate)) { if ($workingDaysCounted >= $leadDays) { // Átfutási idő letelt – az első szállítási napot keressük if ($this->deliveryCalendarService->isDeliveryDay($pc, $supplier, $candidate)) { return $candidate->copy(); } } else { $workingDaysCounted++; } } $candidate->addDay(); } return null; } }