You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sims-hq/apps/hq/test/receipt.test.ts

54 lines
2.8 KiB
TypeScript

// apps/hq/test/receipt.test.ts
import { describe, it, expect } from 'vitest'
import { openDb } from '../src/db'
import { seedIfEmpty } from '../src/seed'
import { createClient } from '../src/repos-clients'
import { createModule, setPrice } from '../src/repos-modules'
import { createDraft, issueDocument, getDocument } from '../src/repos-documents'
import { recordPayment, receiptForPayment } from '../src/repos-payments'
import { documentHtml } from '../src/templates'
function setup() {
const db = openDb(':memory:'); seedIfEmpty(db)
const c = createClient(db, 'u1', { name: 'Acme', code: 'ACME', stateCode: '32', contacts: [{ name: 'R', email: 'r@acme.in' }] })
const m = createModule(db, 'u1', { code: 'POS', name: 'POS', allowedKinds: ['yearly'] })
setPrice(db, 'u1', { moduleId: m.id, kind: 'yearly', pricePaise: 10_000_00, effectiveFrom: '2026-01-01' })
const inv = issueDocument(db, 'u1', createDraft(db, 'u1', { docType: 'INVOICE', clientId: c.id, lines: [{ moduleId: m.id, qty: 1, kind: 'yearly' }] }).id)
return { db, c, inv }
}
describe('payment receipts', () => {
it('issues a zero-GST RECEIPT with its own RCT/ series on recordPayment', () => {
const { db, c, inv } = setup()
const out = recordPayment(db, 'u1', {
clientId: c.id, receivedOn: '2026-07-10', mode: 'bank', amountPaise: 11_800_00,
allocations: [{ documentId: inv.id, amountPaise: 11_800_00 }], issueReceipt: true,
})
expect(out.receipt).toBeDefined()
const rc = out.receipt!
expect(rc.docType).toBe('RECEIPT')
expect(rc.docNo?.startsWith('RCT/')).toBe(true)
expect(rc.payablePaise).toBe(11_800_00)
expect(rc.cgstPaise + rc.sgstPaise + rc.igstPaise).toBe(0) // acknowledgment, not a tax document
expect(rc.payload.receipt?.allocations[0]).toMatchObject({ docNo: inv.docNo, amountPaise: 11_800_00 })
})
it('generates a receipt after the fact from a stored payment', () => {
const { db, c, inv } = setup()
const out = recordPayment(db, 'u1', {
clientId: c.id, receivedOn: '2026-07-10', mode: 'upi', amountPaise: 5_000_00,
allocations: [{ documentId: inv.id, amountPaise: 5_000_00 }],
})
const rc = receiptForPayment(db, 'u1', out.payment.id)
expect(rc.docType).toBe('RECEIPT')
expect(getDocument(db, rc.id)!.docNo).toBe(rc.docNo)
})
it('renders a receipt acknowledgment (no SAC/GST table)', () => {
const { db, c, inv } = setup()
const out = recordPayment(db, 'u1', { clientId: c.id, receivedOn: '2026-07-10', mode: 'bank', amountPaise: 11_800_00, allocations: [{ documentId: inv.id, amountPaise: 11_800_00 }], issueReceipt: true })
const html = documentHtml(out.receipt!, c, { 'company.name': 'Tecnostac' })
expect(html).toContain('RECEIPT')
expect(html).toContain('Received with thanks')
expect(html).not.toContain('>SAC<') // the GST line table header is absent on receipts
})
})