import { formatDocNo } from '@sims/domain' import type { DB } from './db' export const TYPE_PREFIX: Record = { QUOTATION: 'QT', PROFORMA: 'PI', INVOICE: 'INV', RECEIPT: 'RCT', CREDIT_NOTE: 'CN', } export async function nextDocNo(db: DB, docType: string, fy: string): Promise { const prefix = `${TYPE_PREFIX[docType]}/${fy.slice(2)}` await db.run( // Portability quirk: ON CONFLICT upsert is SQLite/Postgres dialect (standard SQL has MERGE). `INSERT INTO doc_series (doc_type, fy, prefix, next_seq) VALUES (?, ?, ?, 1) ON CONFLICT (doc_type, fy) DO NOTHING`, docType, fy, prefix, ) const row = (await db.get<{ prefix: string; next_seq: number }>( `SELECT prefix, next_seq FROM doc_series WHERE doc_type=? AND fy=?`, docType, fy, ))! await db.run(`UPDATE doc_series SET next_seq = next_seq + 1 WHERE doc_type=? AND fy=?`, docType, fy) return formatDocNo(row.prefix, row.next_seq, 4) } /** Mid-FY cutover (spec ยง4): continue after the last APEX-issued number. */ export async function seedSeries(db: DB, docType: string, fy: string, lastUsedSeq: number): Promise { const prefix = `${TYPE_PREFIX[docType]}/${fy.slice(2)}` await db.run( // Portability quirk: ON CONFLICT upsert is SQLite/Postgres dialect (standard SQL has MERGE). `INSERT INTO doc_series (doc_type, fy, prefix, next_seq) VALUES (?, ?, ?, ?) ON CONFLICT (doc_type, fy) DO UPDATE SET next_seq = excluded.next_seq`, docType, fy, prefix, lastUsedSeq + 1, ) }