GWM : items master joined
This commit is contained in:
parent
28d38bc695
commit
382111f7b9
@ -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]
|
||||||
|
|||||||
@ -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) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user