summaryrefslogtreecommitdiff
path: root/lib/vendor-data-plant/services.ts
blob: e8ecd01c0ef899116be122bf1f10e7d0466e52e0 (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
"use server";

import db from "@/db/db"
import { items } from "@/db/schema/items"
import { projects } from "@/db/schema/projects"
import { eq } 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
): Promise<ProjectWithContracts[]> {
    // 세션에서 도메인 정보 가져오기
    const session = await getServerSession(authOptions)
    
    // EVCP 도메인일 때만 전체 조회
    const isEvcpDomain = session?.user?.domain === "evcp"
    
    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))
    
    if (!isEvcpDomain && vendorId) {
        query.where(eq(contracts.vendorId, vendorId))
    }

    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())
}