{{-- The body of an invoice, for TCPDF's writeHTML(). Tables and inline styles, and a narrower dialect than even an email: TCPDF understands a small subset of HTML and almost no CSS. No flexbox, no grid, no shorthand borders on table cells, no percentage padding. What works is a table with widths, and text-align. Every value comes from the frozen snapshot ($s). Nothing here reads a setting or a model — that is the whole reason no PDF has to be stored. --}} @php use App\Services\Billing\InvoiceMath; $issuer = $s['issuer'] ?? []; $customer = $s['customer'] ?? []; $meta = $s['meta'] ?? []; $lines = $s['lines'] ?? []; $totals = $s['totals'] ?? []; @endphp {{-- Sender line above the address, small — the line that shows through a window envelope and tells the postman where to return it. --}}
| {{ collect([$issuer['name'] ?? null, $issuer['address'] ?? null, trim(($issuer['postcode'] ?? '').' '.($issuer['city'] ?? '')), $issuer['country'] ?? null])->filter()->join(' | ') }} |
| {{ $customer['name'] ?? '' }}@if (! empty($customer['address_lines']))@foreach ($customer['address_lines'] as $addressLine) {{ $addressLine }}@endforeach@else {{ $customer['address'] ?? '' }} {{ trim(($customer['postcode'] ?? '').' '.($customer['city'] ?? '')) }} {{ $customer['country'] ?? '' }}@endif@if (! empty($customer['vat_id'])) {{ __('invoice.customer_vat') }}: {{ $customer['vat_id'] }}@endif |
| {{ __('invoice.date') }} | {{ $meta['issued_on'] ?? '' }} | |
| {{ __('invoice.customer_number') }} | {{ $meta['customer_number'] }} | |
| {{ __('invoice.number') }} | {{ $meta['number'] ?? '' }} | |
| {{ __('invoice.due') }} | {{ $meta['due_on'] }} |
| {{ $meta['title'] ?? __('invoice.title') }} {{ $meta['number'] ?? '' }} |
{{ $meta['salutation'] }}
@endif @if (! empty($meta['intro'])){{ $meta['intro'] }}
@endif {{-- Quantity, net unit price, net total AND gross total per line: the invoice goes to businesses and to consumers, and each reads a different column first. --}}| {{ __('invoice.col_pos') }} | {{ __('invoice.col_description') }} | {{ __('invoice.col_quantity') }} | {{ __('invoice.col_unit_net') }} | {{-- A unit price, not a line total. Nobody adds up unit prices, so this column cannot contradict the sum — which a full-price gross TOTAL column would, by 315,60 against 288,60. --}}{{ __('invoice.col_unit_gross') }} | {{ __('invoice.col_total_net') }} |
| {{ $index + 1 }} | {{ $line['description'] ?? '' }}@foreach (($line['details'] ?? []) as $detail) {{ $detail }}@endforeach |
{{ InvoiceMath::quantity((int) $line['quantity_milli']) }}@if (! empty($line['unit'])) {{ $line['unit'] }}@endif | {{ InvoiceMath::money((int) $line['unit_net_cents']) }} | {{ InvoiceMath::money($unitGross) }} | {{ InvoiceMath::money($net) }} |
| {{ __('invoice.subtotal') }} | {{ InvoiceMath::money((int) ($totals['subtotal'] ?? 0)) }} | |
| {{ $meta['adjustment_label'] ?? __('invoice.adjustment') }} | {{ InvoiceMath::money((int) $totals['adjustment']) }} | |
| {{ __('invoice.net') }} | {{ InvoiceMath::money((int) ($totals['net'] ?? 0)) }} | |
| {{ __('invoice.tax', ['rate' => rtrim(rtrim(number_format(($totals['rate_basis_points'] ?? 2000) / 100, 2, ',', '.'), '0'), ',')]) }} | {{ InvoiceMath::money((int) ($totals['tax'] ?? 0)) }} | |
| {{ __('invoice.gross') }} | {{ InvoiceMath::money((int) ($totals['gross'] ?? 0)) }} {{ $meta['currency'] ?? 'EUR' }} |
{{ __('invoice.payment_title') }}
{{ $meta['payment_terms'] }}
@endif @if (! empty($meta['closing'])){{ $meta['closing'] }}
@endif