feat: SPECIAL/UNCLASSIFIED 카테고리 추가 및 WELD GAP 자동 제외
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
주요 변경사항: - SPECIAL 카테고리 추가: 특수 제작 품목 관리 (Type, Drawing, Detail1-4) - UNCLASSIFIED 카테고리 추가: 미분류 자재 원본 그대로 표시 - UNKNOWN → UNCLASSIFIED 통합: 기존 UNKNOWN 카테고리 제거 - WELD GAP 자동 제외: BOM 업로드 시 WELD GAP 항목 자동 필터링 백엔드: - integrated_classifier.py: UNKNOWN → UNCLASSIFIED 변경, SPECIAL 우선순위 분류 - files.py: parse_dataframe에서 WELD GAP 필터링, UNKNOWN 참조 제거 - exclude_classifier.py: WELD GAP 제외 로직 유지 프론트엔드: - SpecialMaterialsView.jsx: 특수 제작 품목 관리 컴포넌트 - UnclassifiedMaterialsView.jsx: 미분류 자재 관리 컴포넌트 - BOMManagementPage.jsx: 새 카테고리 추가 및 라우팅 - excelExport.js: SPECIAL/UNCLASSIFIED 엑셀 내보내기 지원 - 모든 UNKNOWN 참조를 UNCLASSIFIED로 변경 기능 개선: - 저장 기능: 모든 카테고리에 추가요청사항 저장/편집 기능 - P열 납기일 규칙: 모든 카테고리 엑셀 내보내기 통일 - UI 개선: Detail1-4 컬럼명으로 혼동 방지 - 데이터 정리: 모든 프로젝트 및 BOM 데이터 초기화
This commit is contained in:
@@ -8,7 +8,9 @@ import {
|
||||
ValveMaterialsView,
|
||||
GasketMaterialsView,
|
||||
BoltMaterialsView,
|
||||
SupportMaterialsView
|
||||
SupportMaterialsView,
|
||||
SpecialMaterialsView,
|
||||
UnclassifiedMaterialsView
|
||||
} from '../components/bom';
|
||||
import './BOMManagementPage.css';
|
||||
|
||||
@@ -52,7 +54,9 @@ const BOMManagementPage = ({
|
||||
{ key: 'VALVE', label: 'Valves', color: '#ef4444' },
|
||||
{ key: 'GASKET', label: 'Gaskets', color: '#8b5cf6' },
|
||||
{ key: 'BOLT', label: 'Bolts', color: '#6b7280' },
|
||||
{ key: 'SUPPORT', label: 'Supports', color: '#f97316' }
|
||||
{ key: 'SUPPORT', label: 'Supports', color: '#f97316' },
|
||||
{ key: 'SPECIAL', label: 'Special Items', color: '#ec4899' },
|
||||
{ key: 'UNCLASSIFIED', label: 'Unclassified', color: '#64748b' }
|
||||
];
|
||||
|
||||
// 자료 로드 함수들
|
||||
@@ -208,6 +212,10 @@ const BOMManagementPage = ({
|
||||
return <BoltMaterialsView {...commonProps} />;
|
||||
case 'SUPPORT':
|
||||
return <SupportMaterialsView {...commonProps} />;
|
||||
case 'SPECIAL':
|
||||
return <SpecialMaterialsView {...commonProps} />;
|
||||
case 'UNCLASSIFIED':
|
||||
return <UnclassifiedMaterialsView {...commonProps} />;
|
||||
default:
|
||||
return <div>카테고리를 선택해주세요.</div>;
|
||||
}
|
||||
|
||||
@@ -874,7 +874,7 @@
|
||||
background: #d97706;
|
||||
}
|
||||
|
||||
/* UNKNOWN 전용 헤더 - 5개 컬럼 */
|
||||
/* UNCLASSIFIED 전용 헤더 - 5개 컬럼 */
|
||||
.detailed-grid-header.unknown-header {
|
||||
grid-template-columns: 5% 10% 1fr 20% 10%;
|
||||
|
||||
@@ -891,7 +891,7 @@
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* UNKNOWN 전용 행 - 5개 컬럼 */
|
||||
/* UNCLASSIFIED 전용 행 - 5개 컬럼 */
|
||||
.detailed-material-row.unknown-row {
|
||||
grid-template-columns: 5% 10% 1fr 20% 10%;
|
||||
|
||||
@@ -906,7 +906,7 @@
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* UNKNOWN 설명 셀 스타일 */
|
||||
/* UNCLASSIFIED 설명 셀 스타일 */
|
||||
.description-cell {
|
||||
overflow: visible;
|
||||
text-overflow: initial;
|
||||
|
||||
@@ -433,7 +433,7 @@ const NewMaterialsPage = ({
|
||||
const getCategoryCounts = () => {
|
||||
const counts = {};
|
||||
materials.forEach(material => {
|
||||
const category = material.classified_category || 'UNKNOWN';
|
||||
const category = material.classified_category || 'UNCLASSIFIED';
|
||||
counts[category] = (counts[category] || 0) + 1;
|
||||
});
|
||||
return counts;
|
||||
@@ -476,7 +476,7 @@ const NewMaterialsPage = ({
|
||||
'BOLT': 'BOLT',
|
||||
'GASKET': 'GASKET',
|
||||
'INSTRUMENT': 'INSTRUMENT',
|
||||
'UNKNOWN': 'UNKNOWN'
|
||||
'UNCLASSIFIED': 'UNCLASSIFIED'
|
||||
};
|
||||
return categoryMap[category] || category;
|
||||
};
|
||||
@@ -1090,17 +1090,17 @@ const NewMaterialsPage = ({
|
||||
unit: '개',
|
||||
isSpecial: true
|
||||
};
|
||||
} else if (category === 'UNKNOWN') {
|
||||
} else if (category === 'UNCLASSIFIED') {
|
||||
return {
|
||||
type: 'UNKNOWN',
|
||||
description: material.original_description || 'Unknown Item',
|
||||
type: 'UNCLASSIFIED',
|
||||
description: material.original_description || 'Unclassified Item',
|
||||
quantity: Math.round(material.quantity || 0),
|
||||
unit: '개',
|
||||
isUnknown: true
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
type: category || 'UNKNOWN',
|
||||
type: category || 'UNCLASSIFIED',
|
||||
subtype: '-',
|
||||
size: material.size_spec || '-',
|
||||
schedule: '-',
|
||||
@@ -1939,7 +1939,7 @@ const NewMaterialsPage = ({
|
||||
<div>사용자요구</div>
|
||||
<FilterableHeader sortKey="quantity" filterKey="quantity">수량</FilterableHeader>
|
||||
</div>
|
||||
) : selectedCategory === 'UNKNOWN' ? (
|
||||
) : selectedCategory === 'UNCLASSIFIED' ? (
|
||||
<div className="detailed-grid-header unknown-header">
|
||||
<div>선택</div>
|
||||
<div>종류</div>
|
||||
@@ -2464,7 +2464,7 @@ const NewMaterialsPage = ({
|
||||
);
|
||||
}
|
||||
|
||||
if (material.classified_category === 'UNKNOWN') {
|
||||
if (material.classified_category === 'UNCLASSIFIED') {
|
||||
// 구매신청 여부 확인
|
||||
const isPurchased = material.grouped_ids ?
|
||||
material.grouped_ids.some(id => purchasedMaterials.has(id)) :
|
||||
|
||||
@@ -339,7 +339,7 @@ const PurchaseRequestPage = ({ onNavigate, fileId, jobNo, selectedProject }) =>
|
||||
{(() => {
|
||||
// 카테고리별로 자재 그룹화
|
||||
const groupedByCategory = requestMaterials.reduce((acc, material) => {
|
||||
const category = material.category || material.classified_category || 'UNKNOWN';
|
||||
const category = material.category || material.classified_category || 'UNCLASSIFIED';
|
||||
if (!acc[category]) acc[category] = [];
|
||||
acc[category].push(material);
|
||||
return acc;
|
||||
|
||||
Reference in New Issue
Block a user