/*==========================================================================*/ /* ST_MDR.pc - MDR 수수료 원장기표 온라인 서비스 (As-Is 원본, Oracle Pro*C)*/ /*--------------------------------------------------------------------------*/ /* 대상 : BC 매입시스템 / Tuxedo ATMI 서비스 ST_MDR */ /* DBMS : Oracle 19c 전처리 : Pro*C/C++ (proc) */ /* 기능 : 매입건 MDR 수수료를 계산·검증하여 원장(ledger)에 기표한다. */ /* ※ 이 파일은 **As-Is 역사 원본**이다. 현행 오픈스택 이식본은 */ /* app/src/st/svc/ST_MDR.pgc (ECPG/PostgreSQL). 컴파일 제외. */ /*--------------------------------------------------------------------------*/ /* 변경이력 */ /* 2000.03.21 PARK J.S 최초작성 (MDR 원장기표) */ /* 2007.11.05 HAN Y.J 가맹점 요율(mdr_bps) 마스터 연동, DECODE 분기 */ /* 2013.06.30 LEE S.W 부가세 분리기표, 복식부기 차대변 연계 */ /* 2019.09.01 CHOI H.W Oracle 11g -> 19c, 시퀀스 채번 표준화 */ /*==========================================================================*/ #include #include #include #include #include EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE oraca; EXEC ORACLE OPTION (ORACA=YES); #include "stfld.h" EXEC SQL BEGIN DECLARE SECTION; VARCHAR h_merch[64]; VARCHAR h_bizdate[9]; /* YYYYMMDD */ VARCHAR h_pstat[2]; long h_pid; long h_sid; long h_amount; long h_fee; long h_vat; long h_net; long h_mdr_bps; long h_led; long h_dup; EXEC SQL END DECLARE SECTION; /*--------------------------------------------------------------------------*/ /* ST_MDR - Tuxedo 서비스 엔트리 */ /*--------------------------------------------------------------------------*/ void ST_MDR(TPSVCINFO *rqst) { FBFR32 *fb = (FBFR32 *)rqst->data; char merch[64], bizdate[9]; userlog("ST_MDR 진입: MDR 수수료 원장기표"); EXEC SQL WHENEVER SQLERROR GOTO sql_error; /* ---- 1) 요청 FML 파싱 -------------------------------------------- */ h_pid = Fvall(fb, ST_PURCHASE_ID, 0); h_sid = Fvall(fb, ST_SETTLE_ID, 0); h_fee = Fvall(fb, ST_FEE, 0); Fget(fb, ST_BIZDATE, 0, bizdate, (FLDLEN32 *)NULL); strcpy((char *)h_bizdate.arr, bizdate); h_bizdate.len = strlen(bizdate); if (h_bizdate.len == 0) { EXEC SQL SELECT TO_CHAR(SYSDATE,'YYYYMMDD') INTO :h_bizdate FROM DUAL; } if (h_pid <= 0) { userlog("ST_MDR: 매입 ID 필수 pid=%ld", h_pid); Fchg(fb, ST_RC, 0, (char *)"E802", 0L); tpreturn(TPFAIL, 0, (char *)fb, 0L, 0L); return; } /* ---- 2) 매입원장 조회 (금액/가맹점/상태 확보, NVL 널가드) --------- */ EXEC SQL SELECT NVL(p.amount, 0), NVL(p.merchant_id, ' '), NVL(p.status, 'A') INTO :h_amount, :h_merch, :h_pstat FROM purchase p WHERE p.purchase_id = :h_pid; if (sqlca.sqlcode == 1403) { /* 체인 내 신규매입(미커밋)은 전문값을 사용 */ h_amount = Fvall(fb, ST_AMOUNT, 0); Fget(fb, ST_MERCHANT, 0, merch, (FLDLEN32 *)NULL); strcpy((char *)h_merch.arr, merch); h_merch.len = strlen(merch); userlog("ST_MDR: 미커밋 매입 pid=%ld — 전문값 사용", h_pid); } /* ---- 3) 요율조회 및 수수료 산출 (요청 fee 우선, 없으면 재계산) --- */ EXEC SQL SELECT NVL(m.mdr_bps, 25), DECODE(NVL(m.status,'N'), 'A', 0, 1) INTO :h_mdr_bps, :h_dup FROM merchant m WHERE m.merchant_id = :h_merch; if (h_fee <= 0) h_fee = ROUND(h_amount * h_mdr_bps / 10000); h_vat = ROUND(h_fee / 10); /* 수수료 부가세 10% 분리기표 */ h_net = h_amount - h_fee - h_vat; /* ---- 4) 중복기표 방지: 동일 매입 MDR 기존 원장 존재여부 --------- */ EXEC SQL SELECT COUNT(*) INTO :h_dup FROM ledger WHERE purchase_id = :h_pid AND entry_type = 'MDR'; if (h_dup > 0) { userlog("ST_MDR: MDR 기표 이미 존재 pid=%ld — 스킵", h_pid); Fchg(fb, ST_STATUS, 0, (char *)"D", 0L); EXEC SQL COMMIT WORK; tpreturn(TPSUCCESS, 0, (char *)fb, 0L, 0L); return; } /* ---- 5) 원장 기표: 시퀀스 채번 (.NEXTVAL) 후 MDR/VAT 2건 적재 --- */ EXEC SQL SELECT ledger_seq.NEXTVAL INTO :h_led FROM DUAL; EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date, posted_at) VALUES (:h_led, :h_pid, 'MDR', :h_fee, TO_DATE(:h_bizdate,'YYYYMMDD'), SYSDATE); EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date, posted_at) VALUES (ledger_seq.NEXTVAL, :h_pid, 'VAT', :h_vat, TO_DATE(:h_bizdate,'YYYYMMDD'), SYSDATE); /* ---- 6) 복식부기 전표 반영 (PL/SQL 원장 패키지) ----------------- */ EXEC SQL EXECUTE BEGIN pkg_ledger.post_voucher(:h_pid, 'MDR', :h_fee, :h_vat, :h_bizdate); END; END-EXEC; /* ---- 7) 정산연계: 수수료-원장반영 (LG_SETTLEPOST PL/SQL) -------- */ EXEC SQL EXECUTE BEGIN pkg_settle.settle_post(:h_pid, :h_sid, :h_fee, :h_net); END; END-EXEC; EXEC SQL COMMIT WORK; Fchg(fb, ST_LEDGER_ID, 0, (char *)&h_led, 0L); Fchg(fb, ST_FEE, 0, (char *)&h_fee, 0L); Fchg(fb, ST_NET, 0, (char *)&h_net, 0L); Fchg(fb, ST_STATUS, 0, (char *)"S", 0L); userlog("ST_MDR 완료: pid=%ld ledger=%ld fee=%ld vat=%ld net=%ld", h_pid, h_led, h_fee, h_vat, h_net); tpreturn(TPSUCCESS, 0, (char *)fb, 0L, 0L); return; sql_error: userlog("ST_MDR SQL 오류: %.70s (sqlcode=%ld)", sqlca.sqlerrm.sqlerrmc, sqlca.sqlcode); EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK WORK; Fchg(fb, ST_RC, 0, (char *)"E900", 0L); tpreturn(TPFAIL, 0, (char *)fb, 0L, 0L); return; }