Basic support for creating invoices

This commit is contained in:
2026-07-02 23:39:47 +02:00
parent 872972ea48
commit 56b603aba0
15 changed files with 2147 additions and 29 deletions
+1
View File
@@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title inertia>{{ config('app.name', 'Nexus') }}</title>
+336
View File
@@ -0,0 +1,336 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Rechnung {{ $rechnungsnummer }}</title>
<style>
@page {
size: A4 portrait;
margin: 0;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'DejaVu Sans', sans-serif;
font-size: 9.5pt;
color: #1a1a1a;
background: white;
}
/* ── Kohte: steht zwischen Empfänger und Kontaktdaten ── */
.kohte-img {
width: 13mm;
height: 13mm;
display: block;
margin: 0 auto;
}
/* ── Seiteninhalt ── */
.page {
padding: 10mm 18mm 20mm 10mm;
}
/* ── Kopfbereich ── */
.header-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 6mm;
}
.header-table td { vertical-align: top; padding: 0; }
/* Rücksendeadresse (schmale Linie über Empfänger) */
.absender-rueck {
font-size: 6pt;
color: #555;
border-bottom: 0.3pt solid #888;
padding-bottom: 1.5mm;
margin-bottom: 3.5mm;
}
/* Empfängeradresse */
.empfaenger { font-size: 10pt; line-height: 1.65; }
.empfaenger-bold { font-weight: bold; }
/* ── BdP Logo ── */
.logo-img {
width: 36mm;
display: block;
margin-bottom: 4mm;
}
/* Absenderadresse rechts (linksbündig) */
.absender-block {
font-size: 7.5pt;
color: #1a4799;
line-height: 1.7;
}
.absender-name {
font-weight: bold;
font-size: 8pt;
}
/* ── Betreff ── */
.betreff {
font-size: 14pt;
color: #1a4799;
margin-bottom: 5mm;
}
/* ── Referenzdaten ── */
.ref-table {
border-collapse: collapse;
font-size: 8.5pt;
margin-bottom: 7mm;
}
.ref-table td { padding: 0.9mm 7mm 0.9mm 0; vertical-align: top; }
.ref-key { color: #666; white-space: nowrap; }
/* ── Anrede / Text ── */
.salutation { font-size: 9.5pt; margin-bottom: 3mm; }
.intro-text { font-size: 9pt; line-height: 1.6; margin-bottom: 7mm; color: #333; }
/* ── Positionstabelle ── */
.pos-table {
width: 100%;
border-collapse: collapse;
font-size: 8.5pt;
}
.pos-table th {
background-color: #1a4799;
color: white;
padding: 2.5mm 3mm;
text-align: left;
font-size: 7.5pt;
letter-spacing: 0.03em;
}
.pos-table th.r, .pos-table td.r { text-align: right; }
.pos-table td {
padding: 2mm 3mm;
border-bottom: 0.3pt solid #d8dde6;
vertical-align: top;
}
.pos-table tr:nth-child(even) td { background-color: #f7f8fb; }
.pos-table tr:last-child td { border-bottom: none; }
.pos-empty {
text-align: center;
color: #aaa;
font-style: italic;
padding: 3mm 0 !important;
background: none !important;
}
/* ── Summen ── */
.sum-outer { width: 100%; border-collapse: collapse; margin-top: 1mm; margin-bottom: 5mm; }
.sum-outer td { padding: 0; }
.sum-spacer { width: 55%; }
.sum-inner { width: 100%; border-collapse: collapse; font-size: 8.5pt; }
.sum-inner td { padding: 1.2mm 0; }
.sum-key { color: #555; padding-right: 6mm; white-space: nowrap; }
.sum-val { text-align: right; white-space: nowrap; }
.sum-line td { border-top: 0.4pt solid #bbb; padding-top: 2mm; }
.sum-total td {
font-weight: bold;
font-size: 11pt;
color: #1a4799;
border-top: 1.5pt solid #1a4799;
padding-top: 2mm;
}
/* ── Bankverbindung ── */
.bank-box {
border-left: 3pt solid #f5c400;
padding: 3mm 5mm;
background-color: #fffef5;
font-size: 8.5pt;
line-height: 1.6;
margin-bottom: 6mm;
}
.bank-head {
font-size: 7pt;
font-weight: bold;
color: #888;
text-transform: uppercase;
letter-spacing: 0.07em;
margin-bottom: 2mm;
}
.bank-hint {
margin-top: 1.5mm;
font-size: 7.5pt;
color: #999;
}
/* ── Grußformel ── */
.closing { font-size: 9.5pt; line-height: 1.5; }
.gut-pfad { font-size: 13pt; color: #1a4799; margin-top: 1mm; margin-bottom: 1mm; }
.closing-name { margin-top: 3mm; font-size: 9pt; }
</style>
</head>
<body>
<div class="page">
<!-- ══════════ KOPF ══════════ -->
<table class="header-table">
<tr>
<!-- LINKS: Rücksendezeile + Empfänger -->
<td style="width: 50%; padding-top: 4mm;">
<div class="absender-rueck">
BdP Bund der Pfadfinder*innen LV Sachsen e.V. &middot;
c/o Mandy Grazek &middot; Weststra&szlig;e 53c &middot; 09212 Limbach-Oberfrohna
</div>
<div class="empfaenger">
@if($organisation)
<div class="empfaenger-bold">{{ $organisation }}</div>
@endif
@if($vorname || $nachname)
<div class="empfaenger-bold">
{{ trim($anrede . ' ' . $vorname . ' ' . $nachname) }}
</div>
@endif
@if($adresse)
<div>{{ $adresse }}</div>
@endif
@if($plz || $ort)
<div>{{ trim($plz . ' ' . $ort) }}</div>
@endif
@if(!$organisation && !$vorname && !$nachname)
<div style="color:#aaa;font-style:italic;">Kein Empfänger angegeben</div>
@endif
</div>
</td>
<!-- MITTE: Kohte (zwischen Empfänger und Kontaktdaten) -->
<td style="vertical-align: middle; padding-top: 4mm; width: 9%; padding-right: 20px;">
<img src="{{ $kohteDataUri }}" style="width: 115px; height: 130px;" class="kohte-img" />
</td>
<!-- RECHTS: BdP Logo + Kontaktdaten (linksbündig) -->
<td style="width: 41%; vertical-align: top; padding-top: 2mm;">
<!-- BdP Wortmarke -->
<img src="{{ $logoDataUri }}" class="logo-img" />
<!-- Absenderadresse -->
<div class="absender-block">
<div class="absender-name">Bund der Pfadfinder*innen</div>
<div>Landesverband Sachsen e.V.&nbsp;(BdP)</div>
<div>c/o Mandy Grazek</div>
<div style="margin-top:2.5mm;">Weststra&szlig;e&nbsp;53c</div>
<div>09212&nbsp;Limbach&#8209;Oberfrohna</div>
<div style="margin-top:2.5mm;">Thomas Günther</div>
<div style="margin-top:2.5mm;">{{ $absenderEmail }}</div>
@if($absenderTelefon)
<div>{{ $absenderTelefon }}</div>
@endif
</div>
</td>
</tr>
</table>
<!-- ══════════ BETREFF ══════════ -->
<div class="betreff">Rechnung Nr.&nbsp;{{ $rechnungsnummer }}</div>
<!-- ══════════ REFERENZDATEN ══════════ -->
<table class="ref-table">
<tr>
<td class="ref-key">Rechnungsdatum:</td>
<td>{{ $rechnungsdatumFormatiert }}</td>
<td style="width: 8mm;"></td>
<td class="ref-key">Rechnungs-Nr.:</td>
<td>{{ $rechnungsnummer }}</td>
</tr>
@if($zahlungsziel)
<tr>
<td class="ref-key">Zahlungsziel:</td>
<td colspan="4">{{ $zahlungszielFormatiert }}</td>
</tr>
@endif
</table>
<!-- ══════════ ANREDE + EINLEITUNG ══════════ -->
<div class="salutation">
Hallo,
</div>
<div class="intro-text">
anbei übersenden wir folgende Rechnungmit der Bitte um Überweisung des Gesamtbetrags
bis zum {{ $zahlungszielFormatiert }} auf das unten angegebene Konto.
</div>
<!-- ══════════ POSITIONEN ══════════ -->
<table class="pos-table">
<thead>
<tr>
<th style="width:8%;">Nr.</th>
<th style="width:44%;">Bezeichnung</th>
<th style="width:12%;" class="r">Menge</th>
<th style="width:18%;" class="r">Einzelpreis</th>
<th style="width:18%;" class="r">Gesamt</th>
</tr>
</thead>
<tbody>
@forelse($positionen as $i => $pos)
<tr>
<td>{{ $i + 1 }}</td>
<td>{{ $pos['bezeichnung'] }}</td>
<td class="r">{{ number_format((float)($pos['menge'] ?? 0), 2, ',', '.') }}&nbsp;{{ $pos['einheit'] ?? '' }}</td>
<td class="r">{{ number_format((float)($pos['einzelpreis'] ?? 0), 2, ',', '.') }}&nbsp;&euro;</td>
<td class="r">{{ number_format((float)($pos['menge'] ?? 0) * (float)($pos['einzelpreis'] ?? 0), 2, ',', '.') }}&nbsp;&euro;</td>
</tr>
@empty
<tr>
<td colspan="5" class="pos-empty">Keine Positionen erfasst.</td>
</tr>
@endforelse
</tbody>
</table>
<!-- ══════════ SUMMEN ══════════ -->
<table class="sum-outer">
<tr>
<td class="sum-spacer"></td>
<td>
<table class="sum-inner">
<tr>
<td class="sum-key">Nettobetrag</td>
<td class="sum-val">{{ number_format($netto, 2, ',', '.') }}&nbsp;&euro;</td>
</tr>
<tr class="sum-line">
<td class="sum-key">zzgl. {{ $mwstSatz }}&nbsp;% MwSt.</td>
<td class="sum-val">{{ number_format($mwst, 2, ',', '.') }}&nbsp;&euro;</td>
</tr>
<tr class="sum-total">
<td class="sum-key">Gesamtbetrag</td>
<td class="sum-val">{{ number_format($brutto, 2, ',', '.') }}&nbsp;&euro;</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- ══════════ BANKVERBINDUNG ══════════ -->
@if($iban || $bic)
<div class="bank-box">
<div class="bank-head">Bankverbindung</div>
<div>Kontoinhaber: BdP Landesverband Sachsen e.V.</div>
@if($iban)<div>IBAN:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>{{ $iban }}</strong></div>@endif
@if($bic)<div>BIC:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>{{ $bic }}</strong></div>@endif
</div>
@endif
<!-- ══════════ GRUSSFORMEL ══════════ -->
<div class="closing">
<div class="gut-pfad">Herzlichst Gut Pfad.</div>
<div class="closing-name">
BdP Landesverband Sachsen e.V.<br />
Landesschatzmeister<br />
Thomas Günther</div>
</div>
</div>
</body>
</html>