export async function createInvoice(input: InvoiceInput) {
const client = await clients.require(input.clientId);
const rate = await dollarRates.current();
const lines = input.lines.map((l) => priceLine(l, rate));
const total = sum(lines.map((l) => l.amountPaisa));
return db.transaction(async (tx) => {
const number = await counters.next('invoice', tx);
const invoice = await invoices.insert({ number, client, lines, total }, tx);
await audit.record('invoice.created', invoice.id, tx);
await notify.finance({ type: 'invoice.issued', id: invoice.id });
return invoice;
});
}
const schema = z.object({
name: z.string().min(2),
phone: bdPhone,
services: z.array(z.enum(SERVICES)),
});
router.post('/leads', async (req, res) => {
const lead = schema.parse(req.body);
await limiter.hit(req.ip, { max: 5, windowMs: 600_000 });
await crm.leads.create({ ...lead, source: 'website' });
res.status(201).end();
});
export async function createInvoice(input: InvoiceInput) {
const client = await clients.require(input.clientId);
const rate = await dollarRates.current();
const lines = input.lines.map((l) => priceLine(l, rate));
const total = sum(lines.map((l) => l.amountPaisa));
return db.transaction(async (tx) => {
const number = await counters.next('invoice', tx);
const invoice = await invoices.insert({ number, client, lines, total }, tx);
await audit.record('invoice.created', invoice.id, tx);
await notify.finance({ type: 'invoice.issued', id: invoice.id });
return invoice;
});
}
const schema = z.object({
name: z.string().min(2),
phone: bdPhone,
services: z.array(z.enum(SERVICES)),
});
router.post('/leads', async (req, res) => {
const lead = schema.parse(req.body);
await limiter.hit(req.ip, { max: 5, windowMs: 600_000 });
await crm.leads.create({ ...lead, source: 'website' });
res.status(201).end();
});
Software Development · Manufacturing group
One ERP across three factories
Inventory, purchasing and payroll on a single system, replacing eleven spreadsheets.
- Month-end close time
- -70%
Next