A DeliveryCalendarService 4. prioritása a WorkCalendarService::isWorkDay()-t hívta, ami a naptárban nem szereplő napoknál a hétvégére esett vissza. Így egy hétvégét is tartalmazó sablon szombat/vasárnap mezőit sosem érte el a kiértékelés (5. prioritás), és csak egyedi felülbírálással lehetett hétvégi szállítást engedni. - WorkCalendarService: új isHoliday(), ami csak a work_calendars ünnepnap rekordjaira ad true-t, a naptári hétvégére nem. Az isWorkDay() változatlan. - DeliveryCalendarService: a 4. prioritás mostantól isHoliday()-t használ, így a hétvégéről a heti sablon dönt. Ünnepnap továbbra is tilt. - NextDeliveryDateCalculatorService: a szállítási nap keresése kikerült az isWorkDay() blokkból, különben a hétvége a következő szállítási nap számításánál továbbra is kimaradt volna. Az átfutási időbe az új countsTowardLeadTime() szerint a sablon hétvégi napjai is beleszámítanak, a H-P sablonok viselkedése változatlan. - DeliveryCalendarWidget: a szürke "inaktív" festés csak a nem szállítási hétvégékre megy rá. Mellékesen a szállítási napok ciklusa $date->addDay()-jel mutálta a kollekció Carbon objektumait, ez copy()-ra javítva. 7 új teszt, köztük a H-P sablon regresszió-őre. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
114 lines
4.3 KiB
PHP
114 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Enums\OverrideScope;
|
|
use App\Models\DeliveryCalendarOverride;
|
|
use App\Models\ProfitCenter;
|
|
use App\Models\ProfitCenterSupplierSchedule;
|
|
use App\Models\Supplier;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class DeliveryCalendarService extends ServiceBase
|
|
{
|
|
public function __construct(
|
|
protected WorkCalendarService $workCalendarService
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Eldönti, hogy egy adott Profit Center, Beszállító és Dátum kombináció esetén van-e szállítás.
|
|
*
|
|
* A felülbírálás kiértékelése 3 szinten történik (legspecifikusabbtól az általánosig):
|
|
* 1. Profitcenter-specifikus override (csak erre az 1 PC-re)
|
|
* 2. Régió-specifikus override (a PC városához/régiójához tartozó)
|
|
* 3. Általános override (az összes PC-re vonatkozó)
|
|
* Ha egyetlen szinten sem található override, folytatódik a normál kiértékelés.
|
|
*/
|
|
public function isDeliveryDay(ProfitCenter $pc, Supplier $supplier, Carbon $date, ?ProfitCenterSupplierSchedule $assignment = null): bool
|
|
{
|
|
$date = $date->startOfDay();
|
|
|
|
// 1. Prioritás: Profitcenter-specifikus felülbírálás
|
|
$override = DeliveryCalendarOverride::where('supplier_id', $supplier->id)
|
|
->whereDate('date', $date)
|
|
->where('override_scope', OverrideScope::ProfitCenter->value)
|
|
->where('profit_center_id', $pc->id)
|
|
->first();
|
|
|
|
if ($override) {
|
|
return $override->is_delivery_day;
|
|
}
|
|
|
|
// PC-hez rendelt szállítási sablon lekérése (2. és 5. prioritáshoz egyaránt szükséges)
|
|
if ($assignment === null) {
|
|
$assignment = ProfitCenterSupplierSchedule::where('profit_center_id', $pc->id)
|
|
->where('supplier_id', $supplier->id)
|
|
->with('deliverySchedule')
|
|
->first();
|
|
}
|
|
|
|
// 2. Prioritás: DeliverySchedule-specifikus felülbírálás (a PC-hez rendelt szállítási sablon alapján)
|
|
if ($assignment && $assignment->delivery_schedule_id) {
|
|
$override = DeliveryCalendarOverride::where('supplier_id', $supplier->id)
|
|
->whereDate('date', $date)
|
|
->where('override_scope', OverrideScope::Region->value)
|
|
->where('delivery_schedule_id', $assignment->delivery_schedule_id)
|
|
->first();
|
|
|
|
if ($override) {
|
|
return $override->is_delivery_day;
|
|
}
|
|
}
|
|
|
|
// 3. Prioritás: Általános felülbírálás (minden PC-re vonatkozik)
|
|
$override = DeliveryCalendarOverride::where('supplier_id', $supplier->id)
|
|
->whereDate('date', $date)
|
|
->where('override_scope', OverrideScope::General->value)
|
|
->first();
|
|
|
|
if ($override) {
|
|
return $override->is_delivery_day;
|
|
}
|
|
|
|
// 4. Prioritás: Hivatalos munkaszüneti nap (WorkCalendar)
|
|
// Csak a naptárban ünnepnapként rögzített dátum tilt. A naptári hétvége önmagában
|
|
// NEM: azt az 5. pont heti sablonja dönti el, különben egy hétvégét is tartalmazó
|
|
// sablon napjai elérhetetlenek maradnának (EV3-466).
|
|
if ($this->workCalendarService->isHoliday($date)) {
|
|
return false;
|
|
}
|
|
|
|
// 5. Prioritás: Heti sablon (Schedule)
|
|
if (! $assignment || ! $assignment->deliverySchedule || ! $assignment->deliverySchedule->is_active) {
|
|
return false;
|
|
}
|
|
|
|
$dayOfWeek = strtolower($date->format('l')); // 'monday', 'tuesday', etc.
|
|
|
|
return (bool) $assignment->deliverySchedule->{$dayOfWeek};
|
|
}
|
|
|
|
/**
|
|
* Visszaadja az elérhető szállítási napokat egy adott időszakban.
|
|
*
|
|
* @return Collection<Carbon>
|
|
*/
|
|
public function getAvailableDeliveryDates(ProfitCenter $pc, Supplier $supplier, Carbon $start, Carbon $end, ?ProfitCenterSupplierSchedule $assignment = null): Collection
|
|
{
|
|
$dates = collect();
|
|
$current = $start->copy()->startOfDay();
|
|
$end = $end->copy()->startOfDay();
|
|
|
|
while ($current <= $end) {
|
|
if ($this->isDeliveryDay($pc, $supplier, $current, $assignment)) {
|
|
$dates->push($current->copy());
|
|
}
|
|
$current->addDay();
|
|
}
|
|
|
|
return $dates;
|
|
}
|
|
}
|