130 lines
3.3 KiB
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č';
|
|
}
|
|
}
|