7a7f4f03b5
PR-B1 본 편집/저장 (운영 saveMbom.do 1:1)
· 매퍼 7종 1:1 (insert/updateMbomHeader, insert/updateMbomDetail,
deleteMbomDetailByObjid, insertMbomHistory, updateProjectMbomStatus)
· 신규 CREATE: createObjId + generateMbomNo(M-{partNo}-YYMMDD-NN) +
child_objid 재매핑 + detail 일괄 insert + history(CREATE) + project_mgmt.mbom_status='Y'
· 수정 UPDATE: 기존 mbom_header.objid UPSERT(insert/update/delete) + history(UPDATE)
· POST /api/production/mbom/save (BEGIN/COMMIT/ROLLBACK 트랜잭션)
· MbomDetailDialog: '본 편집' 토글 + 13개 셀 인라인 편집 + 저장/취소 가드
M-BOM 컬럼 폴더 아이콘
· production/mbom/page.tsx: mbom_status 컬럼 → mbom_has(0/1) renderType=folder
· onClick → MbomDetailDialog 오픈 (행 더블클릭도 그대로 유지)
· 운영판 wace 견적/partMng 폴더 아이콘 패턴 1:1
DataGrid 서버 페이지네이션
· props 신설: serverPaging/serverPage/serverPageSize/serverTotalItems
+ onPageChange/onPageSizeChange
· 5메뉴 적용: production/mbom, development/change-list/ebom-regist/part-search/part-regist
· pageSizeOptions=[10,15,20,50,100,200,500] 통일
· 클라이언트 모드 하위호환 유지
bigint=varchar fix (mbom 트리 SQL 4종)
· ATTACH_FILE_INFO 서브쿼리: P.OBJID(bigint) = F.TARGET_OBJID(varchar) → P.OBJID::varchar 캐스트
· EBOM_WORKING_TREE_SQL INNER JOIN: P.OBJID = COALESCE(V.LAST_PART_OBJID,V.PART_NO) → ::varchar 캐스트
· 사용자 보고: 폴더 클릭 시 'operator does not exist: bigint = character varying' 토스트
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
3.1 KiB
TypeScript
74 lines
3.1 KiB
TypeScript
// ============================================================
|
||
// 생산관리 > M-BOM 관리 — wace productionplanning.xml 1:1 이식.
|
||
// 라우트:
|
||
// GET /api/production/mbom/list 그리드 (PROJECT_MGMT × CONTRACT_ITEM 펼침)
|
||
// GET /api/production/mbom/detail/:objid 단건 상세 (mBomHeaderPopup.do 1:1)
|
||
// GET /api/production/mbom/tree/:objid read-only 트리 4분기 자동 판별 (mBomPopupLeft.do 1:1)
|
||
// ============================================================
|
||
|
||
import { Response } from "express";
|
||
import { AuthenticatedRequest } from "../types/auth";
|
||
import * as svc from "../services/mbomService";
|
||
import { logger } from "../utils/logger";
|
||
|
||
function parseFilter(q: Record<string, any>): svc.MbomListFilter {
|
||
const filter: svc.MbomListFilter = { ...q };
|
||
if (q.page) filter.page = Number(q.page);
|
||
if (q.page_size) filter.page_size = Number(q.page_size);
|
||
return filter;
|
||
}
|
||
|
||
export async function getList(req: AuthenticatedRequest, res: Response) {
|
||
try {
|
||
const data = await svc.list(parseFilter(req.query as Record<string, any>));
|
||
return res.json({ success: true, data });
|
||
} catch (e: any) {
|
||
logger.error("M-BOM 관리 목록 실패", { error: e.message });
|
||
return res.status(500).json({ success: false, message: e.message });
|
||
}
|
||
}
|
||
|
||
export async function getDetail(req: AuthenticatedRequest, res: Response) {
|
||
try {
|
||
const objid = String(req.params.objid ?? "").trim();
|
||
if (!objid) return res.status(400).json({ success: false, message: "objid 누락" });
|
||
const data = await svc.getDetail(objid);
|
||
if (!data) return res.status(404).json({ success: false, message: "프로젝트를 찾을 수 없습니다" });
|
||
return res.json({ success: true, data });
|
||
} catch (e: any) {
|
||
logger.error("M-BOM 단건 상세 실패", { error: e.message });
|
||
return res.status(500).json({ success: false, message: e.message });
|
||
}
|
||
}
|
||
|
||
export async function getTree(req: AuthenticatedRequest, res: Response) {
|
||
try {
|
||
const objid = String(req.params.objid ?? "").trim();
|
||
if (!objid) return res.status(400).json({ success: false, message: "objid 누락" });
|
||
const data = await svc.getTree(objid);
|
||
return res.json({ success: true, data });
|
||
} catch (e: any) {
|
||
logger.error("M-BOM 트리 조회 실패", { error: e.message });
|
||
return res.status(500).json({ success: false, message: e.message });
|
||
}
|
||
}
|
||
|
||
// PR-B1 — 본 편집 저장 (운영 saveMbom.do 1:1)
|
||
export async function save(req: AuthenticatedRequest, res: Response) {
|
||
try {
|
||
const payload = req.body as svc.MbomSavePayload;
|
||
if (!payload?.project_obj_id) {
|
||
return res.status(400).json({ success: false, message: "project_obj_id 누락" });
|
||
}
|
||
if (!Array.isArray(payload.rows)) {
|
||
return res.status(400).json({ success: false, message: "rows 누락" });
|
||
}
|
||
const userId = req.user?.userId ?? "system";
|
||
const data = await svc.save(payload, userId);
|
||
return res.json({ success: true, data });
|
||
} catch (e: any) {
|
||
logger.error("M-BOM 저장 실패", { error: e.message });
|
||
return res.status(500).json({ success: false, message: e.message });
|
||
}
|
||
}
|