이슈 #5: 산출내역서 담당자/연락처/단위 표시 이슈 #6: 세부산출내역 vs 소요자재내역 분리 주요 변경: - QuoteCalculationReport.tsx: bomMaterials 사용하여 소요자재 내역 표시 - 세부산출내역과 소요자재내역 데이터 소스 분리
This commit is contained in:
@@ -5,9 +5,12 @@
|
||||
*/
|
||||
|
||||
import { QuoteFormData } from "./QuoteRegistration";
|
||||
import type { BomMaterial } from "./types";
|
||||
import type { CompanyFormData } from "@/components/settings/CompanyInfoManagement/types";
|
||||
|
||||
interface QuoteCalculationReportProps {
|
||||
quote: QuoteFormData;
|
||||
companyInfo?: CompanyFormData | null;
|
||||
documentType?: "견적산출내역서" | "견적서";
|
||||
showDetailedBreakdown?: boolean;
|
||||
showMaterialList?: boolean;
|
||||
@@ -15,6 +18,7 @@ interface QuoteCalculationReportProps {
|
||||
|
||||
export function QuoteCalculationReport({
|
||||
quote,
|
||||
companyInfo,
|
||||
documentType = "견적산출내역서",
|
||||
showDetailedBreakdown = true,
|
||||
showMaterialList = true
|
||||
@@ -30,19 +34,26 @@ export function QuoteCalculationReport({
|
||||
return `${date.getFullYear()}년 ${String(date.getMonth() + 1).padStart(2, '0')}월 ${String(date.getDate()).padStart(2, '0')}일`;
|
||||
};
|
||||
|
||||
// 총 금액 계산
|
||||
// 총 금액 계산 (totalAmount > unitPrice * quantity > inspectionFee 우선순위)
|
||||
const totalAmount = quote.items?.reduce((sum, item) => {
|
||||
return sum + (item.inspectionFee || 0) * (item.quantity || 1);
|
||||
const itemTotal = item.totalAmount ||
|
||||
(item.unitPrice || 0) * (item.quantity || 1) ||
|
||||
(item.inspectionFee || 0) * (item.quantity || 1);
|
||||
return sum + itemTotal;
|
||||
}, 0) || 0;
|
||||
|
||||
// 소요자재 내역 생성 (샘플 데이터)
|
||||
const materialItems = quote.items?.map((item, index) => ({
|
||||
// 소요자재 내역 - BOM 자재 목록 (quote.bomMaterials)에서 가져옴
|
||||
// bomMaterials가 없으면 빈 배열 (BOM 계산 데이터 없음)
|
||||
const materialItems = (quote.bomMaterials || []).map((material, index) => ({
|
||||
no: index + 1,
|
||||
name: item.productName || '가이드레일',
|
||||
spec: `${item.openWidth || 0}×${item.openHeight || 0}mm`,
|
||||
quantity: item.quantity || 1,
|
||||
unit: 'SET'
|
||||
})) || [];
|
||||
itemCode: material.itemCode || '-',
|
||||
name: material.itemName || '-',
|
||||
spec: material.specification || '-',
|
||||
quantity: Math.floor(material.quantity || 1),
|
||||
unit: material.unit || 'EA',
|
||||
unitPrice: material.unitPrice || 0,
|
||||
totalPrice: material.totalPrice || 0,
|
||||
}));
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -316,29 +327,29 @@ export function QuoteCalculationReport({
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>상호</th>
|
||||
<td>(주)염진건설</td>
|
||||
<td>{companyInfo?.companyName || '-'}</td>
|
||||
<th>사업자등록번호</th>
|
||||
<td>139-87-00353</td>
|
||||
<td>{companyInfo?.businessNumber || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>대표자</th>
|
||||
<td>김 용 진</td>
|
||||
<td>{companyInfo?.representativeName || '-'}</td>
|
||||
<th>업태</th>
|
||||
<td>제조</td>
|
||||
<td>{companyInfo?.businessType || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>종목</th>
|
||||
<td colSpan={3}>방창, 셔터, 금속창호</td>
|
||||
<td colSpan={3}>{companyInfo?.businessCategory || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>사업장주소</th>
|
||||
<td colSpan={3}>경기도 안성시 공업용지 오성길 45-22</td>
|
||||
<td colSpan={3}>{companyInfo?.address || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>전화</th>
|
||||
<td>031-983-5130</td>
|
||||
<th>팩스</th>
|
||||
<td>02-6911-6315</td>
|
||||
<td>{companyInfo?.managerPhone || '-'}</td>
|
||||
<th>이메일</th>
|
||||
<td>{companyInfo?.email || '-'}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -370,17 +381,23 @@ export function QuoteCalculationReport({
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{quote.items.map((item, index) => (
|
||||
<tr key={item.id || `item-${index}`}>
|
||||
<td style={{ textAlign: 'center' }}>{index + 1}</td>
|
||||
<td>{item.productName}</td>
|
||||
<td style={{ fontSize: '11px' }}>{`${item.openWidth}×${item.openHeight}mm`}</td>
|
||||
<td style={{ textAlign: 'right' }}>{item.quantity}</td>
|
||||
<td style={{ textAlign: 'center' }}>SET</td>
|
||||
<td style={{ textAlign: 'right' }}>{formatAmount(item.inspectionFee)}</td>
|
||||
<td style={{ textAlign: 'right', fontWeight: '600' }}>{formatAmount((item.inspectionFee || 0) * (item.quantity || 1))}</td>
|
||||
</tr>
|
||||
))}
|
||||
{quote.items.map((item, index) => {
|
||||
// 단가: unitPrice > inspectionFee 우선순위
|
||||
const unitPrice = item.unitPrice || item.inspectionFee || 0;
|
||||
// 금액: totalAmount > unitPrice * quantity 우선순위
|
||||
const itemTotal = item.totalAmount || unitPrice * (item.quantity || 1);
|
||||
return (
|
||||
<tr key={item.id || `item-${index}`}>
|
||||
<td style={{ textAlign: 'center' }}>{index + 1}</td>
|
||||
<td>{item.productName}</td>
|
||||
<td style={{ fontSize: '11px' }}>{`${item.openWidth}×${item.openHeight}mm`}</td>
|
||||
<td style={{ textAlign: 'right' }}>{Math.floor(item.quantity || 0)}</td>
|
||||
<td style={{ textAlign: 'center' }}>{item.unit || 'SET'}</td>
|
||||
<td style={{ textAlign: 'right' }}>{formatAmount(unitPrice)}</td>
|
||||
<td style={{ textAlign: 'right', fontWeight: '600' }}>{formatAmount(itemTotal)}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
@@ -416,7 +433,7 @@ export function QuoteCalculationReport({
|
||||
</tr>
|
||||
<tr>
|
||||
<th>수량</th>
|
||||
<td>{quote.items?.[0]?.quantity || 1} SET</td>
|
||||
<td>{Math.floor(quote.items?.[0]?.quantity || 1)} {quote.items?.[0]?.unit || 'SET'}</td>
|
||||
<th>케이스</th>
|
||||
<td>2438 × 550 (mm)</td>
|
||||
</tr>
|
||||
@@ -426,28 +443,42 @@ export function QuoteCalculationReport({
|
||||
</div>
|
||||
|
||||
{/* 자재 목록 테이블 */}
|
||||
<table className="material-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ width: '40px' }}>No.</th>
|
||||
<th>자재명</th>
|
||||
<th style={{ width: '250px' }}>규격</th>
|
||||
<th style={{ width: '80px' }}>수량</th>
|
||||
<th style={{ width: '60px' }}>단위</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{materialItems.map((item, index) => (
|
||||
<tr key={index}>
|
||||
<td style={{ textAlign: 'center' }}>{index + 1}</td>
|
||||
<td>{item.name}</td>
|
||||
<td>{item.spec}</td>
|
||||
<td style={{ textAlign: 'center', fontWeight: '600' }}>{item.quantity}</td>
|
||||
<td style={{ textAlign: 'center' }}>{item.unit}</td>
|
||||
{materialItems.length > 0 ? (
|
||||
<table className="material-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ width: '40px' }}>No.</th>
|
||||
<th style={{ width: '100px' }}>품목코드</th>
|
||||
<th>자재명</th>
|
||||
<th style={{ width: '200px' }}>규격</th>
|
||||
<th style={{ width: '80px' }}>수량</th>
|
||||
<th style={{ width: '60px' }}>단위</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{materialItems.map((item, index) => (
|
||||
<tr key={index}>
|
||||
<td style={{ textAlign: 'center' }}>{index + 1}</td>
|
||||
<td style={{ textAlign: 'center', fontSize: '11px' }}>{item.itemCode}</td>
|
||||
<td>{item.name}</td>
|
||||
<td style={{ fontSize: '11px' }}>{item.spec}</td>
|
||||
<td style={{ textAlign: 'center', fontWeight: '600' }}>{item.quantity}</td>
|
||||
<td style={{ textAlign: 'center' }}>{item.unit}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
) : (
|
||||
<div style={{
|
||||
border: '2px solid #000',
|
||||
padding: '30px',
|
||||
textAlign: 'center',
|
||||
marginTop: '15px',
|
||||
color: '#666'
|
||||
}}>
|
||||
소요자재 정보가 없습니다. (BOM 계산 데이터가 필요합니다)
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -479,7 +510,7 @@ export function QuoteCalculationReport({
|
||||
<div>
|
||||
<div style={{ fontSize: '13px', marginBottom: '5px' }}>{formatDate(quote.registrationDate || '')}</div>
|
||||
<div style={{ fontSize: '15px', fontWeight: '600' }}>
|
||||
공급자: (주)염진건설 (인)
|
||||
공급자: {companyInfo?.companyName || '-'} (인)
|
||||
</div>
|
||||
</div>
|
||||
<div className="stamp-area">
|
||||
@@ -499,7 +530,7 @@ export function QuoteCalculationReport({
|
||||
<p>3. 제작 사양 및 수량 변경 시 견적 금액이 변동될 수 있습니다.</p>
|
||||
<p>4. 현장 여건에 따라 추가 비용이 발생할 수 있습니다.</p>
|
||||
<p style={{ marginTop: '12px', textAlign: 'center', fontWeight: '600' }}>
|
||||
문의: {quote.manager || '담당자'} | {quote.contact || '031-983-5130'}
|
||||
문의: {companyInfo?.managerName || quote.manager || '담당자'} | {companyInfo?.managerPhone || '-'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user