feat: [작업지시] 절곡 공정 단계를 BD 코드 종류에 따라 필터링
This commit is contained in:
@@ -34,6 +34,7 @@ import {
|
||||
SCREEN_PROCESS_STEPS,
|
||||
SLAT_PROCESS_STEPS,
|
||||
BENDING_PROCESS_STEPS,
|
||||
filterBendingSteps,
|
||||
type WorkOrder,
|
||||
type ProcessType,
|
||||
type ProcessStep,
|
||||
@@ -56,13 +57,15 @@ function ProcessStepPills({
|
||||
processType,
|
||||
currentStep,
|
||||
workSteps,
|
||||
itemCodes,
|
||||
}: {
|
||||
processType: ProcessType;
|
||||
currentStep: number;
|
||||
workSteps?: ProcessStep[];
|
||||
itemCodes?: string[];
|
||||
}) {
|
||||
// 동적 workSteps 우선 사용, 없으면 하드코딩 폴백
|
||||
const steps = workSteps && workSteps.length > 0
|
||||
let steps = workSteps && workSteps.length > 0
|
||||
? workSteps
|
||||
: processType === 'screen'
|
||||
? SCREEN_PROCESS_STEPS
|
||||
@@ -70,6 +73,11 @@ function ProcessStepPills({
|
||||
? SLAT_PROCESS_STEPS
|
||||
: BENDING_PROCESS_STEPS;
|
||||
|
||||
// 절곡 공정: BD 코드에 따라 필요한 단계만 필터링
|
||||
if (processType === 'bending' && itemCodes && itemCodes.length > 0) {
|
||||
steps = filterBendingSteps(itemCodes, BENDING_PROCESS_STEPS);
|
||||
}
|
||||
|
||||
if (steps.length === 0) {
|
||||
return <p className="text-gray-500">공정 단계가 설정되지 않았습니다.</p>;
|
||||
}
|
||||
@@ -495,6 +503,7 @@ export function WorkOrderDetail({ orderId }: WorkOrderDetailProps) {
|
||||
processType={order.processType}
|
||||
currentStep={order.currentStep}
|
||||
workSteps={order.workSteps}
|
||||
itemCodes={order.items?.map((i) => i.itemCode).filter(Boolean) as string[]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -95,6 +95,54 @@ export const BENDING_PROCESS_STEPS: { key: BendingProcessStep; label: string; or
|
||||
{ key: 'inspection', label: '검사', order: 4 },
|
||||
];
|
||||
|
||||
// BD 코드 종류코드 → 필요 작업단계 매핑
|
||||
export const BENDING_STEP_MAP: Record<string, BendingProcessStep[]> = {
|
||||
'R': ['guide_rail', 'inspection'], // 가이드레일-벽면
|
||||
'S': ['guide_rail', 'inspection'], // 가이드레일-측면
|
||||
'C': ['case', 'inspection'], // 케이스
|
||||
'B': ['bottom_finish', 'inspection'], // 하단마감재-스크린
|
||||
'T': ['bottom_finish', 'inspection'], // 하단마감재-철재
|
||||
'L': ['guide_rail', 'inspection'], // L-Bar
|
||||
'G': ['guide_rail', 'inspection'], // 연기차단재
|
||||
};
|
||||
|
||||
/**
|
||||
* BD 코드에서 종류코드 추출 (BD-{종류코드}{규격코드}-{길이코드})
|
||||
* 예: BD-RS-30 → 'R', BD-CF-35 → 'C'
|
||||
*/
|
||||
export function extractBendingTypeCode(itemCode: string): string | null {
|
||||
const match = itemCode.match(/^BD-([A-Z])/);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 작업지시 품목들의 BD 코드로 필요한 작업단계 필터링
|
||||
* 여러 품목이면 합집합(union), BD 코드 아닌 품목이면 전체 반환
|
||||
*/
|
||||
export function filterBendingSteps(
|
||||
itemCodes: string[],
|
||||
allSteps: typeof BENDING_PROCESS_STEPS
|
||||
): typeof BENDING_PROCESS_STEPS {
|
||||
if (!itemCodes.length) return allSteps;
|
||||
|
||||
const neededKeys = new Set<string>();
|
||||
let hasNonBdItem = false;
|
||||
|
||||
for (const code of itemCodes) {
|
||||
const typeCode = extractBendingTypeCode(code);
|
||||
if (typeCode && BENDING_STEP_MAP[typeCode]) {
|
||||
BENDING_STEP_MAP[typeCode].forEach((k) => neededKeys.add(k));
|
||||
} else {
|
||||
hasNonBdItem = true;
|
||||
}
|
||||
}
|
||||
|
||||
// BD 코드가 아닌 품목이 있거나 매핑 결과가 없으면 전체 반환
|
||||
if (hasNonBdItem || neededKeys.size === 0) return allSteps;
|
||||
|
||||
return allSteps.filter((step) => neededKeys.has(step.key));
|
||||
}
|
||||
|
||||
// 품목 상태
|
||||
export type ItemStatus = 'waiting' | 'in_progress' | 'completed';
|
||||
|
||||
@@ -109,6 +157,7 @@ export interface WorkOrderItem {
|
||||
id: string;
|
||||
no: number;
|
||||
status: ItemStatus;
|
||||
itemCode: string;
|
||||
productName: string;
|
||||
floorCode: string; // 층/부호
|
||||
specification: string; // 규격
|
||||
@@ -255,6 +304,7 @@ export interface WorkOrderItemApi {
|
||||
id: number;
|
||||
work_order_id: number;
|
||||
item_id: number | null;
|
||||
item?: { id: number; code: string } | null;
|
||||
item_name: string;
|
||||
specification: string | null;
|
||||
quantity: number;
|
||||
@@ -471,6 +521,7 @@ export function transformApiToFrontend(api: WorkOrderApi): WorkOrder {
|
||||
id: String(item.id),
|
||||
no: idx + 1,
|
||||
status: (item.status as ItemStatus) || 'waiting',
|
||||
itemCode: item.item?.code || '',
|
||||
productName: item.item_name,
|
||||
floorCode: [item.source_order_item?.floor_code, item.source_order_item?.symbol_code].filter(Boolean).join('/') || '-',
|
||||
specification: item.specification || '-',
|
||||
|
||||
Reference in New Issue
Block a user