summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-11-04 13:39:00 +0900
committerjoonhoekim <26rote@gmail.com>2025-11-04 13:39:00 +0900
commitd55bc64eb42f3b3072a0df4697946e6399cb1e4e (patch)
tree5045d070aacee74fcc752933246a8c448fce15f5
parent637ed74a18cda35d745375244e45fe6911bf83f4 (diff)
(김준회) dolce: 이유란프로 B4 스테이지(일정) 관련 요구사항 반영
-rw-r--r--db/schema/vendorDocu.ts37
-rw-r--r--lib/vendor-document-list/import-service.ts15
-rw-r--r--lib/vendor-document-list/ship/enhanced-doc-table-columns.tsx84
-rw-r--r--lib/vendor-document-list/ship/enhanced-documents-table.tsx8
4 files changed, 140 insertions, 4 deletions
diff --git a/db/schema/vendorDocu.ts b/db/schema/vendorDocu.ts
index 304fe5ae..bfa43849 100644
--- a/db/schema/vendorDocu.ts
+++ b/db/schema/vendorDocu.ts
@@ -873,6 +873,12 @@ export const simplifiedDocumentsView = pgView("simplified_documents_view", {
secondStagePlanDate: date("second_stage_plan_date"),
secondStageActualDate: date("second_stage_actual_date"),
+ // 세 번째 스테이지 날짜 정보 (B4 문서의 SHI → GTT)
+ thirdStageId: integer("third_stage_id"),
+ thirdStageName: varchar("third_stage_name", { length: 100 }),
+ thirdStagePlanDate: date("third_stage_plan_date"),
+ thirdStageActualDate: date("third_stage_actual_date"),
+
// 전체 스테이지 목록
allStages: json("all_stages").$type<Array<{
id: number;
@@ -1063,6 +1069,30 @@ export const simplifiedDocumentsView = pgView("simplified_documents_view", {
WHERE rn = 1
),
+ -- 세 번째 스테이지 정보 (B4 문서의 SHI → GTT)
+ third_stage_info AS (
+ SELECT
+ document_id,
+ third_stage_id,
+ third_stage_name,
+ third_stage_plan_date,
+ third_stage_actual_date
+ FROM (
+ SELECT
+ ist.document_id,
+ ist.id as third_stage_id,
+ ist.stage_name as third_stage_name,
+ ist.plan_date as third_stage_plan_date,
+ ist.actual_date as third_stage_actual_date,
+ ROW_NUMBER() OVER (PARTITION BY ist.document_id ORDER BY ist.stage_order ASC) as rn
+ FROM issue_stages ist
+ JOIN documents d ON ist.document_id = d.id
+ WHERE
+ d.drawing_kind = 'B4' AND ist.stage_name = 'SHI → GTT'
+ ) ranked
+ WHERE rn = 1
+ ),
+
-- 첨부파일 수 집계
attachment_counts AS (
SELECT
@@ -1133,6 +1163,12 @@ export const simplifiedDocumentsView = pgView("simplified_documents_view", {
ssi.second_stage_plan_date,
ssi.second_stage_actual_date,
+ -- 세 번째 스테이지 정보
+ tsi.third_stage_id,
+ tsi.third_stage_name,
+ tsi.third_stage_plan_date,
+ tsi.third_stage_actual_date,
+
-- 전체 스테이지 (리비전 및 첨부파일 포함)
COALESCE(sa.all_stages, '[]'::json) as all_stages,
@@ -1150,6 +1186,7 @@ export const simplifiedDocumentsView = pgView("simplified_documents_view", {
-- 스테이지 정보 JOIN
LEFT JOIN first_stage_info fsi ON d.id = fsi.document_id
LEFT JOIN second_stage_info ssi ON d.id = ssi.document_id
+ LEFT JOIN third_stage_info tsi ON d.id = tsi.document_id
LEFT JOIN stage_aggregation sa ON d.id = sa.document_id
LEFT JOIN attachment_counts ac ON d.id = ac.document_id
diff --git a/lib/vendor-document-list/import-service.ts b/lib/vendor-document-list/import-service.ts
index 694b3d43..85c706ed 100644
--- a/lib/vendor-document-list/import-service.ts
+++ b/lib/vendor-document-list/import-service.ts
@@ -1882,6 +1882,21 @@ class ImportService {
})
}
+ // SHI → GTT 스테이지 생성 (GTTInput)
+ if (!existingStageNames.includes('SHI → GTT')) {
+ await db.insert(issueStages).values({
+ documentId: documentId,
+ stageName: 'SHI → GTT',
+ planDate: this.convertDolceDateToDate(dolceDoc.GTTInput_PlanDate),
+ actualDate: this.convertDolceDateToDate(dolceDoc.GTTInput_ResultDate),
+ stageStatus: 'PLANNED',
+ stageOrder: 3,
+ priority: 'MEDIUM',
+ reminderDays: 3,
+ description: 'SHI 제출 문서 단계'
+ })
+ }
+
console.log(`Created issue stages for B4 document: ${drawingNo}`)
} catch (error) {
diff --git a/lib/vendor-document-list/ship/enhanced-doc-table-columns.tsx b/lib/vendor-document-list/ship/enhanced-doc-table-columns.tsx
index 882ef885..a2ac622d 100644
--- a/lib/vendor-document-list/ship/enhanced-doc-table-columns.tsx
+++ b/lib/vendor-document-list/ship/enhanced-doc-table-columns.tsx
@@ -33,6 +33,7 @@ import { DocumentSelectionContext } from "@/components/ship-vendor-document/user
interface GetColumnsProps {
setRowAction?: React.Dispatch<React.SetStateAction<DataTableRowAction<SimplifiedDocumentsView> | null>>
+ b4FilterType?: 'all' | 'gtt_deliverable' | 'shi_input'
}
// 날짜 표시 컴포넌트 (간단 버전)
@@ -51,6 +52,7 @@ const DateDisplay = ({ date, isSelected = false }: { date: string | null, isSele
export function getSimplifiedDocumentColumns({
setRowAction,
+ b4FilterType = 'all',
}: GetColumnsProps): ColumnDef<SimplifiedDocumentsView>[] {
const columns: ColumnDef<SimplifiedDocumentsView>[] = [
@@ -258,6 +260,49 @@ export function getSimplifiedDocumentColumns({
],
},
+ // 3차 스테이지 그룹 (SHI → GTT)
+ {
+ id: "thirdStageGroup",
+ header: ({ table }) => {
+ // 첫 번째 행의 thirdStageName을 그룹 헤더로 사용
+ const firstRow = table.getRowModel().rows[0]?.original
+ const stageName = firstRow?.thirdStageName || "SHI → GTT"
+ return (
+ <div className="text-center font-medium text-foreground">
+ {stageName}
+ </div>
+ )
+ },
+ columns: [
+ {
+ accessorKey: "thirdStagePlanDate",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="Planned Date" />
+ ),
+ cell: ({ row }) => {
+ return <ThirdStagePlanDateCell row={row} />
+ },
+ enableResizing: true,
+ meta: {
+ excelHeader: "Third Planned Date"
+ },
+ },
+ {
+ accessorKey: "thirdStageActualDate",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="Actual Date" />
+ ),
+ cell: ({ row }) => {
+ return <ThirdStageActualDateCell row={row} />
+ },
+ enableResizing: true,
+ meta: {
+ excelHeader: "Third Actual Date"
+ },
+ },
+ ],
+ },
+
// 첨부파일 수
{
accessorKey: "attachmentCount",
@@ -341,6 +386,22 @@ export function getSimplifiedDocumentColumns({
// },
]
+ // b4FilterType에 따라 스테이지 컬럼 필터링
+ if (b4FilterType === 'gtt_deliverable') {
+ // GTT Deliverables: GTT → SHI 스테이지만 (firstStageGroup, secondStageGroup)
+ return columns.filter(col => {
+ const id = 'id' in col ? col.id : null
+ return id !== 'thirdStageGroup'
+ })
+ } else if (b4FilterType === 'shi_input') {
+ // SHI Input Document: SHI → GTT 스테이지만 (thirdStageGroup)
+ return columns.filter(col => {
+ const id = 'id' in col ? col.id : null
+ return id !== 'firstStageGroup' && id !== 'secondStageGroup'
+ })
+ }
+
+ // All: 모든 컬럼 표시
return columns
}
@@ -471,6 +532,29 @@ function SecondStageActualDateCell({ row }: { row: any }) {
);
}
+function ThirdStagePlanDateCell({ row }: { row: any }) {
+ const { selectedDocumentId } = React.useContext(DocumentSelectionContext);
+ const isSelected = selectedDocumentId === row.original.documentId;
+
+ return <DateDisplay date={row.original.thirdStagePlanDate} isSelected={isSelected} />;
+}
+
+function ThirdStageActualDateCell({ row }: { row: any }) {
+ const { selectedDocumentId } = React.useContext(DocumentSelectionContext);
+ const isSelected = selectedDocumentId === row.original.documentId;
+ const date = row.original.thirdStageActualDate;
+
+ return (
+ <div className={cn(
+ date ? "text-emerald-600 dark:text-emerald-400 font-medium" : "",
+ isSelected && date && "text-emerald-700 dark:text-emerald-300 font-bold"
+ )}>
+ <DateDisplay date={date} isSelected={isSelected && !date} />
+ {date && <span className="text-xs block">✓ 완료</span>}
+ </div>
+ );
+}
+
function AttachmentCountCell({ count, documentId }: { count: number, documentId: number }) {
const { selectedDocumentId } = React.useContext(DocumentSelectionContext);
const isSelected = selectedDocumentId === documentId;
diff --git a/lib/vendor-document-list/ship/enhanced-documents-table.tsx b/lib/vendor-document-list/ship/enhanced-documents-table.tsx
index 13f8f8d4..d92f16dd 100644
--- a/lib/vendor-document-list/ship/enhanced-documents-table.tsx
+++ b/lib/vendor-document-list/ship/enhanced-documents-table.tsx
@@ -100,10 +100,10 @@ export function SimplifiedDocumentsTable({
}
}, [data, onDataLoaded])
- // 🔥 컬럼 메모이제이션 최적화
+ // 🔥 컬럼 메모이제이션 최적화 (b4FilterType에 따라 동적 변경)
const columns = React.useMemo(
- () => getSimplifiedDocumentColumns({}),
- []
+ () => getSimplifiedDocumentColumns({ b4FilterType }),
+ [b4FilterType]
)
// 🔥 필터 필드들을 메모이제이션
@@ -391,7 +391,7 @@ export function SimplifiedDocumentsTable({
className="gap-2"
>
<FileInput className="h-4 w-4" />
- GTT Deliverable
+ GTT Deliverables
<Badge variant="secondary" className="ml-1">
{b4Stats.gttDeliverableCount}
</Badge>