- 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.
72 lines
2.6 KiB
TypeScript
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;
|