From 2a3097217e872d379bf7c034c745e786c9bd8bd9 Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 29 Jul 2026 20:26:52 +0200 Subject: [PATCH] snapshot the Pfand rate used for returns, like every other money value already is MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Line items correctly snapshot both unit_price_cents and pfand_cents_per_unit, so a later price change doesn't rewrite history. Returns didn't get the same treatment: transactions.pfand_returns stored a bare count, and the euro value came from the bar's pfand_cents at that moment but was never recorded — change a bar's deposit mid-event and no historical refund amount could be recomputed from the database. Writing returns as transaction_items rows (the schema's is_return column) doesn't fit cleanly: a Pfand return isn't tied to a specific drink, but transaction_items.drink_id is NOT NULL. Add transactions.pfand_cents_at_sale instead — same snapshot idea, at the transaction level where pfand_returns already lives. Also added to the transactions CSV export so the recovered value is actually visible somewhere in the app, not just reachable via raw SQL. --- server/migrations/004_pfand_return_snapshot.sql | 7 +++++++ server/src/routes/admin.ts | 4 ++-- server/src/routes/public.ts | 16 +++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 server/migrations/004_pfand_return_snapshot.sql diff --git a/server/migrations/004_pfand_return_snapshot.sql b/server/migrations/004_pfand_return_snapshot.sql new file mode 100644 index 0000000..5b35f72 --- /dev/null +++ b/server/migrations/004_pfand_return_snapshot.sql @@ -0,0 +1,7 @@ +-- Snapshot the Pfand rate used to price this transaction's returns, same +-- as unit_price_cents/pfand_cents_per_unit already do per line item. +-- Without this, transactions.pfand_returns is a bare count and the euro +-- value depends on whatever bars.pfand_cents happens to be *now* — change +-- a bar's deposit mid-event and no historical refund amount is +-- recoverable from the database. +ALTER TABLE transactions ADD COLUMN pfand_cents_at_sale INTEGER NOT NULL DEFAULT 0; diff --git a/server/src/routes/admin.ts b/server/src/routes/admin.ts index c092acd..64ca739 100644 --- a/server/src/routes/admin.ts +++ b/server/src/routes/admin.ts @@ -267,11 +267,11 @@ export function registerAdminRoutes(app: FastifyInstance, db: DB) { let rows: any[]; let header: string[]; if (what === 'transactions') { - header = ['id', 'bar_id', 'bar_name', 'created_at', 'total_cents', 'crew', 'pfand_returns', 'client_ip', 'client_uuid']; + header = ['id', 'bar_id', 'bar_name', 'created_at', 'total_cents', 'crew', 'pfand_returns', 'pfand_cents_at_sale', 'client_ip', 'client_uuid']; rows = db .prepare( `SELECT t.id, t.bar_id, b.name AS bar_name, t.created_at, t.total_cents, - t.crew, t.pfand_returns, t.client_ip, t.client_uuid + t.crew, t.pfand_returns, t.pfand_cents_at_sale, t.client_ip, t.client_uuid FROM transactions t JOIN bars b ON b.id = t.bar_id ORDER BY t.id` ) diff --git a/server/src/routes/public.ts b/server/src/routes/public.ts index b574116..2e82a51 100644 --- a/server/src/routes/public.ts +++ b/server/src/routes/public.ts @@ -135,8 +135,9 @@ export function registerPublicRoutes(app: FastifyInstance, db: DB) { const clientIp = req.ip ?? null; const insertTx = db.prepare( - `INSERT INTO transactions (bar_id, created_at, total_cents, crew, pfand_returns, client_ip, client_uuid) - VALUES (?, ?, ?, ?, ?, ?, ?)` + `INSERT INTO transactions + (bar_id, created_at, total_cents, crew, pfand_returns, pfand_cents_at_sale, client_ip, client_uuid) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)` ); const insertItem = db.prepare( `INSERT INTO transaction_items @@ -148,7 +149,16 @@ export function registerPublicRoutes(app: FastifyInstance, db: DB) { let txId: number; try { txId = db.transaction(() => { - const info = insertTx.run(bar_id, createdAt, paidTotal, crew ? 1 : 0, pfand_returns, clientIp, client_uuid); + const info = insertTx.run( + bar_id, + createdAt, + paidTotal, + crew ? 1 : 0, + pfand_returns, + bar.pfand_cents, + clientIp, + client_uuid + ); const id = Number(info.lastInsertRowid); for (const p of priced) { insertItem.run(id, p.drink_id, p.qty, p.unit_price_cents, p.pfand_cents_per_unit);