summaryrefslogtreecommitdiff
path: root/lib/rfq-last/service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rfq-last/service.ts')
-rw-r--r--lib/rfq-last/service.ts141
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/rfq-last/service.ts b/lib/rfq-last/service.ts
new file mode 100644
index 00000000..f2710f02
--- /dev/null
+++ b/lib/rfq-last/service.ts
@@ -0,0 +1,141 @@
+// lib/rfq/service.ts
+'use server'
+
+import { unstable_noStore } from "next/cache";
+import db from "@/db/db";
+import { rfqsLastView } from "@/db/schema";
+import { and, desc, asc, ilike, or, eq, SQL, count, gte, lte,isNotNull,ne } from "drizzle-orm";
+import { filterColumns } from "@/lib/filter-columns";
+import { GetRfqsSchema } from "./validations";
+
+export async function getRfqs(input: GetRfqsSchema) {
+ unstable_noStore();
+
+ try {
+ const offset = (input.page - 1) * input.perPage;
+
+ // 1. RFQ 타입별 필터링
+ let typeFilter: SQL<unknown> | undefined = undefined;
+ if (input.rfqCategory) {
+ switch (input.rfqCategory) {
+ case "general":
+ // 일반견적: rfqType이 있는 경우
+ typeFilter = and(
+ isNotNull(rfqsLastView.rfqType),
+ ne(rfqsLastView.rfqType, '')
+ );
+ break;
+ case "itb":
+ // ITB: projectCompany가 있는 경우
+ typeFilter = and(
+ isNotNull(rfqsLastView.projectCompany),
+ ne(rfqsLastView.projectCompany, '')
+ );
+ break;
+ case "rfq":
+ // RFQ: prNumber가 있는 경우
+ typeFilter = and(
+ isNotNull(rfqsLastView.prNumber),
+ ne(rfqsLastView.prNumber, '')
+ );
+ break;
+ }
+ }
+
+ // 2. 고급 필터 처리
+ let advancedWhere: SQL<unknown> | undefined = undefined;
+
+ if (input.filters && Array.isArray(input.filters) && input.filters.length > 0) {
+ console.log("필터 적용:", input.filters.map(f => `${f.id} ${f.operator} ${f.value}`));
+
+ try {
+ advancedWhere = filterColumns({
+ table: rfqsLastView,
+ filters: input.filters,
+ joinOperator: input.joinOperator || 'and',
+ });
+
+ console.log("필터 조건 생성 완료");
+ } catch (error) {
+ console.error("필터 조건 생성 오류:", error);
+ advancedWhere = undefined;
+ }
+ }
+
+ // 3. 글로벌 검색 조건
+ let globalWhere: SQL<unknown> | undefined = undefined;
+ if (input.search) {
+ const s = `%${input.search}%`;
+
+ const searchConditions: SQL<unknown>[] = [
+ ilike(rfqsLastView.rfqCode, s),
+ ilike(rfqsLastView.itemCode, s),
+ ilike(rfqsLastView.itemName, s),
+ ilike(rfqsLastView.packageNo, s),
+ ilike(rfqsLastView.packageName, s),
+ ilike(rfqsLastView.picName, s),
+ ilike(rfqsLastView.engPicName, s),
+ ilike(rfqsLastView.projectCode, s),
+ ilike(rfqsLastView.projectName, s),
+ ilike(rfqsLastView.rfqTitle, s),
+ ilike(rfqsLastView.prNumber, s),
+ ].filter(Boolean);
+
+ if (searchConditions.length > 0) {
+ globalWhere = or(...searchConditions);
+ }
+ }
+
+ // 4. 최종 WHERE 조건 결합
+ const whereConditions: SQL<unknown>[] = [];
+ if (typeFilter) whereConditions.push(typeFilter);
+ if (advancedWhere) whereConditions.push(advancedWhere);
+ if (globalWhere) whereConditions.push(globalWhere);
+
+ const finalWhere = whereConditions.length > 0 ? and(...whereConditions) : undefined;
+
+ // 5. 전체 데이터 수 조회
+ const totalResult = await db
+ .select({ count: count() })
+ .from(rfqsLastView)
+ .where(finalWhere);
+
+ const total = totalResult[0]?.count || 0;
+
+ if (total === 0) {
+ return { data: [], pageCount: 0, total: 0 };
+ }
+
+ console.log("총 데이터 수:", total);
+
+ // 6. 정렬 및 페이징 처리
+ const orderByColumns = input.sort.map((sort) => {
+ const column = sort.id as keyof typeof rfqsLastView.$inferSelect;
+ return sort.desc
+ ? desc(rfqsLastView[column])
+ : asc(rfqsLastView[column]);
+ });
+
+ if (orderByColumns.length === 0) {
+ orderByColumns.push(desc(rfqsLastView.createdAt));
+ }
+
+ const rfqData = await db
+ .select()
+ .from(rfqsLastView)
+ .where(finalWhere)
+ .orderBy(...orderByColumns)
+ .limit(input.perPage)
+ .offset(offset);
+
+ const pageCount = Math.ceil(total / input.perPage);
+
+ console.log("반환 데이터 수:", rfqData.length);
+
+ return { data: rfqData, pageCount, total };
+ } catch (err) {
+ console.error("getRfqs 오류:", err);
+ return { data: [], pageCount: 0, total: 0 };
+ }
+}
+