refactor(booking): extract ServiceBookingCalculator from the controller
"Allowed duration of a service combination" lived inside AppointmentController::serviceSlots(). Three upcoming callers need the same computation (PATCH duration validation, service-aware reschedule, reserve conversion); copying it would mean four variants with four different edge-case behaviours. The extraction is behaviour-preserving: BaseController::error() and ExceptionSubscriber emit an identical envelope, so returning $this->error() was replaced by throwing AppException with the same code/message/field. Tenant ownership now goes through TenantOwnershipChecker::belongsToPair() (the documented single point) instead of an inline section pair comparison. The repo property is named itemRepo on purpose: TenantLookupInventoryTest only counts recognised property names, so any other name would slip past the safety net. The naive duration sum is kept deliberately — switching to solo/additional minutes is task 04 and changes one line here. Task: docs/new_feture/taskes/task-00-service-mode-completion/ Slot-mode contract: unchanged (--group=slot-mode-frozen green) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Appointment\ValueObject;
|
||||
|
||||
use App\ClinicService\Entity\ServiceItem;
|
||||
|
||||
/**
|
||||
* نتیجهٔ محاسبهٔ مدت یک ترکیب سرویس در حالت نوبتدهی سرویسی.
|
||||
*
|
||||
* `bufferMinutes` فاصلهٔ بین دو نوبت است و **جزو مدت نوبت نیست**: زمان پایانِ ذخیرهشدهٔ
|
||||
* نوبت `start + totalMinutes` است، نه `start + totalMinutes + buffer`. همان قاعدهای که
|
||||
* {@see \App\Appointment\Service\SlotCalculatorService::getServiceStartTimes()} دارد.
|
||||
*/
|
||||
final readonly class ServiceBookingDuration
|
||||
{
|
||||
/**
|
||||
* @param ServiceItem[] $serviceItems به ترتیب uuidهای ورودی
|
||||
* @param string[] $warnings پیامهای فارسی برای نمایش؛ مانع عملیات نیستند
|
||||
*/
|
||||
public function __construct(
|
||||
public int $totalMinutes,
|
||||
public int $bufferMinutes,
|
||||
public array $serviceItems,
|
||||
public array $warnings = [],
|
||||
) {}
|
||||
|
||||
/** زمان پایان نوبت برای یک زمان شروع مشخص — بدون بافر. */
|
||||
public function endFor(int $slotStart): int
|
||||
{
|
||||
return $slotStart + $this->totalMinutes * 60;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user