GUI + Tisk faktur
parent
497708b5bb
commit
6a39a66e73
|
|
@ -4,13 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Model\Faktura;
|
||||
|
||||
use Mpdf\Config\ConfigVariables;
|
||||
use Mpdf\Config\FontVariables;
|
||||
use Mpdf\Mpdf;
|
||||
use Mpdf\Output\Destination;
|
||||
use Nette\Bridges\ApplicationLatte\LatteFactory;
|
||||
use Nette\Utils\FileSystem;
|
||||
|
||||
/**
|
||||
* Sestava faktury podle rptFaktura3 (PDF, tisk).
|
||||
*/
|
||||
|
|
@ -22,8 +15,7 @@ final class FakturaPdf
|
|||
];
|
||||
|
||||
public function __construct(
|
||||
private LatteFactory $latteFactory,
|
||||
private string $tempDir,
|
||||
private PdfSestava $pdfSestava,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -33,18 +25,13 @@ final class FakturaPdf
|
|||
public function render(object $faktura, array $polozky, bool $autoPrint = false): string
|
||||
{
|
||||
$view = $this->view($faktura, $polozky);
|
||||
$html = $this->latteFactory->create()->renderToString($this->templateFile(), $view);
|
||||
|
||||
$mpdf = $this->createMpdf();
|
||||
$mpdf->SetHTMLFooter($this->footer((string) $view['vytisteno']));
|
||||
$mpdf->SetTitle('Faktura ' . (string) ($faktura->CISLO ?? ''));
|
||||
$mpdf->SetAuthor('Kufřík');
|
||||
if ($autoPrint) {
|
||||
$mpdf->SetJS('this.print();');
|
||||
}
|
||||
$mpdf->WriteHTML($html);
|
||||
|
||||
return $mpdf->Output('', Destination::STRING_RETURN);
|
||||
return $this->pdfSestava->render(
|
||||
$this->templateFile(),
|
||||
$view,
|
||||
'Faktura ' . (string) ($faktura->CISLO ?? ''),
|
||||
$autoPrint,
|
||||
);
|
||||
}
|
||||
|
||||
public static function fileName(string $cislo): string
|
||||
|
|
@ -105,56 +92,9 @@ final class FakturaPdf
|
|||
'polozky' => $radky,
|
||||
'celkem' => 'Celkem: ' . self::formatMoney($celkem),
|
||||
'cinnosti' => $cinnosti === '' ? [] : (preg_split("/\R/u", $cinnosti) ?: []),
|
||||
'vytisteno' => (new \DateTimeImmutable('today'))->format('d.m.Y'),
|
||||
];
|
||||
}
|
||||
|
||||
private function createMpdf(): Mpdf
|
||||
{
|
||||
$tempDir = $this->tempDir . DIRECTORY_SEPARATOR . 'mpdf';
|
||||
FileSystem::createDir($tempDir);
|
||||
|
||||
$fontDir = dirname(__DIR__, 3) . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'fonts';
|
||||
$config = (new ConfigVariables())->getDefaults();
|
||||
$fontData = (new FontVariables())->getDefaults();
|
||||
|
||||
return new Mpdf([
|
||||
'mode' => 'utf-8',
|
||||
'format' => 'A4',
|
||||
'margin_left' => 18,
|
||||
'margin_right' => 16,
|
||||
'margin_top' => 16,
|
||||
'margin_bottom' => 18,
|
||||
'margin_footer' => 8,
|
||||
'default_font' => 'sourcesans3',
|
||||
'default_font_size' => 9,
|
||||
'tempDir' => $tempDir,
|
||||
'shrink_tables_to_fit' => 0,
|
||||
'fontDir' => array_merge($config['fontDir'], [$fontDir]),
|
||||
'fontdata' => $fontData['fontdata'] + [
|
||||
'sourcesans3' => [
|
||||
'R' => 'SourceSans3-Regular.ttf',
|
||||
'B' => 'SourceSans3-Bold.ttf',
|
||||
'I' => 'SourceSans3-It.ttf',
|
||||
'BI' => 'SourceSans3-BoldIt.ttf',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function footer(string $vytisteno): string
|
||||
{
|
||||
$datum = htmlspecialchars($vytisteno, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
return '<table width="100%" style="font-size: 8pt; color: #444; border-top: 0.2mm solid #ccc;">
|
||||
<tr>
|
||||
<td width="33%">Vytvořeno aplikací Kufřík</td>
|
||||
<td width="34%" align="center">Vytištěno dne: ' . $datum . '.</td>
|
||||
<td width="33%" align="right">Strana {PAGENO}/{nbpg}</td>
|
||||
</tr>
|
||||
</table>';
|
||||
}
|
||||
|
||||
private function templateFile(): string
|
||||
{
|
||||
return __DIR__ . DIRECTORY_SEPARATOR . 'faktura.latte';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model\Faktura;
|
||||
|
||||
use Mpdf\Config\ConfigVariables;
|
||||
use Mpdf\Config\FontVariables;
|
||||
use Mpdf\Mpdf;
|
||||
use Mpdf\Output\Destination;
|
||||
use Nette\Bridges\ApplicationLatte\LatteFactory;
|
||||
use Nette\Utils\FileSystem;
|
||||
|
||||
/**
|
||||
* Společné PDF pro sestavy: písmo, stránka a zápatí na každé straně.
|
||||
*/
|
||||
final class PdfSestava
|
||||
{
|
||||
public function __construct(
|
||||
private LatteFactory $latteFactory,
|
||||
private string $tempDir,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $params
|
||||
*/
|
||||
public function render(
|
||||
string $templateFile,
|
||||
array $params,
|
||||
string $title,
|
||||
bool $autoPrint = false,
|
||||
string $orientation = 'P',
|
||||
): string {
|
||||
$html = $this->latteFactory->create()->renderToString($templateFile, $params);
|
||||
|
||||
$mpdf = $this->create($orientation === 'L');
|
||||
$mpdf->SetHTMLFooter($this->footer());
|
||||
$mpdf->SetTitle($title);
|
||||
$mpdf->SetAuthor('Kufřík');
|
||||
if ($autoPrint) {
|
||||
$mpdf->SetJS('this.print();');
|
||||
}
|
||||
$mpdf->WriteHTML($html);
|
||||
|
||||
return $mpdf->Output('', Destination::STRING_RETURN);
|
||||
}
|
||||
|
||||
private function create(bool $landscape): Mpdf
|
||||
{
|
||||
$tempDir = $this->tempDir . DIRECTORY_SEPARATOR . 'mpdf';
|
||||
FileSystem::createDir($tempDir);
|
||||
|
||||
$fontDir = dirname(__DIR__, 3) . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'fonts';
|
||||
$config = (new ConfigVariables())->getDefaults();
|
||||
$fontData = (new FontVariables())->getDefaults();
|
||||
|
||||
return new Mpdf([
|
||||
'mode' => 'utf-8',
|
||||
'format' => 'A4',
|
||||
'orientation' => $landscape ? 'L' : 'P',
|
||||
'margin_left' => $landscape ? 14 : 18,
|
||||
'margin_right' => $landscape ? 14 : 16,
|
||||
'margin_top' => $landscape ? 14 : 16,
|
||||
'margin_bottom' => $landscape ? 16 : 18,
|
||||
'margin_footer' => 8,
|
||||
'default_font' => 'sourcesans3',
|
||||
'default_font_size' => 9,
|
||||
'tempDir' => $tempDir,
|
||||
'shrink_tables_to_fit' => 0,
|
||||
'fontDir' => array_merge($config['fontDir'], [$fontDir]),
|
||||
'fontdata' => $fontData['fontdata'] + [
|
||||
'sourcesans3' => [
|
||||
'R' => 'SourceSans3-Regular.ttf',
|
||||
'B' => 'SourceSans3-Bold.ttf',
|
||||
'I' => 'SourceSans3-It.ttf',
|
||||
'BI' => 'SourceSans3-BoldIt.ttf',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function footer(): string
|
||||
{
|
||||
$datum = htmlspecialchars((new \DateTimeImmutable('today'))->format('d.m.Y'), ENT_QUOTES, 'UTF-8');
|
||||
|
||||
return '<table width="100%" style="font-size: 8pt; color: #444; border-top: 0.2mm solid #ccc;">
|
||||
<tr>
|
||||
<td width="33%">Vytvořeno aplikací Kufřík</td>
|
||||
<td width="34%" align="center">Vytištěno dne: ' . $datum . '.</td>
|
||||
<td width="33%" align="right">Strana {PAGENO}/{nbpg}</td>
|
||||
</tr>
|
||||
</table>';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
<?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č';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { font-family: sourcesans3, sans-serif; font-size: 9pt; color: #1c1c1c; }
|
||||
h1 { font-size: 16pt; line-height: 1.15; margin: 0; font-weight: bold; }
|
||||
.obdobi { margin: 1mm 0 2mm 0; color: #333; font-size: 10pt; }
|
||||
.rule { border-top: 2.2pt solid #222; margin: 0 0 5mm 0; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
.items th, .items td { padding: 1.6mm 1.5mm; border: 0.25mm solid #fff; vertical-align: middle; }
|
||||
.items th { background: #87cefa; font-weight: bold; text-align: center; color: #10283d; }
|
||||
.items td.a { background: #ffffff; }
|
||||
.items td.b { background: #e7f3fb; }
|
||||
.items td.num { text-align: right; white-space: nowrap; }
|
||||
.items td.mid { text-align: center; }
|
||||
.items td.late { color: #b42318; font-weight: bold; }
|
||||
.items tr.empty td { background: #f4f4f4; text-align: center; padding: 4mm; }
|
||||
.soucet { margin-top: 3mm; }
|
||||
.soucet td { background: #d4d4d4; font-weight: bold; padding: 1.8mm 2mm; border: 0.3mm solid #fff; }
|
||||
.right { text-align: right; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Seznam vystavených faktur</h1>
|
||||
<p class="obdobi">Období: {$obdobi}</p>
|
||||
<div class="rule"></div>
|
||||
|
||||
<table class="items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 14%;">Číslo</th>
|
||||
<th style="width: 26%;">Odběratel</th>
|
||||
<th style="width: 12%;">Vystaveno</th>
|
||||
<th style="width: 12%;">Splatnost</th>
|
||||
<th style="width: 12%;">Částka</th>
|
||||
<th style="width: 12%;">Zaplaceno</th>
|
||||
<th style="width: 12%;">Stav</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr n:if="!$radky" class="empty">
|
||||
<td colspan="7">V tomto období nejsou žádné faktury.</td>
|
||||
</tr>
|
||||
<tr n:foreach="$radky as $radek">
|
||||
<td class="{if $radek['sudy']}b{else}a{/if}">{$radek['cislo']}</td>
|
||||
<td class="{if $radek['sudy']}b{else}a{/if}">{$radek['odberatel']}</td>
|
||||
<td class="mid {if $radek['sudy']}b{else}a{/if}">{$radek['vystaveno']}</td>
|
||||
<td class="mid {if $radek['poSplatnosti']}late{/if} {if $radek['sudy']}b{else}a{/if}">{$radek['splatnost']}</td>
|
||||
<td class="num {if $radek['sudy']}b{else}a{/if}">{$radek['castka']}</td>
|
||||
<td class="num {if $radek['sudy']}b{else}a{/if}">{$radek['zaplaceno']}</td>
|
||||
<td class="mid {if $radek['sudy']}b{else}a{/if}">{$radek['stav']}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="soucet">
|
||||
<tr>
|
||||
<td>Počet faktur: {$pocet}</td>
|
||||
<td class="right">Celkem: {$celkem}</td>
|
||||
<td class="right">Zaplaceno: {$zaplaceno}</td>
|
||||
<td class="right">Zbývá uhradit: {$zbyva}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -63,13 +63,6 @@
|
|||
</a>
|
||||
</li>
|
||||
|
||||
<!-- KUFŘÍK -->
|
||||
<li class="nav-item">
|
||||
<a n:href="Uzivatel:edit" n:class="nav-link, $presenter->isLinkCurrent('Uzivatel:*') ? active">
|
||||
<i class="bi bi-box me-1"></i> Kufřík
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- ADMIN — pouze systémový administrátor -->
|
||||
{if $user->isInRole('admin')}
|
||||
<li class="nav-item">
|
||||
|
|
@ -120,6 +113,10 @@
|
|||
|
||||
<!-- FAKTURY -->
|
||||
<div n:class="tab-pane, fade, $presenter->isLinkCurrent('Faktura:*') || $presenter->isLinkCurrent('FakturaEdit:*') ? 'show active'" id="toolbar-invoices" role="tabpanel">
|
||||
{var $aktualniRok = (int) date('Y')}
|
||||
{var $vybranyRok = $selectedRok ?? $aktualniRok}
|
||||
{var $vybranyMesic = (string) ($selectedMesic ?? '')}
|
||||
{var $rokyFiltr = $roky ?? range($aktualniRok, $aktualniRok - 3)}
|
||||
<div class="toolbar-group">
|
||||
<div class="action-buttons">
|
||||
<a n:href="Faktura:" type="button" class="btn btn-outline-primary btn-action">
|
||||
|
|
@ -130,32 +127,16 @@
|
|||
<i class="bi bi-plus-square-fill"></i>
|
||||
<span>Přidat fakturu</span>
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-secondary btn-action" onclick="window.print()">
|
||||
<a n:href="Faktura:seznam, rok => $vybranyRok, mesic => $vybranyMesic" target="_blank" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-printer-fill"></i>
|
||||
<span>Tisk</span>
|
||||
</button>
|
||||
|
||||
<div class="v-divider d-none d-sm-block"></div>
|
||||
|
||||
<button type="button" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-bar-chart-line-fill text-warning"></i>
|
||||
<span>Grafy</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-file-earmark-pdf-fill text-danger"></i>
|
||||
<span>Tiskové sestavy</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Filtr pro Faktury v Toolbaru -->
|
||||
<form n:attr="method => 'get', action => $presenter->link('Faktura:default', ['rok' => null, 'mesic' => null])" class="filter-panel ms-auto ms-lg-0">
|
||||
<i class="bi bi-funnel-fill text-muted fs-5 ms-1"></i>
|
||||
|
||||
{var $aktualniRok = (int) date('Y')}
|
||||
{var $vybranyRok = $selectedRok ?? $aktualniRok}
|
||||
{var $vybranyMesic = (string) ($selectedMesic ?? '')}
|
||||
{var $rokyFiltr = $roky ?? range($aktualniRok, $aktualniRok - 3)}
|
||||
|
||||
<!-- Výběr Roku -->
|
||||
<select name="rok" class="form-select form-select-sm" style="width: 90px;" onchange="this.form.submit()">
|
||||
<option n:foreach="$rokyFiltr as $r" value="{$r}" {if $vybranyRok == $r}selected{/if}>{$r}</option>
|
||||
|
|
@ -209,24 +190,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- KUFŘÍK -->
|
||||
<div n:class="tab-pane, fade, $presenter->isLinkCurrent('Uzivatel:*') ? 'show active'" id="toolbar-briefcase" role="tabpanel">
|
||||
<div class="action-buttons">
|
||||
<a n:href="Uzivatel:edit" n:class="btn, btn-action, $presenter->isLinkCurrent('Uzivatel:edit') ? 'btn-primary active' : 'btn-outline-primary'">
|
||||
<i class="bi bi-person-gear"></i>
|
||||
<span>Profil a připojení</span>
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-info btn-action">
|
||||
<i class="bi bi-question-circle-fill"></i>
|
||||
<span>Nápověda</span>
|
||||
</button>
|
||||
<a href="https://facebook.com" target="_blank" rel="noopener noreferrer" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-facebook"></i>
|
||||
<span>Stránky - FB</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ADMIN -->
|
||||
{if $user->isInRole('admin')}
|
||||
<div n:class="tab-pane, fade, $presenter->isLinkCurrent('Admin:*') ? 'show active'" id="toolbar-admin" role="tabpanel">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\UI\Faktura;
|
||||
|
||||
use App\Model\Faktura\FakturaPdf;
|
||||
use App\Model\Faktura\SeznamFakturPdf;
|
||||
use App\UI\BasePresenter;
|
||||
use App\Model\Facade\FakturaFacade;
|
||||
use Nette\Application\Attributes\Persistent;
|
||||
|
|
@ -22,6 +23,7 @@ class FakturaPresenter extends BasePresenter
|
|||
public function __construct(
|
||||
private FakturaFacade $fakturaFacade,
|
||||
private FakturaPdf $fakturaPdf,
|
||||
private SeznamFakturPdf $seznamFakturPdf,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
|
@ -37,6 +39,31 @@ class FakturaPresenter extends BasePresenter
|
|||
$fileName = FakturaPdf::fileName((string) $faktura->CISLO);
|
||||
$disposition = $tisk ? 'inline' : 'attachment';
|
||||
|
||||
$this->sendPdf($pdf, $fileName, $disposition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tisk seznamu faktur podle filtru rok / měsíc.
|
||||
*/
|
||||
public function actionSeznam(): void
|
||||
{
|
||||
$rok = $this->rok ?? (int) date('Y');
|
||||
$mesic = $this->normalizeMesic($this->mesic);
|
||||
|
||||
$this->fakturaFacade->reconcileUhrady();
|
||||
$faktury = $this->fakturaFacade->getFiltered($rok, $mesic);
|
||||
foreach ($faktury as $faktura) {
|
||||
$celkem = (float) ($faktura->CASTKA_CELKEM ?? 0);
|
||||
$zaplaceno = (float) ($faktura->ZAPLACENO ?? 0);
|
||||
$faktura->STAV_UHRADY = FakturaFacade::stavZCastek($celkem, $zaplaceno);
|
||||
}
|
||||
|
||||
$pdf = $this->seznamFakturPdf->render($faktury, $rok, $mesic, autoPrint: true);
|
||||
$this->sendPdf($pdf, SeznamFakturPdf::fileName($rok, $mesic), 'inline');
|
||||
}
|
||||
|
||||
private function sendPdf(string $pdf, string $fileName, string $disposition): void
|
||||
{
|
||||
$this->sendResponse(new CallbackResponse(function ($httpRequest, $httpResponse) use ($pdf, $fileName, $disposition): void {
|
||||
$httpResponse->setContentType('application/pdf');
|
||||
$httpResponse->setHeader(
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ services:
|
|||
|
||||
- App\Model\Sdf\SdfCompactExporter(%sdfExportScript%, %sdfPassword%)
|
||||
- App\Model\Sdf\SdfKufrikImporter
|
||||
- App\Model\Faktura\FakturaPdf(tempDir: %tempDir%)
|
||||
- App\Model\Faktura\PdfSestava(tempDir: %tempDir%)
|
||||
- App\Model\Faktura\FakturaPdf
|
||||
- App\Model\Faktura\SeznamFakturPdf
|
||||
|
||||
# 1. Factory pro klientskou databázi
|
||||
kufrikConnectionFactory:
|
||||
|
|
|
|||
Loading…
Reference in New Issue