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.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user