diff options
Diffstat (limited to 'app/api/basic-contract')
| -rw-r--r-- | app/api/basic-contract/status/route.ts | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/app/api/basic-contract/status/route.ts b/app/api/basic-contract/status/route.ts new file mode 100644 index 00000000..f543accd --- /dev/null +++ b/app/api/basic-contract/status/route.ts @@ -0,0 +1,141 @@ +// /app/api/basic-contract/status/route.ts + +import { NextRequest, NextResponse } from "next/server"; +import db from "@/db/db"; +import { basicContract, vendors, basicContractTemplates } from "@/db/schema"; +import { eq, and, inArray, desc } from "drizzle-orm"; +import { differenceInDays } from "date-fns"; + +/** + * 계약 요청 상태 확인 API + */ +export async function POST(request: NextRequest) { + try { + // 요청 본문 파싱 + const body = await request.json(); + const { vendorIds, templateIds } = body; + + // 필수 파라미터 확인 + if (!vendorIds || !templateIds || !Array.isArray(vendorIds) || !Array.isArray(templateIds)) { + return NextResponse.json( + { success: false, error: "유효하지 않은 요청 형식입니다." }, + { status: 400 } + ); + } + + // 각 협력업체-템플릿 조합에 대한 최신 계약 요청 상태 확인 + const requests = await db + .select({ + vendorId: basicContract.vendorId, + templateId: basicContract.templateId, + status: basicContract.status, + createdAt: basicContract.createdAt, + updatedAt: basicContract.updatedAt, + }) + .from(basicContract) + .where( + and( + inArray(basicContract.vendorId, vendorIds), + inArray(basicContract.templateId, templateIds) + ) + ) + .orderBy(desc(basicContract.createdAt)); + + // 협력업체 정보 가져오기 + const vendorData = await db + .select({ + id: vendors.id, + vendorName: vendors.vendorName, + }) + .from(vendors) + .where(inArray(vendors.id, vendorIds)); + + // 템플릿 정보 가져오기 + const templateData = await db + .select({ + id: basicContractTemplates.id, + templateName: basicContractTemplates.templateName, + updatedAt: basicContractTemplates.updatedAt, + }) + .from(basicContractTemplates) + .where(inArray(basicContractTemplates.id, templateIds)); + + // 데이터 가공 - 협력업체별, 템플릿별로 상태 매핑 + const vendorMap = new Map(vendorData.map(v => [v.id, v])); + const templateMap = new Map(templateData.map(t => [t.id, t])); + + const uniqueRequests = new Map(); + + // 각 협력업체-템플릿 조합에 대해 가장 최근 요청만 사용 + requests.forEach(req => { + const key = `${req.vendorId}-${req.templateId}`; + if (!uniqueRequests.has(key)) { + uniqueRequests.set(key, req); + } + }); + + // 상태 정보 생성 + const statusData = []; + + // 요청 만료 기준 - 30일 + const EXPIRATION_DAYS = 30; + + // 모든 협력업체-템플릿 조합에 대해 상태 확인 + vendorIds.forEach(vendorId => { + templateIds.forEach(templateId => { + const key = `${vendorId}-${templateId}`; + const request = uniqueRequests.get(key); + const vendor = vendorMap.get(vendorId); + const template = templateMap.get(templateId); + + if (!vendor || !template) return; + + let status = "NONE"; // 기본 상태: 요청 없음 + let createdAt = new Date(); + let isExpired = false; + let isUpdated = false; + + if (request) { + status = request.status; + createdAt = request.createdAt; + + // 요청이 오래되었는지 확인 (PENDING 상태일 때만 적용) + if (status === "PENDING") { + isExpired = differenceInDays(new Date(), createdAt) > EXPIRATION_DAYS; + } + + // 요청 이후 템플릿이 업데이트되었는지 확인 + if (template.updatedAt && request.createdAt) { + isUpdated = template.updatedAt > request.createdAt; + } + } + + statusData.push({ + vendorId, + vendorName: vendor.vendorName, + templateId, + templateName: template.templateName, + status, + createdAt, + isExpired, + isUpdated, + }); + }); + }); + + // 성공 응답 반환 + return NextResponse.json({ success: true, data: statusData }); + + } catch (error) { + console.error("계약 상태 확인 중 오류:", error); + + // 오류 응답 반환 + return NextResponse.json( + { + success: false, + error: "계약 상태 확인 중 오류가 발생했습니다." + }, + { status: 500 } + ); + } +}
\ No newline at end of file |
