summaryrefslogtreecommitdiff
path: root/lib/vendor-data/services.ts
blob: 8c8b21d23b758e0e8f723c963eab3f62e0e96b98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"use server";

import db from "@/db/db"
import { items } from "@/db/schema/items"
import { projects } from "@/db/schema/projects"
import { eq, and } from "drizzle-orm"
import { contractItems, contracts } from "@/db/schema/contract";
import { getServerSession } from "next-auth";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";

export interface ProjectWithContracts {
    projectId: number
    projectCode: string
    projectName: string
    projectType: string
    
    contracts: {
        contractId: number
        contractNo: string
        contractName: string
        packages: {
            itemId: number      // contract_items.id
            itemName: string
        }[]
    }[]
}

export async function getVendorProjectsAndContracts(
    vendorId?: number,
    projectType?: "ship" | "plant"
): Promise<ProjectWithContracts[]> {
    // 세션에서 도메인 정보 가져오기
    const session = await getServerSession(authOptions)
    
    // EVCP 도메인일 때만 전체 조회
    const isEvcpDomain = session?.user?.domain === "evcp"
    
    // where 조건들을 배열로 관리
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const whereConditions: any[] = []
    
    // vendorId 조건 추가
    if (!isEvcpDomain && vendorId) {
        whereConditions.push(eq(contracts.vendorId, vendorId))
    }
    
    // projectType 조건 추가
    if (projectType) {
        whereConditions.push(eq(projects.type, projectType))
    }
    
    const query = db
        .select({
            projectId: projects.id,
            projectCode: projects.code,
            projectName: projects.name,
            projectType: projects.type,
            
            contractId: contracts.id,
            contractNo: contracts.contractNo,
            contractName: contracts.contractName,
            
            itemId: contractItems.id,
            itemName: items.itemName,
        })
        .from(contracts)
        .innerJoin(projects, eq(contracts.projectId, projects.id))
        .innerJoin(contractItems, eq(contractItems.contractId, contracts.id))
        .innerJoin(items, eq(contractItems.itemId, items.id))
    
    // 조건이 있으면 where 절 추가
    if (whereConditions.length > 0) {
        query.where(and(...whereConditions))
    }

    const rows = await query

    const projectMap = new Map<number, ProjectWithContracts>()

    for (const row of rows) {
        // 1) 프로젝트 그룹 찾기
        let projectEntry = projectMap.get(row.projectId)
        if (!projectEntry) {
            // 새 프로젝트 항목 생성
            projectEntry = {
                projectId: row.projectId,
                projectCode: row.projectCode,
                projectName: row.projectName,
                projectType: row.projectType,
                contracts: [],
            }
            projectMap.set(row.projectId, projectEntry)
        }

        // 2) 프로젝트 안에서 계약(contractId) 찾기
        let contractEntry = projectEntry.contracts.find(
            (c) => c.contractId === row.contractId
        )
        if (!contractEntry) {
            
            // 새 계약 항목
            contractEntry = {
                contractId: row.contractId,
                contractNo: row.contractNo,
                contractName: row.contractName,
                packages: [],
            }
            projectEntry.contracts.push(contractEntry)
        }

        // 3) 계약의 packages 배열에 아이템 추가 (중복 체크)
        // itemName이 같은 항목이 이미 존재하는지 확인
        const existingItem = contractEntry.packages.find(
            (pkg) => pkg.itemName === row.itemName
        )
        
        // 같은 itemName이 없는 경우에만 추가
        if (!existingItem) {
            contractEntry.packages.push({
                itemId: row.itemId,
                itemName: row.itemName,
            })
        }
    }

    return Array.from(projectMap.values())
}