Enhance Outbound and Excel Service Functionality

- Added `inventory_unit` to the item selection query in the outbound controller to improve data retrieval.
- Updated the multi-table Excel service to exclude overlapping headers between parent and child levels, ensuring accurate data insertion.
- Introduced new category combobox components for better user interaction in the supplied item page.
- Enhanced the inbound-outbound page to correctly map user IDs, including super admin handling for user information retrieval.

(TASK: ERP-XXX)
This commit is contained in:
kjs
2026-05-20 15:24:19 +09:00
parent b2c96e616a
commit c5364e1d20
8 changed files with 2189 additions and 10 deletions

View File

@@ -740,7 +740,7 @@ export async function getItems(req: AuthenticatedRequest, res: Response) {
const pool = getPool();
const result = await pool.query(
`SELECT
id, item_number, item_name, size AS spec, material, unit,
id, item_number, item_name, size AS spec, material, unit, inventory_unit,
COALESCE(width::text, '') AS width,
COALESCE(height::text, '') AS height,
COALESCE(thickness::text, '') AS thickness,

View File

@@ -156,6 +156,17 @@ class MultiTableExcelService {
() => new Map()
);
// 자식 단계 빈 데이터 판정에 부모와 겹치는 헤더는 제외해야 한다.
// (예: customer_mng/customer_item_mapping 둘 다 '상태','비고' 헤더를 가지면
// 부모용으로 입력한 값이 자식에도 잘못 들어가 자식 INSERT가 시도된다.)
const ownHeadersPerLevel: Set<string>[] = activeLevels.map((lv, i) => {
const headers = new Set(lv.columns.map((c) => c.excelHeader));
for (let j = 0; j < i; j++) {
for (const c of activeLevels[j].columns) headers.delete(c.excelHeader);
}
return headers;
});
for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
const row = rows[rowIdx];
@@ -178,8 +189,19 @@ class MultiTableExcelService {
}
}
const hasAnyData = Object.keys(levelData).length > 0;
if (!hasAnyData && lvlIdx > 0) {
// 자식 레벨은 '부모와 겹치지 않는 고유 헤더'에 값이 있을 때만 INSERT 진행
const ownHeaders = ownHeadersPerLevel[lvlIdx];
const hasOwnData =
lvlIdx === 0
? Object.keys(levelData).length > 0
: level.columns.some(
(c) =>
ownHeaders.has(c.excelHeader) &&
levelData[c.dbColumn] !== undefined &&
levelData[c.dbColumn] !== ""
);
if (!hasOwnData && lvlIdx > 0) {
break;
}