feat(115): wystawianie faktury z zamowienia (lokalne + delegowane Fakturownia)
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>
This commit is contained in:
@@ -9,6 +9,9 @@ $documentsList = is_array($documents ?? null) ? $documents : [];
|
||||
$notesList = is_array($notes ?? null) ? $notes : [];
|
||||
$receiptsList = is_array($receipts ?? null) ? $receipts : [];
|
||||
$receiptConfigsList = is_array($receiptConfigs ?? null) ? $receiptConfigs : [];
|
||||
$invoicesList = is_array($invoices ?? null) ? $invoices : [];
|
||||
$invoiceConfigsList = is_array($invoiceConfigs ?? null) ? $invoiceConfigs : [];
|
||||
$invoiceRequestedFlag = (int) ($orderRow['invoice_requested'] ?? 0) === 1;
|
||||
$emailTemplatesList = is_array($emailTemplates ?? null) ? $emailTemplates : [];
|
||||
$emailMailboxesList = is_array($emailMailboxes ?? null) ? $emailMailboxes : [];
|
||||
$historyList = is_array($history ?? null) ? $history : [];
|
||||
@@ -61,6 +64,13 @@ foreach ($addressesList as $address) {
|
||||
<?php if ($receiptConfigsList !== []): ?>
|
||||
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>/receipt/create" class="btn btn--secondary">Wystaw paragon</a>
|
||||
<?php endif; ?>
|
||||
<span data-invoice-button-wrap style="<?= $invoiceRequestedFlag ? '' : 'display:none;' ?>">
|
||||
<?php if ($invoiceConfigsList !== []): ?>
|
||||
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>/invoice/create" class="btn btn--secondary">Wystaw fakture</a>
|
||||
<?php else: ?>
|
||||
<button type="button" class="btn btn--secondary btn--disabled" title="Brak aktywnych konfiguracji faktur">Wystaw fakture</button>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<?php
|
||||
$emailBuyerAddr = '';
|
||||
foreach ($addressesList as $a) {
|
||||
@@ -712,6 +722,18 @@ foreach ($addressesList as $address) {
|
||||
<section class="card mt-16">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.tabs.payments')) ?></h3>
|
||||
|
||||
<div class="invoice-requested-row mt-12" style="display:flex;align-items:center;gap:8px;padding:8px 12px;border:1px solid var(--border-color, #e5e7eb);border-radius:6px;">
|
||||
<label style="display:inline-flex;align-items:center;gap:6px;cursor:pointer;margin:0;">
|
||||
<input type="checkbox"
|
||||
data-invoice-requested-toggle
|
||||
data-order-id="<?= $e((string) ($orderId ?? 0)) ?>"
|
||||
data-csrf-token="<?= $e((string) ($csrfToken ?? '')) ?>"
|
||||
<?= $invoiceRequestedFlag ? 'checked' : '' ?>>
|
||||
<span><strong>Klient prosi o fakture</strong></span>
|
||||
</label>
|
||||
<span class="muted" style="font-size:12px;">Po zaznaczeniu pojawi sie przycisk "Wystaw fakture" w naglowku zamowienia.</span>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$paymentStatusNum = isset($orderRow['payment_status']) ? (int) $orderRow['payment_status'] : null;
|
||||
$paymentStatusLabels = [0 => 'Nieopłacone', 1 => 'Częściowo opłacone', 2 => 'Opłacone', 3 => 'Zwrócone'];
|
||||
@@ -843,9 +865,56 @@ foreach ($addressesList as $address) {
|
||||
<div class="order-tab-panel" data-order-tab-panel="documents">
|
||||
<section class="card mt-16">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.tabs.documents')) ?></h3>
|
||||
<?php if ($receiptsList === [] && $documentsList === []): ?>
|
||||
<?php if ($receiptsList === [] && $documentsList === [] && $invoicesList === []): ?>
|
||||
<p class="muted mt-12"><?= $e($t('receipts.documents.empty')) ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if ($invoicesList !== []): ?>
|
||||
<h4 class="section-title mt-12">Faktury</h4>
|
||||
<div class="table-wrap mt-8">
|
||||
<table class="table table--details">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Numer</th>
|
||||
<th>Data wystawienia</th>
|
||||
<th>Brutto</th>
|
||||
<th>Tryb</th>
|
||||
<th>Konfiguracja</th>
|
||||
<th>Akcje</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($invoicesList as $inv): ?>
|
||||
<?php
|
||||
$invIssueDate = (string) ($inv['issue_date'] ?? '');
|
||||
$invIsDelegated = trim((string) ($inv['external_invoice_id'] ?? '')) !== '';
|
||||
$invExternalPdf = trim((string) ($inv['external_pdf_url'] ?? ''));
|
||||
?>
|
||||
<tr>
|
||||
<td><strong><?= $e((string) ($inv['invoice_number'] ?? '')) ?></strong></td>
|
||||
<td class="text-nowrap"><?= $e(strlen($invIssueDate) >= 16 ? substr($invIssueDate, 0, 16) : $invIssueDate) ?></td>
|
||||
<td class="text-nowrap"><?= $e($inv['total_gross'] !== null ? number_format((float) $inv['total_gross'], 2, '.', ' ') : '-') ?></td>
|
||||
<td>
|
||||
<?php if ($invIsDelegated): ?>
|
||||
<span class="badge badge--success">Fakturownia<?php if (trim((string) ($inv['account_prefix'] ?? '')) !== ''): ?>: <?= $e((string) $inv['account_prefix']) ?><?php endif; ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge--muted">Lokalnie</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= $e((string) ($inv['config_name'] ?? '-')) ?></td>
|
||||
<td>
|
||||
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>/invoice/<?= $e((string) ($inv['id'] ?? '')) ?>" class="btn btn--sm btn--secondary">Podglad</a>
|
||||
<?php if ($invIsDelegated && $invExternalPdf !== ''): ?>
|
||||
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>/invoice/<?= $e((string) ($inv['id'] ?? '')) ?>/pdf" class="btn btn--sm btn--secondary" target="_blank" rel="noopener">PDF</a>
|
||||
<?php else: ?>
|
||||
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>/invoice/<?= $e((string) ($inv['id'] ?? '')) ?>/pdf" class="btn btn--sm btn--secondary">PDF</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($receiptsList !== []): ?>
|
||||
<h4 class="section-title mt-12">Paragony</h4>
|
||||
<div class="table-wrap mt-8">
|
||||
|
||||
Reference in New Issue
Block a user