- Implement automated synchronization of employees via Arcadia API (EmployeeSyncService, SynchronizeEmployeesWithArcadiaApi, FetchAndUpsertArcadiaEmployees) - Add Back-Office application settings for employee sites (Setting singleton, GetSettingsQuery, UpdateSettings, SettingsController, EmployeeSitesInputComponent.vue) - Strongly type Employee attributes using Domain Value Objects (ShopperEstablishmentCode, ShopperSiteCode, ShopperServiceCode) and Eloquent Casts - Migrate pagination from Domain to Shared\Pagination namespace across queries and inputs - Remove legacy and dead CSV employee import/export code - Restore Domain\Ports\Services\CsvGenerator interface for Regate order generation - Add comprehensive Pest unit, integration, and feature test coverage
84 lines
2 KiB
PHP
84 lines
2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Shared\Pagination;
|
|
|
|
use Shared\DDD\Equatable;
|
|
|
|
/**
|
|
* Immutable value object representing a pagination range.
|
|
*/
|
|
final readonly class Pagination implements Equatable
|
|
{
|
|
/** ERR_TOO_MANY_RECORDS fixed to 10k */
|
|
public const int MAX_PAGE_SIZE = PageSize::MAX_PAGE_SIZE;
|
|
|
|
private function __construct(
|
|
private int $from,
|
|
private int $to,
|
|
) {
|
|
}
|
|
|
|
public function from(): int
|
|
{
|
|
return $this->from;
|
|
}
|
|
|
|
public function to(): int
|
|
{
|
|
return $this->to;
|
|
}
|
|
|
|
public function pageSize(): PageSize
|
|
{
|
|
return new PageSize($this->to - $this->from + 1);
|
|
}
|
|
|
|
public function pageNumber(): PageNumber
|
|
{
|
|
return new PageNumber((int) ($this->from / $this->pageSize()->value()) + 1);
|
|
}
|
|
|
|
public function equals(mixed $other): bool
|
|
{
|
|
return $other instanceof self && $this->from === $other->from && $this->to === $other->to;
|
|
}
|
|
|
|
public static function ofIndexes(int $from, int $to): self
|
|
{
|
|
$from = max(0, $from);
|
|
$to = clamp($to, $from + 1, $from + self::MAX_PAGE_SIZE);
|
|
|
|
return new self($from, $to);
|
|
}
|
|
|
|
public static function ofPage(PageNumber $pageNumber, PageSize $pageSize = new PageSize()): self
|
|
{
|
|
$fromIndex = ($pageNumber->value - 1) * $pageSize->value;
|
|
$toIndex = $fromIndex + $pageSize->value - 1;
|
|
|
|
return new self($fromIndex, $toIndex);
|
|
}
|
|
|
|
public static function ofOffsetAndLimit(int $offset, int $limit): self
|
|
{
|
|
$offset = max(0, $offset);
|
|
$limit = clamp($limit, 1, self::MAX_PAGE_SIZE);
|
|
|
|
$fromIndex = $offset;
|
|
$toIndex = $offset + $limit - 1;
|
|
|
|
return new self($fromIndex, $toIndex);
|
|
}
|
|
|
|
public static function firstPage(PageSize $pageSize = new PageSize()): self
|
|
{
|
|
return self::ofPage(new PageNumber(1), $pageSize);
|
|
}
|
|
|
|
public function __toString(): string
|
|
{
|
|
return sprintf('Pagination{from=%d, to=%d}', $this->from, $this->to);
|
|
}
|
|
}
|