*/ private array $columnLetterMap = []; /** * @var array */ public const COLUMN_METADATA = [ 'reference' => ['label' => 'Referenca'], 'customer' => ['label' => 'Stranka'], 'address' => ['label' => 'Naslov'], 'start' => ['label' => 'Začetek'], 'segment' => ['label' => 'Segment'], 'balance' => ['label' => 'Stanje'], ]; /** * @param array $columns */ public function __construct(private Builder $query, private array $columns) {} /** * @return array */ public static function allowedColumns(): array { return array_keys(self::COLUMN_METADATA); } public static function columnLabel(string $column): string { return self::COLUMN_METADATA[$column]['label'] ?? $column; } public function query(): Builder { return $this->query; } /** * @return array */ public function map($row): array { return array_map(fn (string $column) => $this->resolveValue($row, $column), $this->columns); } /** * @return array */ public function headings(): array { return array_map(fn (string $column) => self::columnLabel($column), $this->columns); } /** * @return array */ public function columnFormats(): array { $formats = []; foreach ($this->getColumnLetterMap() as $letter => $column) { if ($column === 'reference') { $formats[$letter] = self::TEXT_EXCEL_FORMAT; continue; } if ($column === 'start') { $formats[$letter] = self::DATE_EXCEL_FORMAT; } } return $formats; } private function resolveValue(Contract $contract, string $column): mixed { return match ($column) { 'reference' => $contract->reference, 'customer' => optional($contract->clientCase?->person)->full_name, 'address' => optional($contract->clientCase?->person?->address)->address, 'start' => $this->formatDate($contract->start_date), 'segment' => $contract->segments?->first()?->name, 'balance' => optional($contract->account)->balance_amount, default => null, }; } private function formatDate(?string $date): mixed { if (empty($date)) { return null; } try { $carbon = Carbon::parse($date); return ExcelDate::dateTimeToExcel($carbon); } catch (\Exception $e) { return null; } } /** * @return array */ private function getColumnLetterMap(): array { if ($this->columnLetterMap !== []) { return $this->columnLetterMap; } $letter = 'A'; foreach ($this->columns as $column) { $this->columnLetterMap[$letter] = $column; $letter++; } return $this->columnLetterMap; } public function bindValue(Cell $cell, $value): bool { if (is_numeric($value)) { $cell->setValueExplicit($value, DataType::TYPE_NUMERIC); return true; } return parent::bindValue($cell, $value); } }