Feature: Bank-Zuordnung öffnet Buchungsmaske mit vorausgefüllten Feldern
This commit is contained in:
parent
b12f4c9b2b
commit
e4a6995a31
4 changed files with 125 additions and 16 deletions
|
|
@ -11,6 +11,7 @@ use Steuerkram\Models\Asset;
|
|||
use Steuerkram\Models\Supplier;
|
||||
use Steuerkram\View;
|
||||
use Steuerkram\Services\ImageCropService;
|
||||
use Steuerkram\Models\BankTransaction;
|
||||
use Steuerkram\Services\KontierungsvorschlagService;
|
||||
|
||||
class BelegController
|
||||
|
|
@ -205,22 +206,60 @@ class BelegController
|
|||
$kiVorschlag = $beleg['ki_vorschlag'] !== null
|
||||
? json_decode($beleg['ki_vorschlag'], true)
|
||||
: null;
|
||||
// KI-Sektion anzeigen wenn Ergebnis vorhanden ODER LLM gerade verfügbar
|
||||
$kiSektion = $kiAktiv || $kiVorschlag !== null;
|
||||
|
||||
// Bank-Kontext: Vorausfüllen aus Bankbuchung
|
||||
$bankTx = null;
|
||||
$bankTxSupplier = '';
|
||||
$bankTxBrutto = 0.0;
|
||||
$bankFormData = [];
|
||||
|
||||
if (!empty($_GET['bank_tx'])) {
|
||||
$bankTx = BankTransaction::find((int)$_GET['bank_tx']);
|
||||
}
|
||||
|
||||
if ($bankTx) {
|
||||
// Auftraggeber extrahieren: "Auftraggeber: X Buchungstext" → X
|
||||
if (preg_match('/Auftraggeber:\s*(.*?)(?:\s*Buchungstext|\s*$)/si', $bankTx['buchungstext'], $m)) {
|
||||
$bankTxSupplier = trim($m[1]);
|
||||
}
|
||||
$bankTxBrutto = abs((float)$bankTx['wert']);
|
||||
$netto = round($bankTxBrutto / 1.19, 2);
|
||||
|
||||
$bankFormData = [
|
||||
'buchungs_datum' => $bankTx['wertstellung'],
|
||||
'betrag_netto' => number_format($netto, 2, '.', ''),
|
||||
'zahlungs_kontonummer'=> '1200',
|
||||
];
|
||||
|
||||
// Lieferant am Beleg setzen, wenn noch keiner hinterlegt ist
|
||||
if (empty($beleg['supplier_name']) && $bankTxSupplier !== '') {
|
||||
$supplierId = \Steuerkram\Models\Supplier::findOrCreate($bankTxSupplier);
|
||||
\Steuerkram\Database::execute(
|
||||
'UPDATE belege SET supplier_id=?, updated_at=NOW() WHERE id=?',
|
||||
[$supplierId, (int)$params['id']]
|
||||
);
|
||||
$beleg['supplier_name'] = $bankTxSupplier;
|
||||
}
|
||||
}
|
||||
|
||||
$view = new View();
|
||||
$view->render('layout/base.php', [
|
||||
'pageTitle' => 'Beleg ' . $beleg['beleg_nr'],
|
||||
'content' => $this->renderView('belege/detail', [
|
||||
'beleg' => $beleg,
|
||||
'suppliers' => $suppliers,
|
||||
'bookings' => $bookings,
|
||||
'integrity' => $integrity,
|
||||
'accounts' => $accounts,
|
||||
'assets' => $assets,
|
||||
'kiAktiv' => $kiAktiv,
|
||||
'kiSektion' => $kiSektion,
|
||||
'kiVorschlag' => $kiVorschlag,
|
||||
'beleg' => $beleg,
|
||||
'suppliers' => $suppliers,
|
||||
'bookings' => $bookings,
|
||||
'integrity' => $integrity,
|
||||
'accounts' => $accounts,
|
||||
'assets' => $assets,
|
||||
'kiAktiv' => $kiAktiv,
|
||||
'kiSektion' => $kiSektion,
|
||||
'kiVorschlag' => $kiVorschlag,
|
||||
'bankTx' => $bankTx,
|
||||
'bankTxSupplier' => $bankTxSupplier,
|
||||
'bankTxBrutto' => $bankTxBrutto,
|
||||
'formData' => $bankFormData,
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace Steuerkram\Controllers;
|
|||
use Steuerkram\Models\Booking;
|
||||
use Steuerkram\Models\Account;
|
||||
use Steuerkram\Models\Beleg;
|
||||
use Steuerkram\Models\BankTransaction;
|
||||
use Steuerkram\Models\FiscalYear;
|
||||
use Steuerkram\Models\Setting;
|
||||
use Steuerkram\View;
|
||||
|
|
@ -182,8 +183,16 @@ class BookingController
|
|||
}
|
||||
}
|
||||
|
||||
// Bankbuchung verknüpfen wenn aus Bank-Kontext
|
||||
$bankTxId = (int)($data['bank_tx_id'] ?? 0);
|
||||
if ($bankTxId > 0) {
|
||||
BankTransaction::linkBeleg($bankTxId, $belegId);
|
||||
}
|
||||
|
||||
if ($newAssetId !== null) {
|
||||
View::redirect("/assets/{$newAssetId}/edit", 'Buchung erfasst. Bitte Wirtschaftsgut-Details ergänzen.');
|
||||
} elseif ($bankTxId > 0) {
|
||||
View::redirect('/bank', 'Buchung erfasst und Bankbuchung verknüpft.');
|
||||
} else {
|
||||
View::redirect("/belege/{$belegId}", 'Buchung erfasst.');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,10 +123,8 @@ $vorschauHoehe = (int)($settings['beleg_vorschau_hoehe'] ?? 300);
|
|||
<?= $b['betrag_brutto'] ? $fmt($b['betrag_brutto']) : '<span class="text-muted">–</span>' ?>
|
||||
</td>
|
||||
<td onclick="event.stopPropagation()">
|
||||
<form method="post" action="/bank/<?= (int)$transaction['id'] ?>/link" style="display:inline">
|
||||
<input type="hidden" name="beleg_id" value="<?= (int)$b['id'] ?>">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Verknüpfen</button>
|
||||
</form>
|
||||
<a href="/belege/<?= (int)$b['id'] ?>?bank_tx=<?= (int)$transaction['id'] ?>"
|
||||
class="btn btn-primary btn-sm">Verknüpfen</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ $suppliers = $suppliers ?? [];
|
|||
<div class="form-group" style="margin:0;min-width:180px">
|
||||
<label style="font-size:.8rem">Lieferant</label>
|
||||
<input type="text" name="supplier_name" id="supplier_name_input"
|
||||
value="<?= $h($beleg['supplier_name'] ?? '') ?>"
|
||||
value="<?= $h($beleg['supplier_name'] ?? ($bankTxSupplier ?? '')) ?>"
|
||||
placeholder="Name eingeben oder wählen…"
|
||||
list="supplier-datalist"
|
||||
autocomplete="off">
|
||||
|
|
@ -295,8 +295,25 @@ $suppliers = $suppliers ?? [];
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- BankBuchung-Badge (ersetzt KI-Badge wenn aus Bank-Kontext) -->
|
||||
<?php if (!$beleg['locked'] && ($bankTx ?? null)): ?>
|
||||
<div class="card mb-2" style="border-left:4px solid var(--color-primary,#3b82f6)">
|
||||
<div class="card-body" style="padding:.75rem 1.25rem">
|
||||
<div style="display:flex;align-items:center;gap:.75rem;flex-wrap:wrap">
|
||||
<span class="badge badge-blue" style="font-size:.8rem">Bankbuchung</span>
|
||||
<span class="td-mono text-sm"><?= View::formatDate($bankTx['wertstellung']) ?></span>
|
||||
<span class="text-sm"><?= $h($bankTx['vorgang']) ?></span>
|
||||
<span class="text-sm" style="flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
|
||||
title="<?= $h($bankTx['buchungstext']) ?>"><?= $h($bankTx['buchungstext']) ?></span>
|
||||
<?php $bwert = (float)$bankTx['wert']; ?>
|
||||
<strong style="color:<?= $bwert >= 0 ? 'var(--color-success)' : 'var(--color-danger)' ?>;white-space:nowrap">
|
||||
<?= $bwert >= 0 ? '+' : '' ?><?= number_format($bwert, 2, ',', '.') ?> €
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif (!$beleg['locked'] && ($kiSektion ?? false)): ?>
|
||||
<!-- KI-Kontierungsvorschlag -->
|
||||
<?php if (!$beleg['locked'] && ($kiSektion ?? false)): ?>
|
||||
<div id="ki-badge" style="margin-bottom:1rem"></div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
|
@ -336,6 +353,9 @@ $suppliers = $suppliers ?? [];
|
|||
</div>
|
||||
<?php endif; ?>
|
||||
<form method="post" action="/belege/<?= $h($beleg['id']) ?>/bookings">
|
||||
<?php if ($bankTx ?? null): ?>
|
||||
<input type="hidden" name="bank_tx_id" value="<?= (int)$bankTx['id'] ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Buchungstyp -->
|
||||
<div class="form-group">
|
||||
|
|
@ -508,6 +528,49 @@ $suppliers = $suppliers ?? [];
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($bankTx ?? null): ?>
|
||||
<script>
|
||||
(function () {
|
||||
const brutto = <?= (float)($bankTxBrutto ?? 0) ?>;
|
||||
let manualNetto = false;
|
||||
|
||||
const nettoInput = document.getElementById('betrag_netto_input');
|
||||
const ustSelect = document.getElementById('ust_satz_select');
|
||||
|
||||
// Netto aus Brutto bei USt-Wechsel neu berechnen (solange nicht manuell geändert)
|
||||
function recalcNetto() {
|
||||
if (manualNetto || !brutto) return;
|
||||
const ust = parseFloat(ustSelect.value) / 100;
|
||||
const netto = Math.round(brutto / (1 + ust) * 100) / 100;
|
||||
nettoInput.value = netto.toFixed(2);
|
||||
if (typeof updateNettoAnzeige === 'function') updateNettoAnzeige();
|
||||
}
|
||||
|
||||
nettoInput.addEventListener('input', function () { manualNetto = true; });
|
||||
ustSelect.addEventListener('change', recalcNetto);
|
||||
|
||||
// Zahlungskonto 1200 vorauswählen
|
||||
const zkSelect = document.getElementById('zahlungskonto_id');
|
||||
if (zkSelect) {
|
||||
for (const opt of zkSelect.options) {
|
||||
if ((opt.dataset.search || '').startsWith('1200 ')) {
|
||||
opt.selected = true;
|
||||
zkSelect.dispatchEvent(new Event('change'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Meta-Formular mit Lieferant aufklappen wenn noch nicht gespeichert
|
||||
<?php if (!empty($bankTxSupplier) && empty($beleg['supplier_name'])): ?>
|
||||
const metaForm = document.getElementById('beleg-meta-form');
|
||||
if (metaForm) metaForm.style.display = 'block';
|
||||
<?php endif; ?>
|
||||
})();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="flash flash-info">Dieser Beleg ist gesperrt (GoBD). Keine weiteren Buchungen möglich.</div>
|
||||
<?php endif; ?>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue