summaryrefslogtreecommitdiff
path: root/lib/vendor-document-list
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-document-list')
-rw-r--r--lib/vendor-document-list/plant/document-stages-columns.tsx150
-rw-r--r--lib/vendor-document-list/plant/document-stages-service.ts37
-rw-r--r--lib/vendor-document-list/plant/document-stages-table.tsx37
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>