ldc-arcadia-api/src/Infra/Adapters/Directories/ArcadiaIncoSheetDirectory.php
Jérémy Munsch cec8d1ea66
refactor(infra): replace Eloquent directory adapters with direct QueryBuilder adapters and mappers
- Replace Eloquent models for replicated Oracle tables with direct QueryBuilder directory adapters
- Bind ArcadiaEmployeeDirectory, ArcadiaIncoSheetDirectory, ArcadiaIncoShortSheetDirectory, ArcadiaIncoCompositionDirectory, and ArcadiaMarqueBrandDirectory
- Remove obsolete Eloquent directory classes and models
2026-08-26 17:29:08 +02:00

166 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Infra\Adapters\Directories;
use Domain\Models\Entities\Inco\IncoSheet;
use Domain\Models\ValueObjects\Brand\BrandCode;
use Domain\Models\ValueObjects\Inco\IncoId;
use Domain\Models\ValueObjects\Inco\IncoIdQuery;
use Domain\Models\ValueObjects\Inco\IncoSheetFilter;
use Domain\Models\ValueObjects\Inco\IncoSheetSortColumn;
use Domain\Models\ValueObjects\Inco\IncoSheetSorter;
use Domain\Ports\Directories\IncoSheetDirectory;
use Domain\Ports\Repositories\BrandRepository;
use Illuminate\Database\Connection;
use Illuminate\Database\Query\Builder;
use Infra\Adapters\Mappers\IncoMapper;
use Shared\Paginated;
use Shared\Pagination;
final class ArcadiaIncoSheetDirectory implements IncoSheetDirectory
{
public function __construct(
private readonly Connection $connection,
private readonly BrandRepository $brandRepository,
private readonly IncoMapper $mapper,
) {
}
#[\Override]
public function findAll(
Pagination $pagination,
IncoSheetSorter $sorter,
?IncoSheetFilter $filter = null
): Paginated {
$query = $this->connection
->table('INCO')
->leftJoin('FAM_VENTE', 'INCO.FAMILLE_VTE', '=', 'FAM_VENTE.COD_FAMVTE')
->select(['INCO.*', 'FAM_VENTE.LIB_FAMVTE as FAMILLE_VTE_LIBELLE']);
if ($filter !== null) {
if ($filter->since !== null) {
$query->where(static function (Builder $q) use ($filter): void {
$q->where('INCO.DAT_MAJ', '>=', $filter->since)
->orWhere('INCO.DAT_CRE', '>=', $filter->since);
});
}
if (! empty($filter->brands)) {
$resolvedBrands = $this->resolveBrandFilterCodes(...$filter->brands);
$query->whereIn('INCO.MARQUE', $resolvedBrands);
}
}
$total = (int) (clone $query)->count();
$rows = (clone $query)
->orderBy(
$this->toSqlColumn($sorter->sortBy),
$sorter->direction
)
->offset($pagination->from())
->limit($pagination->pageSize())
->get();
$items = [];
foreach ($rows as $row) {
$items[] = $this->mapper->toDomain($row);
}
/** @var IncoSheet[] $items */
return new Paginated($pagination, $items, $total);
}
#[\Override]
public function search(
IncoIdQuery $query,
Pagination $pagination,
BrandCode ...$brands
): Paginated {
$dbQuery = $this->connection
->table('INCO')
->leftJoin('FAM_VENTE', 'INCO.FAMILLE_VTE', '=', 'FAM_VENTE.COD_FAMVTE')
->select(['INCO.*', 'FAM_VENTE.LIB_FAMVTE as FAMILLE_VTE_LIBELLE']);
$dbQuery->where('INCO.NO_ART', 'LIKE', $query->value);
if (! empty($brands)) {
$resolvedBrands = $this->resolveBrandFilterCodes(...$brands);
$dbQuery->whereIn('INCO.MARQUE', $resolvedBrands);
}
$total = (int) (clone $dbQuery)->count();
$rows = $dbQuery
->offset($pagination->from())
->limit($pagination->pageSize())
->get();
$items = [];
foreach ($rows as $row) {
$items[] = $this->mapper->toDomain($row);
}
/** @var IncoSheet[] $items */
return new Paginated($pagination, $items, $total);
}
#[\Override]
public function find(IncoId $id): ?IncoSheet
{
$row = $this->connection
->table('INCO')
->leftJoin('FAM_VENTE', 'INCO.FAMILLE_VTE', '=', 'FAM_VENTE.COD_FAMVTE')
->select(['INCO.*', 'FAM_VENTE.LIB_FAMVTE as FAMILLE_VTE_LIBELLE'])
->where('INCO.NO_ART', $id->value)
->first();
if ($row === null) {
return null;
}
return $this->mapper->toDomain($row);
}
/**
* @return array<int|string>
*/
private function resolveBrandFilterCodes(BrandCode ...$brandCodes): array
{
$resolved = [];
foreach ($brandCodes as $brandCode) {
$brand = $this->brandRepository->findByCode($brandCode);
if ($brand !== null) {
$resolved[] = (int) $brand->arcadiaId->value;
$resolved[] = $brand->arcadiaId->value;
}
}
if (empty($resolved) && ! empty($brandCodes)) {
return [0];
}
$unique = [];
foreach ($resolved as $item) {
if (! in_array($item, $unique, true)) {
$unique[] = $item;
}
}
return $unique;
}
private function toSqlColumn(IncoSheetSortColumn $column): string
{
return match ($column) {
IncoSheetSortColumn::incoSheetId => 'NO_ART',
IncoSheetSortColumn::createdAt => 'DAT_CRE',
IncoSheetSortColumn::updatedAt => 'DAT_MAJ',
};
}
}