feat(WEB): 수입검사 관리 대폭 개선, 캘린더 DayTimeView 추가 및 출고 기능 보완
- 수입검사: InspectionCreate/Detail/List 대폭 개선, OrderSelectModal/문서 컴포넌트 신규 추가 - 수입검사: actions/types/mockData/inspectionConfig 전면 리팩토링 - QMS: InspectionModalV2/ImportInspectionDocument 개선 - 캘린더: DayTimeView 신규 추가, CalendarHeader/ScheduleCalendar/utils 확장 - 출고: ShipmentDetail/List/actions 개선, ShipmentOrderDocument/ShippingSlip 수정 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
'use client';
|
||||
|
||||
/**
|
||||
* 제품검사요청서 문서
|
||||
*
|
||||
* 기획서 기반:
|
||||
* - 결재라인 (작성/승인)
|
||||
* - 기본정보 (수주처, 업체명, 담당자 등)
|
||||
* - 입력사항 (건축공사장, 자재유통업자, 공사시공자, 공사감리자)
|
||||
* - 검사대상 사전 고지 정보 테이블
|
||||
*/
|
||||
|
||||
import { ConstructionApprovalTable } from '@/components/document-system';
|
||||
import { isOrderSpecSame } from '../mockData';
|
||||
import type { InspectionRequestDocument as InspectionRequestDocumentType } from '../types';
|
||||
|
||||
interface InspectionRequestDocumentProps {
|
||||
data: InspectionRequestDocumentType;
|
||||
}
|
||||
|
||||
export function InspectionRequestDocument({ data }: InspectionRequestDocumentProps) {
|
||||
return (
|
||||
<div className="bg-white p-8 min-h-full text-[11px]">
|
||||
{/* 헤더: 제목 (좌측) + 결재란 (우측) */}
|
||||
<div className="flex justify-between items-start mb-4">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold tracking-widest mb-2">제 품 검 사 요 청 서</h1>
|
||||
<div className="text-[10px] space-y-1">
|
||||
<div className="flex gap-4">
|
||||
<span>문서번호: <strong>{data.documentNumber}</strong></span>
|
||||
<span>작성일자: <strong>{data.createdDate}</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ConstructionApprovalTable
|
||||
approvers={{
|
||||
writer: data.approvalLine[0]
|
||||
? { name: data.approvalLine[0].name, department: data.approvalLine[0].department }
|
||||
: undefined,
|
||||
approver1: data.approvalLine[1]
|
||||
? { name: data.approvalLine[1].name, department: data.approvalLine[1].department }
|
||||
: undefined,
|
||||
approver2: data.approvalLine[2]
|
||||
? { name: data.approvalLine[2].name, department: data.approvalLine[2].department }
|
||||
: undefined,
|
||||
approver3: data.approvalLine[3]
|
||||
? { name: data.approvalLine[3].name, department: data.approvalLine[3].department }
|
||||
: undefined,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 기본 정보 */}
|
||||
<div className="border border-gray-400 mb-4">
|
||||
<div className="bg-gray-200 text-center py-1 font-bold border-b border-gray-400">기본 정보</div>
|
||||
<table className="w-full">
|
||||
<tbody>
|
||||
<tr className="border-b border-gray-300">
|
||||
<td className="bg-gray-100 px-2 py-1 w-28 font-medium border-r border-gray-300">수주처</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.client || '-'}</td>
|
||||
<td className="bg-gray-100 px-2 py-1 w-28 font-medium border-r border-gray-300">업체명</td>
|
||||
<td className="px-2 py-1">{data.companyName || '-'}</td>
|
||||
</tr>
|
||||
<tr className="border-b border-gray-300">
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">담당자</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.manager || '-'}</td>
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">수주번호</td>
|
||||
<td className="px-2 py-1">{data.orderNumber || '-'}</td>
|
||||
</tr>
|
||||
<tr className="border-b border-gray-300">
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">담당자 연락처</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.managerContact || '-'}</td>
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">현장명</td>
|
||||
<td className="px-2 py-1">{data.siteName || '-'}</td>
|
||||
</tr>
|
||||
<tr className="border-b border-gray-300">
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">납품일</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.deliveryDate || '-'}</td>
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">현장 주소</td>
|
||||
<td className="px-2 py-1">{data.siteAddress || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">총 개소</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.totalLocations || '-'}</td>
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">접수일</td>
|
||||
<td className="px-2 py-1">{data.receptionDate || '-'}</td>
|
||||
</tr>
|
||||
<tr className="border-t border-gray-300">
|
||||
<td className="bg-gray-100 px-2 py-1 font-medium border-r border-gray-300">검사방문요청일</td>
|
||||
<td className="px-2 py-1" colSpan={3}>{data.visitRequestDate || '-'}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* 입력사항: 4개 섹션 */}
|
||||
<div className="border border-gray-400 mb-4">
|
||||
<div className="bg-gray-200 text-center py-1 font-bold border-b border-gray-400">입력사항</div>
|
||||
|
||||
{/* 건축공사장 정보 */}
|
||||
<div className="border-b border-gray-300">
|
||||
<div className="bg-gray-100 px-2 py-1 font-medium border-b border-gray-300">건축공사장 정보</div>
|
||||
<table className="w-full">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">현장명</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.constructionSite.siteName || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">대지위치</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.constructionSite.landLocation || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 w-20 font-medium border-r border-gray-300">지번</td>
|
||||
<td className="px-2 py-1">{data.constructionSite.lotNumber || '-'}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* 자재유통업자 정보 */}
|
||||
<div className="border-b border-gray-300">
|
||||
<div className="bg-gray-100 px-2 py-1 font-medium border-b border-gray-300">자재유통업자 정보</div>
|
||||
<table className="w-full">
|
||||
<tbody>
|
||||
<tr className="border-b border-gray-300">
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">회사명</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.materialDistributor.companyName || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">회사주소</td>
|
||||
<td className="px-2 py-1">{data.materialDistributor.companyAddress || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-50 px-2 py-1 font-medium border-r border-gray-300">대표자명</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.materialDistributor.representativeName || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 font-medium border-r border-gray-300">전화번호</td>
|
||||
<td className="px-2 py-1">{data.materialDistributor.phone || '-'}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* 공사시공자 정보 */}
|
||||
<div className="border-b border-gray-300">
|
||||
<div className="bg-gray-100 px-2 py-1 font-medium border-b border-gray-300">공사시공자 정보</div>
|
||||
<table className="w-full">
|
||||
<tbody>
|
||||
<tr className="border-b border-gray-300">
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">회사명</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.constructorInfo.companyName || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">회사주소</td>
|
||||
<td className="px-2 py-1">{data.constructorInfo.companyAddress || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-50 px-2 py-1 font-medium border-r border-gray-300">성명</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.constructorInfo.name || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 font-medium border-r border-gray-300">전화번호</td>
|
||||
<td className="px-2 py-1">{data.constructorInfo.phone || '-'}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* 공사감리자 정보 */}
|
||||
<div>
|
||||
<div className="bg-gray-100 px-2 py-1 font-medium border-b border-gray-300">공사감리자 정보</div>
|
||||
<table className="w-full">
|
||||
<tbody>
|
||||
<tr className="border-b border-gray-300">
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">사무소명</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.supervisor.officeName || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 w-28 font-medium border-r border-gray-300">사무소주소</td>
|
||||
<td className="px-2 py-1">{data.supervisor.officeAddress || '-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-50 px-2 py-1 font-medium border-r border-gray-300">성명</td>
|
||||
<td className="px-2 py-1 border-r border-gray-300">{data.supervisor.name || '-'}</td>
|
||||
<td className="bg-gray-50 px-2 py-1 font-medium border-r border-gray-300">전화번호</td>
|
||||
<td className="px-2 py-1">{data.supervisor.phone || '-'}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 검사대상 사전 고지 정보 */}
|
||||
<div className="border border-gray-400 mb-4">
|
||||
<div className="bg-gray-200 text-center py-1 font-bold border-b border-gray-400">검사대상 사전 고지 정보</div>
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b border-gray-400">
|
||||
<th className="border-r border-gray-400 px-2 py-1 w-10 text-center">No.</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1">수주번호</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1">층수</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1">부호</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1 text-center">수주 가로</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1 text-center">수주 세로</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1 text-center">시공 가로</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1 text-center">시공 세로</th>
|
||||
<th className="border-r border-gray-400 px-2 py-1 text-center">일치</th>
|
||||
<th className="px-2 py-1">변경사유</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.priorNoticeItems.map((item, index) => {
|
||||
const isSame = isOrderSpecSame(item);
|
||||
return (
|
||||
<tr key={item.id} className="border-b border-gray-300">
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">{index + 1}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1">{item.orderNumber}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1">{item.floor}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1">{item.symbol}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">{item.orderWidth}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">{item.orderHeight}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">{item.constructionWidth}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">{item.constructionHeight}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center font-medium">
|
||||
<span className={isSame ? 'text-green-700' : 'text-red-700'}>
|
||||
{isSame ? '일치' : '불일치'}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-2 py-1">{item.changeReason || '-'}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
{data.priorNoticeItems.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={10} className="px-2 py-4 text-center text-gray-400">
|
||||
검사대상 사전 고지 정보가 없습니다.
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* 서명 영역 */}
|
||||
<div className="mt-8 text-center text-[10px]">
|
||||
<p>위 내용과 같이 제품검사를 요청합니다.</p>
|
||||
<div className="mt-6">
|
||||
<p>{data.createdDate}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user