GWM : items master joined

This commit is contained in:
Gowtham M 2026-07-10 15:32:28 +05:30
parent 28d38bc695
commit 382111f7b9
2 changed files with 104 additions and 9 deletions

View File

@ -154,7 +154,52 @@ components:
id: { type: string, example: '1' } id: { type: string, example: '1' }
item_code: { type: string, example: 'ITM-00006', description: Auto-generated on create via ITEM document series; read-only } item_code: { type: string, example: 'ITM-00006', description: Auto-generated on create via ITEM document series; read-only }
item_name: { type: string, example: 'LABSA' } item_name: { type: string, example: 'LABSA' }
hsn_code_id: { type: integer, nullable: true, example: 1 } item_category_id: { type: string, example: '38' }
item_subcategory_id: { type: string, nullable: true, example: '30' }
hsn_code_id: { type: string, nullable: true, example: '1' }
item_category:
type: object
nullable: true
properties:
id: { type: string, example: '38' }
code: { type: string, example: 'RAW' }
name: { type: string, example: 'Raw Material' }
item_subcategory:
type: object
nullable: true
properties:
id: { type: string, example: '30' }
code: { type: string, example: 'CHEM' }
name: { type: string, example: 'Chemicals' }
item_category_id: { type: string, example: '38' }
hsn_code:
type: object
nullable: true
properties:
id: { type: string, example: '1' }
code: { type: string, example: '34029099' }
description: { type: string, example: 'Organic surface-active agents' }
uom:
type: object
nullable: true
properties:
id: { type: string }
code: { type: string }
name: { type: string }
gst_rate:
type: object
nullable: true
properties:
id: { type: string }
rate_pct: { type: number }
description: { type: string, nullable: true }
brand:
type: object
nullable: true
properties:
id: { type: string }
code: { type: string }
name: { type: string }
BrandsCreateBody: BrandsCreateBody:
type: object type: object
required: [code, name, brand_type] required: [code, name, brand_type]

View File

@ -15,6 +15,50 @@ const SOFT_DELETE_TABLES = new Set([
'brands', 'brands',
]); ]);
const itemInclude = {
item_categories: { select: { id: true, code: true, name: true } },
item_subcategories: { select: { id: true, code: true, name: true, item_category_id: true } },
hsn_codes: { select: { id: true, code: true, description: true } },
uom: { select: { id: true, code: true, name: true } },
gst_rates: { select: { id: true, rate_pct: true, description: true } },
brands: { select: { id: true, code: true, name: true } },
};
const toDecimal = (value) =>
value !== null && value !== undefined ? Number(value) : value;
const sanitizeItem = (row) => {
if (!row) return null;
const {
item_categories,
item_subcategories,
hsn_codes,
uom,
gst_rates,
brands,
...rest
} = row;
return {
...rest,
min_order_qty: toDecimal(rest.min_order_qty),
reorder_level: toDecimal(rest.reorder_level),
item_category: item_categories || null,
item_subcategory: item_subcategories || null,
hsn_code: hsn_codes || null,
uom: uom || null,
gst_rate: gst_rates
? { ...gst_rates, rate_pct: toDecimal(gst_rates.rate_pct) }
: null,
brand: brands || null,
item_categories: undefined,
item_subcategories: undefined,
hsn_codes: undefined,
gst_rates: undefined,
brands: undefined,
};
};
const normalizeString = (value) => { const normalizeString = (value) => {
if (value === undefined || value === null) return value; if (value === undefined || value === null) return value;
const str = String(value).trim(); const str = String(value).trim();
@ -138,19 +182,22 @@ const createItems = async (payload, userId, requestId) => {
if (data.is_asset_item === undefined) data.is_asset_item = false; if (data.is_asset_item === undefined) data.is_asset_item = false;
if (data.is_active === undefined) data.is_active = true; if (data.is_active === undefined) data.is_active = true;
const created = await prisma.items.create({ data }); const created = await prisma.items.create({
data,
include: itemInclude,
});
await auditLog({ await auditLog({
tableName: 'items', tableName: 'items',
recordId: created.id, recordId: created.id,
action: 'CREATE', action: 'CREATE',
oldValue: null, oldValue: null,
newValue: created, newValue: sanitizeItem(created),
userId, userId,
requestId, requestId,
}); });
return created; return sanitizeItem(created);
}; };
const listItems = async (query) => { const listItems = async (query) => {
@ -169,9 +216,10 @@ const listItems = async (query) => {
: {}), : {}),
}; };
const [data, total] = await Promise.all([ const [rows, total] = await Promise.all([
prisma.items.findMany({ prisma.items.findMany({
where, where,
include: itemInclude,
orderBy: { created_at: 'desc' }, orderBy: { created_at: 'desc' },
skip, skip,
take: limit, take: limit,
@ -179,15 +227,16 @@ const listItems = async (query) => {
prisma.items.count({ where }), prisma.items.count({ where }),
]); ]);
return { data, meta: { page, limit, total } }; return { data: rows.map(sanitizeItem), meta: { page, limit, total } };
}; };
const getItemsById = async (id) => { const getItemsById = async (id) => {
const one = await prisma.items.findFirst({ const one = await prisma.items.findFirst({
where: { id: BigInt(id), deleted_at: null }, where: { id: BigInt(id), deleted_at: null },
include: itemInclude,
}); });
if (!one) throw new ApiError(404, 'items not found'); if (!one) throw new ApiError(404, 'items not found');
return one; return sanitizeItem(one);
}; };
const updateItems = async (id, payload, userId, requestId) => { const updateItems = async (id, payload, userId, requestId) => {
@ -204,6 +253,7 @@ const updateItems = async (id, payload, userId, requestId) => {
const updated = await prisma.items.update({ const updated = await prisma.items.update({
where: { id: BigInt(id) }, where: { id: BigInt(id) },
data, data,
include: itemInclude,
}); });
await auditLog({ await auditLog({
@ -211,12 +261,12 @@ const updateItems = async (id, payload, userId, requestId) => {
recordId: id, recordId: id,
action: 'UPDATE', action: 'UPDATE',
oldValue: existing, oldValue: existing,
newValue: updated, newValue: sanitizeItem(updated),
userId, userId,
requestId, requestId,
}); });
return updated; return sanitizeItem(updated);
}; };
const deleteItems = async (id, userId, requestId) => { const deleteItems = async (id, userId, requestId) => {