Fix code review items: atomic qty increment, unit updatedAt, suppliers/all endpoint, SKU unique index
This commit is contained in:
@@ -36,6 +36,7 @@ export const categoryMutations = {
|
|||||||
|
|
||||||
export const supplierKeys = {
|
export const supplierKeys = {
|
||||||
all: ['suppliers'] as const,
|
all: ['suppliers'] as const,
|
||||||
|
allSuppliers: ['suppliers', 'all'] as const,
|
||||||
list: (params: PaginationInput) => [...supplierKeys.all, 'list', params] as const,
|
list: (params: PaginationInput) => [...supplierKeys.all, 'list', params] as const,
|
||||||
detail: (id: string) => [...supplierKeys.all, 'detail', id] as const,
|
detail: (id: string) => [...supplierKeys.all, 'detail', id] as const,
|
||||||
}
|
}
|
||||||
@@ -47,6 +48,13 @@ export function supplierListOptions(params: PaginationInput) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function supplierAllOptions() {
|
||||||
|
return queryOptions({
|
||||||
|
queryKey: supplierKeys.allSuppliers,
|
||||||
|
queryFn: () => api.get<{ data: Supplier[] }>('/v1/suppliers/all'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const supplierMutations = {
|
export const supplierMutations = {
|
||||||
create: (data: Record<string, unknown>) => api.post<Supplier>('/v1/suppliers', data),
|
create: (data: Record<string, unknown>) => api.post<Supplier>('/v1/suppliers', data),
|
||||||
update: (id: string, data: Record<string, unknown>) => api.patch<Supplier>(`/v1/suppliers/${id}`, data),
|
update: (id: string, data: Record<string, unknown>) => api.patch<Supplier>(`/v1/suppliers/${id}`, data),
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- Add unique index on products.sku (null values are excluded from uniqueness)
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS products_sku_unique ON product (sku) WHERE sku IS NOT NULL;
|
||||||
@@ -73,6 +73,11 @@ export const inventoryRoutes: FastifyPluginAsync = async (app) => {
|
|||||||
return reply.send(result)
|
return reply.send(result)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.get('/suppliers/all', { preHandler: [app.authenticate, app.requirePermission('inventory.view')] }, async (request, reply) => {
|
||||||
|
const rows = await SupplierService.listAll(app.db)
|
||||||
|
return reply.send({ data: rows })
|
||||||
|
})
|
||||||
|
|
||||||
app.get('/suppliers/:id', { preHandler: [app.authenticate, app.requirePermission('inventory.view')] }, async (request, reply) => {
|
app.get('/suppliers/:id', { preHandler: [app.authenticate, app.requirePermission('inventory.view')] }, async (request, reply) => {
|
||||||
const { id } = request.params as { id: string }
|
const { id } = request.params as { id: string }
|
||||||
const supplier = await SupplierService.getById(app.db, id)
|
const supplier = await SupplierService.getById(app.db, id)
|
||||||
|
|||||||
@@ -131,6 +131,14 @@ export const SupplierService = {
|
|||||||
return paginatedResponse(data, total, params.page, params.limit)
|
return paginatedResponse(data, total, params.page, params.limit)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async listAll(db: PostgresJsDatabase<any>) {
|
||||||
|
return db
|
||||||
|
.select()
|
||||||
|
.from(suppliers)
|
||||||
|
.where(eq(suppliers.isActive, true))
|
||||||
|
.orderBy(suppliers.name)
|
||||||
|
},
|
||||||
|
|
||||||
async update(db: PostgresJsDatabase<any>, id: string, input: SupplierUpdateInput) {
|
async update(db: PostgresJsDatabase<any>, id: string, input: SupplierUpdateInput) {
|
||||||
const [supplier] = await db
|
const [supplier] = await db
|
||||||
.update(suppliers)
|
.update(suppliers)
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ export const InventoryUnitService = {
|
|||||||
if (!valid) throw new ValidationError(`Invalid status: "${input.status}"`)
|
if (!valid) throw new ValidationError(`Invalid status: "${input.status}"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updates: Record<string, unknown> = { ...input }
|
const updates: Record<string, unknown> = { ...input, updatedAt: new Date() }
|
||||||
if (input.purchaseCost !== undefined) updates.purchaseCost = input.purchaseCost.toString()
|
if (input.purchaseCost !== undefined) updates.purchaseCost = input.purchaseCost.toString()
|
||||||
|
|
||||||
const [unit] = await db
|
const [unit] = await db
|
||||||
@@ -317,14 +317,11 @@ export const StockReceiptService = {
|
|||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
|
|
||||||
// For non-serialized products, increment qty_on_hand
|
// For non-serialized products, increment qty_on_hand atomically
|
||||||
const [product] = await db.select().from(products).where(eq(products.id, productId)).limit(1)
|
await db
|
||||||
if (product && !product.isSerialized) {
|
.update(products)
|
||||||
await db
|
.set({ qtyOnHand: sql`${products.qtyOnHand} + ${input.qty}`, updatedAt: new Date() })
|
||||||
.update(products)
|
.where(and(eq(products.id, productId), eq(products.isSerialized, false)))
|
||||||
.set({ qtyOnHand: product.qtyOnHand + input.qty, updatedAt: new Date() })
|
|
||||||
.where(eq(products.id, productId))
|
|
||||||
}
|
|
||||||
|
|
||||||
return receipt
|
return receipt
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user