// Generated, do not edit. sha256:f8255fd8148a61f4a49cc0a84d161f8b1bc531a1a315349c9aef9328871b9d6f import * as db from '../db.js'; import { fail } from '../../shared/app-error.js'; import { assertTimestamp, nowIso } from './_shared.js'; import { createEvent, deleteEvent, EVENT_JOIN } from './events.js'; import { trackUpdate } from './change-log.js'; import { emitChange } from './_events.js'; export function listReservations() { return db.all(`${EVENT_JOIN} WHERE e.type = 'reservation' ORDER BY e.occurredAt ASC, e.id ASC`); } export function listReservationsForAccount(accountId) { return db.all(`${EVENT_JOIN} WHERE e.type = 'reservation' AND (e.fromAccountId = ?1 OR e.toAccountId = ?1) ORDER BY e.occurredAt ASC, e.id ASC`, [accountId]); } export function listDueReservations(untilIso = nowIso()) { return db.all(`${EVENT_JOIN} WHERE e.type = 'reservation' AND e.occurredAt <= ? ORDER BY e.occurredAt ASC, e.id ASC`, [untilIso]); } function rowOf(r) { if (!r.accountId) throw new Error('A reservation needs an account.'); if (r.direction !== 'in' && r.direction !== 'out') throw new Error(`Unknown direction '${r.direction}'; use 'in' or 'out'.`); return { assetId: r.assetId, type: 'reservation', occurredAt: r.occurredAt, amount: r.amount, fromAccountId: r.direction === 'out' ? r.accountId : null, toAccountId: r.direction === 'in' ? r.accountId : null, source: 'manual', note: r.note ?? null, }; } function openReservation(id) { const row = db.one(`SELECT * FROM Event WHERE id = ?`, [id]); if (!row || row.type !== 'reservation') fail('reservations.notOpen', null, 'This reservation is no longer open.'); return row; } export async function createReservation(r) { return createEvent(rowOf(r)); } export async function updateReservation(id, r) { openReservation(id); const e = rowOf(r); trackUpdate('Event', id, () => db.run( `UPDATE Event SET assetId = ?, occurredAt = ?, amount = ?, fromAccountId = ?, toAccountId = ?, note = ? WHERE id = ? AND type = 'reservation'`, [e.assetId, e.occurredAt, e.amount, e.fromAccountId, e.toAccountId, e.note, id])); await db.persist(); emitChange('ledger-changed'); } export async function deleteReservation(id) { openReservation(id); await deleteEvent(id); } export async function bookReservation(id, { occurredAt, amount, otherAccountId = null, note }) { const row = openReservation(id); assertTimestamp('occurredAt', occurredAt); if (!Number.isInteger(amount) || amount <= 0) throw new Error(`A booking needs an amount > 0 in the smallest unit (got ${amount}).`); const out = row.fromAccountId != null; const own = out ? row.fromAccountId : row.toAccountId; if (otherAccountId != null && otherAccountId === own) throw new Error('The other side of a booking is another account.'); const [from, to] = out ? [own, otherAccountId] : [otherAccountId, own]; trackUpdate('Event', id, () => db.run( `UPDATE Event SET type = 'transfer', occurredAt = ?, amount = ?, fromAccountId = ?, toAccountId = ?, note = ? WHERE id = ? AND type = 'reservation'`, [occurredAt, amount, from, to, note === undefined ? row.note : (note || null), id])); await db.persist(); emitChange('ledger-changed'); }