feat: add invoice lifecycle schema
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE `invoices` ADD `status` text DEFAULT 'draft' NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE `invoices` ADD `sent_at` integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE `invoices` ADD `paid_at` integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE `invoices` ADD `voided_at` integer;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -113,6 +113,13 @@
|
|||||||
"when": 1782338642144,
|
"when": 1782338642144,
|
||||||
"tag": "0015_fuzzy_vampiro",
|
"tag": "0015_fuzzy_vampiro",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 16,
|
||||||
|
"version": "6",
|
||||||
|
"when": 1782383895120,
|
||||||
|
"tag": "0016_outstanding_talkback",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { moneyGbp, optionalText, requiredText } from './shared.schema';
|
import { moneyGbp, optionalText, requiredText } from './shared.schema';
|
||||||
|
|
||||||
|
export const invoiceStatusValues = ['draft', 'sent', 'paid', 'void'] as const;
|
||||||
|
export const invoiceStatusSchema = z.enum(invoiceStatusValues);
|
||||||
|
|
||||||
export const invoiceCreateSchema = z.object({
|
export const invoiceCreateSchema = z.object({
|
||||||
clientId: requiredText('Client'),
|
clientId: requiredText('Client'),
|
||||||
invoiceNumber: requiredText('Invoice number', 80),
|
invoiceNumber: requiredText('Invoice number', 80),
|
||||||
|
status: invoiceStatusSchema.default('draft'),
|
||||||
issueDate: requiredText('Issue date', 40),
|
issueDate: requiredText('Issue date', 40),
|
||||||
dueDate: requiredText('Due date', 40),
|
dueDate: requiredText('Due date', 40),
|
||||||
subtotalGbp: moneyGbp,
|
subtotalGbp: moneyGbp,
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { index, real, sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
import { index, integer, real, sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
||||||
import { clients } from './clients.schema';
|
import { clients } from './clients.schema';
|
||||||
import { organizations } from './organizations.schema';
|
import { organizations } from './organizations.schema';
|
||||||
import { timestamps } from './shared.schema';
|
import { timestamps } from './shared.schema';
|
||||||
|
|
||||||
|
export const invoiceStatusValues = ['draft', 'sent', 'paid', 'void'] as const;
|
||||||
|
|
||||||
export const invoices = sqliteTable(
|
export const invoices = sqliteTable(
|
||||||
'invoices',
|
'invoices',
|
||||||
{
|
{
|
||||||
@@ -16,6 +18,10 @@ export const invoices = sqliteTable(
|
|||||||
.notNull()
|
.notNull()
|
||||||
.references(() => clients.id, { onDelete: 'restrict' }),
|
.references(() => clients.id, { onDelete: 'restrict' }),
|
||||||
invoiceNumber: text('invoice_number').notNull().unique(),
|
invoiceNumber: text('invoice_number').notNull().unique(),
|
||||||
|
status: text('status', { enum: invoiceStatusValues }).notNull().default('draft'),
|
||||||
|
sentAt: integer('sent_at', { mode: 'timestamp_ms' }),
|
||||||
|
paidAt: integer('paid_at', { mode: 'timestamp_ms' }),
|
||||||
|
voidedAt: integer('voided_at', { mode: 'timestamp_ms' }),
|
||||||
issueDate: text('issue_date').notNull(),
|
issueDate: text('issue_date').notNull(),
|
||||||
dueDate: text('due_date').notNull(),
|
dueDate: text('due_date').notNull(),
|
||||||
subtotalGbp: real('subtotal_gbp').notNull().default(0),
|
subtotalGbp: real('subtotal_gbp').notNull().default(0),
|
||||||
|
|||||||
Reference in New Issue
Block a user