diff options
Diffstat (limited to 'lib/vendor-document-list/plant')
3 files changed, 153 insertions, 71 deletions
diff --git a/lib/vendor-document-list/plant/document-stages-columns.tsx b/lib/vendor-document-list/plant/document-stages-columns.tsx index 742b8a8a..d4baf7fb 100644 --- a/lib/vendor-document-list/plant/document-stages-columns.tsx +++ b/lib/vendor-document-list/plant/document-stages-columns.tsx @@ -35,6 +35,7 @@ import { cn } from "@/lib/utils" interface GetColumnsProps { setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<DocumentStagesOnlyView> | null>> projectType: string + domain?: "evcp" | "partners" // 선택적 파라미터로 유지 } // 유틸리티 함수들 @@ -76,7 +77,7 @@ const getPriorityText = (priority: string) => { case 'HIGH': return 'High' case 'MEDIUM': return 'Medium' case 'LOW': return 'Low' - default: priority + default: return priority } } @@ -136,9 +137,11 @@ const DueDateInfo = ({ export function getDocumentStagesColumns({ setRowAction, - projectType + projectType, + domain = "partners", // 기본값 설정 }: GetColumnsProps): ColumnDef<DocumentStagesOnlyView>[] { const isPlantProject = projectType === "plant" + const isEvcpDomain = domain === "evcp" const columns: ColumnDef<DocumentStagesOnlyView>[] = [ // 체크박스 선택 @@ -167,7 +170,11 @@ export function getDocumentStagesColumns({ enableSorting: false, enableHiding: false, }, - { + ] + + // EVCP 도메인일 때만 Project 컬럼 추가 (앞쪽으로 이동) + if (isEvcpDomain) { + columns.push({ accessorKey: "projectCode", header: ({ column }) => ( <DataTableColumnHeaderSimple column={column} title="Project" /> @@ -183,57 +190,101 @@ export function getDocumentStagesColumns({ meta: { excelHeader: "Project" }, - }, - - + }) + } - // 문서번호 - { - accessorKey: "docNumber", - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Document Number" /> - ), - cell: ({ row }) => { - const doc = row.original - return ( - <span className="font-mono text-sm font-medium">{doc.docNumber}</span> - ) - }, - size: 140, - enableResizing: true, - meta: { - excelHeader: "Document Number" + // EVCP 도메인일 때만 Vendor 정보 컬럼들 추가 (앞쪽으로 이동) + if (isEvcpDomain) { + columns.push( + // Vendor Code + { + accessorKey: "vendorCode", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Vendor Code" /> + ), + cell: ({ row }) => { + const doc = row.original + return doc.vendorCode ? ( + <span className="font-mono text-sm font-medium text-blue-600">{doc.vendorCode}</span> + ) : ( + <span className="text-gray-400 text-sm">-</span> + ) + }, + size: 120, + enableResizing: true, + meta: { + excelHeader: "Vendor Code" + }, }, - }, + // Vendor Name + { + accessorKey: "vendorName", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Vendor Name" /> + ), + cell: ({ row }) => { + const doc = row.original + return doc.vendorName ? ( + <span className="text-sm font-medium">{doc.vendorName}</span> + ) : ( + <span className="text-gray-400 text-sm">-</span> + ) + }, + size: 150, + enableResizing: true, + meta: { + excelHeader: "Vendor Name" + }, + } + ) + } - // 문서명 (PIC 포함) - { - accessorKey: "title", - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Document Name" /> - ), - cell: ({ row }) => { - const doc = row.original - return ( - <div className="min-w-0 flex-1"> - <div className="font-medium text-gray-900 truncate text-sm" title={doc.title}> - {doc.title} - </div> - {doc.pic && ( - <span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded mt-1 inline-block"> - PIC: {doc.pic} - </span> - )} + // 문서번호 + columns.push({ + accessorKey: "docNumber", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Document Number" /> + ), + cell: ({ row }) => { + const doc = row.original + return ( + <span className="font-mono text-sm font-medium">{doc.docNumber}</span> + ) + }, + size: 140, + enableResizing: true, + meta: { + excelHeader: "Document Number" + }, + }) + + // 문서명 (PIC 포함) + columns.push({ + accessorKey: "title", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Document Name" /> + ), + cell: ({ row }) => { + const doc = row.original + return ( + <div className="min-w-0 flex-1"> + <div className="font-medium text-gray-900 truncate text-sm" title={doc.title}> + {doc.title} </div> - ) - }, - size: 220, - enableResizing: true, - meta: { - excelHeader: "Document Name" - }, + {doc.pic && ( + <span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded mt-1 inline-block"> + PIC: {doc.pic} + </span> + )} + </div> + ) }, - ] + size: 220, + enableResizing: true, + meta: { + excelHeader: "Document Name" + }, + }) // Plant 프로젝트용 추가 컬럼들 if (isPlantProject) { @@ -258,7 +309,6 @@ export function getDocumentStagesColumns({ excelHeader: "Vendor Doc No." }, }, - ) } diff --git a/lib/vendor-document-list/plant/document-stages-service.ts b/lib/vendor-document-list/plant/document-stages-service.ts index c6a891c8..57f17bae 100644 --- a/lib/vendor-document-list/plant/document-stages-service.ts +++ b/lib/vendor-document-list/plant/document-stages-service.ts @@ -30,6 +30,8 @@ import { unstable_noStore as noStore } from "next/cache" import { filterColumns } from "@/lib/filter-columns" import { GetEnhancedDocumentsSchema, GetDocumentsSchema } from "../enhanced-document-service" import { countDocumentStagesOnly, selectDocumentStagesOnly } from "../repository" +import { getServerSession } from "next-auth" +import { authOptions } from "@/app/api/auth/[...nextauth]/route" interface UpdateDocumentData { documentId: number @@ -1013,7 +1015,6 @@ export async function getDocumentStagesOnly( ) { try { const offset = (input.page - 1) * input.perPage - // 고급 필터 처리 const advancedWhere = filterColumns({ table: stageDocumentsView, @@ -1034,21 +1035,39 @@ export async function getDocumentStagesOnly( ) } - // 최종 WHERE 조건 - const finalWhere = and( - advancedWhere, - globalWhere, - eq(stageDocumentsView.contractId, contractId) - ) - // 정렬 처리 + // 세션에서 도메인 정보 가져오기 + const session = await getServerSession(authOptions) + const isEvcpDomain = session?.user?.domain === "evcp" + + // 도메인별 WHERE 조건 설정 + let finalWhere + if (isEvcpDomain) { + // EVCP: 전체 계약 조회 (contractId 조건 제거) + finalWhere = and( + advancedWhere, + globalWhere + ) + } else { + // Partners: 특정 계약 조회 + finalWhere = and( + advancedWhere, + globalWhere, + eq(documentStagesOnlyView.contractId, contractId) + ) + } + + + + // 정렬 처리 const orderBy = input.sort && input.sort.length > 0 ? input.sort.map((item) => item.desc ? desc(stageDocumentsView[item.id]) : asc(stageDocumentsView[item.id]) ) - : [desc(stageDocumentsView.createdAt)] + : [desc(documentStagesOnlyView.createdAt)] + // 트랜잭션 실행 const { data, total } = await db.transaction(async (tx) => { diff --git a/lib/vendor-document-list/plant/document-stages-table.tsx b/lib/vendor-document-list/plant/document-stages-table.tsx index ccf35f4b..8bfae284 100644 --- a/lib/vendor-document-list/plant/document-stages-table.tsx +++ b/lib/vendor-document-list/plant/document-stages-table.tsx @@ -34,6 +34,7 @@ import { EditDocumentDialog } from "./document-stage-dialogs" import { EditStageDialog } from "./document-stage-dialogs" import { ExcelImportDialog } from "./document-stage-dialogs" import { DocumentsTableToolbarActions } from "./document-stage-toolbar" +import { useSession } from "next-auth/react" interface DocumentStagesTableProps { promises: Promise<[Awaited<ReturnType<typeof getDocumentStagesOnly>>]> @@ -46,13 +47,18 @@ export function DocumentStagesTable({ contractId, projectType, }: DocumentStagesTableProps) { - const [{ data, pageCount, total }] = React.use(promises) + const [{ data, pageCount }] = React.use(promises) + + const { data: session } = useSession() + // URL에서 언어 파라미터 가져오기 const params = useParams() const lng = (params?.lng as string) || 'ko' const { t } = useTranslation(lng, 'document') + // 세션에서 도메인을 가져오기 + const currentDomain = session?.user?.domain as "evcp" | "partners" // 상태 관리 const [rowAction, setRowAction] = React.useState<DataTableRowAction<DocumentStagesOnlyView> | null>(null) @@ -100,27 +106,31 @@ export function DocumentStagesTable({ } } }, - projectType + projectType, + domain: currentDomain }), - [expandedRows, projectType] + [expandedRows, projectType, currentDomain] ) // 통계 계산 const stats = React.useMemo(() => { - const totalDocs = data.length - const overdue = data.filter(doc => doc.isOverdue).length - const dueSoon = data.filter(doc => + console.log('DocumentStagesTable - data:', data) + console.log('DocumentStagesTable - data length:', data?.length) + + const totalDocs = data?.length || 0 + const overdue = data?.filter(doc => doc.isOverdue)?.length || 0 + const dueSoon = data?.filter(doc => doc.daysUntilDue !== null && doc.daysUntilDue >= 0 && doc.daysUntilDue <= 3 - ).length - const inProgress = data.filter(doc => doc.currentStageStatus === 'IN_PROGRESS').length - const highPriority = data.filter(doc => doc.currentStagePriority === 'HIGH').length + )?.length || 0 + const inProgress = data?.filter(doc => doc.currentStageStatus === 'IN_PROGRESS')?.length || 0 + const highPriority = data?.filter(doc => doc.currentStagePriority === 'HIGH')?.length || 0 const avgProgress = totalDocs > 0 - ? Math.round(data.reduce((sum, doc) => sum + (doc.progressPercentage || 0), 0) / totalDocs) + ? Math.round((data?.reduce((sum, doc) => sum + (doc.progressPercentage || 0), 0) || 0) / totalDocs) : 0 - return { + const result = { total: totalDocs, overdue, dueSoon, @@ -128,6 +138,9 @@ export function DocumentStagesTable({ highPriority, avgProgress } + + console.log('DocumentStagesTable - stats:', result) + return result }, [data]) // 빠른 필터링 @@ -273,7 +286,7 @@ export function DocumentStagesTable({ <CardContent> <div className="text-2xl font-bold">{stats.total}</div> <p className="text-xs text-muted-foreground"> - {t('documentList.dashboard.totalDocumentCount', { total })} + {t('documentList.dashboard.totalDocumentCount', { total: stats.total })} </p> </CardContent> </Card> |
