feat: Add BOM version initialization feature and enhance version handling

- Implemented a new endpoint to initialize BOM versions, automatically creating the first version and updating related details.
- Enhanced the BOM service to include logic for version name handling and duplication checks during version creation.
- Updated the BOM controller to support the new initialization functionality, improving BOM management capabilities.
- Improved the BOM version modal to allow users to specify version names during creation, enhancing user experience and flexibility.
This commit is contained in:
DDD1542
2026-02-26 20:48:56 +09:00
parent afc66a4971
commit 385a10e2e7
7 changed files with 321 additions and 82 deletions

View File

@@ -138,6 +138,23 @@ export function BomTreeComponent({
const showHistory = features.showHistory !== false;
const showVersion = features.showVersion !== false;
// 카테고리 라벨 캐시 (process_type 등)
const [categoryLabels, setCategoryLabels] = useState<Record<string, Record<string, string>>>({});
useEffect(() => {
const loadLabels = async () => {
try {
const res = await apiClient.get(`/table-categories/${detailTable}/process_type/values`);
const vals = res.data?.data || [];
if (vals.length > 0) {
const map: Record<string, string> = {};
vals.forEach((v: any) => { map[v.value_code] = v.value_label; });
setCategoryLabels((prev) => ({ ...prev, process_type: map }));
}
} catch { /* 무시 */ }
};
loadLabels();
}, [detailTable]);
// ─── 데이터 로드 ───
// BOM 헤더 데이터로 가상 0레벨 루트 노드 생성
@@ -168,7 +185,18 @@ export function BomTreeComponent({
setLoading(true);
try {
const searchFilter: Record<string, any> = { [foreignKey]: bomId };
const versionId = headerData?.current_version_id;
let versionId = headerData?.current_version_id;
// version_id가 없으면 서버에서 자동 초기화
if (!versionId) {
try {
const initRes = await apiClient.post(`/bom/${bomId}/initialize-version`);
if (initRes.data?.success && initRes.data.data?.versionId) {
versionId = initRes.data.data.versionId;
}
} catch { /* 무시 */ }
}
if (versionId) {
searchFilter.version_id = versionId;
}
@@ -461,6 +489,11 @@ export function BomTreeComponent({
return <span className="font-medium text-gray-900">{value || "-"}</span>;
}
if (col.key === "status") {
const statusMap: Record<string, string> = { active: "사용", inactive: "미사용", developing: "개발중" };
return <span>{statusMap[String(value)] || value || "-"}</span>;
}
if (col.key === "quantity" || col.key === "base_qty") {
return (
<span className="font-medium tabular-nums text-gray-800">
@@ -469,6 +502,11 @@ export function BomTreeComponent({
);
}
if (col.key === "process_type" && value) {
const label = categoryLabels.process_type?.[String(value)] || String(value);
return <span>{label}</span>;
}
if (col.key === "loss_rate") {
const num = Number(value);
if (!num) return <span className="text-gray-300">-</span>;