diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-03 10:15:45 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-03 10:15:45 +0000 |
| commit | f2fafe555b65f9207c2c6e216b7d7b2ff83af866 (patch) | |
| tree | 4a230e4bde10a612150a299922bc04cb15b0930f /lib/rfq-last/service.ts | |
| parent | 1e857a0b1443ad2124caf3d180b7195651fe33e4 (diff) | |
(최겸) 구매 PQ/실사 수정
Diffstat (limited to 'lib/rfq-last/service.ts')
| -rw-r--r-- | lib/rfq-last/service.ts | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/lib/rfq-last/service.ts b/lib/rfq-last/service.ts index 8475aac0..2c1aa2ca 100644 --- a/lib/rfq-last/service.ts +++ b/lib/rfq-last/service.ts @@ -5515,4 +5515,233 @@ export async function getVendorDocumentConfirmStatus( console.error("문서 확정 상태 조회 중 오류:", error); return { isConfirmed: false, count: 0 }; } +} + +// 일반견적 수정 입력 인터페이스 +interface UpdateGeneralRfqInput { + id: number; // 수정할 RFQ ID + rfqType: string; + rfqTitle: string; + dueDate: Date; + picUserId: number; + projectId?: number; + remark?: string; + items: Array<{ + itemCode: string; + itemName: string; + materialCode?: string; + materialName?: string; + quantity: number; + uom: string; + remark?: string; + }>; + updatedBy: number; +} + +// 일반견적 수정 서버 액션 +export async function updateGeneralRfqAction(input: UpdateGeneralRfqInput) { + try { + // 트랜잭션으로 처리 + const result = await db.transaction(async (tx) => { + // 1. 기존 RFQ 조회 (존재 확인 및 상태 확인) + const existingRfq = await tx + .select() + .from(rfqsLast) + .where(eq(rfqsLast.id, input.id)) + .limit(1); + + if (!existingRfq || existingRfq.length === 0) { + throw new Error("수정할 일반견적을 찾을 수 없습니다"); + } + + const rfq = existingRfq[0]; + + // 상태 검증 (RFQ 생성 상태만 수정 가능) + if (rfq.status !== "RFQ 생성") { + throw new Error("RFQ 생성 상태인 일반견적만 수정할 수 있습니다"); + } + + // 2. 구매 담당자 정보 조회 + const picUser = await tx + .select({ + name: users.name, + email: users.email, + userCode: users.userCode + }) + .from(users) + .where(eq(users.id, input.picUserId)) + .limit(1); + + if (!picUser || picUser.length === 0) { + throw new Error("구매 담당자를 찾을 수 없습니다"); + } + + // 3. userCode 확인 (3자리) + const userCode = picUser[0].userCode; + if (!userCode || userCode.length !== 3) { + throw new Error("구매 담당자의 userCode가 올바르지 않습니다 (3자리 필요)"); + } + + // 4. 대표 아이템 정보 추출 (첫 번째 아이템) + const representativeItem = input.items[0]; + + // 5. rfqsLast 테이블 업데이트 + const [updatedRfq] = await tx + .update(rfqsLast) + .set({ + rfqType: input.rfqType, + rfqTitle: input.rfqTitle, + dueDate: input.dueDate, + projectId: input.projectId || null, + itemCode: representativeItem.itemCode, + itemName: representativeItem.itemName, + pic: input.picUserId, + picCode: userCode, + picName: picUser[0].name || '', + remark: input.remark || null, + updatedBy: input.updatedBy, + updatedAt: new Date(), + }) + .where(eq(rfqsLast.id, input.id)) + .returning(); + + // 6. 기존 rfqPrItems 삭제 후 재삽입 + await tx + .delete(rfqPrItems) + .where(eq(rfqPrItems.rfqsLastId, input.id)); + + // 7. rfqPrItems 테이블에 아이템들 재삽입 + const prItemsData = input.items.map((item, index) => ({ + rfqsLastId: input.id, + rfqItem: `${index + 1}`.padStart(3, '0'), // 001, 002, ... + prItem: null, // 일반견적에서는 PR 아이템 번호를 null로 설정 + prNo: null, // 일반견적에서는 PR 번호를 null로 설정 + + materialCode: item.materialCode || item.itemCode, // SAP 자재코드 (없으면 자재그룹코드 사용) + materialCategory: item.itemCode, // 자재그룹코드 + materialDescription: item.materialName || item.itemName, // SAP 자재명 (없으면 자재그룹명 사용) + quantity: item.quantity, + uom: item.uom, + + majorYn: index === 0, // 첫 번째 아이템을 주요 아이템으로 설정 + remark: item.remark || null, + })); + + await tx.insert(rfqPrItems).values(prItemsData); + + return updatedRfq; + }); + + return { + success: true, + message: "일반견적이 성공적으로 수정되었습니다", + data: { + id: result.id, + rfqCode: result.rfqCode, + }, + }; + + } catch (error) { + console.error("일반견적 수정 오류:", error); + + if (error instanceof Error) { + return { + success: false, + error: error.message, + }; + } + + return { + success: false, + error: "일반견적 수정 중 오류가 발생했습니다", + }; + } +} + +// 일반견적 수정용 데이터 조회 함수 +export async function getGeneralRfqForUpdate(rfqId: number) { + try { + // RFQ 기본 정보 조회 + const rfqData = await db + .select({ + id: rfqsLast.id, + rfqCode: rfqsLast.rfqCode, + rfqType: rfqsLast.rfqType, + rfqTitle: rfqsLast.rfqTitle, + status: rfqsLast.status, + dueDate: rfqsLast.dueDate, + projectId: rfqsLast.projectId, + pic: rfqsLast.pic, + picCode: rfqsLast.picCode, + picName: rfqsLast.picName, + remark: rfqsLast.remark, + createdAt: rfqsLast.createdAt, + updatedAt: rfqsLast.updatedAt, + }) + .from(rfqsLast) + .where( + and( + eq(rfqsLast.id, rfqId), + eq(rfqsLast.status, "RFQ 생성") // RFQ 생성 상태만 조회 + ) + ) + .limit(1); + + if (!rfqData || rfqData.length === 0) { + return { + success: false, + error: "수정할 일반견적을 찾을 수 없거나 수정할 수 없는 상태입니다", + }; + } + + const rfq = rfqData[0]; + + // RFQ 아이템들 조회 + const items = await db + .select({ + rfqItem: rfqPrItems.rfqItem, + materialCode: rfqPrItems.materialCode, + materialCategory: rfqPrItems.materialCategory, + materialDescription: rfqPrItems.materialDescription, + quantity: rfqPrItems.quantity, + uom: rfqPrItems.uom, + remark: rfqPrItems.remark, + }) + .from(rfqPrItems) + .where(eq(rfqPrItems.rfqsLastId, rfqId)) + .orderBy(rfqPrItems.rfqItem); + + // 아이템 데이터를 폼 형식으로 변환 + const formItems = items.map(item => ({ + itemCode: item.materialCategory || "", // 자재그룹코드 + itemName: item.materialDescription || "", // 자재그룹명 + materialCode: item.materialCode || "", // SAP 자재코드 + materialName: item.materialDescription || "", // SAP 자재명 (설명으로 사용) + quantity: Math.floor(Number(item.quantity)), // 소수점 제거 + uom: item.uom, + remark: item.remark || "", + })); + + return { + success: true, + data: { + id: rfq.id, + rfqCode: rfq.rfqCode, + rfqType: rfq.rfqType, + rfqTitle: rfq.rfqTitle, + dueDate: rfq.dueDate, + picUserId: rfq.pic, + projectId: rfq.projectId, + remark: rfq.remark, + items: formItems, + }, + }; + + } catch (error) { + console.error("일반견적 조회 오류:", error); + return { + success: false, + error: "일반견적 조회 중 오류가 발생했습니다", + }; + } }
\ No newline at end of file |
