..., 'ust_7'=>..., 'zahlungskonto_id'=>..., ...] * @param string $datum Buchungsdatum (YYYY-MM-DD) * @return int[] IDs der erstellten Buchungen */ public function buchen(int $belegId, int $vorlageId, array $inputDaten, string $datum): array { $vorlage = Buchungsvorlage::find($vorlageId); if (!$vorlage) { throw new \RuntimeException('Buchungsvorlage nicht gefunden.'); } $beleg = Beleg::find($belegId); if (!$beleg) { throw new \RuntimeException('Beleg nicht gefunden.'); } if ($beleg['locked']) { throw new \RuntimeException('Beleg ist gesperrt.'); } $zahlungskontoId = (int)($inputDaten['zahlungskonto_id'] ?? 0); if ($zahlungskontoId === 0) { throw new \RuntimeException('Kein Zahlungskonto gewählt.'); } $regeln = Buchungsvorlage::getRegeln($vorlageId); if (empty($regeln)) { throw new \RuntimeException('Vorlage hat keine Buchungsregeln.'); } $buchungsIds = []; Database::beginTransaction(); try { $this->updateBelegMeta($belegId, $beleg, $inputDaten); foreach ($regeln as $regel) { if (!$this->bedingungErfuellt($regel, $inputDaten)) { continue; } foreach ($regel['buchungen'] as $buchung) { $betrag = round((float)str_replace(',', '.', (string)($inputDaten[$buchung['betrag_ref']] ?? 0)), 2); if ($betrag == 0.0) { continue; } $nachKonto = Account::findByKontonummer($buchung['nach_konto']); if (!$nachKonto) { throw new \RuntimeException("Konto {$buchung['nach_konto']} nicht gefunden."); } $buchungsIds[] = Booking::create([ 'beleg_id' => $belegId, 'buchungs_datum' => $datum, 'buchungstyp' => 'Ausgabe', 'kategorie_konto_id' => (int)$nachKonto['id'], 'zahlungskonto_id' => $zahlungskontoId, 'betrag_netto' => $betrag, 'ust_satz' => 0, 'steuerart' => 'normal', 'buchungstext' => $vorlage['name'], ]); } } Database::commit(); } catch (\Throwable $e) { Database::rollBack(); throw $e; } return $buchungsIds; } private function bedingungErfuellt(array $regel, array $inputDaten): bool { $feld = $regel['bedingung_feld']; $op = $regel['bedingung_op'] ?? 'neq_zero'; if ($op === 'always') { return true; } return round((float)($inputDaten[$feld] ?? 0), 4) != 0.0; } private function updateBelegMeta(int $belegId, array $beleg, array $inputDaten): void { $supplierId = $beleg['supplier_id'] ?? null; if (!empty($inputDaten['lieferant'])) { $supplierId = Supplier::findOrCreate(trim($inputDaten['lieferant'])); } Beleg::updateMeta($belegId, [ 'rechnungs_nr' => $inputDaten['rechnungsnr'] ?? $beleg['rechnungs_nr'] ?? null, 'belegtyp' => $beleg['belegtyp'] ?? 'Eingangsrechnung', 'beleg_datum' => !empty($inputDaten['belegdatum']) ? $inputDaten['belegdatum'] : ($beleg['beleg_datum'] ?? null), 'supplier_id' => $supplierId, ]); } }