fix: [quote] QA 견적 관련 버그 수정

- BOM 탭 순서 통일 (주자재→모터→제어기→절곡품→부자재→검사비→기타)
- 스크린+스틸 혼합 등록 차단 밸리데이션
- 저장/확정 분리 (저장=draft, 견적확정=finalized)
- 수동 품목 추가 시 기타 탭 병합 + 탭 스크롤
- 필터 셀렉트박스 라벨 접두어 추가
- 수식 모달 하단 여백, tabLabel 중복 제거
This commit is contained in:
2026-03-17 13:51:18 +09:00
parent 9b6f4c6684
commit 704ea3c02d
9 changed files with 127 additions and 44 deletions

View File

@@ -38,6 +38,7 @@ import { ItemSearchModal } from "./ItemSearchModal";
import type { LocationItem } from "./QuoteRegistration";
import type { FinishedGoods } from "./actions";
import type { BomCalculationResultItem } from "./types";
import { BOM_CATEGORY_ORDER, BOM_CATEGORY_LABELS } from "./types";
// 납품길이 옵션
const DELIVERY_LENGTH_OPTIONS = [
@@ -161,16 +162,34 @@ export function LocationDetailPanel({
const subtotals = location.bomResult.subtotals;
const tabs: TabDefinition[] = [];
const remaining = new Set(Object.keys(subtotals));
Object.entries(subtotals).forEach(([key, value]) => {
// 고정 순서대로 탭 추가
for (const key of BOM_CATEGORY_ORDER) {
if (remaining.has(key)) {
const value = subtotals[key];
if (typeof value === "object" && value !== null) {
const obj = value as { name?: string };
tabs.push({
value: key,
label: BOM_CATEGORY_LABELS[key] || obj.name || key,
});
}
remaining.delete(key);
}
}
// 미정의 카테고리 뒤에 추가
for (const key of remaining) {
const value = subtotals[key];
if (typeof value === "object" && value !== null) {
const obj = value as { name?: string };
tabs.push({
value: key,
label: obj.name || key,
label: BOM_CATEGORY_LABELS[key] || obj.name || key,
});
}
});
}
// 기타 탭 추가
tabs.push({ value: "etc", label: "기타" });
@@ -751,6 +770,8 @@ export function LocationDetailPanel({
<ItemSearchModal
open={itemSearchOpen}
onOpenChange={setItemSearchOpen}
tabLabel={detailTabs.find((t) => t.value === activeTab)?.label}
bomCategory={activeTab !== "etc" ? activeTab : undefined}
onSelectItem={async (item) => {
if (!location) return;
@@ -834,7 +855,6 @@ export function LocationDetailPanel({
totalPrice: updatedGrandTotal * location.quantity,
});
}}
tabLabel={detailTabs.find((t) => t.value === activeTab)?.label}
/>
</div>
);