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:
292
resources/views/accounting/invoice_form.php
Normal file
292
resources/views/accounting/invoice_form.php
Normal file
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
$orderRow = is_array($order ?? null) ? $order : [];
|
||||
$itemsList = is_array($items ?? null) ? $items : [];
|
||||
$configsList = is_array($configs ?? null) ? $configs : [];
|
||||
$sellerData = is_array($seller ?? null) ? $seller : [];
|
||||
$buyerAddr = is_array($buyerAddress ?? null) ? $buyerAddress : null;
|
||||
$autoNip = (string) ($autoTaxNumber ?? '');
|
||||
$existingInvoicesList = is_array($existingInvoices ?? null) ? $existingInvoices : [];
|
||||
$hasExistingInvoices = $existingInvoicesList !== [];
|
||||
$orderIdVal = (int) ($orderId ?? 0);
|
||||
$errorMsg = (string) ($errorMessage ?? '');
|
||||
|
||||
$buyerNameDefault = trim((string) ($buyerAddr['name'] ?? ''));
|
||||
$buyerCompanyDefault = trim((string) ($buyerAddr['company_name'] ?? ''));
|
||||
$buyerStreetDefault = trim(((string) ($buyerAddr['street_name'] ?? '')) . ' ' . ((string) ($buyerAddr['street_number'] ?? '')));
|
||||
$buyerCityDefault = trim((string) ($buyerAddr['city'] ?? ''));
|
||||
$buyerPostalDefault = trim((string) ($buyerAddr['zip_code'] ?? ''));
|
||||
$buyerEmailDefault = trim((string) ($buyerAddr['email'] ?? $orderRow['buyer_email'] ?? ''));
|
||||
?>
|
||||
|
||||
<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">Wystaw fakture</h2>
|
||||
<div class="order-details-sub mt-4">
|
||||
Zamowienie <?= $e((string) ($orderRow['internal_order_number'] ?? ('#' . $orderIdVal))) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($errorMsg !== ''): ?>
|
||||
<div class="alert alert--danger mt-12"><?= $e($errorMsg) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($hasExistingInvoices): ?>
|
||||
<div class="alert alert--warning mt-12">
|
||||
<strong>Uwaga!</strong> Do tego zamowienia wystawiono juz <?= $e((string) count($existingInvoicesList)) ?> fakture/y:
|
||||
<ul class="mt-4">
|
||||
<?php foreach ($existingInvoicesList as $ei): ?>
|
||||
<li>
|
||||
<strong><?= $e((string) ($ei['invoice_number'] ?? '-')) ?></strong>
|
||||
— <?= $e(substr((string) ($ei['issue_date'] ?? ''), 0, 16)) ?>,
|
||||
<?= $e(number_format((float) ($ei['total_gross'] ?? 0), 2, '.', ' ')) ?> PLN
|
||||
(<?= $e((string) ($ei['config_name'] ?? '-')) ?><?php if (trim((string) ($ei['external_invoice_id'] ?? '')) !== ''): ?>, Fakturownia<?php endif; ?>)
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form id="invoice-create-form" method="post" action="/orders/<?= $e((string) $orderIdVal) ?>/invoice/store" class="mt-16">
|
||||
<input type="hidden" name="_token" value="<?= $e((string) ($csrfToken ?? '')) ?>">
|
||||
|
||||
<div class="form-grid-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="config_id">Konfiguracja faktury</label>
|
||||
<select name="config_id" id="config_id" class="form-control" required>
|
||||
<option value="">— wybierz konfiguracje —</option>
|
||||
<?php foreach ($configsList as $cfg): ?>
|
||||
<?php
|
||||
$cfgId = (int) ($cfg['id'] ?? 0);
|
||||
$cfgIsDelegated = (int) ($cfg['is_delegated'] ?? 0) === 1;
|
||||
$cfgIntName = trim((string) ($cfg['integration_name'] ?? ''));
|
||||
$cfgLabel = trim((string) ($cfg['name'] ?? ''))
|
||||
. ' — '
|
||||
. ($cfgIsDelegated ? ('Fakturownia' . ($cfgIntName !== '' ? ': ' . $cfgIntName : '')) : 'Lokalnie')
|
||||
. ' (' . trim((string) ($cfg['number_format'] ?? '')) . ')';
|
||||
?>
|
||||
<option value="<?= $e((string) $cfgId) ?>"><?= $e($cfgLabel) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="issue_date">Data wystawienia</label>
|
||||
<input type="datetime-local" name="issue_date" id="issue_date" class="form-control" value="<?= $e(date('Y-m-d\TH:i')) ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="section-title mt-16">Dane nabywcy</h3>
|
||||
<div class="form-grid-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="buyer_tax_number">NIP nabywcy</label>
|
||||
<div style="display:flex;gap:8px;align-items:flex-start;">
|
||||
<input type="text" name="buyer_tax_number" id="buyer_tax_number" class="form-control"
|
||||
value="<?= $e($autoNip) ?>"
|
||||
placeholder="np. 1234567890"
|
||||
style="flex:1;">
|
||||
<button type="button" id="btn-gus-lookup" class="btn btn--secondary" style="white-space:nowrap;">
|
||||
Pobierz z GUS
|
||||
</button>
|
||||
</div>
|
||||
<?php if ($autoNip !== ''): ?>
|
||||
<small class="muted">Auto-wykryty z payload zamowienia. Mozesz nadpisac lub kliknac "Pobierz z GUS".</small>
|
||||
<?php else: ?>
|
||||
<small class="muted">Wpisz NIP i kliknij "Pobierz z GUS" — dane firmy zostana wypelnione automatycznie.</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="buyer_name">Imie i nazwisko</label>
|
||||
<input type="text" name="buyer_name" id="buyer_name" class="form-control"
|
||||
value="<?= $e($buyerNameDefault) ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="buyer_company_name">Nazwa firmy</label>
|
||||
<input type="text" name="buyer_company_name" id="buyer_company_name" class="form-control"
|
||||
value="<?= $e($buyerCompanyDefault) ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="buyer_email">Email</label>
|
||||
<input type="email" name="buyer_email" id="buyer_email" class="form-control"
|
||||
value="<?= $e($buyerEmailDefault) ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="buyer_street">Ulica i numer</label>
|
||||
<input type="text" name="buyer_street" id="buyer_street" class="form-control"
|
||||
value="<?= $e($buyerStreetDefault) ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="buyer_city">Miejscowosc</label>
|
||||
<input type="text" name="buyer_city" id="buyer_city" class="form-control"
|
||||
value="<?= $e($buyerCityDefault) ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="buyer_postal_code">Kod pocztowy</label>
|
||||
<input type="text" name="buyer_postal_code" id="buyer_postal_code" class="form-control"
|
||||
value="<?= $e($buyerPostalDefault) ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="section-title mt-16">Pozycje zamowienia</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 brutto</th>
|
||||
<th>VAT</th>
|
||||
<th>Suma brutto</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($itemsList === []): ?>
|
||||
<tr><td colspan="6" class="muted">Brak pozycji</td></tr>
|
||||
<?php endif; ?>
|
||||
<?php $totalGross = 0.0; ?>
|
||||
<?php foreach ($itemsList as $idx => $item): ?>
|
||||
<?php
|
||||
$qty = (float) ($item['quantity'] ?? 0);
|
||||
$price = $item['original_price_with_tax'] !== null ? (float) $item['original_price_with_tax'] : (float) ($item['price_gross'] ?? 0);
|
||||
$vat = (float) ($item['vat'] ?? 23);
|
||||
$sum = $qty * $price;
|
||||
$totalGross += $sum;
|
||||
?>
|
||||
<tr>
|
||||
<td><?= $e((string) ($idx + 1)) ?></td>
|
||||
<td><?= $e((string) ($item['original_name'] ?? $item['name'] ?? '')) ?></td>
|
||||
<td><?= $e((string) $qty) ?></td>
|
||||
<td><?= $e(number_format($price, 2, '.', ' ')) ?></td>
|
||||
<td><?= $e(number_format($vat, 0, '.', '')) ?>%</td>
|
||||
<td><?= $e(number_format($sum, 2, '.', ' ')) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php
|
||||
$deliveryPrice = (float) ($orderRow['delivery_price'] ?? 0);
|
||||
if ($deliveryPrice > 0) {
|
||||
$totalGross += $deliveryPrice;
|
||||
?>
|
||||
<tr>
|
||||
<td><?= $e((string) (count($itemsList) + 1)) ?></td>
|
||||
<td>Koszt wysylki</td>
|
||||
<td>1</td>
|
||||
<td><?= $e(number_format($deliveryPrice, 2, '.', ' ')) ?></td>
|
||||
<td>23%</td>
|
||||
<td><?= $e(number_format($deliveryPrice, 2, '.', ' ')) ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5" class="text-right"><strong>Razem brutto:</strong></td>
|
||||
<td><strong><?= $e(number_format($totalGross, 2, '.', ' ')) ?> <?= $e((string) ($orderRow['currency'] ?? 'PLN')) ?></strong></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 class="section-title mt-16">Sprzedawca (z ustawien firmy)</h3>
|
||||
<div class="receipt-seller-preview mt-8">
|
||||
<dl class="order-kv">
|
||||
<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>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="mt-16">
|
||||
<?php if ($hasExistingInvoices): ?>
|
||||
<button type="button" id="invoice-submit-btn" class="btn btn--primary">Wystaw fakture</button>
|
||||
<?php else: ?>
|
||||
<button type="submit" class="btn btn--primary">Wystaw fakture</button>
|
||||
<?php endif; ?>
|
||||
<a href="/orders/<?= $e((string) $orderIdVal) ?>" class="btn btn--secondary ml-8">Anuluj</a>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var btn = document.getElementById('btn-gus-lookup');
|
||||
if (!btn) { return; }
|
||||
|
||||
btn.addEventListener('click', function () {
|
||||
var nipInput = document.getElementById('buyer_tax_number');
|
||||
var nip = (nipInput.value || '').replace(/[\s\-]/g, '');
|
||||
|
||||
if (!/^\d{10}$/.test(nip)) {
|
||||
if (window.OrderProAlerts && window.OrderProAlerts.error) {
|
||||
window.OrderProAlerts.error('Wpisz poprawny NIP (10 cyfr) przed klikniem "Pobierz z GUS".');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var originalLabel = btn.textContent;
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Pobieram...';
|
||||
|
||||
var url = '/api/nip/lookup?nip=' + encodeURIComponent(nip);
|
||||
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(function (resp) { return resp.json().then(function (j) { return { ok: resp.ok, data: j }; }); })
|
||||
.then(function (res) {
|
||||
if (!res.ok || !res.data || !res.data.success) {
|
||||
var msg = res.data && res.data.error ? res.data.error : 'Blad pobierania danych z GUS.';
|
||||
throw new Error(msg);
|
||||
}
|
||||
var d = res.data.data || {};
|
||||
if (d.tax_number) { nipInput.value = d.tax_number; }
|
||||
var fields = {
|
||||
buyer_company_name: d.company_name,
|
||||
buyer_street: d.street,
|
||||
buyer_postal_code: d.postal_code,
|
||||
buyer_city: d.city
|
||||
};
|
||||
Object.keys(fields).forEach(function (key) {
|
||||
var el = document.getElementById(key);
|
||||
if (el && fields[key]) { el.value = fields[key]; }
|
||||
});
|
||||
})
|
||||
.catch(function (err) {
|
||||
if (window.OrderProAlerts && window.OrderProAlerts.error) {
|
||||
window.OrderProAlerts.error(err && err.message ? err.message : 'Blad GUS.');
|
||||
} else {
|
||||
alert(err && err.message ? err.message : 'Blad GUS.');
|
||||
}
|
||||
})
|
||||
.finally(function () {
|
||||
btn.disabled = false;
|
||||
btn.textContent = originalLabel;
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?php if ($hasExistingInvoices): ?>
|
||||
<script>
|
||||
document.getElementById('invoice-submit-btn').addEventListener('click', function() {
|
||||
window.OrderProAlerts.confirm({
|
||||
title: 'Wystawic kolejna fakture?',
|
||||
message: 'Do tego zamowienia wystawiono juz fakture. Czy na pewno chcesz wystawic kolejna?',
|
||||
confirmLabel: 'Wystaw',
|
||||
danger: false,
|
||||
onConfirm: function() {
|
||||
document.getElementById('invoice-create-form').submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
156
resources/views/accounting/invoice_pdf.php
Normal file
156
resources/views/accounting/invoice_pdf.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Faktura <?= $e((string) ($invoice['invoice_number'] ?? '')) ?></title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font-family: "DejaVu Sans", "Segoe UI", Arial, sans-serif; font-size: 12px; color: #1a1a1a; padding: 20mm 15mm; }
|
||||
.invoice-print { max-width: 740px; margin: 0 auto; }
|
||||
.invoice-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px; padding-bottom: 12px; border-bottom: 2px solid #333; }
|
||||
.invoice-header__seller { flex: 1; }
|
||||
.invoice-header__seller strong { font-size: 14px; display: block; margin-bottom: 4px; }
|
||||
.invoice-header__title { text-align: right; }
|
||||
.invoice-header__title h1 { font-size: 18px; font-weight: 700; margin-bottom: 4px; }
|
||||
.invoice-header__title .invoice-number { font-size: 14px; font-weight: 600; }
|
||||
.invoice-parties { display: flex; gap: 12px; margin-bottom: 16px; }
|
||||
.invoice-party { flex: 1; padding: 8px 12px; border: 1px solid #ccc; }
|
||||
.invoice-party strong { display: block; margin-bottom: 4px; font-size: 11px; text-transform: uppercase; color: #666; }
|
||||
.invoice-items { width: 100%; border-collapse: collapse; margin-bottom: 16px; }
|
||||
.invoice-items th { background: #f0f0f0; text-align: left; padding: 6px 8px; font-size: 11px; border-bottom: 1px solid #999; }
|
||||
.invoice-items td { padding: 5px 8px; border-bottom: 1px solid #ddd; }
|
||||
.invoice-items .text-right { text-align: right; }
|
||||
.invoice-items .text-nowrap { white-space: nowrap; }
|
||||
.invoice-items tfoot td { border-top: 1px solid #999; font-weight: 600; padding: 6px 8px; }
|
||||
.invoice-items tfoot .total-row td { border-top: 2px solid #333; font-weight: 700; }
|
||||
.invoice-meta { margin-top: 16px; font-size: 11px; color: #555; }
|
||||
.invoice-meta dt { display: inline; font-weight: 600; }
|
||||
.invoice-meta dd { display: inline; margin: 0 16px 0 4px; }
|
||||
.invoice-payment { margin-top: 16px; padding: 8px 12px; border: 1px solid #ccc; background: #fafafa; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?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 : [];
|
||||
$totalGross = (float) ($invoiceData['total_gross'] ?? 0);
|
||||
$totalNet = (float) ($invoiceData['total_net'] ?? 0);
|
||||
$totalVat = max(0.0, $totalGross - $totalNet);
|
||||
?>
|
||||
<div class="invoice-print">
|
||||
<div class="invoice-header">
|
||||
<div class="invoice-header__seller">
|
||||
<strong><?= $e((string) ($sellerData['company_name'] ?? '')) ?></strong>
|
||||
<?php if (($sellerData['tax_number'] ?? '') !== ''): ?>
|
||||
<div>NIP: <?= $e((string) $sellerData['tax_number']) ?></div>
|
||||
<?php endif; ?>
|
||||
<div><?= $e((string) ($sellerData['street'] ?? '')) ?></div>
|
||||
<div><?= $e((string) ($sellerData['postal_code'] ?? '')) ?> <?= $e((string) ($sellerData['city'] ?? '')) ?></div>
|
||||
<?php if (($sellerData['phone'] ?? '') !== ''): ?>
|
||||
<div>Tel: <?= $e((string) $sellerData['phone']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (($sellerData['email'] ?? '') !== ''): ?>
|
||||
<div>Email: <?= $e((string) $sellerData['email']) ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="invoice-header__title">
|
||||
<h1>FAKTURA VAT</h1>
|
||||
<div class="invoice-number"><?= $e((string) ($invoiceData['invoice_number'] ?? '')) ?></div>
|
||||
<?php $issueDate = (string) ($invoiceData['issue_date'] ?? ''); ?>
|
||||
<div>Data wystawienia: <?= $e(substr($issueDate, 0, 10)) ?></div>
|
||||
<?php $saleDate = (string) ($invoiceData['sale_date'] ?? ''); ?>
|
||||
<?php if ($saleDate !== ''): ?>
|
||||
<div>Data sprzedazy: <?= $e(substr($saleDate, 0, 10)) ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($buyerData !== null): ?>
|
||||
<div class="invoice-parties">
|
||||
<div class="invoice-party">
|
||||
<strong>Sprzedawca</strong>
|
||||
<div><?= $e((string) ($sellerData['company_name'] ?? '')) ?></div>
|
||||
<?php if (($sellerData['tax_number'] ?? '') !== ''): ?>
|
||||
<div>NIP: <?= $e((string) $sellerData['tax_number']) ?></div>
|
||||
<?php endif; ?>
|
||||
<div><?= $e((string) ($sellerData['street'] ?? '')) ?></div>
|
||||
<div><?= $e((string) ($sellerData['postal_code'] ?? '')) ?> <?= $e((string) ($sellerData['city'] ?? '')) ?></div>
|
||||
</div>
|
||||
<div class="invoice-party">
|
||||
<strong>Nabywca</strong>
|
||||
<?php if (($buyerData['company_name'] ?? '') !== ''): ?>
|
||||
<div><?= $e((string) $buyerData['company_name']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (($buyerData['name'] ?? '') !== ''): ?>
|
||||
<div><?= $e((string) $buyerData['name']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (($buyerData['tax_number'] ?? '') !== ''): ?>
|
||||
<div>NIP: <?= $e((string) $buyerData['tax_number']) ?></div>
|
||||
<?php endif; ?>
|
||||
<div><?= $e((string) ($buyerData['street'] ?? '')) ?></div>
|
||||
<div><?= $e((string) ($buyerData['postal_code'] ?? '')) ?> <?= $e((string) ($buyerData['city'] ?? '')) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<table class="invoice-items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Lp.</th>
|
||||
<th>Nazwa</th>
|
||||
<th class="text-right">Ilosc</th>
|
||||
<th class="text-right">Cena netto</th>
|
||||
<th class="text-right">VAT</th>
|
||||
<th class="text-right">Cena brutto</th>
|
||||
<th class="text-right">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 class="text-right text-nowrap"><?= $e((string) ($item['quantity'] ?? 0)) ?></td>
|
||||
<td class="text-right text-nowrap"><?= $e(number_format((float) ($item['price_net'] ?? 0), 2, '.', ' ')) ?></td>
|
||||
<td class="text-right"><?= $e(number_format((float) ($item['vat'] ?? 0), 0, '.', '')) ?>%</td>
|
||||
<td class="text-right text-nowrap"><?= $e(number_format((float) ($item['price_gross'] ?? 0), 2, '.', ' ')) ?></td>
|
||||
<td class="text-right text-nowrap"><?= $e(number_format((float) ($item['total_gross'] ?? 0), 2, '.', ' ')) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="6" class="text-right">Razem netto</td>
|
||||
<td class="text-right text-nowrap"><?= $e(number_format($totalNet, 2, '.', ' ')) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" class="text-right">Razem VAT</td>
|
||||
<td class="text-right text-nowrap"><?= $e(number_format($totalVat, 2, '.', ' ')) ?></td>
|
||||
</tr>
|
||||
<tr class="total-row">
|
||||
<td colspan="6" class="text-right">Razem brutto</td>
|
||||
<td class="text-right text-nowrap"><?= $e(number_format($totalGross, 2, '.', ' ')) ?> PLN</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<?php if (($invoiceData['payment_due_date'] ?? null) !== null): ?>
|
||||
<div class="invoice-payment">
|
||||
<strong>Termin platnosci:</strong> <?= $e(substr((string) $invoiceData['payment_due_date'], 0, 10)) ?>
|
||||
<?php if (trim((string) ($sellerData['bank_account'] ?? '')) !== ''): ?>
|
||||
| <strong>Konto:</strong> <?= $e((string) $sellerData['bank_account']) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<dl class="invoice-meta">
|
||||
<?php if (($invoiceData['order_reference_value'] ?? null) !== null): ?>
|
||||
<dt>Nr referencyjny:</dt><dd><?= $e((string) $invoiceData['order_reference_value']) ?></dd>
|
||||
<?php endif; ?>
|
||||
<dt>Typ dokumentu:</dt><dd><?= $e((string) ($invoiceData['kind'] ?? 'vat')) ?></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
131
resources/views/accounting/invoice_preview.php
Normal file
131
resources/views/accounting/invoice_preview.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?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>
|
||||
144
resources/views/accounting/invoices_issued_list.php
Normal file
144
resources/views/accounting/invoices_issued_list.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
$invoicesList = is_array($invoices ?? null) ? $invoices : [];
|
||||
$configsList = is_array($configs ?? null) ? $configs : [];
|
||||
$filtersData = is_array($filters ?? null) ? $filters : [];
|
||||
$totalCount = (int) ($total ?? 0);
|
||||
$pageNum = (int) ($page ?? 1);
|
||||
$totalPagesNum = (int) ($totalPages ?? 1);
|
||||
$perPageNum = (int) ($perPage ?? 50);
|
||||
?>
|
||||
|
||||
<section class="card">
|
||||
<div class="orders-head">
|
||||
<div>
|
||||
<a href="/settings/accounting" class="order-back-link">← Ksiegowosc</a>
|
||||
<h2 class="section-title mt-12">Wystawione faktury</h2>
|
||||
<div class="muted mt-4">Lacznie: <?= $e((string) $totalCount) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="get" action="/settings/accounting/invoices/issued" class="mt-12">
|
||||
<div class="form-grid-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="search">Szukaj (numer, zamowienie)</label>
|
||||
<input type="text" name="search" id="search" class="form-control" value="<?= $e((string) ($filtersData['search'] ?? '')) ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="config_id">Konfiguracja</label>
|
||||
<select name="config_id" id="config_id" class="form-control">
|
||||
<option value="0">Wszystkie</option>
|
||||
<?php foreach ($configsList as $cfg): ?>
|
||||
<option value="<?= $e((string) ($cfg['id'] ?? '')) ?>" <?= ((int) ($filtersData['config_id'] ?? 0) === (int) ($cfg['id'] ?? 0)) ? 'selected' : '' ?>>
|
||||
<?= $e((string) ($cfg['name'] ?? '')) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="mode">Tryb</label>
|
||||
<select name="mode" id="mode" class="form-control">
|
||||
<?php $modeVal = (string) ($filtersData['mode'] ?? ''); ?>
|
||||
<option value="" <?= $modeVal === '' ? 'selected' : '' ?>>Wszystkie</option>
|
||||
<option value="local" <?= $modeVal === 'local' ? 'selected' : '' ?>>Lokalnie</option>
|
||||
<option value="delegated" <?= $modeVal === 'delegated' ? 'selected' : '' ?>>Fakturownia</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="date_from">Data od</label>
|
||||
<input type="date" name="date_from" id="date_from" class="form-control" value="<?= $e((string) ($filtersData['date_from'] ?? '')) ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="date_to">Data do</label>
|
||||
<input type="date" name="date_to" id="date_to" class="form-control" value="<?= $e((string) ($filtersData['date_to'] ?? '')) ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-12">
|
||||
<button type="submit" class="btn btn--primary">Filtruj</button>
|
||||
<a href="/settings/accounting/invoices/issued" class="btn btn--secondary ml-8">Wyczysc</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="table-wrap mt-16">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Numer</th>
|
||||
<th>Data wystawienia</th>
|
||||
<th>Nabywca</th>
|
||||
<th>Brutto</th>
|
||||
<th>Tryb</th>
|
||||
<th>Konfiguracja</th>
|
||||
<th>Zamowienie</th>
|
||||
<th>Akcje</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($invoicesList === []): ?>
|
||||
<tr><td colspan="8" class="muted">Brak faktur w wybranych filtrach</td></tr>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($invoicesList as $inv): ?>
|
||||
<?php
|
||||
$buyer = json_decode((string) ($inv['buyer_data_json'] ?? '{}'), true);
|
||||
$buyer = is_array($buyer) ? $buyer : [];
|
||||
$buyerLabel = trim((string) ($buyer['company_name'] ?? '')) !== ''
|
||||
? (string) $buyer['company_name']
|
||||
: (string) ($buyer['name'] ?? '-');
|
||||
$buyerNip = trim((string) ($buyer['tax_number'] ?? ''));
|
||||
$isDelegated = trim((string) ($inv['external_invoice_id'] ?? '')) !== '';
|
||||
$issueDate = (string) ($inv['issue_date'] ?? '');
|
||||
$orderRef = (int) ($inv['order_id'] ?? 0);
|
||||
$orderLabel = trim((string) ($inv['internal_order_number'] ?? '')) !== ''
|
||||
? (string) $inv['internal_order_number']
|
||||
: ('#' . $orderRef);
|
||||
?>
|
||||
<tr>
|
||||
<td><strong><?= $e((string) ($inv['invoice_number'] ?? '')) ?></strong></td>
|
||||
<td class="text-nowrap"><?= $e(strlen($issueDate) >= 16 ? substr($issueDate, 0, 16) : $issueDate) ?></td>
|
||||
<td>
|
||||
<?= $e($buyerLabel) ?>
|
||||
<?php if ($buyerNip !== ''): ?>
|
||||
<div class="muted">NIP: <?= $e($buyerNip) ?></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-nowrap"><?= $e(number_format((float) ($inv['total_gross'] ?? 0), 2, '.', ' ')) ?> PLN</td>
|
||||
<td>
|
||||
<?php if ($isDelegated): ?>
|
||||
<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) $orderRef) ?>"><?= $e($orderLabel) ?></a></td>
|
||||
<td>
|
||||
<a href="/orders/<?= $e((string) $orderRef) ?>/invoice/<?= $e((string) ($inv['id'] ?? '')) ?>" class="btn btn--sm btn--secondary">Podglad</a>
|
||||
<?php if ($isDelegated && trim((string) ($inv['external_pdf_url'] ?? '')) !== ''): ?>
|
||||
<a href="/orders/<?= $e((string) $orderRef) ?>/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) $orderRef) ?>/invoice/<?= $e((string) ($inv['id'] ?? '')) ?>/pdf" class="btn btn--sm btn--secondary">PDF</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php if ($totalPagesNum > 1): ?>
|
||||
<div class="pagination mt-12">
|
||||
<?php for ($p = 1; $p <= $totalPagesNum; $p++): ?>
|
||||
<?php
|
||||
$qs = http_build_query(array_merge(
|
||||
$filtersData,
|
||||
['page' => $p]
|
||||
));
|
||||
?>
|
||||
<?php if ($p === $pageNum): ?>
|
||||
<strong class="pagination__current"><?= $e((string) $p) ?></strong>
|
||||
<?php else: ?>
|
||||
<a class="pagination__page" href="/settings/accounting/invoices/issued?<?= $e($qs) ?>"><?= $e((string) $p) ?></a>
|
||||
<?php endif; ?>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
@@ -192,6 +192,7 @@
|
||||
<script src="/assets/js/modules/global-search.js?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/js/modules/global-search.js') ?: 0 ?>"></script>
|
||||
<script src="/assets/js/modules/checkbox-multiselect.js?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/js/modules/checkbox-multiselect.js') ?: 0 ?>"></script>
|
||||
<script src="/assets/js/modules/invoice-config-form.js?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/js/modules/invoice-config-form.js') ?: 0 ?>"></script>
|
||||
<script src="/assets/js/modules/invoice-requested-toggle.js?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/js/modules/invoice-requested-toggle.js') ?: 0 ?>"></script>
|
||||
<script src="/assets/js/modules/confirm-delete.js?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/js/modules/confirm-delete.js') ?: 0 ?>"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script>
|
||||
<script src="/assets/js/modules/statistics-summary-charts.js?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/js/modules/statistics-summary-charts.js') ?: 0 ?>"></script>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -29,6 +29,7 @@ $error = trim((string) ($errorMessage ?? ''));
|
||||
<p class="muted mt-12">Konfiguracje wystawiania faktur: numeracja lokalna lub delegacja do Fakturowni, termin platnosci, typ dokumentu.</p>
|
||||
<div class="form-actions mt-16">
|
||||
<a class="btn btn--primary" href="/settings/accounting/invoices">Zarzadzaj fakturami</a>
|
||||
<a class="btn btn--secondary ml-8" href="/settings/accounting/invoices/issued">Faktury wystawione</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user