Merge pull request 'Cleanup: eingangs_datum aus Tests entfernt, Storno-Doku präzisiert' (#38) from fds2610-bot/Steuerkram:main into main

Reviewed-on: https://codeberg.org/fds2610/Steuerkram/pulls/38
This commit is contained in:
fds2610 2026-04-13 15:41:43 +02:00
commit 10ef07780f
19 changed files with 343 additions and 175 deletions

View file

@ -9,7 +9,7 @@ Dieses Dokument beschreibt, wie Buchungen in die beiden steuerlichen Berichte ei
**Datei:** `src/Services/EuerCalculator.php` **Datei:** `src/Services/EuerCalculator.php`
Die EÜR basiert auf dem Feld `accounts.kontenart` sowie `accounts.euer_zeile` des Kategorie-Kontos. Das Feld `buchungstyp` wird nicht ausgewertet. Stornobuchungen (`is_reversal = 1`) werden ausgeschlossen. Die EÜR basiert auf dem Feld `accounts.kontenart` sowie `accounts.euer_zeile` des Kategorie-Kontos. Das Feld `buchungstyp` wird nicht ausgewertet. Stornobuchungen (`is_reversal = 1`) werden **nicht** explizit ausgefiltert – sie tragen negative Beträge und heben damit die ursprüngliche Buchung automatisch auf (Summe = 0).
### Spaltenauswahl nach Kontenart und euer_zeile ### Spaltenauswahl nach Kontenart und euer_zeile

View file

@ -0,0 +1,6 @@
ALTER TABLE company_settings
ADD COLUMN IF NOT EXISTS logo_max_width INT NOT NULL DEFAULT 600,
ADD COLUMN IF NOT EXISTS logo_max_height INT NOT NULL DEFAULT 100,
ADD COLUMN IF NOT EXISTS logo_position VARCHAR(10) NOT NULL DEFAULT 'center',
ADD COLUMN IF NOT EXISTS logo_margin_side INT NOT NULL DEFAULT 75,
ADD COLUMN IF NOT EXISTS logo_margin_top INT NOT NULL DEFAULT 6;

View file

@ -109,8 +109,9 @@ img { max-width: 100%; }
.main-content { .main-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 100vh; height: 100vh;
overflow: hidden; overflow-y: auto;
overflow-x: hidden;
} }
.topbar { .topbar {
@ -121,6 +122,9 @@ img { max-width: 100%; }
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
gap: 1rem; gap: 1rem;
position: sticky;
top: 0;
z-index: 10;
} }
.topbar-title { .topbar-title {
@ -368,6 +372,18 @@ td { padding: .65rem 1rem; vertical-align: middle; }
} }
/* ── Invoice preview (DIN 5008) ──────────────────────────────── */ /* ── Invoice preview (DIN 5008) ──────────────────────────────── */
.invoice-preview thead th {
text-transform: none;
letter-spacing: normal;
font-size: inherit;
font-weight: normal;
background: revert;
padding: revert;
white-space: revert;
color: inherit;
border-bottom: none;
}
.invoice-preview { .invoice-preview {
background: #fff; background: #fff;
padding: 2cm 2cm 2.5cm; padding: 2cm 2cm 2.5cm;
@ -379,6 +395,29 @@ td { padding: .65rem 1rem; vertical-align: middle; }
color: #000; color: #000;
} }
/*
* Adressbereich: DIN 5008-Proportionen (50% = 85mm bei vollem A4-Preview).
* Breakpoint: nav (220px) + page-body-padding (45px) + A4-max-width (794px) = 1059px.
* Darunter stapeln sich die Spalten vertikal.
*/
.invoice-address {
display: grid;
grid-template-columns: 50% 1fr;
gap: 1rem;
}
@media (max-width: 1059px) {
.invoice-address {
grid-template-columns: 1fr;
}
.invoice-address > div:last-child {
justify-content: flex-start !important;
border-top: 1px solid #ddd;
padding-top: 0.75rem;
font-size: .85rem;
}
}
/* ── Modals ──────────────────────────────────────────────────── */ /* ── Modals ──────────────────────────────────────────────────── */
.modal-overlay { .modal-overlay {
display: none; display: none;

View file

@ -16,6 +16,7 @@ class SettingsController
$view = new View(); $view = new View();
$view->render('layout/base.php', [ $view->render('layout/base.php', [
'pageTitle' => 'Einstellungen', 'pageTitle' => 'Einstellungen',
'topbarActions' => '<button type="submit" form="settings-form" class="btn btn-primary">Einstellungen speichern</button>',
'content' => $this->renderView('settings/form', [ 'content' => $this->renderView('settings/form', [
'settings' => $settings, 'settings' => $settings,
'errors' => [], 'errors' => [],

View file

@ -21,6 +21,10 @@ class Setting
public static function update(array $data): void public static function update(array $data): void
{ {
$logoPosition = in_array($data['logo_position'] ?? '', ['center', 'left', 'right'])
? $data['logo_position']
: 'center';
Database::execute( Database::execute(
'UPDATE company_settings SET 'UPDATE company_settings SET
firma=?, inhaber=?, strasse=?, plz=?, ort=?, firma=?, inhaber=?, strasse=?, plz=?, ort=?,
@ -31,7 +35,9 @@ class Setting
invoice_nr_prefix=?, beleg_nr_prefix=?, invoice_nr_prefix=?, beleg_nr_prefix=?,
payment_days_default=?, test_mode=?, ki_vorschlag_aktiv=?, ocr_aktiv=?, payment_days_default=?, test_mode=?, ki_vorschlag_aktiv=?, ocr_aktiv=?,
nextcloud_url=?, nextcloud_user=?, nextcloud_pass=?, nextcloud_url=?, nextcloud_user=?, nextcloud_pass=?,
nextcloud_folder=?, nextcloud_done=? nextcloud_folder=?, nextcloud_done=?,
logo_max_width=?, logo_max_height=?,
logo_position=?, logo_margin_side=?, logo_margin_top=?
WHERE id=1', WHERE id=1',
[ [
$data['firma'] ?? '', $data['firma'] ?? '',
@ -61,6 +67,11 @@ class Setting
$data['nextcloud_pass'] ?: null, $data['nextcloud_pass'] ?: null,
$data['nextcloud_folder'] ?: '/Belege/Import', $data['nextcloud_folder'] ?: '/Belege/Import',
$data['nextcloud_done'] ?: null, $data['nextcloud_done'] ?: null,
max(50, (int)($data['logo_max_width'] ?? 600)),
max(20, (int)($data['logo_max_height'] ?? 100)),
$logoPosition,
max(0, (int)($data['logo_margin_side'] ?? 75)),
max(0, (int)($data['logo_margin_top'] ?? 6)),
] ]
); );
} }

View file

@ -5,8 +5,6 @@ declare(strict_types=1);
namespace Steuerkram\Services; namespace Steuerkram\Services;
use Mpdf\Mpdf; use Mpdf\Mpdf;
use Mpdf\Config\ConfigVariables;
use Mpdf\Config\FontVariables;
class PdfInvoiceService class PdfInvoiceService
{ {
@ -19,8 +17,8 @@ class PdfInvoiceService
'format' => 'A4', 'format' => 'A4',
'margin_top' => 15, 'margin_top' => 15,
'margin_bottom' => 25, 'margin_bottom' => 25,
'margin_left' => 20, 'margin_left' => 25, // DIN 5008: 25mm links
'margin_right' => 20, 'margin_right' => 15, // DIN 5008: 15mm rechts
]); ]);
$mpdf->SetTitle('Rechnung ' . ($invoice['rechnungs_nr'] ?? 'Entwurf')); $mpdf->SetTitle('Rechnung ' . ($invoice['rechnungs_nr'] ?? 'Entwurf'));
@ -31,28 +29,45 @@ class PdfInvoiceService
$mpdf->WriteHTML($html, \Mpdf\HTMLParserMode::HTML_BODY); $mpdf->WriteHTML($html, \Mpdf\HTMLParserMode::HTML_BODY);
$filename = 'Rechnung-' . ($invoice['rechnungs_nr'] ?? 'Entwurf') . '.pdf'; $filename = 'Rechnung-' . ($invoice['rechnungs_nr'] ?? 'Entwurf') . '.pdf';
$mpdf->Output($filename, 'D'); // D = Download $mpdf->Output($filename, 'D');
} }
private function buildHtml(array $inv, array $lines, array $settings): string private function buildHtml(array $inv, array $lines, array $settings): string
{ {
$h = fn($v) => htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); $h = fn($v) => htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8');
$fmt = fn($v) => number_format((float)$v, 2, ',', '.') . ' €'; $fmt = fn($v) => number_format((float)$v, 2, ',', '.') . ' €';
$fmtNum = fn($v) => number_format((float)$v, 3, ',', '.'); $fmtNum = fn($v) => number_format((float)$v, 1, ',', '.');
$fmtDate = fn($v) => $v ? date('d.m.Y', strtotime($v)) : '–'; $fmtDate = fn($v) => $v ? date('d.m.Y', strtotime($v)) : '–';
// Customer address // Kundenname
$customerName = !empty($inv['firma']) ? $inv['firma'] : trim(($inv['anrede'] ?? '') . ' ' . ($inv['vorname'] ?? '') . ' ' . $inv['nachname']); $customerName = !empty($inv['firma'])
? $inv['firma']
: trim(($inv['anrede'] ?? '') . ' ' . ($inv['vorname'] ?? '') . ' ' . $inv['nachname']);
// Logo // Logo
$logoHtml = ''; $logoHtml = '';
if (!empty($settings['logo_path'])) { if (!empty($settings['logo_path'])) {
$logoPath = dirname(__DIR__, 2) . '/public/' . $settings['logo_path']; $logoPath = dirname(__DIR__, 2) . '/public/' . $settings['logo_path'];
if (file_exists($logoPath)) { if (file_exists($logoPath)) {
$logoHtml = '<img src="' . $h($settings['logo_path']) . '" alt="Logo" class="logo">'; $maxW = max(50, (int)($settings['logo_max_width'] ?? 600));
$maxH = max(20, (int)($settings['logo_max_height'] ?? 100));
$logoHtml = '<img src="' . $h($settings['logo_path']) . '" alt="Logo"'
. ' style="max-width:' . $maxW . 'px;max-height:' . $maxH . 'px">';
} }
} }
$logoPosition = $settings['logo_position'] ?? 'center';
$logoMarginSide = max(0, (int)($settings['logo_margin_side'] ?? 75));
$logoMarginTop = max(0, (int)($settings['logo_margin_top'] ?? 6));
if ($logoPosition === 'left') {
$logoWrapStyle = "text-align:left;margin-left:{$logoMarginSide}px;margin-top:{$logoMarginTop}px";
} elseif ($logoPosition === 'right') {
$logoWrapStyle = "text-align:right;margin-right:{$logoMarginSide}px;margin-top:{$logoMarginTop}px";
} else {
$logoWrapStyle = 'text-align:center';
}
// Leistungszeitraum // Leistungszeitraum
$lz = ''; $lz = '';
if (!empty($inv['leistungszeitraum_von'])) { if (!empty($inv['leistungszeitraum_von'])) {
@ -62,7 +77,12 @@ class PdfInvoiceService
} }
} }
// Build positions table // Fälligkeitsdatum
$fälligText = !empty($inv['faellig_datum'])
? ' Fällig am: <strong>' . $fmtDate($inv['faellig_datum']) . '</strong>'
: '';
// Positionszeilen
$posRows = ''; $posRows = '';
foreach ($lines as $line) { foreach ($lines as $line) {
$posRows .= '<tr> $posRows .= '<tr>
@ -78,26 +98,31 @@ class PdfInvoiceService
$payDays = $inv['payment_days'] ?? 14; $payDays = $inv['payment_days'] ?? 14;
// Empfänger-Land nur wenn nicht DE
$land = ($inv['land'] ?? 'DE') !== 'DE' ? '<br>' . $h($inv['land']) : '';
return <<<HTML return <<<HTML
<div class="invoice-wrap"> <div class="invoice-wrap">
<!-- Logo --> <!-- Logo -->
<div class="logo-wrap">{$logoHtml}</div> <div class="logo-wrap" style="{$logoWrapStyle}">{$logoHtml}</div>
<!-- Adressbereich (DIN 5008) --> <!-- Adressbereich DIN 5008 Typ A (Anschriftfeld 85mm × 45mm) -->
<div class="address-block"> <table class="address-block">
<div class="address-left"> <tr>
<!-- Linke Spalte: Anschriftfeld 85mm (Kuvertfenster) -->
<td class="address-left">
<div class="return-address">{$h($settings['firma'] ?? '')} · {$h($settings['strasse'] ?? '')} · {$h($settings['plz'] ?? '')} {$h($settings['ort'] ?? '')}</div> <div class="return-address">{$h($settings['firma'] ?? '')} · {$h($settings['strasse'] ?? '')} · {$h($settings['plz'] ?? '')} {$h($settings['ort'] ?? '')}</div>
<div class="recipient"> <div class="recipient">
{$h($customerName)}<br> {$h($customerName)}<br>
{$h($inv['strasse'])}<br> {$h($inv['strasse'])}<br>
{$h($inv['plz'])} {$h($inv['ort'])}<br> {$h($inv['plz'])} {$h($inv['ort'])}{$land}
{$h($inv['land'] !== 'DE' ? $inv['land'] : '')}
</div> </div>
</div> </td>
<div class="address-right"> <!-- Rechte Spalte: Absenderinformationen -->
<td class="address-right">
<table class="sender-table"> <table class="sender-table">
<tr><td>{$h($settings['firma'] ?? '')}</td></tr> <tr><td><strong>{$h($settings['firma'] ?? '')}</strong></td></tr>
<tr><td>{$h($settings['inhaber'] ?? '')}</td></tr> <tr><td>{$h($settings['inhaber'] ?? '')}</td></tr>
<tr><td>{$h($settings['strasse'] ?? '')}</td></tr> <tr><td>{$h($settings['strasse'] ?? '')}</td></tr>
<tr><td>{$h($settings['plz'] ?? '')} {$h($settings['ort'] ?? '')}</td></tr> <tr><td>{$h($settings['plz'] ?? '')} {$h($settings['ort'] ?? '')}</td></tr>
@ -106,11 +131,13 @@ class PdfInvoiceService
<tr><td>{$h($settings['email'] ?? '')}</td></tr> <tr><td>{$h($settings['email'] ?? '')}</td></tr>
<tr><td>USt-ID: {$h($settings['ust_id'] ?? '')}</td></tr> <tr><td>USt-ID: {$h($settings['ust_id'] ?? '')}</td></tr>
</table> </table>
</div> </td>
</div> </tr>
</table>
<!-- Meta-Felder --> <!-- Meta-Felder -->
<table class="meta-table"> <table class="meta-table">
<thead>
<tr> <tr>
<th>Betreff</th> <th>Betreff</th>
<th>Rechnungsnummer</th> <th>Rechnungsnummer</th>
@ -118,13 +145,16 @@ class PdfInvoiceService
<th>Leistungszeitraum</th> <th>Leistungszeitraum</th>
<th>Datum</th> <th>Datum</th>
</tr> </tr>
</thead>
<tbody>
<tr> <tr>
<td>{$h($inv['betreff'])}</td> <td>{$h($inv['betreff'])}</td>
<td>{$h($inv['rechnungs_nr'] ?? 'Entwurf')}</td> <td><strong>{$h($inv['rechnungs_nr'] ?? 'Entwurf')}</strong></td>
<td>{$h($inv['kundennummer'])}</td> <td>{$h($inv['kundennummer'])}</td>
<td>{$h($lz)}</td> <td>{$h($lz ?: '–')}</td>
<td>{$fmtDate($inv['rechnungs_datum'])}</td> <td>{$fmtDate($inv['rechnungs_datum'])}</td>
</tr> </tr>
</tbody>
</table> </table>
<!-- Positionen --> <!-- Positionen -->
@ -145,16 +175,19 @@ class PdfInvoiceService
</tbody> </tbody>
</table> </table>
<!-- Summen --> <!-- Summen (rechtsbündig) -->
<table class="sum-table"> <table class="sum-table" align="right">
<tr><td>Nettobetrag:</td> <td class="sum-val">{$fmt($inv['betrag_netto'])}</td></tr> <tr><td>Nettobetrag:</td> <td class="sum-val">{$fmt($inv['betrag_netto'])}</td></tr>
<tr><td>zzgl. Umsatzsteuer:</td><td class="sum-val">{$fmt($inv['betrag_ust'])}</td></tr> <tr><td>zzgl. Umsatzsteuer:</td><td class="sum-val">{$fmt($inv['betrag_ust'])}</td></tr>
<tr class="sum-total"><td><strong>Rechnungsbetrag:</strong></td><td class="sum-val"><strong>{$fmt($inv['betrag_brutto'])}</strong></td></tr> <tr class="sum-total">
<td><strong>Rechnungsbetrag:</strong></td>
<td class="sum-val"><strong>{$fmt($inv['betrag_brutto'])}</strong></td>
</tr>
</table> </table>
<!-- Zahlungshinweis --> <!-- Zahlungshinweis -->
<p class="payment-note"> <p class="payment-note">
Bitte überweisen Sie den Rechnungsbetrag innerhalb {$h($payDays)} Tagen auf das unten genannte Konto. Bitte überweisen Sie den Rechnungsbetrag innerhalb {$h($payDays)} Tagen auf das unten genannte Konto.{$fälligText}
</p> </p>
</div> </div>
@ -197,48 +230,60 @@ HTML;
return <<<CSS return <<<CSS
body { font-family: DejaVu Sans, sans-serif; font-size: 10pt; color: #000; } body { font-family: DejaVu Sans, sans-serif; font-size: 10pt; color: #000; }
.invoice-wrap { width: 100%; } .invoice-wrap { width: 100%; }
.logo-wrap { text-align: center; margin-bottom: 10mm; }
.logo { max-height: 25mm; max-width: 80mm; } /* Logo */
.logo-wrap { margin-bottom: 8mm; }
/* DIN 5008 Adressbereich */ /* DIN 5008 Adressbereich */
.address-block { display: flex; justify-content: space-between; margin-bottom: 10mm; } .address-block { width: 100%; border-collapse: collapse; margin-bottom: 8mm; }
.address-left { width: 85mm; } .address-left { width: 85mm; vertical-align: top; padding: 0; }
.return-address { font-size: 7pt; color: #555; border-bottom: 0.3pt solid #aaa; padding-bottom: 1mm; margin-bottom: 2mm; } .address-right { vertical-align: top; padding: 0 0 0 5mm; }
.recipient { font-size: 10pt; line-height: 1.4; min-height: 27.3mm; }
.address-right { width: 75mm; text-align: left; } .return-address {
.sender-table td { font-size: 9pt; padding: 0.5mm 0; } font-size: 7pt; color: #555;
border-bottom: 0.3pt solid #aaa;
padding-bottom: 1mm; margin-bottom: 2mm;
}
.recipient { font-size: 10pt; line-height: 1.5; min-height: 27.3mm; }
/* Absendertabelle: auf Inhaltsbreite schrumpfen, rechtsbündig */
.sender-table { border-collapse: collapse; font-size: 9pt; margin-left: auto; }
.sender-table td { padding: 0.4mm 0; white-space: nowrap; }
/* Meta-Felder */ /* Meta-Felder */
.meta-table { width: 100%; border-collapse: collapse; margin-bottom: 8mm; font-size: 9pt; } .meta-table { width: 100%; table-layout: fixed; border-collapse: collapse; margin-bottom: 8mm; font-size: 9pt; }
.meta-table th { background: #f0f0f0; padding: 2mm 2mm; text-align: left; font-size: 8pt; color: #555; border: 0.5pt solid #ccc; } .meta-table th { background: #f0f0f0; padding: 2mm; text-align: left; font-size: 8pt; color: #555; border: 0.5pt solid #ccc; }
.meta-table td { padding: 2mm; border: 0.5pt solid #ccc; } .meta-table td { padding: 2mm; border: 0.5pt solid #ccc; }
/* Positionen */ /* Positionen */
.pos-table { width: 100%; border-collapse: collapse; margin-bottom: 5mm; font-size: 9pt; } .pos-table { width: 100%; table-layout: fixed; border-collapse: collapse; margin-bottom: 5mm; font-size: 9pt; }
.pos-table thead th { background: #1e293b; color: #fff; padding: 2mm; text-align: left; } .pos-table thead th { background: #f0f0f0; color: #000; padding: 2mm; }
.pos-table tbody tr:nth-child(even) { background: #f8f8f8; } .pos-table tbody tr:nth-child(even) { background: #f8f8f8; }
.pos-table tbody td { padding: 1.5mm 2mm; border-bottom: 0.3pt solid #e0e0e0; } .pos-table tbody td { padding: 1.5mm 2mm; border-bottom: 0.3pt solid #e0e0e0; }
.pos-nr { width: 10mm; } .pos-nr { width: 8%; }
.pos-bez { width: 55mm; } .pos-bez { /* nimmt den Rest */ }
.pos-menge { width: 18mm; text-align: right; } .pos-menge { width: 11%; text-align: right; }
.pos-einheit { width: 15mm; } .pos-einheit { width: 10%; }
.pos-ust { width: 12mm; text-align: right; } .pos-ust { width: 8%; text-align: right; }
.pos-preis { width: 20mm; text-align: right; } .pos-preis { width: 15%; text-align: right; }
.pos-gesamt { width: 22mm; text-align: right; } .pos-gesamt { width: 16%; text-align: right; }
/* Summen */ /* Summen */
.sum-table { float: right; width: 70mm; border-collapse: collapse; margin-bottom: 8mm; font-size: 9.5pt; } .sum-table { border-collapse: collapse; margin-bottom: 8mm; font-size: 9pt; }
.sum-table td { padding: 1.5mm 2mm; } .sum-table td { padding: 1.5mm 2mm; }
.sum-table .sum-val { text-align: right; border-top: 0.3pt solid #ccc; } .sum-table .sum-val { text-align: right; border-top: 0.3pt solid #ccc; }
.sum-table .sum-total td { border-top: 1pt solid #000; font-size: 10.5pt; } .sum-table .sum-total td { border-top: 1pt solid #000; }
/* Zahlungshinweis */ /* Zahlungshinweis */
.payment-note { clear: both; margin-top: 5mm; font-size: 9pt; padding: 3mm; background: #f8f8f8; border-left: 2pt solid #2563eb; } .payment-note { margin-top: 5mm; font-size: 9pt; padding: 3mm; background: #f8f8f8; border-left: 2pt solid #2563eb; }
/* Fußzeile */ /* Fußzeile */
.footer-table { width: 100%; border-collapse: collapse; font-size: 7.5pt; border-top: 0.5pt solid #ccc; padding-top: 2mm; } .footer-table { width: 100%; border-collapse: collapse; font-size: 7.5pt; border-top: 0.5pt solid #ccc; }
.footer-table td { width: 25%; padding: 1mm 2mm; vertical-align: top; } .footer-table td { padding: 1mm 2mm; vertical-align: top; }
.page-nr { text-align: right; } .footer-table td:nth-child(1) { width: 35%; }
.footer-table td:nth-child(2) { width: 25%; }
.footer-table td:nth-child(3) { width: 28%; }
.page-nr { width: 12%; text-align: right; }
CSS; CSS;
} }
} }

View file

@ -15,6 +15,15 @@ if (!empty($invoice['leistungszeitraum_von'])) {
} }
} }
// Leistungszeitraum mit <br> für die Vorschau-Tabelle (Datumsangaben untereinander)
$lzHtml = '';
if (!empty($invoice['leistungszeitraum_von'])) {
$lzHtml = $h(View::formatDate($invoice['leistungszeitraum_von']));
if (!empty($invoice['leistungszeitraum_bis']) && $invoice['leistungszeitraum_bis'] !== $invoice['leistungszeitraum_von']) {
$lzHtml .= '<br>' . $h(View::formatDate($invoice['leistungszeitraum_bis']));
}
}
$badgeClass = match($invoice['status']) { $badgeClass = match($invoice['status']) {
'Bezahlt' => 'badge-green', 'Bezahlt' => 'badge-green',
'Storniert' => 'badge-red', 'Storniert' => 'badge-red',
@ -56,13 +65,28 @@ $badgeClass = match($invoice['status']) {
<!-- Logo --> <!-- Logo -->
<?php if (!empty($settings['logo_path'])): ?> <?php if (!empty($settings['logo_path'])): ?>
<div style="text-align:center;margin-bottom:1.5rem"> <?php
<img src="/<?= $h($settings['logo_path']) ?>" alt="Logo" style="max-height:60px;max-width:250px"> $logoMaxW = max(50, (int)($settings['logo_max_width'] ?? 600));
$logoMaxH = max(20, (int)($settings['logo_max_height'] ?? 100));
$logoPos = $settings['logo_position'] ?? 'center';
$logoMSide = max(0, (int)($settings['logo_margin_side'] ?? 75));
$logoMTop = max(0, (int)($settings['logo_margin_top'] ?? 6));
if ($logoPos === 'left') {
$logoWrapStyle = "text-align:left;margin-left:{$logoMSide}px;margin-top:{$logoMTop}px;margin-bottom:1.5rem";
} elseif ($logoPos === 'right') {
$logoWrapStyle = "text-align:right;margin-right:{$logoMSide}px;margin-top:{$logoMTop}px;margin-bottom:1.5rem";
} else {
$logoWrapStyle = 'text-align:center;margin-bottom:1.5rem';
}
?>
<div style="<?= $logoWrapStyle ?>">
<img src="/<?= $h($settings['logo_path']) ?>" alt="Logo"
style="max-width:<?= $logoMaxW ?>px;max-height:<?= $logoMaxH ?>px">
</div> </div>
<?php endif; ?> <?php endif; ?>
<!-- Adressbereich --> <!-- Adressbereich (DIN 5008: 50% = 85mm bei vollem A4-Preview) -->
<div style="display:grid;grid-template-columns:100mm 1fr;gap:1rem;margin-bottom:1.5rem"> <div class="invoice-address" style="margin-bottom:1.5rem">
<div> <div>
<div style="font-size:8pt;color:#666;border-bottom:1px solid #ccc;padding-bottom:2px;margin-bottom:4px"> <div style="font-size:8pt;color:#666;border-bottom:1px solid #ccc;padding-bottom:2px;margin-bottom:4px">
<?= $h($settings['firma'] ?? '') ?> · <?= $h($settings['strasse'] ?? '') ?> · <?= $h(($settings['plz'] ?? '') . ' ' . ($settings['ort'] ?? '')) ?> <?= $h($settings['firma'] ?? '') ?> · <?= $h($settings['strasse'] ?? '') ?> · <?= $h(($settings['plz'] ?? '') . ' ' . ($settings['ort'] ?? '')) ?>
@ -74,7 +98,8 @@ $badgeClass = match($invoice['status']) {
<?php if ($invoice['land'] !== 'DE'): ?><br><?= $h($invoice['land']) ?><?php endif; ?> <?php if ($invoice['land'] !== 'DE'): ?><br><?= $h($invoice['land']) ?><?php endif; ?>
</div> </div>
</div> </div>
<div style="text-align:left;font-size:.85rem;line-height:1.7"> <div style="display:flex;justify-content:flex-end;font-size:.85rem;line-height:1.7">
<div style="text-align:left">
<strong><?= $h($settings['firma'] ?? '') ?></strong><br> <strong><?= $h($settings['firma'] ?? '') ?></strong><br>
<?= $h($settings['inhaber'] ?? '') ?><br> <?= $h($settings['inhaber'] ?? '') ?><br>
<?= $h($settings['strasse'] ?? '') ?><br> <?= $h($settings['strasse'] ?? '') ?><br>
@ -84,40 +109,41 @@ $badgeClass = match($invoice['status']) {
USt-ID: <?= $h($settings['ust_id'] ?? '') ?> USt-ID: <?= $h($settings['ust_id'] ?? '') ?>
</div> </div>
</div> </div>
</div>
<!-- Meta-Tabelle --> <!-- Meta-Tabelle -->
<table style="width:100%;border-collapse:collapse;margin-bottom:1.5rem;font-size:.9rem"> <table style="width:100%;border-collapse:collapse;margin-bottom:1.5rem;font-size:.9rem">
<thead> <thead>
<tr style="background:#f0f0f0"> <tr style="background:#f0f0f0">
<th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-size:.8rem">Betreff</th> <th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-weight:normal;white-space:nowrap">Betreff</th>
<th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-size:.8rem">Rechnungsnummer</th> <th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-weight:normal;white-space:nowrap">Rechnungsnummer</th>
<th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-size:.8rem">Kundennummer</th> <th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-weight:normal;white-space:nowrap">Kundennummer</th>
<th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-size:.8rem">Leistungszeitraum</th> <th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-weight:normal;white-space:nowrap">Leistungszeitraum</th>
<th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-size:.8rem">Datum</th> <th style="padding:.4rem .5rem;text-align:left;border:1px solid #ddd;font-weight:normal;white-space:nowrap;width:100%">Datum</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td style="padding:.4rem .5rem;border:1px solid #ddd"><?= $h($invoice['betreff']) ?></td> <td style="padding:.4rem .5rem;border:1px solid #ddd;white-space:nowrap"><?= $h($invoice['betreff']) ?></td>
<td style="padding:.4rem .5rem;border:1px solid #ddd;font-weight:700"><?= $h($invoice['rechnungs_nr'] ?? 'Entwurf') ?></td> <td style="padding:.4rem .5rem;border:1px solid #ddd;white-space:nowrap;font-weight:700"><?= $h($invoice['rechnungs_nr'] ?? 'Entwurf') ?></td>
<td style="padding:.4rem .5rem;border:1px solid #ddd"><?= $h($invoice['kundennummer']) ?></td> <td style="padding:.4rem .5rem;border:1px solid #ddd;white-space:nowrap"><?= $h($invoice['kundennummer']) ?></td>
<td style="padding:.4rem .5rem;border:1px solid #ddd"><?= $h($lz ?: '–') ?></td> <td style="padding:.4rem .5rem;border:1px solid #ddd"><?= $lzHtml ?: '–' ?></td>
<td style="padding:.4rem .5rem;border:1px solid #ddd"><?= View::formatDate($invoice['rechnungs_datum']) ?></td> <td style="padding:.4rem .5rem;border:1px solid #ddd;white-space:nowrap"><?= $h(View::formatDate($invoice['rechnungs_datum'])) ?></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<!-- Positionen --> <!-- Positionen -->
<table style="width:100%;border-collapse:collapse;margin-bottom:1.5rem;font-size:.9rem"> <table style="width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:1.5rem;font-size:.9rem">
<thead> <thead>
<tr style="background:#1e293b;color:#fff"> <tr style="background:#f0f0f0">
<th style="padding:.5rem;text-align:left;width:40px">Pos.</th> <th style="padding:.5rem;text-align:left;width:6%">Pos.</th>
<th style="padding:.5rem;text-align:left">Bezeichnung</th> <th style="padding:.5rem;text-align:left">Bezeichnung</th>
<th style="padding:.5rem;text-align:right;width:70px">Menge</th> <th style="padding:.5rem;text-align:right;width:11%">Menge</th>
<th style="padding:.5rem;text-align:left;width:70px">Einheit</th> <th style="padding:.5rem;text-align:left;width:10%">Einheit</th>
<th style="padding:.5rem;text-align:right;width:60px">USt.</th> <th style="padding:.5rem;text-align:right;width:8%">USt.</th>
<th style="padding:.5rem;text-align:right;width:100px">Einzelpreis</th> <th style="padding:.5rem;text-align:right;width:15%">Einzelpreis</th>
<th style="padding:.5rem;text-align:right;width:110px">Gesamt</th> <th style="padding:.5rem;text-align:right;width:16%">Gesamt</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -125,7 +151,7 @@ $badgeClass = match($invoice['status']) {
<tr style="border-bottom:1px solid #eee"> <tr style="border-bottom:1px solid #eee">
<td style="padding:.4rem .5rem"><?= $h($line['position']) ?></td> <td style="padding:.4rem .5rem"><?= $h($line['position']) ?></td>
<td style="padding:.4rem .5rem"><?= $h($line['bezeichnung']) ?></td> <td style="padding:.4rem .5rem"><?= $h($line['bezeichnung']) ?></td>
<td style="padding:.4rem .5rem;text-align:right"><?= number_format((float)$line['menge'], 3, ',', '.') ?></td> <td style="padding:.4rem .5rem;text-align:right"><?= number_format((float)$line['menge'], 1, ',', '.') ?></td>
<td style="padding:.4rem .5rem"><?= $h($line['einheit']) ?></td> <td style="padding:.4rem .5rem"><?= $h($line['einheit']) ?></td>
<td style="padding:.4rem .5rem;text-align:right"><?= number_format((float)$line['ust_satz'], 0) ?> %</td> <td style="padding:.4rem .5rem;text-align:right"><?= number_format((float)$line['ust_satz'], 0) ?> %</td>
<td style="padding:.4rem .5rem;text-align:right"><?= $fmt($line['einzelpreis']) ?></td> <td style="padding:.4rem .5rem;text-align:right"><?= $fmt($line['einzelpreis']) ?></td>
@ -154,20 +180,20 @@ $badgeClass = match($invoice['status']) {
</div> </div>
<!-- Fußzeile --> <!-- Fußzeile -->
<div style="border-top:1px solid #ccc;padding-top:.75rem;display:grid;grid-template-columns:1fr 1fr 1fr 80px;gap:1rem;font-size:.75rem;color:#555"> <div style="border-top:1px solid #ccc;padding-top:.75rem;display:grid;grid-template-columns:auto auto auto 1fr;gap:1rem;font-size:.75rem;color:#555">
<div> <div style="min-width:0">
<strong><?= $h($settings['firma'] ?? '') ?></strong><br> <strong><?= $h($settings['firma'] ?? '') ?></strong><br>
<?= $h($settings['inhaber'] ?? '') ?><br> <?= $h($settings['inhaber'] ?? '') ?><br>
<?= $h($settings['strasse'] ?? '') ?><br> <?= $h($settings['strasse'] ?? '') ?><br>
<?= $h(($settings['plz'] ?? '') . ' ' . ($settings['ort'] ?? '')) ?><br> <?= $h(($settings['plz'] ?? '') . ' ' . ($settings['ort'] ?? '')) ?><br>
USt-ID: <?= $h($settings['ust_id'] ?? '') ?> USt-ID: <?= $h($settings['ust_id'] ?? '') ?>
</div> </div>
<div> <div style="min-width:0">
Tel: <?= $h($settings['telefon'] ?? '') ?><br> Tel: <?= $h($settings['telefon'] ?? '') ?><br>
E-Mail: <?= $h($settings['email'] ?? '') ?><br> E-Mail: <?= $h($settings['email'] ?? '') ?><br>
Web: <?= $h($settings['website'] ?? '') ?> Web: <?= $h($settings['website'] ?? '') ?>
</div> </div>
<div> <div style="min-width:0">
<?= $h($settings['bank_name'] ?? '') ?><br> <?= $h($settings['bank_name'] ?? '') ?><br>
IBAN: <?= $h($settings['iban'] ?? '') ?><br> IBAN: <?= $h($settings['iban'] ?? '') ?><br>
BIC: <?= $h($settings['bic'] ?? '') ?> BIC: <?= $h($settings['bic'] ?? '') ?>

View file

@ -1,6 +1,6 @@
<?php use Steuerkram\View; $h = fn($v) => View::h($v); ?> <?php use Steuerkram\View; $h = fn($v) => View::h($v); ?>
<form method="post" action="/settings"> <form id="settings-form" method="post" action="/settings">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;align-items:start"> <div style="display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;align-items:start">
<!-- Firmendaten --> <!-- Firmendaten -->
@ -85,8 +85,6 @@
<!-- Bankdaten + Logo + Nummernkreise --> <!-- Bankdaten + Logo + Nummernkreise -->
<div> <div>
<button type="submit" class="btn btn-primary btn-lg w-full" style="margin-bottom:1rem">Einstellungen speichern</button>
<!-- Betriebsmodus --> <!-- Betriebsmodus -->
<div class="card mb-2" style="border:2px solid <?= ($settings['test_mode'] ?? 1) ? 'var(--color-warning,#f59e0b)' : 'var(--color-success,#22c55e)' ?>"> <div class="card mb-2" style="border:2px solid <?= ($settings['test_mode'] ?? 1) ? 'var(--color-warning,#f59e0b)' : 'var(--color-success,#22c55e)' ?>">
<div class="card-header"> <div class="card-header">
@ -239,28 +237,6 @@
</div> </div>
</div> </div>
<div class="card mb-2">
<div class="card-header"><div class="card-title">Logo</div></div>
<div class="card-body">
<?php if (!empty($settings['logo_path'])): ?>
<div style="text-align:center;margin-bottom:1rem">
<img src="/<?= $h($settings['logo_path']) ?>" alt="Logo" style="max-height:80px;max-width:200px">
</div>
<form method="post" action="/settings/logo/delete" style="margin-bottom:1rem">
<button type="submit" class="btn btn-danger btn-sm w-full">Logo löschen</button>
</form>
<?php endif; ?>
<form method="post" action="/settings/logo" enctype="multipart/form-data">
<div class="form-group">
<label>Logo hochladen (PNG, JPG)</label>
<input type="file" name="logo" accept=".png,.jpg,.jpeg">
<div class="form-hint">Empfohlen: transparentes PNG, mind. 300px breit</div>
</div>
<button type="submit" class="btn btn-secondary">Logo hochladen</button>
</form>
</div>
</div>
<div class="card mb-2"> <div class="card mb-2">
<div class="card-header"><div class="card-title">Nummernkreise</div></div> <div class="card-header"><div class="card-title">Nummernkreise</div></div>
<div class="card-body"> <div class="card-body">
@ -286,6 +262,82 @@
</div> </div>
</form> </form>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;margin-top:0">
<div></div>
<div>
<div class="card mb-2">
<div class="card-header"><div class="card-title">Logo</div></div>
<div class="card-body">
<?php if (!empty($settings['logo_path'])): ?>
<div style="text-align:center;margin-bottom:1rem">
<img src="/<?= $h($settings['logo_path']) ?>" alt="Logo" style="max-height:80px;max-width:400px">
</div>
<?php endif; ?>
<form method="post" action="/settings/logo" enctype="multipart/form-data">
<div class="form-group">
<label>Logo hochladen (PNG, JPG)</label>
<input type="file" name="logo" accept=".png,.jpg,.jpeg">
<div class="form-hint">Empfohlen: transparentes PNG, mind. 300px breit</div>
</div>
<div style="display:flex;gap:.5rem;flex-wrap:wrap">
<button type="submit" class="btn btn-secondary">Hochladen</button>
<?php if (!empty($settings['logo_path'])): ?>
<button type="submit" form="delete-logo-form" class="btn btn-danger btn-sm">Löschen</button>
<?php endif; ?>
</div>
</form>
<?php if (!empty($settings['logo_path'])): ?>
<form id="delete-logo-form" method="post" action="/settings/logo/delete"></form>
<?php endif; ?>
<div style="margin-top:1rem;border-top:1px solid var(--color-border,#e5e7eb);padding-top:1rem">
<div class="form-hint" style="margin-bottom:.75rem">Darstellung in der Rechnung</div>
<div class="form-grid form-grid-2">
<div class="form-group">
<label>Max-Breite</label>
<input type="number" name="logo_max_width" form="settings-form"
value="<?= $h($settings['logo_max_width'] ?? 600) ?>" min="50" max="2000">
</div>
<div class="form-group">
<label>Max-Höhe</label>
<input type="number" name="logo_max_height" form="settings-form"
value="<?= $h($settings['logo_max_height'] ?? 100) ?>" min="20" max="500">
</div>
</div>
<div class="form-group">
<label>Position</label>
<div style="display:flex;gap:1.5rem;margin-top:.35rem">
<?php foreach (['center' => 'Zentriert', 'left' => 'Links', 'right' => 'Rechts'] as $val => $label): ?>
<label style="display:flex;align-items:center;gap:.35rem;cursor:pointer">
<input type="radio" name="logo_position" value="<?= $val ?>" form="settings-form"
<?= ($settings['logo_position'] ?? 'center') === $val ? 'checked' : '' ?>
onchange="logoPositionChanged()">
<?= $label ?>
</label>
<?php endforeach; ?>
</div>
</div>
<?php $showMargins = in_array($settings['logo_position'] ?? 'center', ['left', 'right']); ?>
<div id="logo-margin-fields" style="display:<?= $showMargins ? 'block' : 'none' ?>">
<div class="form-grid form-grid-2">
<div class="form-group">
<label>Rand Seite</label>
<input type="number" name="logo_margin_side" form="settings-form"
value="<?= $h($settings['logo_margin_side'] ?? 75) ?>" min="0">
</div>
<div class="form-group">
<label>Rand oben</label>
<input type="number" name="logo_margin_top" form="settings-form"
value="<?= $h($settings['logo_margin_top'] ?? 6) ?>" min="0">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script> <script>
function updateModeLabel(cb) { function updateModeLabel(cb) {
const track = document.getElementById('toggle_track'); const track = document.getElementById('toggle_track');
@ -312,4 +364,10 @@ function updateModeLabel(cb) {
cb.closest('.card').querySelector('.badge').textContent = 'Produktiv'; cb.closest('.card').querySelector('.badge').textContent = 'Produktiv';
} }
} }
function logoPositionChanged() {
const pos = document.querySelector('input[name="logo_position"]:checked')?.value;
document.getElementById('logo-margin-fields').style.display =
(pos === 'left' || pos === 'right') ? 'block' : 'none';
}
</script> </script>

View file

@ -47,7 +47,6 @@ class BelegBuchungTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', $belegNr . 'buch'), 'file_hash' => hash('sha256', $belegNr . 'buch'),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'rechnungs_nr' => 'RE-BUCH-001', 'rechnungs_nr' => 'RE-BUCH-001',
'betrag_brutto' => 59.50, 'betrag_brutto' => 59.50,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',

View file

@ -74,7 +74,6 @@ class InvoiceBuchungTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', $nr), 'file_hash' => hash('sha256', $nr),
'beleg_datum' => $invoice['rechnungs_datum'], 'beleg_datum' => $invoice['rechnungs_datum'],
'eingangs_datum' => $invoice['rechnungs_datum'],
'rechnungs_nr' => $nr, 'rechnungs_nr' => $nr,
'betrag_brutto' => $invoice['betrag_brutto'], 'betrag_brutto' => $invoice['betrag_brutto'],
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',

View file

@ -66,7 +66,6 @@ class TaxSummenTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-ar'), 'file_hash' => hash('sha256', 'test-ar'),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([
@ -89,7 +88,6 @@ class TaxSummenTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-er'), 'file_hash' => hash('sha256', 'test-er'),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([

View file

@ -59,7 +59,6 @@ class EuerBuchungsTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'einnahme-' . uniqid()), 'file_hash' => hash('sha256', 'einnahme-' . uniqid()),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',
]); ]);
@ -90,7 +89,6 @@ class EuerBuchungsTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'ausgabe-' . uniqid()), 'file_hash' => hash('sha256', 'ausgabe-' . uniqid()),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',
]); ]);

View file

@ -44,7 +44,6 @@ class UstvaAuslandTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-igl'), 'file_hash' => hash('sha256', 'test-igl'),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([
@ -67,7 +66,6 @@ class UstvaAuslandTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-exp'), 'file_hash' => hash('sha256', 'test-exp'),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([
@ -90,7 +88,6 @@ class UstvaAuslandTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-ige19'), 'file_hash' => hash('sha256', 'test-ige19'),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([
@ -113,7 +110,6 @@ class UstvaAuslandTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-ige7'), 'file_hash' => hash('sha256', 'test-ige7'),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([

View file

@ -63,7 +63,6 @@ class LieferantTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', $belegNr), 'file_hash' => hash('sha256', $belegNr),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'rechnungs_nr' => 'RE-SUP-001', 'rechnungs_nr' => 'RE-SUP-001',
'betrag_brutto' => 59.50, 'betrag_brutto' => 59.50,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',

View file

@ -73,7 +73,6 @@ class InvoiceToReportsTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', $rechnungsNr), 'file_hash' => hash('sha256', $rechnungsNr),
'beleg_datum' => $invoice['rechnungs_datum'], 'beleg_datum' => $invoice['rechnungs_datum'],
'eingangs_datum' => $invoice['rechnungs_datum'],
'rechnungs_nr' => $rechnungsNr, 'rechnungs_nr' => $rechnungsNr,
'betrag_brutto' => $invoice['betrag_brutto'], 'betrag_brutto' => $invoice['betrag_brutto'],
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',

View file

@ -76,7 +76,6 @@ class IstVersteuerungTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', $nr), 'file_hash' => hash('sha256', $nr),
'beleg_datum' => $rechnungsDatum, 'beleg_datum' => $rechnungsDatum,
'eingangs_datum' => $rechnungsDatum,
'rechnungs_nr' => $nr, 'rechnungs_nr' => $nr,
'betrag_brutto' => $invoice['betrag_brutto'], 'betrag_brutto' => $invoice['betrag_brutto'],
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',

View file

@ -28,7 +28,6 @@ class BelegGebuechtStatusTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => sha1('test'), 'file_hash' => sha1('test'),
'beleg_datum' => date('Y-m-d'), 'beleg_datum' => date('Y-m-d'),
'eingangs_datum'=> date('Y-m-d'),
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',
'betrag_brutto' => 119.00, 'betrag_brutto' => 119.00,
]); ]);

View file

@ -40,7 +40,6 @@ class NichtAbzugsfaehigEuerTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'kz165ein' . uniqid()), 'file_hash' => hash('sha256', 'kz165ein' . uniqid()),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([
@ -62,7 +61,6 @@ class NichtAbzugsfaehigEuerTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'kz165aus' . uniqid()), 'file_hash' => hash('sha256', 'kz165aus' . uniqid()),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([
@ -84,7 +82,6 @@ class NichtAbzugsfaehigEuerTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'kz165na' . uniqid()), 'file_hash' => hash('sha256', 'kz165na' . uniqid()),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Eingangsrechnung', 'belegtyp' => 'Eingangsrechnung',
]); ]);
\Steuerkram\Models\Booking::create([ \Steuerkram\Models\Booking::create([

View file

@ -34,7 +34,6 @@ class StornoBuchungTest extends TestCase
'mime_type' => 'application/pdf', 'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'storno-test-' . uniqid()), 'file_hash' => hash('sha256', 'storno-test-' . uniqid()),
'beleg_datum' => $datum, 'beleg_datum' => $datum,
'eingangs_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung', 'belegtyp' => 'Ausgangsrechnung',
]); ]);