Segment view contract export option
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\Contract;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate;
|
||||
|
||||
class SegmentContractsExport implements FromQuery, ShouldAutoSize, WithColumnFormatting, WithHeadings, WithMapping
|
||||
{
|
||||
public const DATE_EXCEL_FORMAT = 'dd"."mm"."yyyy';
|
||||
|
||||
/**
|
||||
* @var array<string, array{label: string}>
|
||||
*/
|
||||
public const COLUMN_METADATA = [
|
||||
'reference' => ['label' => 'Pogodba'],
|
||||
'client_case' => ['label' => 'Primer'],
|
||||
'client' => ['label' => 'Stranka'],
|
||||
'type' => ['label' => 'Vrsta'],
|
||||
'start_date' => ['label' => 'Začetek'],
|
||||
'end_date' => ['label' => 'Konec'],
|
||||
'account' => ['label' => 'Stanje'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array<int, string> $columns
|
||||
*/
|
||||
public function __construct(private Builder $query, private array $columns) {}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
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<int, mixed>
|
||||
*/
|
||||
public function map($row): array
|
||||
{
|
||||
return array_map(fn (string $column) => $this->resolveValue($row, $column), $this->columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public function headings(): array
|
||||
{
|
||||
return array_map(fn (string $column) => self::columnLabel($column), $this->columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function columnFormats(): array
|
||||
{
|
||||
$formats = [];
|
||||
|
||||
foreach ($this->columns as $index => $column) {
|
||||
if (in_array($column, ['start_date', 'end_date'], true)) {
|
||||
$formats[$this->columnLetter($index)] = self::DATE_EXCEL_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
return $formats;
|
||||
}
|
||||
|
||||
private function resolveValue(Contract $contract, string $column): mixed
|
||||
{
|
||||
return match ($column) {
|
||||
'reference' => $contract->reference,
|
||||
'client_case' => optional($contract->clientCase?->person)->full_name,
|
||||
'client' => optional($contract->clientCase?->client?->person)->full_name,
|
||||
'type' => optional($contract->type)->name,
|
||||
'start_date' => $this->formatDate($contract->start_date),
|
||||
'end_date' => $this->formatDate($contract->end_date),
|
||||
'account' => optional($contract->account)->balance_amount,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
private function formatDate(mixed $value): ?float
|
||||
{
|
||||
$carbon = Carbon::make($value);
|
||||
|
||||
if (! $carbon) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ExcelDate::dateTimeToExcel($carbon->copy()->startOfDay());
|
||||
}
|
||||
|
||||
private function columnLetter(int $index): string
|
||||
{
|
||||
$index++;
|
||||
$letter = '';
|
||||
|
||||
while ($index > 0) {
|
||||
$remainder = ($index - 1) % 26;
|
||||
$letter = chr(65 + $remainder).$letter;
|
||||
$index = intdiv($index - 1, 26);
|
||||
}
|
||||
|
||||
return $letter;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user