Wave E/F: 업무흐름 tpcall 오케스트레이션 + 크로스브랜치 교착 제거
477개 서비스를 tpcall 체인으로 연결하고(2 → 477), 그 과정에서 드러난
런타임 결함들을 실행 검증으로 잡아냈다.
체인 오케스트레이션 (Wave E)
- 매입/승인/정산/지급/대사/원장/마감/마스터/전문 흐름을 모듈 간 tpcall 로 연결
- 호출그래프 553노드 494엣지, 순환 0, SELFCALL 0
- 핵심 경로: ACQUIRE→RECONCILE→SETTLE→ST_MDR→LG_SETTLEPOST (6단, XA 2PC)
런타임 결함 수정 (Wave F) — 정적 게이트로는 잡히지 않던 것들
1. 모듈내 체인 자기교착: 모듈 서버 카피가 1이면 SETTLE→ST_MDR 처럼 같은
서버로 되돌아오는 호출이 자기 요청을 못 꺼내 TPETIME. 카피 4로 상향.
2. 크로스브랜치 핫로우 교착: 한 글로벌 트랜잭션의 형제 XA 브랜치가 같은 행을
UPDATE 하면 같은 트랜잭션이라 락이 안 풀려 타임아웃까지 블록된다.
- mg_channel: 비소유자 96개 서비스의 UPDATE 제거, STAN 은 시퀀스 채번으로
(실제 전문 스위치 방식). 생애주기 소유자 7개만 UPDATE 유지.
- lg_merch_bal: ACQ_SETTLELINK 의 LG_SETTLEPOST 다이아몬드 호출 제거.
교착일 뿐 아니라 같은 정산건이 원장에 이중 전기되는 회계 오류였다.
- cl_close_log / py_payout / lg_account_bal: CHAIN 마커로 쓰기 소유자 일원화.
py_payout 건은 피호출자가 호출자의 미커밋 승인을 볼 수 없어 기능적으로도
동작 불능이었다.
3. cm_log PK 충돌: st 131개 파일이 max(log_id)+1 로 채번해 nextval 을 쓰는
피호출자와 동일 PK 를 INSERT, 미커밋 인덱스 엔트리에 걸려 블록. 전부
nextval('cm_log_seq') 로 전환.
4. strncpy 스택 파괴: cmdb_get_param 이 strncpy(out, h_val, 127) 로 항상 128
바이트를 써서, bizdate[16] 을 넘기는 호출부 133곳이 매번 호출자 스택 112
바이트를 훼손했다. 인접 ecpg 호스트 변수가 오염돼 서버 카피가 세그폴트.
DB 락 대기가 0인데 60초 블록되는 증상의 원인. cm_code/py_payout_reject 동일.
5. ACQ_CANCEL→LIMIT_RST 입력계약 불일치: 카드번호를 안 실어 보내 항상 거절.
승인원장에서 카드를 끌어오고, 무승인 매입은 한도원복을 생략하도록 수정.
6. mgdb_channel_bump_stan: 활동 채널 전체를 한 번에 잠그는 다중행 UPDATE
(호출자 0인 잠복 지뢰). 시퀀스 채번 + 집계 조회로 교체.
화면
- 기본값을 실존 시드 키로 부팅 시 조회해 덮어쓴다. 기존 플레이스홀더
(card_limit 에 없는 카드, 8자리 영업일)로는 처리성 화면이 전부 거절당했다.
- 게이트웨이가 단일 스레드 직렬 루프라 기본값 조회도 순차로 수행.
검증 (실측)
- 통합 빌드: modules=11 servers=11 batches=506, error 0
- 도메인: 45 프로세스, 1,466 서비스 AVAIL
- 체인 전수 스모크 477/477 응답, TPETIME/TPEABORT 0건, 최대 530ms
- AUTH: 수정 전 60초 블록→TPEABORT, 수정 후 0.215초 ok:true
- 6단 매입 체인 COMMIT OK, 미결 2PC 0
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4cede852a0
commit
074d244bba
654 changed files with 36008 additions and 2805 deletions
|
|
@ -34,6 +34,72 @@ void SETTLE(TPSVCINFO *p)
|
|||
setl(b, T_SETTLE_ID, h_sid);
|
||||
Bchg(b, T_STATUS, 0, "S", 0L);
|
||||
userlog("SETTLE pid=%ld settlement_id=%ld net=%ld", h_pid, h_sid, h_net);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: SETTLE -> ST_MDR (정산확정-수수료산출) =====
|
||||
* XA 규율: tpcall 로 부르는 ST_MDR 는 별도 XA 브랜치라 SETTLE 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "SETTLE", 0L);
|
||||
Bchg(b, T_REASON, 0, "정산확정-수수료산출", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[SETTLE] 정산확정-수수료산출: 체인 호출 -> ST_MDR pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("ST_MDR", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[SETTLE] tpcall(ST_MDR) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8710);
|
||||
Bchg(b, T_MSG, 0, "수수료 산출 체인(ST_MDR) 호출 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* SETTLE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "SETTLE", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[SETTLE] 정산확정-수수료산출: 체인 완료 <- ST_MDR pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_ADJHIST(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "매입별 조정 이력 요약. (심화판) [ST_ADJHIST] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_ADJREVERSE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "기존 조정을 반대부호로 상쇄. (심화판) [ST_ADJREVERSE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -130,6 +130,67 @@ void ST_ADJREVERSE(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 기존 조정을 반대부호로 상쇄. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_ADJREVERSE -> LG_REVERSE (조정취소-원장역분개) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_REVERSE 는 별도 XA 브랜치라 ST_ADJREVERSE 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_ADJREVERSE", 0L);
|
||||
Bchg(b, T_REASON, 0, "조정취소-원장역분개", 0L);
|
||||
userlog("[ST_ADJREVERSE] 조정취소-원장역분개: 체인 호출 -> LG_REVERSE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_ADJREVERSE] tpcall(LG_REVERSE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8720);
|
||||
Bchg(b, T_MSG, 0, "조정취소 역분개(LG_REVERSE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_ADJREVERSE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_ADJREVERSE", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_ADJREVERSE] 조정취소-원장역분개: 체인 완료 <- LG_REVERSE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ void ST_ADJUST(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 조정 (가감) 기록. (심화판) [ST_ADJUST] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -137,6 +137,67 @@ void ST_ADJUST(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 정산 조정 (가감) 기록. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_ADJUST -> LG_POST (정산조정-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_ADJUST 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_ADJUST", 0L);
|
||||
Bchg(b, T_REASON, 0, "정산조정-원장반영", 0L);
|
||||
userlog("[ST_ADJUST] 정산조정-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_ADJUST] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8719);
|
||||
Bchg(b, T_MSG, 0, "정산조정 원장반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_ADJUST 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_ADJUST", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_ADJUST] 정산조정-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_ADVANCE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "선지급 예약: 지급 레코드(SCHEDULED) 생성. (심화판) [ST_ADVANCE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_APPEALSTAT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "이의신청 조정 건수/금액 통계. (심화판) [ST_APPEALSTAT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_APPROVE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 승인 (CONFIRMED -> APPROVED). (심화판) [ST_APPROVE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -143,6 +143,72 @@ void ST_APPROVE(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 정산 승인 (CONFIRMED -> APPROVED). (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_APPROVE -> PAY_FILEGEN (정산승인-지급파일생성) =====
|
||||
* XA 규율: tpcall 로 부르는 PAY_FILEGEN 는 별도 XA 브랜치라 ST_APPROVE 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_APPROVE", 0L);
|
||||
Bchg(b, T_REASON, 0, "정산승인-지급파일생성", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[ST_APPROVE] 정산승인-지급파일생성: 체인 호출 -> PAY_FILEGEN pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("PAY_FILEGEN", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_APPROVE] tpcall(PAY_FILEGEN) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8715);
|
||||
Bchg(b, T_MSG, 0, "지급 파일생성(PAY_FILEGEN) 트리거 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_APPROVE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_APPROVE", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_APPROVE] 정산승인-지급파일생성: 체인 완료 <- PAY_FILEGEN pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_APPROVEALL(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "당일 지급 예정 일괄 승인(->PAID). (심화판) [ST_APPROVEALL] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -137,6 +137,72 @@ void ST_APPROVEALL(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 당일 지급 예정 일괄 승인(->PAID). (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_APPROVEALL -> PAY_FILEGEN (일괄승인-지급파일생성) =====
|
||||
* XA 규율: tpcall 로 부르는 PAY_FILEGEN 는 별도 XA 브랜치라 ST_APPROVEALL 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_APPROVEALL", 0L);
|
||||
Bchg(b, T_REASON, 0, "일괄승인-지급파일생성", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[ST_APPROVEALL] 일괄승인-지급파일생성: 체인 호출 -> PAY_FILEGEN pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("PAY_FILEGEN", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_APPROVEALL] tpcall(PAY_FILEGEN) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8716);
|
||||
Bchg(b, T_MSG, 0, "일괄 지급파일 생성 트리거 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_APPROVEALL 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_APPROVEALL", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_APPROVEALL] 일괄승인-지급파일생성: 체인 완료 <- PAY_FILEGEN pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_BADDEBT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "장기 미수 대손 상각(상계+취소). (심화판) [ST_BADDEBT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_BANDRATE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "금액 구간 요율(bps) 조회. (심화판) [ST_BANDRATE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_BANDSIM(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "적용가능 구간 중 최고 요율 시뮬. (심화판) [ST_BANDSIM] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_BIWEEKLY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "2주 주기 net 합계 지급 예정. (심화판) [ST_BIWEEKLY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_BYMERCH(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "가맹점별 정산 집계 upsert. (심화판) [ST_BYMERCH] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ void ST_CANCEL(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 취소: 상태 CANCELLED + 취소 조정. (심화판) [ST_CANCEL] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -145,6 +145,67 @@ void ST_CANCEL(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 정산 취소: 상태 CANCELLED + 취소 조정. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_CANCEL -> LG_REVERSE (정산취소-원장역분개) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_REVERSE 는 별도 XA 브랜치라 ST_CANCEL 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CANCEL", 0L);
|
||||
Bchg(b, T_REASON, 0, "정산취소-원장역분개", 0L);
|
||||
userlog("[ST_CANCEL] 정산취소-원장역분개: 체인 호출 -> LG_REVERSE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_CANCEL] tpcall(LG_REVERSE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8718);
|
||||
Bchg(b, T_MSG, 0, "정산취소 역분개(LG_REVERSE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_CANCEL 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CANCEL", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_CANCEL] 정산취소-원장역분개: 체인 완료 <- LG_REVERSE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_CAP(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "수수료 상한 적용: 상한 초과분을 감액 조정. (심화판) [ST_CAP] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ void ST_CAPCHECK(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "상한 초과 여부 판정 (조정 없음). (심화판) [ST_CAPCHECK] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -135,6 +135,67 @@ void ST_CAPCHECK(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 상한 초과 여부 판정 (조정 없음). (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_CAPCHECK -> VL_SETTLE (상한검증-정산검증) =====
|
||||
* XA 규율: tpcall 로 부르는 VL_SETTLE 는 별도 XA 브랜치라 ST_CAPCHECK 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CAPCHECK", 0L);
|
||||
Bchg(b, T_REASON, 0, "상한검증-정산검증", 0L);
|
||||
userlog("[ST_CAPCHECK] 상한검증-정산검증: 체인 호출 -> VL_SETTLE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("VL_SETTLE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_CAPCHECK] tpcall(VL_SETTLE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8732);
|
||||
Bchg(b, T_MSG, 0, "상한검증(VL_SETTLE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_CAPCHECK 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CAPCHECK", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_CAPCHECK] 상한검증-정산검증: 체인 완료 <- VL_SETTLE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CARRYOVER(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "미정산분 익영업일 이월 예약. (심화판) [ST_CARRYOVER] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_CASHBACK(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "캐시백 지급 예정 등록. (심화판) [ST_CASHBACK] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CHAINSET(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "업종 체인 통합 net 지급. (심화판) [ST_CHAINSET] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CHARGEBACK(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "차지백 회수 조정 + 지급 보류. (심화판) [ST_CHARGEBACK] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -139,6 +139,67 @@ void ST_CHARGEBACK(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 차지백 회수 조정 + 지급 보류. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_CHARGEBACK -> LG_REVERSE (차지백-원장역분개) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_REVERSE 는 별도 XA 브랜치라 ST_CHARGEBACK 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CHARGEBACK", 0L);
|
||||
Bchg(b, T_REASON, 0, "차지백-원장역분개", 0L);
|
||||
userlog("[ST_CHARGEBACK] 차지백-원장역분개: 체인 호출 -> LG_REVERSE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_CHARGEBACK] tpcall(LG_REVERSE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8736);
|
||||
Bchg(b, T_MSG, 0, "차지백 역분개(LG_REVERSE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_CHARGEBACK 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CHARGEBACK", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_CHARGEBACK] 차지백-원장역분개: 체인 완료 <- LG_REVERSE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ void ST_CHNLSTAT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "채널별 정산 net 분해 통계. (심화판) [ST_CHNLSTAT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_COLLATERAL(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "가맹점 누적 보증금 잔액 조회. (심화판) [ST_COLLATERAL] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_CONFIRM(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 확정 (SETTLED -> CONFIRMED). (심화판) [ST_CONFIRM] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -143,6 +143,72 @@ void ST_CONFIRM(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 정산 확정 (SETTLED -> CONFIRMED). (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_CONFIRM -> PAY_FILEGEN (정산확정-지급파일생성) =====
|
||||
* XA 규율: tpcall 로 부르는 PAY_FILEGEN 는 별도 XA 브랜치라 ST_CONFIRM 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CONFIRM", 0L);
|
||||
Bchg(b, T_REASON, 0, "정산확정-지급파일생성", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[ST_CONFIRM] 정산확정-지급파일생성: 체인 호출 -> PAY_FILEGEN pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("PAY_FILEGEN", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_CONFIRM] tpcall(PAY_FILEGEN) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8714);
|
||||
Bchg(b, T_MSG, 0, "지급 파일생성(PAY_FILEGEN) 트리거 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_CONFIRM 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CONFIRM", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_CONFIRM] 정산확정-지급파일생성: 체인 완료 <- PAY_FILEGEN pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_COUPONADJ(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "쿠폰 사용액 정산 조정(가산). (심화판) [ST_COUPONADJ] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ void ST_CXLRECALC(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "취소 누계 반영 정산 net 재계산. (심화판) [ST_CXLRECALC] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -145,6 +145,72 @@ void ST_CXLRECALC(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 취소 누계 반영 정산 net 재계산. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_CXLRECALC -> ST_MDR (취소재계산-수수료재산출) =====
|
||||
* XA 규율: tpcall 로 부르는 ST_MDR 는 별도 XA 브랜치라 ST_CXLRECALC 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CXLRECALC", 0L);
|
||||
Bchg(b, T_REASON, 0, "취소재계산-수수료재산출", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[ST_CXLRECALC] 취소재계산-수수료재산출: 체인 호출 -> ST_MDR pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("ST_MDR", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_CXLRECALC] tpcall(ST_MDR) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8728);
|
||||
Bchg(b, T_MSG, 0, "취소 재계산 수수료 재산출 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_CXLRECALC 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_CXLRECALC", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_CXLRECALC] 취소재계산-수수료재산출: 체인 완료 <- ST_MDR pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CYCLED1(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "D+1 주기 지급 예약. (심화판) [ST_CYCLED1] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CYCLED2(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "D+2 주기 지급 예약 (확정분만). (심화판) [ST_CYCLED2] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CYCLED3(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "D+3 영업일 지급 예정 등록. (심화판) [ST_CYCLED3] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CYCLEMON(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "월간 통합 지급 예약 (직접 INSERT). (심화판) [ST_CYCLEMON] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CYCLEQTR(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "기준일까지 누적 net 분기 지급. (심화판) [ST_CYCLEQTR] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CYCLESET(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "가맹점 한도 기반 정산주기 코드 파생. (심화판) [ST_CYCLESET] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_CYCLEWEEK(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "주간(7일 윈도) 통합 지급 예약. (심화판) [ST_CYCLEWEEK] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_DAILYCLOSE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 일마감 선언 (3원 집계 + 마감 원장). (심화판) [ST_DAILYCLOSE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -134,6 +134,67 @@ void ST_DAILYCLOSE(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 정산 일마감 선언 (3원 집계 + 마감 원장). (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_DAILYCLOSE -> LG_POST (일마감-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_DAILYCLOSE 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_DAILYCLOSE", 0L);
|
||||
Bchg(b, T_REASON, 0, "일마감-원장반영", 0L);
|
||||
userlog("[ST_DAILYCLOSE] 일마감-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_DAILYCLOSE] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8741);
|
||||
Bchg(b, T_MSG, 0, "일마감 원장반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_DAILYCLOSE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_DAILYCLOSE", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_DAILYCLOSE] 일마감-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_DEBTCOLLECT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "채권 회수 입금 정산. (심화판) [ST_DEBTCOLLECT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_DEBTNET(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "지급 채무 대 미수 채권 상계. (심화판) [ST_DEBTNET] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_DELAYINT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "지연이자(net * bps/10000 * 일수) 정산 상세 기록. (심화판) [ST_DELAYINT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_DEPOSITCUT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "지급액 보증금 원천 차감. (심화판) [ST_DEPOSITCUT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_DEPOSITSET(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "보증금 예치 기록 + net 차감. (심화판) [ST_DEPOSITSET] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ void ST_DIFFCHK(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 net vs 매입 net 차이 점검. (심화판) [ST_DIFFCHK] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -144,6 +144,67 @@ void ST_DIFFCHK(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 정산 net vs 매입 net 차이 점검. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_DIFFCHK -> VL_SETTLE (차액검증-정산검증) =====
|
||||
* XA 규율: tpcall 로 부르는 VL_SETTLE 는 별도 XA 브랜치라 ST_DIFFCHK 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_DIFFCHK", 0L);
|
||||
Bchg(b, T_REASON, 0, "차액검증-정산검증", 0L);
|
||||
userlog("[ST_DIFFCHK] 차액검증-정산검증: 체인 호출 -> VL_SETTLE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("VL_SETTLE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_DIFFCHK] tpcall(VL_SETTLE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8730);
|
||||
Bchg(b, T_MSG, 0, "차액검증(VL_SETTLE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_DIFFCHK 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_DIFFCHK", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_DIFFCHK] 차액검증-정산검증: 체인 완료 <- VL_SETTLE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_DISPUTE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 이의신청 접수 (지급 보류 + 조정). (심화판) [ST_DISPUTE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_DISPUTERSV(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "이의신청 인용/기각 후속 처리. (심화판) [ST_DISPUTERSV] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_DTLSUM(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 상세 다중 집계 (건수/합/min/max/평균). (심화판) [ST_DTLSUM] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_EDIRECON(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "EDI 청구 vs 정산 집계 대사. (심화판) [ST_EDIRECON] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_EVENTFEE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "이벤트 반값 수수료 감면 기록. (심화판) [ST_EVENTFEE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_FEEPREVIEW(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 실수령 예상 견적. (심화판) [ST_FEEPREVIEW] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_FEERATIO(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "실효 수수료율 vs 계약 요율 편차 검증. (심화판) [ST_FEERATIO] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_FLATFEE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정액 수수료 적용 (고정액 정산 상세 기록). (심화판) [ST_FLATFEE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_FLATVSPCT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정액/정률 중 저가 방식 선택. (심화판) [ST_FLATVSPCT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_FXCONV(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "외화 환산: fx * rate/100 = KRW. (심화판) [ST_FXCONV] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_FXSETTLE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "외화 환산액 정산 상세 기록. (심화판) [ST_FXSETTLE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ void ST_GRADESTAT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "mdr_bps 등급별 가맹점 분포. (심화판) [ST_GRADESTAT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_GROWTHINC(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "전기 대비 매출 성장분 인센티브. (심화판) [ST_GROWTHINC] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_GRPALLOC(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "net 비중 안분 후 구성원별 지급 등록. (심화판) [ST_GRPALLOC] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ void ST_GRPROLLUP(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "그룹 구성원 매출/수수료/net rollup. (심화판) [ST_GRPROLLUP] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_GRPSETTLE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "그룹 prefix 통합정산 지급. (심화판) [ST_GRPSETTLE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -139,6 +139,67 @@ void ST_GRPSETTLE(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 그룹 prefix 통합정산 지급. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_GRPSETTLE -> LG_POST (그룹정산-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_GRPSETTLE 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_GRPSETTLE", 0L);
|
||||
Bchg(b, T_REASON, 0, "그룹정산-원장반영", 0L);
|
||||
userlog("[ST_GRPSETTLE] 그룹정산-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_GRPSETTLE] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8742);
|
||||
Bchg(b, T_MSG, 0, "그룹정산 원장반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_GRPSETTLE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_GRPSETTLE", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_GRPSETTLE] 그룹정산-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_HOLD(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "가맹점 지급 보류 (SCHEDULED -> HELD). (심화판) [ST_HOLD] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -137,6 +137,67 @@ void ST_HOLD(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 가맹점 지급 보류 (SCHEDULED -> HELD). (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_HOLD -> LG_POST (정산보류-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_HOLD 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_HOLD", 0L);
|
||||
Bchg(b, T_REASON, 0, "정산보류-원장반영", 0L);
|
||||
userlog("[ST_HOLD] 정산보류-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_HOLD] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8739);
|
||||
Bchg(b, T_MSG, 0, "정산보류 원장반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_HOLD 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_HOLD", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_HOLD] 정산보류-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_HOLDAMT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "임계액 이상 지급 일괄 보류. (심화판) [ST_HOLDAMT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_INSTANTPAY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "즉시 지급(PAID) 등록. (심화판) [ST_INSTANTPAY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -138,6 +138,72 @@ void ST_INSTANTPAY(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 즉시 지급(PAID) 등록. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_INSTANTPAY -> PAY_FILEGEN (즉시지급-지급파일생성) =====
|
||||
* XA 규율: tpcall 로 부르는 PAY_FILEGEN 는 별도 XA 브랜치라 ST_INSTANTPAY 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_INSTANTPAY", 0L);
|
||||
Bchg(b, T_REASON, 0, "즉시지급-지급파일생성", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[ST_INSTANTPAY] 즉시지급-지급파일생성: 체인 호출 -> PAY_FILEGEN pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("PAY_FILEGEN", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_INSTANTPAY] tpcall(PAY_FILEGEN) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8743);
|
||||
Bchg(b, T_MSG, 0, "즉시지급 파일생성 트리거 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_INSTANTPAY 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_INSTANTPAY", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_INSTANTPAY] 즉시지급-지급파일생성: 체인 완료 <- PAY_FILEGEN pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_ISSUERSTAT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "발급사별 수수료 분해 통계. (심화판) [ST_ISSUERSTAT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_LEDGERLINK(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정산 연계 원장 기록. (심화판) [ST_LEDGERLINK] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -130,6 +130,67 @@ void ST_LEDGERLINK(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 정산 연계 원장 기록. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_LEDGERLINK -> LG_POST (원장연계-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_LEDGERLINK 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_LEDGERLINK", 0L);
|
||||
Bchg(b, T_REASON, 0, "원장연계-원장반영", 0L);
|
||||
userlog("[ST_LEDGERLINK] 원장연계-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_LEDGERLINK] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8734);
|
||||
Bchg(b, T_MSG, 0, "원장연계 반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_LEDGERLINK 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_LEDGERLINK", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_LEDGERLINK] 원장연계-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_LEDGERSNAP(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "당일 정산 총액 원장 스냅샷. (심화판) [ST_LEDGERSNAP] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_LIMITCHK(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "일 매입 한도 잔여 점검. (심화판) [ST_LIMITCHK] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -132,6 +132,67 @@ void ST_LIMITCHK(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 일 매입 한도 잔여 점검. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_LIMITCHK -> VL_SETTLE (한도검증-정산검증) =====
|
||||
* XA 규율: tpcall 로 부르는 VL_SETTLE 는 별도 XA 브랜치라 ST_LIMITCHK 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_LIMITCHK", 0L);
|
||||
Bchg(b, T_REASON, 0, "한도검증-정산검증", 0L);
|
||||
userlog("[ST_LIMITCHK] 한도검증-정산검증: 체인 호출 -> VL_SETTLE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("VL_SETTLE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_LIMITCHK] tpcall(VL_SETTLE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8731);
|
||||
Bchg(b, T_MSG, 0, "한도검증(VL_SETTLE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_LIMITCHK 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_LIMITCHK", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_LIMITCHK] 한도검증-정산검증: 체인 완료 <- VL_SETTLE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_LOCKBATCH(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "당일 정산 일괄 잠금(SETTLED->LOCKED). (심화판) [ST_LOCKBATCH] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_LOYALTY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "누적 매출 기반 로열티 보상. (심화판) [ST_LOYALTY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,67 @@ void ST_MDR(TPSVCINFO *p)
|
|||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (nextval('ledger_seq'), :h_pid, 'MDR', :h_fee, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_MDR -> LG_SETTLEPOST (수수료-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_SETTLEPOST 는 별도 XA 브랜치라 ST_MDR 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_MDR", 0L);
|
||||
Bchg(b, T_REASON, 0, "수수료-원장반영", 0L);
|
||||
userlog("[ST_MDR] 수수료-원장반영: 체인 호출 -> LG_SETTLEPOST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_SETTLEPOST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_MDR] tpcall(LG_SETTLEPOST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8711);
|
||||
Bchg(b, T_MSG, 0, "수수료 원장반영(LG_SETTLEPOST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_MDR 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_MDR", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_MDR] 수수료-원장반영: 체인 완료 <- LG_SETTLEPOST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_MERCHRATE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "가맹점 계약 요율 수수료 산출/기록. (심화판) [ST_MERCHRATE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_MINFEE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "최저 수수료 미달분 보정. (심화판) [ST_MINFEE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_MKTGSHARE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "매출 기반 마케팅 분담금 부과. (심화판) [ST_MKTGSHARE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ void ST_MONTHLY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "월별 정산 net 합계 (biz_date LIKE 'YYYY-MM%'). (심화판) [ST_MONTHLY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_MONTHSTAT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "월(YYYY-MM) 정산 집계. (심화판) [ST_MONTHSTAT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ void ST_NEGSWEEP(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "음수 net 정산 일괄 취소. (심화판) [ST_NEGSWEEP] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_NETTING(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "당일 net 합계 조회. (심화판) [ST_NETTING] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -134,6 +134,67 @@ void ST_NETTING(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 당일 net 합계 조회. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_NETTING -> LG_POST (상계-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_NETTING 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_NETTING", 0L);
|
||||
Bchg(b, T_REASON, 0, "상계-원장반영", 0L);
|
||||
userlog("[ST_NETTING] 상계-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_NETTING] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8712);
|
||||
Bchg(b, T_MSG, 0, "상계 원장반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_NETTING 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_NETTING", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_NETTING] 상계-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_NEXTPAYDT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "다음 영업일(지급일) 계산. (심화판) [ST_NEXTPAYDT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -139,6 +139,70 @@ void ST_NEXTPAYDT(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 다음 영업일(지급일) 계산. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_NEXTPAYDT -> CM_BIZDAY (차기지급일-영업일계산) =====
|
||||
* XA 규율: tpcall 로 부르는 CM_BIZDAY 는 별도 XA 브랜치라 ST_NEXTPAYDT 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_NEXTPAYDT", 0L);
|
||||
Bchg(b, T_REASON, 0, "차기지급일-영업일계산", 0L);
|
||||
|
||||
Bchg(b, T_STR1, 0, "BIZDAY", 0L);
|
||||
if (getl(b, T_ARG1) <= 0) setl(b, T_ARG1, 1);
|
||||
userlog("[ST_NEXTPAYDT] 차기지급일-영업일계산: 체인 호출 -> CM_BIZDAY pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("CM_BIZDAY", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_NEXTPAYDT] tpcall(CM_BIZDAY) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8725);
|
||||
Bchg(b, T_MSG, 0, "차기지급일 영업일계산 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_NEXTPAYDT 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_NEXTPAYDT", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_NEXTPAYDT] 차기지급일-영업일계산: 체인 완료 <- CM_BIZDAY pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_OFFSET(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "상계: 음수 조정으로 채권 상계 기록. (심화판) [ST_OFFSET] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -130,6 +130,67 @@ void ST_OFFSET(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 상계: 음수 조정으로 채권 상계 기록. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_OFFSET -> LG_POST (차감-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_OFFSET 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_OFFSET", 0L);
|
||||
Bchg(b, T_REASON, 0, "차감-원장반영", 0L);
|
||||
userlog("[ST_OFFSET] 차감-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_OFFSET] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8713);
|
||||
Bchg(b, T_MSG, 0, "차감 원장반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_OFFSET 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_OFFSET", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_OFFSET] 차감-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_PARTIAL(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "부분정산 (잔여 한도 검증 후 PARTIAL 정산 생성). (심화판) [ST_PARTIAL] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_PARTNERSET(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "제휴사 지분 지급 예정 등록. (심화판) [ST_PARTNERSET] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void ST_PARTPAY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "net 일부 부분 지급(PAID). (심화판) [ST_PARTPAY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_PAYDATE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "지급일 산정(익영업일) 후 지급일 갱신. (심화판) [ST_PAYDATE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -139,6 +139,70 @@ void ST_PAYDATE(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 지급일 산정(익영업일) 후 지급일 갱신. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_PAYDATE -> CM_BIZDAY (지급일-영업일계산) =====
|
||||
* XA 규율: tpcall 로 부르는 CM_BIZDAY 는 별도 XA 브랜치라 ST_PAYDATE 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_PAYDATE", 0L);
|
||||
Bchg(b, T_REASON, 0, "지급일-영업일계산", 0L);
|
||||
|
||||
Bchg(b, T_STR1, 0, "BIZDAY", 0L);
|
||||
if (getl(b, T_ARG1) <= 0) setl(b, T_ARG1, 1);
|
||||
userlog("[ST_PAYDATE] 지급일-영업일계산: 체인 호출 -> CM_BIZDAY pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("CM_BIZDAY", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_PAYDATE] tpcall(CM_BIZDAY) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8724);
|
||||
Bchg(b, T_MSG, 0, "지급일 영업일계산(CM_BIZDAY) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_PAYDATE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_PAYDATE", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_PAYDATE] 지급일-영업일계산: 체인 완료 <- CM_BIZDAY pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_PAYRETRY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "취소 지급 익영업일 재예약. (심화판) [ST_PAYRETRY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ void ST_PAYSTATUS(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "가맹점 최신 지급 상태 조회. (심화판) [ST_PAYSTATUS] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_PCTFEE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정률 수수료 계산 (금액 x bps). (심화판) [ST_PCTFEE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ void ST_PRECONFIRM(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "보류 잔여 여부로 확정 가능 판정. (심화판) [ST_PRECONFIRM] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -135,6 +135,67 @@ void ST_PRECONFIRM(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 보류 잔여 여부로 확정 가능 판정. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_PRECONFIRM -> VL_SETTLE (사전확정-정산검증) =====
|
||||
* XA 규율: tpcall 로 부르는 VL_SETTLE 는 별도 XA 브랜치라 ST_PRECONFIRM 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_PRECONFIRM", 0L);
|
||||
Bchg(b, T_REASON, 0, "사전확정-정산검증", 0L);
|
||||
userlog("[ST_PRECONFIRM] 사전확정-정산검증: 체인 호출 -> VL_SETTLE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("VL_SETTLE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_PRECONFIRM] tpcall(VL_SETTLE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8717);
|
||||
Bchg(b, T_MSG, 0, "사전확정 정산검증(VL_SETTLE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_PRECONFIRM 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_PRECONFIRM", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_PRECONFIRM] 사전확정-정산검증: 체인 완료 <- VL_SETTLE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_PROMOAPPLY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "수수료 프로모션 할인(음수 조정). (심화판) [ST_PROMOAPPLY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_PROMOCALC(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "프로모션/이벤트 수수료 할인 정산. (심화판) [ST_PROMOCALC] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_RATEAPPLY(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "구간요율 적용 수수료 계산 + 정산 상세 기록. (심화판) [ST_RATEAPPLY] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -148,6 +148,72 @@ void ST_RATEAPPLY(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 구간요율 적용 수수료 계산 + 정산 상세 기록. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_RATEAPPLY -> ST_MDR (요율적용-수수료재산출) =====
|
||||
* XA 규율: tpcall 로 부르는 ST_MDR 는 별도 XA 브랜치라 ST_RATEAPPLY 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_RATEAPPLY", 0L);
|
||||
Bchg(b, T_REASON, 0, "요율적용-수수료재산출", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[ST_RATEAPPLY] 요율적용-수수료재산출: 체인 호출 -> ST_MDR pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("ST_MDR", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_RATEAPPLY] tpcall(ST_MDR) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8727);
|
||||
Bchg(b, T_MSG, 0, "요율적용 수수료 재산출 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_RATEAPPLY 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_RATEAPPLY", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_RATEAPPLY] 요율적용-수수료재산출: 체인 완료 <- ST_MDR pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_RATECARD(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "요율표 요약(구간수/최소/최대 bps). (심화판) [ST_RATECARD] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_RATECMP(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "두 요율 유형 적용 bps 비교. (심화판) [ST_RATECMP] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_RATEFLOOR(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정률 수수료 하한 보정 후 기록. (심화판) [ST_RATEFLOOR] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void ST_RATEMAX(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "정률 수수료 상한 절삭 후 기록. (심화판) [ST_RATEMAX] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_RATESIM(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "요율 시뮬레이션 (구간 판정 + 예상 수수료). (심화판) [ST_RATESIM] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_REBATE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "수수료 기반 리베이트 환급 조정. (심화판) [ST_REBATE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_RECALC(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "매입 수수료 기준 정산 net 재계산 + 갱신. (심화판) [ST_RECALC] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -143,6 +143,72 @@ void ST_RECALC(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 매입 수수료 기준 정산 net 재계산 + 갱신. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_RECALC -> ST_MDR (정산재계산-수수료재산출) =====
|
||||
* XA 규율: tpcall 로 부르는 ST_MDR 는 별도 XA 브랜치라 ST_RECALC 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_RECALC", 0L);
|
||||
Bchg(b, T_REASON, 0, "정산재계산-수수료재산출", 0L);
|
||||
|
||||
{
|
||||
long cx_dl = getl(b, T_DELTA);
|
||||
if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
|
||||
}
|
||||
userlog("[ST_RECALC] 정산재계산-수수료재산출: 체인 호출 -> ST_MDR pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("ST_MDR", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_RECALC] tpcall(ST_MDR) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8726);
|
||||
Bchg(b, T_MSG, 0, "수수료 재산출(ST_MDR) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_RECALC 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_RECALC", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_RECALC] 정산재계산-수수료재산출: 체인 완료 <- ST_MDR pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ void ST_RECVAGE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "기준일 이전 보류 미수금 집계. (심화판) [ST_RECVAGE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_RECVOFFSET(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "미수금-지급 상계 처리. (심화판) [ST_RECVOFFSET] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ST_RECVSTAT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "지급 상태별 분포 통계. (심화판) [ST_RECVSTAT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_REFERRAL(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "추천 유치 건당 보상 지급. (심화판) [ST_REFERRAL] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ST_REFUNDCALC(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "환불 비례 수수료 환급 기록. (심화판) [ST_REFUNDCALC] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -130,6 +130,67 @@ void ST_REFUNDCALC(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 환불 비례 수수료 환급 기록. (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_REFUNDCALC -> LG_REVERSE (환불정산-원장역분개) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_REVERSE 는 별도 XA 브랜치라 ST_REFUNDCALC 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_REFUNDCALC", 0L);
|
||||
Bchg(b, T_REASON, 0, "환불정산-원장역분개", 0L);
|
||||
userlog("[ST_REFUNDCALC] 환불정산-원장역분개: 체인 호출 -> LG_REVERSE pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_REFUNDCALC] tpcall(LG_REVERSE) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8737);
|
||||
Bchg(b, T_MSG, 0, "환불정산 역분개(LG_REVERSE) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_REFUNDCALC 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_REFUNDCALC", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_REFUNDCALC] 환불정산-원장역분개: 체인 완료 <- LG_REVERSE pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_RELAYFEE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "중계 수수료: 구간요율 조회 후 정산 상세 기록. (심화판) [ST_RELAYFEE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void ST_RELAYSPLIT(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "중계수수료 2자 분배 기록. (심화판) [ST_RELAYSPLIT] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void ST_RELEASE(TPSVCINFO *p)
|
|||
snprintf(msgbuf, sizeof(msgbuf), "지급 보류 해제 (HELD -> SCHEDULED). (심화판) [ST_RELEASE] pid=%ld fee=%ld delta=%ld net=%ld", h_pid, h_fee, h_delta, h_netsum);
|
||||
strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0;
|
||||
EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
|
||||
VALUES ((SELECT coalesce(max(log_id),0)+1 FROM cm_log), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 91); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }
|
||||
vstep = 5;
|
||||
|
||||
|
|
@ -137,6 +137,67 @@ void ST_RELEASE(TPSVCINFO *p)
|
|||
setl(b, T_ARG4, (long)vstep);
|
||||
/* ===== 9) 완료 로깅 ===== */
|
||||
userlog("[정산심화] 지급 보류 해제 (HELD -> SCHEDULED). (심화판) 완료 rc=0 pid=%ld fee=%ld net=%ld", h_pid, h_fee, h_netsum);
|
||||
|
||||
/* ===== 8b) 업무 체인 호출부: ST_RELEASE -> LG_POST (보류해제-원장반영) =====
|
||||
* XA 규율: tpcall 로 부르는 LG_POST 는 별도 XA 브랜치라 ST_RELEASE 가 방금
|
||||
* INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
|
||||
* UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
|
||||
* 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
|
||||
{
|
||||
long cx_rlen = 0;
|
||||
long cx_pid = getl(b, T_PURCHASE_ID);
|
||||
long cx_sid = getl(b, T_SETTLE_ID);
|
||||
long cx_amt = getl(b, T_AMOUNT);
|
||||
long cx_fee = getl(b, T_FEE);
|
||||
long cx_net = getl(b, T_NET);
|
||||
long cx_cnt = getl(b, T_COUNT);
|
||||
long cx_grs = getl(b, T_GROSS);
|
||||
long cx_samt, cx_sfee, cx_snet;
|
||||
char cx_bd[16], cx_mid[64], cx_sts[16];
|
||||
|
||||
gets_(b, T_BIZDATE, cx_bd, sizeof(cx_bd));
|
||||
gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
|
||||
gets_(b, T_STATUS, cx_sts, sizeof(cx_sts));
|
||||
if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
|
||||
if (cx_pid < 0) cx_pid = 0;
|
||||
if (cx_sid < 0) cx_sid = 0;
|
||||
cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
|
||||
cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
|
||||
cx_snet = (cx_net < 0) ? 0 : cx_net;
|
||||
|
||||
/* 하위가 필요로 하는 값을 전문에 적재 */
|
||||
Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
|
||||
if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_SETTLE_ID, cx_sid);
|
||||
setl(b, T_AMOUNT, cx_samt);
|
||||
setl(b, T_FEE, cx_sfee);
|
||||
setl(b, T_NET, cx_snet);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_RELEASE", 0L);
|
||||
Bchg(b, T_REASON, 0, "보류해제-원장반영", 0L);
|
||||
userlog("[ST_RELEASE] 보류해제-원장반영: 체인 호출 -> LG_POST pid=%ld sid=%ld amt=%ld biz=%s",
|
||||
cx_pid, cx_sid, cx_samt, cx_bd);
|
||||
if (tpcall("LG_POST", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
|
||||
userlog("[ST_RELEASE] tpcall(LG_POST) 실패: %s", tpstrerror(tperrno));
|
||||
setl(b, T_RC, 8740);
|
||||
Bchg(b, T_MSG, 0, "보류해제 원장반영(LG_POST) 실패", 0L);
|
||||
FAIL(b);
|
||||
}
|
||||
/* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
|
||||
* ST_RELEASE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
|
||||
setl(b, T_PURCHASE_ID, cx_pid);
|
||||
setl(b, T_AMOUNT, cx_amt);
|
||||
setl(b, T_FEE, cx_fee);
|
||||
setl(b, T_NET, cx_net);
|
||||
setl(b, T_COUNT, cx_cnt);
|
||||
setl(b, T_GROSS, cx_grs);
|
||||
if (cx_sid > 0) setl(b, T_SETTLE_ID, cx_sid);
|
||||
if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
|
||||
Bchg(b, T_SVCNAME, 0, "ST_RELEASE", 0L);
|
||||
setl(b, T_RC, 0);
|
||||
userlog("[ST_RELEASE] 보류해제-원장반영: 체인 완료 <- LG_POST pid=%ld", cx_pid);
|
||||
}
|
||||
|
||||
OK(b);
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue