feat: 견적 V2 품목 검색 API 연동 및 수동 품목 관리 개선
- ItemSearchModal: API 프록시 라우트 연동, 검색 유효성 검사 (영문/한글 1자 이상) - items.ts: HttpOnly 쿠키 인증을 위한 프록시 라우트 사용 - LocationDetailPanel: 수동 품목 추가 시 subtotals/grouped_items 동시 업데이트 - QuoteRegistrationV2: 견적 산출 시 수동 추가 품목(is_manual) 보존 - 상세별 합계에서 수동 추가 품목이 카테고리별로 표시되도록 개선
This commit is contained in:
@@ -618,7 +618,91 @@ export function LocationDetailPanel({
|
||||
open={itemSearchOpen}
|
||||
onOpenChange={setItemSearchOpen}
|
||||
onSelectItem={(item) => {
|
||||
console.log(`[테스트] 품목 선택: ${item.code} - ${item.name} (탭: ${activeTab})`);
|
||||
if (!location) return;
|
||||
|
||||
// 탭 → process_group_key 매핑
|
||||
const tabToProcessGroup: Record<string, string> = {
|
||||
body: "screen",
|
||||
"guide-rail": "bending",
|
||||
case: "steel",
|
||||
bottom: "electric",
|
||||
motor: "motor",
|
||||
accessory: "accessory",
|
||||
};
|
||||
|
||||
const processGroupKey = tabToProcessGroup[activeTab] || "screen";
|
||||
const processGroupLabel = DETAIL_TABS.find((t) => t.value === activeTab)?.label || activeTab;
|
||||
|
||||
// 새 품목 생성 (수동 추가 플래그 포함)
|
||||
const newItem: BomCalculationResultItem & { process_group_key?: string; is_manual?: boolean } = {
|
||||
item_code: item.code,
|
||||
item_name: item.name,
|
||||
specification: item.specification || "",
|
||||
unit: "EA",
|
||||
quantity: 1,
|
||||
unit_price: 0,
|
||||
total_price: 0,
|
||||
process_group: processGroupLabel,
|
||||
process_group_key: processGroupKey,
|
||||
is_manual: true, // 수동 추가 품목 표시
|
||||
};
|
||||
|
||||
// 기존 bomResult 가져오기
|
||||
const existingBomResult = location.bomResult || {
|
||||
finished_goods: { code: location.productCode || "", name: location.productName || "" },
|
||||
subtotals: {},
|
||||
grouped_items: {},
|
||||
grand_total: 0,
|
||||
items: [],
|
||||
};
|
||||
|
||||
// 기존 items에 새 아이템 추가
|
||||
const existingItems = existingBomResult.items || [];
|
||||
const updatedItems = [...existingItems, newItem];
|
||||
|
||||
// subtotals 업데이트 (해당 카테고리의 count, subtotal 증가)
|
||||
const existingSubtotals = existingBomResult.subtotals || {};
|
||||
const categorySubtotal = existingSubtotals[processGroupKey] || {
|
||||
name: processGroupLabel,
|
||||
count: 0,
|
||||
subtotal: 0,
|
||||
};
|
||||
const updatedSubtotals = {
|
||||
...existingSubtotals,
|
||||
[processGroupKey]: {
|
||||
...categorySubtotal,
|
||||
name: processGroupLabel,
|
||||
count: (categorySubtotal.count || 0) + 1,
|
||||
subtotal: (categorySubtotal.subtotal || 0) + (newItem.total_price || 0),
|
||||
},
|
||||
};
|
||||
|
||||
// grouped_items 업데이트 (해당 카테고리의 items 배열에 추가)
|
||||
const existingGroupedItems = existingBomResult.grouped_items || {};
|
||||
const categoryGroupedItems = existingGroupedItems[processGroupKey] || { items: [] };
|
||||
const updatedGroupedItems = {
|
||||
...existingGroupedItems,
|
||||
[processGroupKey]: {
|
||||
...categoryGroupedItems,
|
||||
items: [...(categoryGroupedItems.items || []), newItem],
|
||||
},
|
||||
};
|
||||
|
||||
// grand_total 업데이트
|
||||
const updatedGrandTotal = (existingBomResult.grand_total || 0) + (newItem.total_price || 0);
|
||||
|
||||
const updatedBomResult = {
|
||||
...existingBomResult,
|
||||
items: updatedItems,
|
||||
subtotals: updatedSubtotals,
|
||||
grouped_items: updatedGroupedItems,
|
||||
grand_total: updatedGrandTotal,
|
||||
};
|
||||
|
||||
// location 업데이트
|
||||
onUpdateLocation(location.id, { bomResult: updatedBomResult });
|
||||
|
||||
console.log(`[품목 추가] ${item.code} - ${item.name} → ${processGroupLabel} (${processGroupKey})`);
|
||||
}}
|
||||
tabLabel={DETAIL_TABS.find((t) => t.value === activeTab)?.label}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user