summaryrefslogtreecommitdiff
path: root/app/api/basic-contract
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/basic-contract')
-rw-r--r--app/api/basic-contract/status/route.ts141
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