Files
trackgo-be/src/database/sales-invoices-table.ts
T
shancheas 34d4f2c120 Add products and sales management modules with database schema and validation
- Introduced `ProductsModule` to manage product data, including read and write controllers.
- Created database migrations for the `products`, `sales_requests`, `sales_orders`, `sales_invoices`, and related tables, including constraints and unique indexes.
- Implemented validation for product fields such as code, name, unit, and brand with corresponding utility functions.
- Developed service and repository layers for handling product and sales data operations.
- Added unit tests for the products and sales services, repositories, and controllers to ensure functionality and correctness.
- Updated application module to include the new `ProductsModule` and related sales modules for better organization.
2026-08-25 09:54:16 +07:00

72 lines
2.6 KiB
TypeScript

import {
bigint,
index,
numeric,
pgTable,
text,
uniqueIndex,
uuid,
varchar,
} from 'drizzle-orm/pg-core';
import { branches } from './branches-table';
import { customers } from './customers-table';
import { employees } from './employees-table';
import { packingSlips } from './packing-slips-table';
import { products } from './products-table';
import { primaryEntityColumns } from './primary-entity-columns';
import { salesOrders } from './sales-orders-table';
import { divisions, users } from './schema';
export const salesInvoices = pgTable(
'sales_invoices',
{
id: uuid('id').defaultRandom().notNull().primaryKey(),
code: varchar('code', { length: 32 }).notNull(),
date: bigint('date', { mode: 'number' }).notNull(),
salesPersonId: uuid('sales_person_id')
.notNull()
.references(() => employees.id, { onDelete: 'restrict' }),
branchId: uuid('branch_id')
.notNull()
.references(() => branches.id, { onDelete: 'restrict' }),
divisionId: uuid('division_id')
.notNull()
.references(() => divisions.id, { onDelete: 'restrict' }),
customerId: uuid('customer_id')
.notNull()
.references(() => customers.id, { onDelete: 'restrict' }),
salesOrderId: uuid('sales_order_id').references(() => salesOrders.id, {
onDelete: 'restrict',
}),
salesOrderCode: varchar('sales_order_code', { length: 32 }),
packingSlipId: uuid('packing_slip_id').references(() => packingSlips.id, {
onDelete: 'restrict',
}),
packingSlipCode: varchar('packing_slip_code', { length: 32 }),
balance: numeric('balance', { precision: 18, scale: 4 }).notNull(),
notes: text('notes'),
...primaryEntityColumns(users),
},
(t) => [uniqueIndex('sales_invoices_code_unique').on(t.code)],
);
export const salesInvoiceProducts = pgTable(
'sales_invoice_products',
{
id: uuid('id').defaultRandom().notNull().primaryKey(),
salesInvoiceId: uuid('sales_invoice_id')
.notNull()
.references(() => salesInvoices.id, { onDelete: 'cascade' }),
productId: uuid('product_id')
.notNull()
.references(() => products.id, { onDelete: 'restrict' }),
quantity: numeric('quantity', { precision: 18, scale: 4 }).notNull(),
price: numeric('price', { precision: 18, scale: 4 }).notNull(),
},
(t) => [index('sales_invoice_products_invoice_id_idx').on(t.salesInvoiceId)],
);
export type SalesInvoiceRow = typeof salesInvoices.$inferSelect;
export type NewSalesInvoiceRow = typeof salesInvoices.$inferInsert;
export type SalesInvoiceProductRow = typeof salesInvoiceProducts.$inferSelect;