M5 abschliessen: Schreibseiten aufs Ledger umstellen, Storno statt Delete
- stricheintragen.php und einzahlung.php erhielten bisher gar keine Zugriffskontrolle (nur CSRF), jetzt Rollen-/Legacy-Fallback wie in kaffeeliste.php; Sammeleintraege spiegeln transaktional ins Ledger (ledger_mirror_legacy_payment neu ergaenzt). - letzteneintraege.php war rein ueber Legacy-Admin gesperrt und haette neue SaaS-Mandanten ausgeschlossen; Loeschen markiert den gespiegelten Ledger-Eintrag jetzt per voided_at statt ihn zu entfernen (ledger_void_entry_by_legacy_id). - check-m4-ledger-migration.php an das Storno-Modell angepasst: verwaiste Ledger-Zeilen sind nur noch ein Fehler, wenn sie nicht voided sind. - Nebenbei: PHP-Warning bei Sammelerfassung behoben, toten Code entfernt, veraltete README (verwies auf nicht existierende saas-app/-Struktur) korrigiert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -319,6 +319,74 @@ function ledger_mirror_legacy_consumption(PDO $pdo, int $tenantId, int $legacyCo
|
||||
}
|
||||
}
|
||||
|
||||
function ledger_mirror_legacy_payment(PDO $pdo, int $tenantId, int $legacyPaymentId): void
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
"INSERT INTO ledger_entries
|
||||
(tenant_id, participant_id, type, amount_cents, marks_count,
|
||||
unit_price_cents, booked_at, source, note, legacy_table, legacy_id)
|
||||
SELECT
|
||||
p.tenant_id,
|
||||
p.id,
|
||||
'payment',
|
||||
CAST(ROUND(e.Betrag * 100) AS SIGNED),
|
||||
NULL,
|
||||
NULL,
|
||||
e.Datum,
|
||||
'legacy_payment',
|
||||
NULL,
|
||||
'kl_Einzahlungen',
|
||||
e.EinzahlungsID
|
||||
FROM kl_Einzahlungen e
|
||||
JOIN participants p
|
||||
ON p.tenant_id = ?
|
||||
AND p.legacy_mitarbeiter_id = e.MitarbeiterID
|
||||
WHERE e.EinzahlungsID = ?
|
||||
ON DUPLICATE KEY UPDATE
|
||||
participant_id = VALUES(participant_id),
|
||||
type = VALUES(type),
|
||||
amount_cents = VALUES(amount_cents),
|
||||
marks_count = VALUES(marks_count),
|
||||
unit_price_cents = VALUES(unit_price_cents),
|
||||
booked_at = VALUES(booked_at),
|
||||
source = VALUES(source),
|
||||
note = VALUES(note)"
|
||||
);
|
||||
$stmt->execute([$tenantId, $legacyPaymentId]);
|
||||
|
||||
$check = $pdo->prepare(
|
||||
"SELECT COUNT(*)
|
||||
FROM ledger_entries
|
||||
WHERE tenant_id = ?
|
||||
AND legacy_table = 'kl_Einzahlungen'
|
||||
AND legacy_id = ?"
|
||||
);
|
||||
$check->execute([$tenantId, $legacyPaymentId]);
|
||||
if ((int)$check->fetchColumn() !== 1) {
|
||||
throw new RuntimeException('Die Legacy-Einzahlung konnte nicht ins Ledger gespiegelt werden.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the ledger entry mirrored from a legacy row as voided instead of
|
||||
* deleting it, so corrections stay auditable. Idempotent: voiding an
|
||||
* already-voided or missing entry is a no-op and returns false.
|
||||
*/
|
||||
function ledger_void_entry_by_legacy_id(PDO $pdo, int $tenantId, string $legacyTable, int $legacyId): bool
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
"UPDATE ledger_entries
|
||||
SET voided_at = NOW()
|
||||
WHERE tenant_id = ?
|
||||
AND legacy_table = ?
|
||||
AND legacy_id = ?
|
||||
AND voided_at IS NULL"
|
||||
);
|
||||
$stmt->execute([$tenantId, $legacyTable, $legacyId]);
|
||||
|
||||
return $stmt->rowCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options:
|
||||
* - participant_id: int
|
||||
|
||||
Reference in New Issue
Block a user