Модуль отчетов

This commit is contained in:
brusnitsyn
2026-06-21 23:40:55 +09:00
parent f163b95663
commit bd2cc24b98
27 changed files with 2781 additions and 3 deletions

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Services\Reports;
use App\Models\Department;
use App\Services\DateRange;
use Closure;
readonly class ReportSource
{
/**
* @param array<string,string> $columns ключ колонки => подпись (все колонки, доступные для этого источника)
* @param array<string,array{label:string,options:?array<int|string,string>}> $filterableFields allow-list полей, по которым можно фильтровать в конструкторе шаблонов
* @param Closure(Department,DateRange,array<int,string>,array<int,array{field:string,value:mixed}>):array<int,array<string,mixed>> $resolver
*/
public function __construct(
public string $key,
public string $label,
public array $columns,
public array $filterableFields,
private Closure $resolver,
) {}
/**
* @param array<int,string> $columns ключи выбранных колонок (по умолчанию все)
* @param array<int,array{field:string,value:mixed}> $filters
* @return array<int,array<string,mixed>>
*/
public function rows(Department $department, DateRange $dateRange, ?array $columns = null, array $filters = []): array
{
$columns ??= array_keys($this->columns);
return ($this->resolver)($department, $dateRange, $columns, $filters);
}
public function toSection(
Department $department,
DateRange $dateRange,
?array $columns = null,
array $filters = [],
?string $title = null,
): ReportSection {
$columns ??= array_keys($this->columns);
$columnDefs = [];
foreach ($columns as $key) {
if (isset($this->columns[$key])) {
$columnDefs[$key] = $this->columns[$key];
}
}
if (empty($columnDefs)) {
$columnDefs = $this->columns;
$columns = array_keys($this->columns);
}
return new ReportSection(
$title ?? $this->label,
$columnDefs,
$this->rows($department, $dateRange, $columns, $filters),
);
}
}