자재별 구매 수량 계산 시스템 구현

- 파이프: 6,000mm 단위 + 절단여유분 2mm/조각 계산
- 볼트/너트: +5% 후 4의 배수로 올림
- 가스켓: 5의 배수로 올림
- 피팅/계기/밸브: BOM 수량 그대로
- MaterialsPage에 '필요 수량' 칼럼 추가
- 엑셀 내보내기에 구매 수량 정보 포함
- 리비전 비교시 구매 수량 변화량도 계산
This commit is contained in:
Hyungi Ahn
2025-07-23 10:41:50 +09:00
parent 5fa0ac4202
commit 905344681f
4 changed files with 235 additions and 1 deletions

View File

@@ -28,6 +28,7 @@ import ShoppingCart from '@mui/icons-material/ShoppingCart';
import { Compare as CompareIcon, Download } from '@mui/icons-material';
import { api, fetchFiles } from '../api';
import { exportMaterialsToExcel } from '../utils/excelExport';
import { calculatePurchaseQuantity } from '../utils/purchaseCalculator';
const MaterialsPage = () => {
const [materials, setMaterials] = useState([]);
@@ -871,6 +872,7 @@ const MaterialsPage = () => {
</>
)}
<TableCell align="center"><strong>개수</strong></TableCell>
<TableCell align="center"><strong>필요 수량</strong></TableCell>
</TableRow>
</TableHead>
<TableBody>
@@ -1064,6 +1066,31 @@ const MaterialsPage = () => {
color="default"
/>
</TableCell>
<TableCell align="center">
{(() => {
// 구매 수량 계산
const purchaseInfo = calculatePurchaseQuantity({
classified_category: category,
quantity: spec.totalQuantity,
pipe_details: spec.pipe_details || (category === 'PIPE' ? {
length_mm: spec.averageLength || 0,
total_length_mm: spec.totalLength || 0
} : null),
unit: spec.unit
});
return (
<Box>
<Typography variant="body2" fontWeight="bold" color="primary">
{purchaseInfo.purchaseQuantity} {purchaseInfo.unit}
</Typography>
<Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.7rem' }}>
{purchaseInfo.calculation}
</Typography>
</Box>
);
})()}
</TableCell>
</TableRow>
))}
</TableBody>