Phase 115 complete (vertical slice "zamowienie z NIP -> faktura PDF"):
- Task 1: InvoiceRepository + InvoiceService (dual-flow orchestrator) +
InvoiceIssueException + FakturowniaApiClient::createInvoice + buildPdfUrl
- Task 2: InvoiceController + OrdersController::toggleInvoiceRequested +
OrdersRepository::setInvoiceRequested + auto-import invoice_requested z
Allegro (invoice.required) i shopPRO (5-key flexible parser) + show.php
(toggle w zakladce Platnosci + warunkowy przycisk Wystaw fakture)
- Task 3: Lista wystawionych /settings/accounting/invoices/issued z filtrami
+ invoice_preview + invoice_pdf Dompdf template + hub link
- Task 3b (dodany): NIP lookup przez MF Biala Lista (publiczne API, bez
rejestracji) — MfWhitelistApiClient w src/Core/Http/ + /api/nip/lookup +
przycisk "Pobierz z GUS" w formularzu
Auto-fixes podczas smoke testu (5):
- GUS endpoint Fakturowni nie istnial (HTML 404 -> "json is not valid");
switch na MF Biala Liste
- PHP 8.5 curl_close() deprecation wycieka HTML przed JSON; usuniete z
MfWhitelistApiClient i FakturowniaApiClient (3 miejsca)
- Fakturownia 422 payment_to_kind_days (nieistniejace pole) -> usuniete
- Generic "error" w 422 -> parser plaskuje errors: {pole: [...]} +
error_log z 1000 znakow raw body
- Fakturownia security odrzuca seller_*/department_id jako "create new
department"; usuniete z payloadu (Fakturownia uzywa danych konta)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
132 lines
6.4 KiB
PHP
132 lines
6.4 KiB
PHP
<?php
|
|
$invoiceData = is_array($invoice ?? null) ? $invoice : [];
|
|
$sellerData = is_array($seller ?? null) ? $seller : [];
|
|
$buyerData = is_array($buyer ?? null) ? $buyer : null;
|
|
$itemsList = is_array($items ?? null) ? $items : [];
|
|
$orderIdVal = (int) ($orderId ?? 0);
|
|
$configNameVal = (string) ($configName ?? '');
|
|
$invoiceNumber = (string) ($invoiceData['invoice_number'] ?? '');
|
|
$totalGross = (float) ($invoiceData['total_gross'] ?? 0);
|
|
$totalNet = (float) ($invoiceData['total_net'] ?? 0);
|
|
$isDelegatedFlag = (bool) ($isDelegated ?? false);
|
|
$externalIdVal = trim((string) ($invoiceData['external_invoice_id'] ?? ''));
|
|
$externalPdfVal = trim((string) ($invoiceData['external_pdf_url'] ?? ''));
|
|
?>
|
|
|
|
<section class="card">
|
|
<div class="order-details-head">
|
|
<div>
|
|
<a href="/orders/<?= $e((string) $orderIdVal) ?>" class="order-back-link">← Powrot do zamowienia</a>
|
|
<h2 class="section-title mt-12">Faktura <?= $e($invoiceNumber) ?></h2>
|
|
<div class="order-details-sub mt-4">
|
|
<?php if ($isDelegatedFlag): ?>
|
|
<span class="badge badge--success">Wystawione w Fakturowni<?php if (trim((string) ($accountPrefix ?? '')) !== ''): ?>: <?= $e((string) $accountPrefix) ?><?php endif; ?></span>
|
|
<?php if ($externalIdVal !== ''): ?> <span class="muted">(id zewnetrzne: <?= $e($externalIdVal) ?>)</span><?php endif; ?>
|
|
<?php else: ?>
|
|
<span class="badge badge--muted">Wystawione lokalnie</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<div class="order-details-head__actions">
|
|
<?php if ($isDelegatedFlag && $externalPdfVal !== ''): ?>
|
|
<a href="/orders/<?= $e((string) $orderIdVal) ?>/invoice/<?= $e((string) ($invoiceData['id'] ?? '')) ?>/pdf" class="btn btn--primary" target="_blank" rel="noopener">PDF (Fakturownia)</a>
|
|
<?php else: ?>
|
|
<a href="/orders/<?= $e((string) $orderIdVal) ?>/invoice/<?= $e((string) ($invoiceData['id'] ?? '')) ?>/pdf" class="btn btn--primary">Pobierz PDF</a>
|
|
<?php endif; ?>
|
|
<a href="/orders/<?= $e((string) $orderIdVal) ?>" class="btn btn--secondary">Powrot</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-grid-2 mt-16">
|
|
<div>
|
|
<h3 class="section-title">Sprzedawca</h3>
|
|
<dl class="order-kv mt-8">
|
|
<dt>Firma</dt><dd><?= $e((string) ($sellerData['company_name'] ?? '-')) ?></dd>
|
|
<dt>NIP</dt><dd><?= $e((string) ($sellerData['tax_number'] ?? '-')) ?></dd>
|
|
<dt>Adres</dt><dd><?= $e((string) ($sellerData['street'] ?? '')) ?>, <?= $e((string) ($sellerData['postal_code'] ?? '')) ?> <?= $e((string) ($sellerData['city'] ?? '')) ?></dd>
|
|
<dt>Telefon</dt><dd><?= $e((string) ($sellerData['phone'] ?? '-')) ?></dd>
|
|
<dt>Email</dt><dd><?= $e((string) ($sellerData['email'] ?? '-')) ?></dd>
|
|
<?php if (trim((string) ($sellerData['bank_account'] ?? '')) !== ''): ?>
|
|
<dt>Konto</dt><dd><?= $e((string) $sellerData['bank_account']) ?></dd>
|
|
<?php endif; ?>
|
|
</dl>
|
|
</div>
|
|
<?php if ($buyerData !== null): ?>
|
|
<div>
|
|
<h3 class="section-title">Nabywca</h3>
|
|
<dl class="order-kv mt-8">
|
|
<?php if (($buyerData['company_name'] ?? '') !== ''): ?>
|
|
<dt>Firma</dt><dd><?= $e((string) $buyerData['company_name']) ?></dd>
|
|
<?php endif; ?>
|
|
<?php if (($buyerData['name'] ?? '') !== ''): ?>
|
|
<dt>Nazwa</dt><dd><?= $e((string) $buyerData['name']) ?></dd>
|
|
<?php endif; ?>
|
|
<?php if (($buyerData['tax_number'] ?? '') !== ''): ?>
|
|
<dt>NIP</dt><dd><?= $e((string) $buyerData['tax_number']) ?></dd>
|
|
<?php endif; ?>
|
|
<dt>Adres</dt><dd><?= $e((string) ($buyerData['street'] ?? '')) ?>, <?= $e((string) ($buyerData['postal_code'] ?? '')) ?> <?= $e((string) ($buyerData['city'] ?? '')) ?></dd>
|
|
<?php if (($buyerData['email'] ?? '') !== ''): ?>
|
|
<dt>Email</dt><dd><?= $e((string) $buyerData['email']) ?></dd>
|
|
<?php endif; ?>
|
|
</dl>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<h3 class="section-title mt-16">Pozycje</h3>
|
|
<div class="table-wrap mt-8">
|
|
<table class="table table--details">
|
|
<thead>
|
|
<tr>
|
|
<th>Lp.</th>
|
|
<th>Nazwa</th>
|
|
<th>Ilosc</th>
|
|
<th>Cena netto</th>
|
|
<th>VAT</th>
|
|
<th>Cena brutto</th>
|
|
<th>Suma brutto</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($itemsList as $idx => $item): ?>
|
|
<tr>
|
|
<td><?= $e((string) ($idx + 1)) ?></td>
|
|
<td><?= $e((string) ($item['name'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($item['quantity'] ?? 0)) ?></td>
|
|
<td class="text-nowrap"><?= $e(number_format((float) ($item['price_net'] ?? 0), 2, '.', ' ')) ?></td>
|
|
<td><?= $e(number_format((float) ($item['vat'] ?? 0), 0, '.', '')) ?>%</td>
|
|
<td class="text-nowrap"><?= $e(number_format((float) ($item['price_gross'] ?? 0), 2, '.', ' ')) ?></td>
|
|
<td class="text-nowrap"><?= $e(number_format((float) ($item['total_gross'] ?? 0), 2, '.', ' ')) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr>
|
|
<td colspan="6" class="text-right"><strong>Razem netto</strong></td>
|
|
<td class="text-nowrap"><strong><?= $e(number_format($totalNet, 2, '.', ' ')) ?></strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="6" class="text-right"><strong>Razem brutto</strong></td>
|
|
<td class="text-nowrap"><strong><?= $e(number_format($totalGross, 2, '.', ' ')) ?> PLN</strong></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="form-grid-2 mt-16">
|
|
<dl class="order-kv">
|
|
<?php $issueDateShow = (string) ($invoiceData['issue_date'] ?? '-'); ?>
|
|
<dt>Data wystawienia</dt><dd><?= $e(strlen($issueDateShow) >= 16 ? substr($issueDateShow, 0, 16) : $issueDateShow) ?></dd>
|
|
<dt>Data sprzedazy</dt><dd><?= $e((string) ($invoiceData['sale_date'] ?? '-')) ?></dd>
|
|
<?php if (($invoiceData['payment_due_date'] ?? null) !== null): ?>
|
|
<dt>Termin platnosci</dt><dd><?= $e(substr((string) $invoiceData['payment_due_date'], 0, 10)) ?></dd>
|
|
<?php endif; ?>
|
|
<dt>Konfiguracja</dt><dd><?= $e($configNameVal !== '' ? $configNameVal : '-') ?></dd>
|
|
<dt>Typ</dt><dd><?= $e((string) ($invoiceData['kind'] ?? 'vat')) ?></dd>
|
|
<?php if (($invoiceData['order_reference_value'] ?? null) !== null): ?>
|
|
<dt>Nr referencyjny</dt><dd><?= $e((string) $invoiceData['order_reference_value']) ?></dd>
|
|
<?php endif; ?>
|
|
</dl>
|
|
</div>
|
|
</section>
|