140 lines
4.2 KiB
PHP
140 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Infra\Adapters\Directories;
|
|
|
|
use Domain\Models\Entities\Inco\IncoShortSheet;
|
|
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\IncoShortSheetDirectory;
|
|
use Infra\Database\Models\IncoSheet as IncoSheetModel;
|
|
use Shared\Helpers\DatesHelper;
|
|
use Shared\Paginated;
|
|
use Shared\Pagination;
|
|
|
|
final class EloquentIncoShortSheetDirectory implements IncoShortSheetDirectory
|
|
{
|
|
private const SHORT_FIELDS = ['id', 'name', 'label', 'created_at', 'updated_at'];
|
|
|
|
#[\Override]
|
|
public function findAll(
|
|
Pagination $pagination,
|
|
IncoSheetSorter $sorter,
|
|
?IncoSheetFilter $filter = null
|
|
): Paginated {
|
|
$query = IncoSheetModel::query()->select(self::SHORT_FIELDS);
|
|
|
|
if ($filter !== null) {
|
|
if ($filter->since !== null) {
|
|
$query->where(static function ($q) use ($filter): void {
|
|
$q->where('updated_at', '>=', $filter->since)
|
|
->orWhere('created_at', '>=', $filter->since);
|
|
});
|
|
}
|
|
|
|
if (! empty($filter->brands)) {
|
|
$query->whereIn('brand->code', $filter->brands);
|
|
}
|
|
}
|
|
|
|
$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->toDomain($row);
|
|
}
|
|
|
|
/** @var IncoShortSheet[] $items */
|
|
return new Paginated($pagination, $items, $total);
|
|
}
|
|
|
|
#[\Override]
|
|
public function search(
|
|
IncoIdQuery $query,
|
|
Pagination $pagination,
|
|
string ...$brands
|
|
): Paginated {
|
|
$dbQuery = IncoSheetModel::query()->select(self::SHORT_FIELDS);
|
|
|
|
$dbQuery->where('id', 'LIKE', $query->value);
|
|
|
|
if (! empty($brands)) {
|
|
$dbQuery->whereIn('brand->code', $brands);
|
|
}
|
|
|
|
$total = (int) (clone $dbQuery)->count();
|
|
|
|
$rows = $dbQuery
|
|
->offset($pagination->from())
|
|
->limit($pagination->pageSize())
|
|
->get();
|
|
|
|
$items = [];
|
|
foreach ($rows as $row) {
|
|
$items[] = $this->toDomain($row);
|
|
}
|
|
|
|
/** @var IncoShortSheet[] $items */
|
|
return new Paginated($pagination, $items, $total);
|
|
}
|
|
|
|
#[\Override]
|
|
public function find(IncoId $id): ?IncoShortSheet
|
|
{
|
|
$model = IncoSheetModel::query()
|
|
->select(self::SHORT_FIELDS)
|
|
->where('id', $id->value)
|
|
->first();
|
|
|
|
if ($model === null) {
|
|
return null;
|
|
}
|
|
|
|
return $this->toDomain($model);
|
|
}
|
|
|
|
private function toDomain(IncoSheetModel $model): IncoShortSheet
|
|
{
|
|
$rawId = $model->getAttribute('id');
|
|
$rawName = $model->getAttribute('name');
|
|
$rawLabel = $model->getAttribute('label');
|
|
$rawCreatedAt = $model->getAttribute('created_at');
|
|
$rawUpdatedAt = $model->getAttribute('updated_at');
|
|
|
|
$id = is_string($rawId) || is_numeric($rawId) ? (string) $rawId : '';
|
|
$name = is_string($rawName) ? $rawName : '';
|
|
$label = is_string($rawLabel) ? $rawLabel : '';
|
|
$createdAt = is_string($rawCreatedAt) ? DatesHelper::parseDateTime($rawCreatedAt) : null;
|
|
$updatedAt = is_string($rawUpdatedAt) ? DatesHelper::parseDateTime($rawUpdatedAt) : null;
|
|
|
|
return new IncoShortSheet(
|
|
id: new IncoId($id),
|
|
name: $name,
|
|
label: $label,
|
|
createdAt: $createdAt,
|
|
updatedAt: $updatedAt,
|
|
);
|
|
}
|
|
|
|
private function toSqlColumn(IncoSheetSortColumn $column): string
|
|
{
|
|
return match ($column) {
|
|
IncoSheetSortColumn::incoSheetId => 'id',
|
|
IncoSheetSortColumn::createdAt => 'created_at',
|
|
IncoSheetSortColumn::updatedAt => 'updated_at',
|
|
};
|
|
}
|
|
}
|