Kufrik/app/Model/Faktura/SeznamFakturPdf.php

130 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Model\Faktura;
use App\Model\Facade\FakturaFacade;
/**
* Tisková sestava vyfiltrovaného seznamu faktur.
*/
final class SeznamFakturPdf
{
private const MESICE = [
1 => 'leden',
2 => 'únor',
3 => 'březen',
4 => 'duben',
5 => 'květen',
6 => 'červen',
7 => 'červenec',
8 => 'srpen',
9 => 'září',
10 => 'říjen',
11 => 'listopad',
12 => 'prosinec',
];
public function __construct(
private PdfSestava $pdfSestava,
) {
}
/**
* @param array<int, object> $faktury
*/
public function render(array $faktury, int $rok, string $mesic, bool $autoPrint = false): string
{
$mesicCislo = (int) $mesic;
$obdobi = ($mesicCislo >= 1 && $mesicCislo <= 12)
? self::MESICE[$mesicCislo] . ' ' . $rok
: 'rok ' . $rok;
$radky = [];
$celkem = 0.0;
$zaplaceno = 0.0;
$dnes = new \DateTimeImmutable('today');
foreach ($faktury as $faktura) {
$castka = (float) ($faktura->CASTKA_CELKEM ?? 0);
$uhrazeno = (float) ($faktura->ZAPLACENO ?? 0);
$celkem += $castka;
$zaplaceno += $uhrazeno;
$stav = (string) ($faktura->STAV_UHRADY ?? FakturaFacade::stavZCastek($castka, $uhrazeno));
$splatnost = self::asDate($faktura->DATUM_SPLATNOSTI ?? null);
$poSplatnosti = $stav !== FakturaFacade::STAV_ZAPLACENO
&& $splatnost !== null
&& $splatnost->format('Y-m-d') < $dnes->format('Y-m-d');
$radky[] = [
'cislo' => (string) ($faktura->CISLO ?? ''),
'odberatel' => trim((string) ($faktura->O_PRAJM ?? '')) !== '' ? (string) $faktura->O_PRAJM : '—',
'vystaveno' => self::formatDate(self::asDate($faktura->DATUM_VYSTAVENI ?? null)),
'splatnost' => self::formatDate($splatnost),
'poSplatnosti' => $poSplatnosti,
'castka' => self::formatMoney($castka),
'zaplaceno' => self::formatMoney($uhrazeno),
'stav' => match ($stav) {
FakturaFacade::STAV_ZAPLACENO => 'Zaplaceno',
FakturaFacade::STAV_CASTECNE => 'Částečně',
default => 'Neuhrazeno',
},
'sudy' => count($radky) % 2 === 1,
];
}
return $this->pdfSestava->render(
__DIR__ . DIRECTORY_SEPARATOR . 'seznam.latte',
[
'obdobi' => $obdobi,
'radky' => $radky,
'pocet' => count($radky),
'celkem' => self::formatMoney($celkem),
'zaplaceno' => self::formatMoney($zaplaceno),
'zbyva' => self::formatMoney(max(0, round($celkem - $zaplaceno, 2))),
],
'Seznam faktur — ' . $obdobi,
$autoPrint,
'L',
);
}
public static function fileName(int $rok, string $mesic): string
{
$mesicCislo = (int) $mesic;
$suffix = ($mesicCislo >= 1 && $mesicCislo <= 12)
? $rok . '_' . sprintf('%02d', $mesicCislo)
: (string) $rok;
return 'Seznam_faktur_' . $suffix . '.pdf';
}
private static function asDate(mixed $value): ?\DateTimeImmutable
{
if ($value instanceof \DateTimeImmutable) {
return $value;
}
if ($value instanceof \DateTimeInterface) {
return \DateTimeImmutable::createFromInterface($value);
}
if (!is_string($value) || trim($value) === '') {
return null;
}
$timestamp = strtotime($value);
return $timestamp ? (new \DateTimeImmutable())->setTimestamp($timestamp) : null;
}
private static function formatDate(?\DateTimeInterface $value): string
{
return $value ? $value->format('d.m.Y') : '';
}
private static function formatMoney(float $value): string
{
return number_format($value, 2, ',', ' ') . ' Kč';
}
}