ldc-boutique-cnc-sable/domain/Services/ShopperService.php
Jérémy Munsch c40016bba1
feat(order): implement order placement and related DTOs
- Add methods to convert OrderLine and DeliveryAddress to DTOs.
- Introduce toPlacedEvent method in Order to generate domain event.
- Enhance OrderUnit with Regate code mapping.
- Implement tests for new functionality and ensure correctness.
2026-10-29 20:35:13 +01:00

73 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Domain\Services;
use Domain\Models\Entities\Shop;
use Domain\Models\Entities\Shopper;
use Domain\Models\ValueObjects\Entities\ShopperId;
use Domain\Ports\Repositories\ShopperRepository;
use Domain\Ports\Repositories\ShopRepository;
class ShopperService
{
public function __construct(
private readonly ShopRepository $shopRepository,
private readonly ShopperRepository $shopperRepository
) {
}
public function getShopperFor(ShopperId $shopperId): ?Shopper
{
return $this->shopperRepository->find($shopperId);
}
/**
* Resolve the shop assigned to a customer through their employee record.
*
* Resolution order:
* 1. Direct exception override (shop_employee_exception table)
* 2. Site + service mapping (shop_employees table, with service_code)
* 3. Site-only mapping (shop_employees table, service_code IS NULL)
* 4. Default shop (shops.default = true)
*/
public function getShopFor(ShopperId $shopperId): ?Shop
{
$shopper = $this->getShopperFor($shopperId);
return $shopper !== null ? $this->resolveShopForEmployee($shopper) : null;
}
public function resolveShopForEmployee(Shopper $shopper): Shop
{
// 1. Check for a direct exception override
$exceptionShop = $this->shopRepository
->findExceptionShopFor($shopper->matricule);
if ($exceptionShop !== null) {
return $exceptionShop;
}
// 2. Try matching on site_code + service_code
$serviceShop = $this->shopRepository
->findShopForSiteAndService($shopper->site, $shopper->service);
if ($serviceShop !== null) {
return $serviceShop;
}
// 3. Fall back to site_code only (service_code IS NULL)
$siteShop = $this->shopRepository
->findShopForSiteAndService($shopper->site, null);
if ($siteShop !== null) {
return $siteShop;
}
// 4. Ultimate fallback: the default shop
return $this->shopRepository->getDefaultShop();
}
public function canCustomerPassOrdersApp(ShopperId $shopperId): bool
{
return $this->getShopperFor($shopperId)?->isActive() ?? false;
}
}