규모확장 Wave A: 전 11모듈 svc 30→75·batch 22→35 + 전 모듈 운영데이터 시드
- svc 330→825 (모듈당 +45 고유 실업무: chargeback·재매입·심사워크플로·전문유형별· 대사세분·정산시뮬·지급재처리·복식결산·마감워크플로·마스터심사·검증룰·전문라우팅 등) - batch 242→385 (모듈당 +13), 카피북 헤더·디스패처 advertise 전 75 반영 - db/schema.d/95-module-seed.sql: 전 모듈 테이블 운영데이터(au 8.4k·st 15.9k·mg 16.9k· lg 14.6k·rc 7.7k·py 2.9k·vl 8.5k·cm 10.4k 등, 총 ~171k행) — base 거래와 정합 - 화면 매니페스트 825 재생성, 큐 메모리 튜닝(NDRX_MSGMAX 50→30) - 검증: build DONE modules=11 batches=385, 12서버 runok, xadmin psc 828 AVAIL, 매입체인 XA 커밋(status=S), 새서비스 시드데이터 스모크(ACQ_MERCHSUM/RC_STATS 실값), 전 코퍼스 .pgc 클론 0, 헤드리스 스크린샷 확인 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
19acf4ed96
commit
ea90bef264
1292 changed files with 53968 additions and 20 deletions
48
app/src/st/batch/st_approve_batch.pgc
Normal file
48
app/src/st/batch/st_approve_batch.pgc
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* st_approve_batch.pgc - 정산 승인 워크플로 배치 (2단 검증 + 집합 승격 + XA).
|
||||
* 당일 CONFIRMED 정산을 확인한 뒤 net>0 건만 APPROVED 로 일괄 승격하고,
|
||||
* 승인 대상에서 빠진 건수(net<=0)를 별도 집계한다. 승인 원장 마커 기록.
|
||||
* 사용법: st_approve_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_approve_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_approve_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_confirmed;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(*) INTO :h_confirmed FROM settlement
|
||||
WHERE biz_date = :h_bizdate AND status = 'CONFIRMED';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "CHECK FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
EXEC SQL UPDATE settlement SET status = 'APPROVED'
|
||||
WHERE biz_date = :h_bizdate AND status = 'CONFIRMED' AND net > 0;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "APPROVE FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.approved = (long) sqlca.sqlerrd[2];
|
||||
rec.skipped = h_confirmed - rec.approved;
|
||||
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (nextval('ledger_seq'), 0, 'STAPPROVE', :h_confirmed, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "MARKER FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s approved=%ld skipped=%ld\n", ST_APPROVE_TAG, bizdate, rec.approved, rec.skipped);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
47
app/src/st/batch/st_deposit_batch.pgc
Normal file
47
app/src/st/batch/st_deposit_batch.pgc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* st_deposit_batch.pgc - 보증금 차감 배치 (조건부 집합 UPDATE + 총액 조정 + XA).
|
||||
* 차감 후에도 지급액이 남는(net_amount > cut) SCHEDULED 지급 전체에서 보증금
|
||||
* 단위를 일괄 차감하고, 총 차감액을 음수 조정 1건으로 기록한다.
|
||||
* 사용법: st_deposit_batch [YYYY-MM-DD] [cut]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_deposit_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_deposit_rec_t rec;
|
||||
rec.cut_each = (argc > 2) ? atol(argv[2]) : ST_DEPOSIT_DEF_CUT;
|
||||
rec.cut_rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cut;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
h_cut = rec.cut_each;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL UPDATE st_payment SET net_amount = net_amount - :h_cut
|
||||
WHERE biz_date = :h_bizdate AND status = 'SCHEDULED' AND net_amount > :h_cut;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "CUT FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.cut_rows = (long) sqlca.sqlerrd[2];
|
||||
|
||||
if (rec.cut_rows > 0) {
|
||||
if (stdb_insert_adjust(0, 0, -(rec.cut_each * rec.cut_rows), "DEPOSIT", bizdate) < 0) { tpabort(0); return 1; }
|
||||
}
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s cut_each=%ld cut_rows=%ld total=%ld\n",
|
||||
ST_DEPOSIT_TAG, bizdate, rec.cut_each, rec.cut_rows, rec.cut_each * rec.cut_rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
54
app/src/st/batch/st_grproll_batch.pgc
Normal file
54
app/src/st/batch/st_grproll_batch.pgc
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* st_grproll_batch.pgc - 가맹점그룹 통합정산 롤업 배치 (prefix 그룹 커서 + upsert + XA).
|
||||
* 가맹점 ID 앞 2자리를 그룹키로 삼아 당일 정산을 그룹 단위로 롤업 집계하고,
|
||||
* 그룹키 행을 st_merch_settle 에 upsert 한다 (그룹 통합정산 기초).
|
||||
* 사용법: st_grproll_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_grproll_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_grproll_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_grp[8];
|
||||
long h_cnt, h_net;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE grproll_bc CURSOR FOR
|
||||
SELECT substr(merchant_id, 1, 2), count(*), coalesce(sum(net),0)
|
||||
FROM settlement WHERE biz_date = :h_bizdate
|
||||
GROUP BY substr(merchant_id, 1, 2) ORDER BY 1;
|
||||
EXEC SQL OPEN grproll_bc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
for (;;) {
|
||||
EXEC SQL FETCH grproll_bc INTO :h_grp, :h_cnt, :h_net;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE grproll_bc; tpabort(0); return 1; }
|
||||
{
|
||||
char grpkey[16];
|
||||
snprintf(grpkey, sizeof(grpkey), "GRP:%s", h_grp);
|
||||
if (stdb_upsert_merch_settle(grpkey, bizdate, h_net, 0, h_net, h_cnt) < 0) { EXEC SQL CLOSE grproll_bc; tpabort(0); return 1; }
|
||||
rec.groups++;
|
||||
rec.rolled_net += h_net;
|
||||
}
|
||||
}
|
||||
EXEC SQL CLOSE grproll_bc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s groups=%ld rolled_net=%ld\n", ST_GRPROLL_TAG, bizdate, rec.groups, rec.rolled_net);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
58
app/src/st/batch/st_incent_batch.pgc
Normal file
58
app/src/st/batch/st_incent_batch.pgc
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* st_incent_batch.pgc - 구간별 인센티브 정산 배치 (커서 + 3단 요율 사다리 + XA).
|
||||
* 가맹점 일 집계(gross) 를 내림차순 커서로 순회, 1억/5천만/1천만 구간별
|
||||
* 인센티브(30/20/10bps)를 산정해 양수 조정으로 지급한다. 사용법: st_incent_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_incent_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_incent_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
long h_gross;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE incent_bc CURSOR FOR
|
||||
SELECT merchant_id, gross_amount FROM st_merch_settle
|
||||
WHERE biz_date = :h_bizdate AND gross_amount >= 10000000
|
||||
ORDER BY gross_amount DESC;
|
||||
EXEC SQL OPEN incent_bc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
for (;;) {
|
||||
EXEC SQL FETCH incent_bc INTO :h_merch, :h_gross;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE incent_bc; tpabort(0); return 1; }
|
||||
{
|
||||
long bps;
|
||||
if (h_gross >= 100000000) { bps = 30; rec.tier1++; }
|
||||
else if (h_gross >= 50000000) { bps = 20; rec.tier2++; }
|
||||
else { bps = 10; rec.tier3++; }
|
||||
{
|
||||
long inc = h_gross * bps / 10000;
|
||||
if (stdb_insert_adjust(0, 0, inc, "INCENTIVE", bizdate) < 0) { EXEC SQL CLOSE incent_bc; tpabort(0); return 1; }
|
||||
rec.paid_sum += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXEC SQL CLOSE incent_bc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s t1=%ld t2=%ld t3=%ld incentive_sum=%ld\n",
|
||||
ST_INCENT_TAG, bizdate, rec.tier1, rec.tier2, rec.tier3, rec.paid_sum);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
54
app/src/st/batch/st_partial_batch.pgc
Normal file
54
app/src/st/batch/st_partial_batch.pgc
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* st_partial_batch.pgc - 부분정산 잔여 스윕 배치 (HAVING 커서 + XA).
|
||||
* 부분정산으로 인해 정산 합계가 매입 net 에 못 미치는 매입을 HAVING 커서로
|
||||
* 찾아, 잔여분을 PARTIAL 정산 레코드로 마저 생성한다. 사용법: st_partial_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_partial_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_partial_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
long h_pid, h_remain;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE partial_bc CURSOR FOR
|
||||
SELECT p.purchase_id, p.merchant_id, p.net - sum(s.net)
|
||||
FROM purchase p JOIN settlement s ON s.purchase_id = p.purchase_id
|
||||
WHERE p.biz_date = :h_bizdate AND s.status <> 'CANCELLED'
|
||||
GROUP BY p.purchase_id, p.merchant_id, p.net
|
||||
HAVING sum(s.net) < p.net;
|
||||
EXEC SQL OPEN partial_bc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
for (;;) {
|
||||
EXEC SQL FETCH partial_bc INTO :h_pid, :h_merch, :h_remain;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE partial_bc; tpabort(0); return 1; }
|
||||
if (h_remain <= 0) continue;
|
||||
EXEC SQL INSERT INTO settlement (settlement_id, purchase_id, merchant_id, net, biz_date, status)
|
||||
VALUES (nextval('settlement_seq'), :h_pid, :h_merch, :h_remain, :h_bizdate, 'PARTIAL');
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE partial_bc; tpabort(0); return 1; }
|
||||
rec.swept++;
|
||||
rec.swept_amt += h_remain;
|
||||
}
|
||||
EXEC SQL CLOSE partial_bc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s partial_swept=%ld amt=%ld\n", ST_PARTIAL_TAG, bizdate, rec.swept, rec.swept_amt);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
43
app/src/st/batch/st_promo_batch.pgc
Normal file
43
app/src/st/batch/st_promo_batch.pgc
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* st_promo_batch.pgc - 프로모션/이벤트 정산 배치 (집합 INSERT..SELECT + XA).
|
||||
* 당일 거래대금이 기준액 이상인 가맹점 집계에 대해 수수료의 10% 를 이벤트
|
||||
* 환급 조정(PROMO)으로 일괄 생성한다. 사용법: st_promo_batch [YYYY-MM-DD] [threshold]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_promo_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_promo_rec_t rec;
|
||||
rec.threshold = (argc > 2) ? atol(argv[2]) : ST_PROMO_DEF_THRESH;
|
||||
rec.granted = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_thr;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
h_thr = rec.threshold;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL INSERT INTO st_adjust (adj_id, settlement_id, purchase_id, delta, reason, biz_date)
|
||||
SELECT nextval('st_adj_seq'), 0, 0, fee_amount / 10, 'PROMO', biz_date
|
||||
FROM st_merch_settle
|
||||
WHERE biz_date = :h_bizdate AND gross_amount >= :h_thr AND fee_amount > 0;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "%s FAIL [%d] %s\n", ST_PROMO_TAG, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.granted = (long) sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s threshold=%ld promo_granted=%ld\n", ST_PROMO_TAG, bizdate, rec.threshold, rec.granted);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
58
app/src/st/batch/st_ratesim_batch.pgc
Normal file
58
app/src/st/batch/st_ratesim_batch.pgc
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* st_ratesim_batch.pgc - 요율 시뮬레이션 배치 (XA 배치).
|
||||
* 당일 매입 총액을 기준으로 요율표(st_fee_rate)의 모든 구간 요율을 커서로
|
||||
* 순회하며 구간별 예상 수수료를 시뮬레이션 출력한다 (조회 전용).
|
||||
* ATMI 클라이언트: tpinit/tpopen 으로 ECPG XA RM 를 열고 tpbegin 으로 ONE global tx
|
||||
* 를 시작, EXEC SQL 수행 후 tpcommit 이 XA 2PC 를 구동. 사용법: st_ratesim_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_ratesim_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_ratesim_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_type[16];
|
||||
long h_gross, h_min, h_bps;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_gross FROM purchase WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "GROSS FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.day_gross = h_gross;
|
||||
|
||||
EXEC SQL DECLARE ratesim_bc CURSOR FOR
|
||||
SELECT fee_type, band_min, rate_bps FROM st_fee_rate ORDER BY fee_type, band_min;
|
||||
EXEC SQL OPEN ratesim_bc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
for (;;) {
|
||||
EXEC SQL FETCH ratesim_bc INTO :h_type, :h_min, :h_bps;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE ratesim_bc; tpabort(0); return 1; }
|
||||
{
|
||||
long sim = h_gross * h_bps / 10000; /* 이 구간 요율이 전액 적용됐을 때 */
|
||||
rec.bands++;
|
||||
rec.projected += sim;
|
||||
printf(" SIM %-8s band_min=%ld bps=%ld -> fee=%ld\n", h_type, h_min, h_bps, sim);
|
||||
}
|
||||
}
|
||||
EXEC SQL CLOSE ratesim_bc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s gross=%ld bands=%ld projected_total=%ld\n",
|
||||
ST_RATESIM_TAG, bizdate, rec.day_gross, rec.bands, rec.projected);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
62
app/src/st/batch/st_recvsweep_batch.pgc
Normal file
62
app/src/st/batch/st_recvsweep_batch.pgc
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* st_recvsweep_batch.pgc - 미수금 상계 스윕 배치 (미수 가맹점 커서 + 상계 + XA).
|
||||
* 매입 조인으로 미수금(음수 조정 누계)이 있는 가맹점을 커서로 찾고, 각
|
||||
* 가맹점의 당일 예정 지급에서 미수금과 가용액의 min 만큼 상계 차감한다.
|
||||
* 사용법: st_recvsweep_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_recvsweep_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_recvsweep_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
long h_recv, h_avail, h_off;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE recvsweep_bc CURSOR FOR
|
||||
SELECT p.merchant_id, -sum(a.delta)
|
||||
FROM st_adjust a JOIN purchase p ON p.purchase_id = a.purchase_id
|
||||
WHERE a.delta < 0
|
||||
GROUP BY p.merchant_id
|
||||
HAVING sum(a.delta) < 0
|
||||
ORDER BY p.merchant_id;
|
||||
EXEC SQL OPEN recvsweep_bc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
for (;;) {
|
||||
EXEC SQL FETCH recvsweep_bc INTO :h_merch, :h_recv;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE recvsweep_bc; tpabort(0); return 1; }
|
||||
EXEC SQL SELECT coalesce(sum(net_amount),0) INTO :h_avail FROM st_payment
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'SCHEDULED';
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE recvsweep_bc; tpabort(0); return 1; }
|
||||
h_off = (h_recv < h_avail) ? h_recv : h_avail;
|
||||
if (h_off <= 0) continue;
|
||||
EXEC SQL UPDATE st_payment SET net_amount = net_amount - :h_off
|
||||
WHERE pay_id = (SELECT min(pay_id) FROM st_payment
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'SCHEDULED');
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE recvsweep_bc; tpabort(0); return 1; }
|
||||
rec.merchants++;
|
||||
rec.offset_sum += h_off;
|
||||
}
|
||||
EXEC SQL CLOSE recvsweep_bc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s offset_merchants=%ld offset_sum=%ld\n",
|
||||
ST_RECVSWEEP_TAG, bizdate, rec.merchants, rec.offset_sum);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
43
app/src/st/batch/st_rerun_batch.pgc
Normal file
43
app/src/st/batch/st_rerun_batch.pgc
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* st_rerun_batch.pgc - 정산 재실행 배치 (DELETE + INSERT..SELECT + XA).
|
||||
* 당일 MDR 정산 상세를 전량 삭제한 뒤 정산-매입 조인으로 매입 fee 기준의
|
||||
* MDR 상세를 집합 재생성한다 (정산 재실행). 사용법: st_rerun_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_rerun_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_rerun_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DELETE FROM st_settle_dtl WHERE biz_date = :h_bizdate AND fee_type = 'MDR';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "PURGE FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.purged = (long) sqlca.sqlerrd[2];
|
||||
|
||||
EXEC SQL INSERT INTO st_settle_dtl (dtl_id, settlement_id, purchase_id, merchant_id, fee_type, amount, biz_date)
|
||||
SELECT nextval('st_dtl_seq'), s.settlement_id, s.purchase_id, s.merchant_id, 'MDR', p.fee, s.biz_date
|
||||
FROM settlement s JOIN purchase p ON p.purchase_id = s.purchase_id
|
||||
WHERE s.biz_date = :h_bizdate AND s.status <> 'CANCELLED';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "REBUILD FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.rebuilt = (long) sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s purged=%ld rebuilt=%ld\n", ST_RERUN_TAG, bizdate, rec.purged, rec.rebuilt);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
57
app/src/st/batch/st_retrorate_batch.pgc
Normal file
57
app/src/st/batch/st_retrorate_batch.pgc
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* st_retrorate_batch.pgc - 요율 소급적용 배치 (조인 커서 + 행별 조정 + XA).
|
||||
* 당일 MDR 정산 상세를 매입 금액과 조인 순회하며 신규 bps 로 재계산, 기계상
|
||||
* 수수료와의 차액을 건별 소급 조정으로 기록한다. 사용법: st_retrorate_batch [YYYY-MM-DD] [bps]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_retrorate_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_retrorate_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
rec.new_bps = (argc > 2) ? atol(argv[2]) : ST_RETRORATE_DEF_BPS;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_sid, h_pid, h_old, h_amount;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE retro_bc CURSOR FOR
|
||||
SELECT d.settlement_id, d.purchase_id, d.amount, p.amount
|
||||
FROM st_settle_dtl d JOIN purchase p ON p.purchase_id = d.purchase_id
|
||||
WHERE d.biz_date = :h_bizdate AND d.fee_type = 'MDR';
|
||||
EXEC SQL OPEN retro_bc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
for (;;) {
|
||||
EXEC SQL FETCH retro_bc INTO :h_sid, :h_pid, :h_old, :h_amount;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE retro_bc; tpabort(0); return 1; }
|
||||
{
|
||||
long newfee = h_amount * rec.new_bps / 10000;
|
||||
long diff = newfee - h_old;
|
||||
if (diff == 0) continue;
|
||||
if (stdb_insert_adjust(h_sid, h_pid, diff, "RETRO_RATE", bizdate) < 0) { EXEC SQL CLOSE retro_bc; tpabort(0); return 1; }
|
||||
rec.adjusted++;
|
||||
rec.delta_sum += diff;
|
||||
}
|
||||
}
|
||||
EXEC SQL CLOSE retro_bc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: bizdate=%s new_bps=%ld adjusted=%ld delta_sum=%ld\n",
|
||||
ST_RETRORATE_TAG, bizdate, rec.new_bps, rec.adjusted, rec.delta_sum);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
52
app/src/st/batch/st_vatreport_batch.pgc
Normal file
52
app/src/st/batch/st_vatreport_batch.pgc
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* st_vatreport_batch.pgc - 부가세 신고자료 생성 배치 (월 집계 + 원장 마커 + XA).
|
||||
* 대상 월의 정산 상세 VAT 합계와 세금계산서 공급가/세액/건수를 집계·대사해
|
||||
* 신고 기초자료를 출력하고, VATRPT 원장 마커를 남긴다.
|
||||
* 사용법: st_vatreport_batch [YYYY-MM-DD (해당 월 기준일)]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_vatreport_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_vatreport_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_dtlvat, h_cnt, h_supply, h_invvat;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_dtlvat FROM st_settle_dtl
|
||||
WHERE fee_type = 'VAT'
|
||||
AND to_char(biz_date,'YYYY-MM') = to_char(:h_bizdate::date,'YYYY-MM');
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "DTLVAT FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.dtl_vat = h_dtlvat;
|
||||
|
||||
EXEC SQL SELECT count(*), coalesce(sum(supply),0), coalesce(sum(vat),0)
|
||||
INTO :h_cnt, :h_supply, :h_invvat FROM ac_tax_invoice
|
||||
WHERE to_char(biz_date,'YYYY-MM') = to_char(:h_bizdate::date,'YYYY-MM');
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "INV FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.inv_cnt = h_cnt; rec.inv_supply = h_supply; rec.inv_vat = h_invvat;
|
||||
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (nextval('ledger_seq'), 0, 'VATRPT', :h_dtlvat, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "MARKER FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: base=%s dtl_vat=%ld inv_cnt=%ld supply=%ld inv_vat=%ld diff=%ld\n",
|
||||
ST_VATREPORT_TAG, bizdate, rec.dtl_vat, rec.inv_cnt, rec.inv_supply, rec.inv_vat,
|
||||
rec.inv_vat - rec.dtl_vat);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
42
app/src/st/batch/st_weekly_batch.pgc
Normal file
42
app/src/st/batch/st_weekly_batch.pgc
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* st_weekly_batch.pgc - 주간 정산주기 배치 (7일 윈도 집합 INSERT..SELECT + XA).
|
||||
* 주 종료일 기준 직전 7일 정산 net 을 가맹점별 GROUP BY/HAVING 으로 합산해
|
||||
* 주 1회 지급(SCHEDULED)을 일괄 생성한다. 사용법: st_weekly_batch [주종료일 YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_weekly_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_weekly_rec_t rec;
|
||||
rec.merchants = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL INSERT INTO st_payment (pay_id, merchant_id, net_amount, pay_date, status, biz_date)
|
||||
SELECT nextval('st_pay_seq'), merchant_id, sum(net), :h_bizdate::date + 1, 'SCHEDULED', :h_bizdate
|
||||
FROM settlement
|
||||
WHERE status <> 'CANCELLED'
|
||||
AND biz_date BETWEEN :h_bizdate::date - 6 AND :h_bizdate::date
|
||||
GROUP BY merchant_id
|
||||
HAVING sum(net) > 0;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "%s FAIL [%d] %s\n", ST_WEEKLY_TAG, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
rec.merchants = (long) sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: week_end=%s weekly_payments=%ld\n", ST_WEEKLY_TAG, bizdate, rec.merchants);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
51
app/src/st/batch/st_whtreport_batch.pgc
Normal file
51
app/src/st/batch/st_whtreport_batch.pgc
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* st_whtreport_batch.pgc - 원천세 명세 배치 (가맹점별 커서 명세 출력 + XA).
|
||||
* 대상 월의 정산 상세(WHT)를 가맹점별 GROUP BY 커서로 순회하며 원천세 명세
|
||||
* 라인을 한 줄씩 출력하고 총액을 집계한다 (신고 명세서 생성, 조회 전용).
|
||||
* 사용법: st_whtreport_batch [YYYY-MM-DD (해당 월 기준일)]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "st_dbio.h"
|
||||
#include "st_whtreport_batch.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
st_whtreport_rec_t rec;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
long h_cnt, h_wht;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE whtrpt_bc CURSOR FOR
|
||||
SELECT merchant_id, count(*), coalesce(sum(amount),0) FROM st_settle_dtl
|
||||
WHERE fee_type = 'WHT'
|
||||
AND to_char(biz_date,'YYYY-MM') = to_char(:h_bizdate::date,'YYYY-MM')
|
||||
GROUP BY merchant_id ORDER BY merchant_id;
|
||||
EXEC SQL OPEN whtrpt_bc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
for (;;) {
|
||||
EXEC SQL FETCH whtrpt_bc INTO :h_merch, :h_cnt, :h_wht;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE whtrpt_bc; tpabort(0); return 1; }
|
||||
printf(" WHT %-16s lines=%ld tax=%ld\n", h_merch, h_cnt, h_wht);
|
||||
rec.lines++;
|
||||
rec.wht_total += h_wht;
|
||||
}
|
||||
EXEC SQL CLOSE whtrpt_bc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> %s COMMIT: base=%s merchants=%ld wht_total=%ld\n", ST_WHTREPORT_TAG, bizdate, rec.lines, rec.wht_total);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
6
app/src/st/dbio/st_approve_batch.h
Normal file
6
app/src/st/dbio/st_approve_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_approve_batch.h - st 정산 승인 워크플로 배치 copybook. */
|
||||
#ifndef ST_APPROVE_BATCH_H
|
||||
#define ST_APPROVE_BATCH_H
|
||||
#define ST_APPROVE_TAG "st_approve_batch"
|
||||
typedef struct { long approved; long skipped; } st_approve_rec_t;
|
||||
#endif
|
||||
7
app/src/st/dbio/st_deposit_batch.h
Normal file
7
app/src/st/dbio/st_deposit_batch.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* st_deposit_batch.h - st 보증금 차감 배치 copybook. */
|
||||
#ifndef ST_DEPOSIT_BATCH_H
|
||||
#define ST_DEPOSIT_BATCH_H
|
||||
#define ST_DEPOSIT_TAG "st_deposit_batch"
|
||||
#define ST_DEPOSIT_DEF_CUT 50000L
|
||||
typedef struct { long cut_each; long cut_rows; } st_deposit_rec_t;
|
||||
#endif
|
||||
7
app/src/st/dbio/st_grproll_batch.h
Normal file
7
app/src/st/dbio/st_grproll_batch.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* st_grproll_batch.h - st 가맹점그룹 통합정산 롤업 배치 copybook. */
|
||||
#ifndef ST_GRPROLL_BATCH_H
|
||||
#define ST_GRPROLL_BATCH_H
|
||||
#define ST_GRPROLL_TAG "st_grproll_batch"
|
||||
#define ST_GRPROLL_PFX_LEN 2
|
||||
typedef struct { long groups; long rolled_net; } st_grproll_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_incent_batch.h
Normal file
6
app/src/st/dbio/st_incent_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_incent_batch.h - st 구간별 인센티브 배치 copybook. */
|
||||
#ifndef ST_INCENT_BATCH_H
|
||||
#define ST_INCENT_BATCH_H
|
||||
#define ST_INCENT_TAG "st_incent_batch"
|
||||
typedef struct { long tier1; long tier2; long tier3; long paid_sum; } st_incent_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_partial_batch.h
Normal file
6
app/src/st/dbio/st_partial_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_partial_batch.h - st 부분정산 잔여 스윕 배치 copybook. */
|
||||
#ifndef ST_PARTIAL_BATCH_H
|
||||
#define ST_PARTIAL_BATCH_H
|
||||
#define ST_PARTIAL_TAG "st_partial_batch"
|
||||
typedef struct { long swept; long swept_amt; } st_partial_rec_t;
|
||||
#endif
|
||||
7
app/src/st/dbio/st_promo_batch.h
Normal file
7
app/src/st/dbio/st_promo_batch.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* st_promo_batch.h - st 프로모션/이벤트 정산 배치 copybook. */
|
||||
#ifndef ST_PROMO_BATCH_H
|
||||
#define ST_PROMO_BATCH_H
|
||||
#define ST_PROMO_TAG "st_promo_batch"
|
||||
#define ST_PROMO_DEF_THRESH 10000000L
|
||||
typedef struct { long threshold; long granted; } st_promo_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_ratesim_batch.h
Normal file
6
app/src/st/dbio/st_ratesim_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_ratesim_batch.h - st 요율 시뮬레이션 배치 copybook. */
|
||||
#ifndef ST_RATESIM_BATCH_H
|
||||
#define ST_RATESIM_BATCH_H
|
||||
#define ST_RATESIM_TAG "st_ratesim_batch"
|
||||
typedef struct { long day_gross; long bands; long projected; } st_ratesim_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_recvsweep_batch.h
Normal file
6
app/src/st/dbio/st_recvsweep_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_recvsweep_batch.h - st 미수금 상계 스윕 배치 copybook. */
|
||||
#ifndef ST_RECVSWEEP_BATCH_H
|
||||
#define ST_RECVSWEEP_BATCH_H
|
||||
#define ST_RECVSWEEP_TAG "st_recvsweep_batch"
|
||||
typedef struct { long merchants; long offset_sum; } st_recvsweep_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_rerun_batch.h
Normal file
6
app/src/st/dbio/st_rerun_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_rerun_batch.h - st 정산 재실행 배치 copybook. */
|
||||
#ifndef ST_RERUN_BATCH_H
|
||||
#define ST_RERUN_BATCH_H
|
||||
#define ST_RERUN_TAG "st_rerun_batch"
|
||||
typedef struct { long purged; long rebuilt; } st_rerun_rec_t;
|
||||
#endif
|
||||
7
app/src/st/dbio/st_retrorate_batch.h
Normal file
7
app/src/st/dbio/st_retrorate_batch.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* st_retrorate_batch.h - st 요율 소급적용 배치 copybook. */
|
||||
#ifndef ST_RETRORATE_BATCH_H
|
||||
#define ST_RETRORATE_BATCH_H
|
||||
#define ST_RETRORATE_TAG "st_retrorate_batch"
|
||||
#define ST_RETRORATE_DEF_BPS 22L
|
||||
typedef struct { long new_bps; long adjusted; long delta_sum; } st_retrorate_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_vatreport_batch.h
Normal file
6
app/src/st/dbio/st_vatreport_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_vatreport_batch.h - st 부가세 신고자료 생성 배치 copybook. */
|
||||
#ifndef ST_VATREPORT_BATCH_H
|
||||
#define ST_VATREPORT_BATCH_H
|
||||
#define ST_VATREPORT_TAG "st_vatreport_batch"
|
||||
typedef struct { long dtl_vat; long inv_cnt; long inv_supply; long inv_vat; } st_vatreport_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_weekly_batch.h
Normal file
6
app/src/st/dbio/st_weekly_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_weekly_batch.h - st 주간 정산주기 배치 copybook. */
|
||||
#ifndef ST_WEEKLY_BATCH_H
|
||||
#define ST_WEEKLY_BATCH_H
|
||||
#define ST_WEEKLY_TAG "st_weekly_batch"
|
||||
typedef struct { long merchants; } st_weekly_rec_t;
|
||||
#endif
|
||||
6
app/src/st/dbio/st_whtreport_batch.h
Normal file
6
app/src/st/dbio/st_whtreport_batch.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* st_whtreport_batch.h - st 원천세 명세 배치 copybook. */
|
||||
#ifndef ST_WHTREPORT_BATCH_H
|
||||
#define ST_WHTREPORT_BATCH_H
|
||||
#define ST_WHTREPORT_TAG "st_whtreport_batch"
|
||||
typedef struct { long lines; long wht_total; } st_whtreport_rec_t;
|
||||
#endif
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
* st_svr.pgc - st (정산/수수료) MODULE SERVER (thin dispatcher).
|
||||
*
|
||||
* The legacy "one module server, many services" pattern: this binary owns NO
|
||||
* business logic. Each of st's 30 online services now lives in its own file
|
||||
* business logic. Each of st's 75 online services now lives in its own file
|
||||
* (app/src/st/svc/<SVCNAME>.pgc) with its own copybook header
|
||||
* (app/src/st/svc/<SVCNAME>.h); those objects are archived into libstsvc.a and
|
||||
* linked into this server. Here we only include every service copybook, tpopen()
|
||||
* the ECPG XA RM, tpadvertise() all services from a {name, fn} table, and
|
||||
* tpclose() at shutdown.
|
||||
*
|
||||
* st_svr: ONE binary that tpadvertise()s ALL 30 online st(정산/수수료) services.
|
||||
* st_svr: ONE binary that tpadvertise()s ALL 75 online st(정산/수수료) services.
|
||||
* SETTLE keeps the proven behavior: its own XA branch writes the settlement +
|
||||
* settle ledger rows. Terminal service of the 매입 chain.
|
||||
*/
|
||||
|
|
@ -48,6 +48,51 @@
|
|||
#include "ST_FXCONV.h"
|
||||
#include "ST_CONFIRM.h"
|
||||
#include "ST_STATUS.h"
|
||||
#include "ST_RATESIM.h"
|
||||
#include "ST_PROMOCALC.h"
|
||||
#include "ST_PARTIAL.h"
|
||||
#include "ST_RERUN.h"
|
||||
#include "ST_CXLRECALC.h"
|
||||
#include "ST_RETRORATE.h"
|
||||
#include "ST_TIERINCENT.h"
|
||||
#include "ST_CYCLED1.h"
|
||||
#include "ST_CYCLED2.h"
|
||||
#include "ST_CYCLEWEEK.h"
|
||||
#include "ST_CYCLEMON.h"
|
||||
#include "ST_DEPOSITCUT.h"
|
||||
#include "ST_RECVOFFSET.h"
|
||||
#include "ST_DEBTCOLLECT.h"
|
||||
#include "ST_VATREPORT.h"
|
||||
#include "ST_WHTREPORT.h"
|
||||
#include "ST_APPROVE.h"
|
||||
#include "ST_GRPSETTLE.h"
|
||||
#include "ST_DISPUTE.h"
|
||||
#include "ST_STATDETAIL.h"
|
||||
#include "ST_FEEPREVIEW.h"
|
||||
#include "ST_HOLDAMT.h"
|
||||
#include "ST_PAYSTATUS.h"
|
||||
#include "ST_ADJHIST.h"
|
||||
#include "ST_DTLSUM.h"
|
||||
#include "ST_MERCHRATE.h"
|
||||
#include "ST_CAPCHECK.h"
|
||||
#include "ST_ROUNDING.h"
|
||||
#include "ST_MINFEE.h"
|
||||
#include "ST_DAILYCLOSE.h"
|
||||
#include "ST_REOPEN.h"
|
||||
#include "ST_CARRYOVER.h"
|
||||
#include "ST_NEGSWEEP.h"
|
||||
#include "ST_TOPMERCH.h"
|
||||
#include "ST_FEERATIO.h"
|
||||
#include "ST_SPLITEVEN.h"
|
||||
#include "ST_CHNLSTAT.h"
|
||||
#include "ST_ISSUERSTAT.h"
|
||||
#include "ST_TAXINVCHK.h"
|
||||
#include "ST_FXSETTLE.h"
|
||||
#include "ST_EDIRECON.h"
|
||||
#include "ST_UNPAIDSUM.h"
|
||||
#include "ST_PAYRETRY.h"
|
||||
#include "ST_LIMITCHK.h"
|
||||
#include "ST_LEDGERSNAP.h"
|
||||
|
||||
/* ----- advertise table: {service name, function} ---------------------- */
|
||||
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
|
||||
|
|
@ -66,6 +111,29 @@ static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
|
|||
{"ST_LEDGERLINK", ST_LEDGERLINK}, {"ST_BANDRATE", ST_BANDRATE},
|
||||
{"ST_CAP", ST_CAP}, {"ST_FXCONV", ST_FXCONV},
|
||||
{"ST_CONFIRM", ST_CONFIRM}, {"ST_STATUS", ST_STATUS},
|
||||
{"ST_RATESIM", ST_RATESIM}, {"ST_PROMOCALC", ST_PROMOCALC},
|
||||
{"ST_PARTIAL", ST_PARTIAL}, {"ST_RERUN", ST_RERUN},
|
||||
{"ST_CXLRECALC", ST_CXLRECALC}, {"ST_RETRORATE", ST_RETRORATE},
|
||||
{"ST_TIERINCENT", ST_TIERINCENT}, {"ST_CYCLED1", ST_CYCLED1},
|
||||
{"ST_CYCLED2", ST_CYCLED2}, {"ST_CYCLEWEEK", ST_CYCLEWEEK},
|
||||
{"ST_CYCLEMON", ST_CYCLEMON}, {"ST_DEPOSITCUT", ST_DEPOSITCUT},
|
||||
{"ST_RECVOFFSET", ST_RECVOFFSET}, {"ST_DEBTCOLLECT", ST_DEBTCOLLECT},
|
||||
{"ST_VATREPORT", ST_VATREPORT}, {"ST_WHTREPORT", ST_WHTREPORT},
|
||||
{"ST_APPROVE", ST_APPROVE}, {"ST_GRPSETTLE", ST_GRPSETTLE},
|
||||
{"ST_DISPUTE", ST_DISPUTE}, {"ST_STATDETAIL", ST_STATDETAIL},
|
||||
{"ST_FEEPREVIEW", ST_FEEPREVIEW}, {"ST_HOLDAMT", ST_HOLDAMT},
|
||||
{"ST_PAYSTATUS", ST_PAYSTATUS}, {"ST_ADJHIST", ST_ADJHIST},
|
||||
{"ST_DTLSUM", ST_DTLSUM}, {"ST_MERCHRATE", ST_MERCHRATE},
|
||||
{"ST_CAPCHECK", ST_CAPCHECK}, {"ST_ROUNDING", ST_ROUNDING},
|
||||
{"ST_MINFEE", ST_MINFEE}, {"ST_DAILYCLOSE", ST_DAILYCLOSE},
|
||||
{"ST_REOPEN", ST_REOPEN}, {"ST_CARRYOVER", ST_CARRYOVER},
|
||||
{"ST_NEGSWEEP", ST_NEGSWEEP}, {"ST_TOPMERCH", ST_TOPMERCH},
|
||||
{"ST_FEERATIO", ST_FEERATIO}, {"ST_SPLITEVEN", ST_SPLITEVEN},
|
||||
{"ST_CHNLSTAT", ST_CHNLSTAT}, {"ST_ISSUERSTAT", ST_ISSUERSTAT},
|
||||
{"ST_TAXINVCHK", ST_TAXINVCHK}, {"ST_FXSETTLE", ST_FXSETTLE},
|
||||
{"ST_EDIRECON", ST_EDIRECON}, {"ST_UNPAIDSUM", ST_UNPAIDSUM},
|
||||
{"ST_PAYRETRY", ST_PAYRETRY}, {"ST_LIMITCHK", ST_LIMITCHK},
|
||||
{"ST_LEDGERSNAP", ST_LEDGERSNAP},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
|||
19
app/src/st/svc/ST_ADJHIST.h
Normal file
19
app/src/st/svc/ST_ADJHIST.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_ADJHIST.h - st 서비스 ST_ADJHIST 카피북 (copybook / record header).
|
||||
* 조정 이력 조회: 매입 단위 조정 건수/증감 합계/최근 사유.
|
||||
*/
|
||||
#ifndef ST_ADJHIST_H
|
||||
#define ST_ADJHIST_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long adj_count;
|
||||
long delta_sum;
|
||||
char last_reason[128];
|
||||
} st_st_adjhist_rec_t;
|
||||
|
||||
void ST_ADJHIST(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_ADJHIST_H */
|
||||
39
app/src/st/svc/ST_ADJHIST.pgc
Normal file
39
app/src/st/svc/ST_ADJHIST.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* ST_ADJHIST.pgc - st 모듈 서비스 ST_ADJHIST (one service = one file).
|
||||
* 조정 이력 조회: 매입에 걸린 정산 조정을 최신순 커서로 순회해 건수·증감
|
||||
* 누계와 가장 최근 조정 사유를 회신한다. 이력 없으면 RC=1. 조회 전용.
|
||||
*/
|
||||
#include "ST_ADJHIST.h"
|
||||
|
||||
/* 54. ST_ADJHIST - 매입별 조정 이력 요약. */
|
||||
void ST_ADJHIST(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char last[128] = "";
|
||||
long cnt = 0, sum = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_delta;
|
||||
char h_reason[128];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
EXEC SQL DECLARE adjhist_c CURSOR FOR
|
||||
SELECT delta, reason FROM st_adjust WHERE purchase_id = :h_pid ORDER BY adj_id DESC;
|
||||
EXEC SQL OPEN adjhist_c;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH adjhist_c INTO :h_delta, :h_reason;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE adjhist_c; FAIL(b); }
|
||||
if (cnt == 0) { strncpy(last, h_reason, sizeof(last)-1); last[sizeof(last)-1] = 0; }
|
||||
cnt++;
|
||||
sum += h_delta;
|
||||
}
|
||||
EXEC SQL CLOSE adjhist_c;
|
||||
if (cnt == 0) { setl(b, T_RC, 1); OK(b); }
|
||||
setl(b, T_COUNT, cnt);
|
||||
setl(b, T_DELTA, sum);
|
||||
Bchg(b, T_REASON, 0, last, 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
18
app/src/st/svc/ST_APPROVE.h
Normal file
18
app/src/st/svc/ST_APPROVE.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ST_APPROVE.h - st 서비스 ST_APPROVE 카피북 (copybook / record header).
|
||||
* 정산 확정/승인 워크플로: CONFIRMED -> APPROVED 승격 + 승인 원장.
|
||||
*/
|
||||
#ifndef ST_APPROVE_H
|
||||
#define ST_APPROVE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
char approver[32];
|
||||
char cur_status[16];
|
||||
} st_st_approve_rec_t;
|
||||
|
||||
void ST_APPROVE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_APPROVE_H */
|
||||
37
app/src/st/svc/ST_APPROVE.pgc
Normal file
37
app/src/st/svc/ST_APPROVE.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ST_APPROVE.pgc - st 모듈 서비스 ST_APPROVE (one service = one file).
|
||||
* 정산 승인 워크플로: 최신 정산 상태를 검증해 CONFIRMED 인 건만 APPROVED 로
|
||||
* 승격하고 승인 원장(STAPPROVE)을 남긴다. 상태 위반 시 RC=2 로 현재 상태 회신.
|
||||
*/
|
||||
#include "ST_APPROVE.h"
|
||||
|
||||
/* 47. ST_APPROVE - 정산 승인 (CONFIRMED -> APPROVED). */
|
||||
void ST_APPROVE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid;
|
||||
char h_status[16], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
EXEC SQL SELECT status, to_char(biz_date,'YYYY-MM-DD') INTO :h_status, :h_bizdate
|
||||
FROM settlement WHERE purchase_id = :h_pid ORDER BY settlement_id DESC LIMIT 1;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (sqlca.sqlcode == 100) { setl(b, T_RC, 1); Bchg(b, T_STATUS, 0, "NONE", 0L); OK(b); }
|
||||
if (strcmp(h_status, "CONFIRMED") != 0) {
|
||||
setl(b, T_RC, 2); /* 워크플로 순서 위반: 확정 전 승인 불가 */
|
||||
Bchg(b, T_STATUS, 0, h_status, 0L);
|
||||
OK(b);
|
||||
}
|
||||
EXEC SQL UPDATE settlement SET status = 'APPROVED'
|
||||
WHERE purchase_id = :h_pid AND status = 'CONFIRMED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (nextval('ledger_seq'), :h_pid, 'STAPPROVE', 0, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_RC, 0);
|
||||
Bchg(b, T_STATUS, 0, "A", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
18
app/src/st/svc/ST_CAPCHECK.h
Normal file
18
app/src/st/svc/ST_CAPCHECK.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ST_CAPCHECK.h - st 서비스 ST_CAPCHECK 카피북 (copybook / record header).
|
||||
* 수수료 상한 도달 점검: 상한 초과 여부/초과분 조회 (판정 전용).
|
||||
*/
|
||||
#ifndef ST_CAPCHECK_H
|
||||
#define ST_CAPCHECK_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long fee;
|
||||
long cap;
|
||||
long over;
|
||||
} st_st_capcheck_rec_t;
|
||||
|
||||
void ST_CAPCHECK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CAPCHECK_H */
|
||||
26
app/src/st/svc/ST_CAPCHECK.pgc
Normal file
26
app/src/st/svc/ST_CAPCHECK.pgc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* ST_CAPCHECK.pgc - st 모듈 서비스 ST_CAPCHECK (one service = one file).
|
||||
* 수수료 상한 도달 점검: 수수료가 상한을 초과하는지 판정만 하고 초과분을
|
||||
* 회신한다. ST_CAP 과 달리 조정을 기록하지 않는 순수 판정 서비스 (SQL 없음).
|
||||
*/
|
||||
#include "ST_CAPCHECK.h"
|
||||
|
||||
/* 57. ST_CAPCHECK - 상한 초과 여부 판정 (조정 없음). */
|
||||
void ST_CAPCHECK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long fee = getl(b, T_FEE), cap = getl(b, T_ARG1), over;
|
||||
if (cap <= 0) cap = 100000;
|
||||
over = fee - cap;
|
||||
if (over > 0) {
|
||||
setl(b, T_RC, 1); /* 상한 초과: 감액 대상 */
|
||||
setl(b, T_DELTA, over);
|
||||
} else {
|
||||
setl(b, T_RC, 0);
|
||||
setl(b, T_DELTA, 0);
|
||||
}
|
||||
setl(b, T_AMT1, cap);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_CARRYOVER.h
Normal file
20
app/src/st/svc/ST_CARRYOVER.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_CARRYOVER.h - st 서비스 ST_CARRYOVER 카피북 (copybook / record header).
|
||||
* 이월 정산: 미정산 매입 합계를 익영업일 지급으로 이월 예약.
|
||||
*/
|
||||
#ifndef ST_CARRYOVER_H
|
||||
#define ST_CARRYOVER_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
long unsettled_cnt;
|
||||
long unsettled_sum;
|
||||
char carry_date[16];
|
||||
} st_st_carryover_rec_t;
|
||||
|
||||
void ST_CARRYOVER(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CARRYOVER_H */
|
||||
37
app/src/st/svc/ST_CARRYOVER.pgc
Normal file
37
app/src/st/svc/ST_CARRYOVER.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ST_CARRYOVER.pgc - st 모듈 서비스 ST_CARRYOVER (one service = one file).
|
||||
* 이월 정산: 대사완료(M) 상태이지만 정산 레코드가 없는 매입(NOT EXISTS)을
|
||||
* 집계해 익영업일 지급으로 이월 예약한다. 대상 없으면 RC=1 (dbio).
|
||||
*/
|
||||
#include "ST_CARRYOVER.h"
|
||||
|
||||
/* 62. ST_CARRYOVER - 미정산분 익영업일 이월 예약. */
|
||||
void ST_CARRYOVER(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16], carry[16];
|
||||
long pay;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_sum;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_sum FROM purchase p
|
||||
WHERE p.merchant_id = :h_merch AND p.biz_date = :h_bizdate AND p.status = 'M'
|
||||
AND NOT EXISTS (SELECT 1 FROM settlement s WHERE s.purchase_id = p.purchase_id);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_cnt == 0) { setl(b, T_RC, 1); setl(b, T_COUNT, 0); OK(b); }
|
||||
if (acq_next_bizday(bizdate, carry) < 0) FAIL(b);
|
||||
pay = stdb_insert_payment(merch, h_sum, carry, "SCHEDULED", bizdate);
|
||||
if (pay < 0) FAIL(b);
|
||||
setl(b, T_ID1, pay);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_NET, h_sum);
|
||||
Bchg(b, T_KEY1, 0, carry, 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_CHNLSTAT.h
Normal file
20
app/src/st/svc/ST_CHNLSTAT.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_CHNLSTAT.h - st 서비스 ST_CHNLSTAT 카피북 (copybook / record header).
|
||||
* 채널별 정산 통계: 매입 채널 단위 정산 분해 + 최대 채널.
|
||||
*/
|
||||
#ifndef ST_CHNLSTAT_H
|
||||
#define ST_CHNLSTAT_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long channel_cnt;
|
||||
long grand_net;
|
||||
char top_channel[16];
|
||||
long top_net;
|
||||
} st_st_chnlstat_rec_t;
|
||||
|
||||
void ST_CHNLSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CHNLSTAT_H */
|
||||
46
app/src/st/svc/ST_CHNLSTAT.pgc
Normal file
46
app/src/st/svc/ST_CHNLSTAT.pgc
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* ST_CHNLSTAT.pgc - st 모듈 서비스 ST_CHNLSTAT (one service = one file).
|
||||
* 채널별 정산 통계 세분: 정산-매입 조인 커서로 채널(POS/EDC/EDI/FOREIGN)별
|
||||
* 건수·net 을 분해 집계하고 최대 채널을 회신한다. 조회 전용.
|
||||
*/
|
||||
#include "ST_CHNLSTAT.h"
|
||||
|
||||
/* 67. ST_CHNLSTAT - 채널별 정산 net 분해 통계. */
|
||||
void ST_CHNLSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], topch[16] = "";
|
||||
long channels = 0, grand = 0, topsum = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_net;
|
||||
char h_ch[16], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL DECLARE chnlstat_c CURSOR FOR
|
||||
SELECT p.channel, count(*), coalesce(sum(s.net),0)
|
||||
FROM settlement s JOIN purchase p ON p.purchase_id = s.purchase_id
|
||||
WHERE s.biz_date = :h_bizdate GROUP BY p.channel ORDER BY 3 DESC;
|
||||
EXEC SQL OPEN chnlstat_c;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH chnlstat_c INTO :h_ch, :h_cnt, :h_net;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE chnlstat_c; FAIL(b); }
|
||||
if (channels == 0) {
|
||||
strncpy(topch, h_ch, sizeof(topch)-1); topch[sizeof(topch)-1] = 0;
|
||||
topsum = h_net;
|
||||
}
|
||||
channels++;
|
||||
grand += h_net;
|
||||
}
|
||||
EXEC SQL CLOSE chnlstat_c;
|
||||
if (channels == 0) { setl(b, T_RC, 1); OK(b); }
|
||||
setl(b, T_COUNT, channels);
|
||||
setl(b, T_GROSS, grand);
|
||||
setl(b, T_AMT1, topsum);
|
||||
Bchg(b, T_CHANNEL, 0, topch, 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
18
app/src/st/svc/ST_CXLRECALC.h
Normal file
18
app/src/st/svc/ST_CXLRECALC.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ST_CXLRECALC.h - st 서비스 ST_CXLRECALC 카피북 (copybook / record header).
|
||||
* 정산 취소분 재계산: 취소 누계를 반영한 정산 net 재산정.
|
||||
*/
|
||||
#ifndef ST_CXLRECALC_H
|
||||
#define ST_CXLRECALC_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long cancel_sum;
|
||||
long new_net;
|
||||
} st_st_cxlrecalc_rec_t;
|
||||
|
||||
void ST_CXLRECALC(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CXLRECALC_H */
|
||||
29
app/src/st/svc/ST_CXLRECALC.pgc
Normal file
29
app/src/st/svc/ST_CXLRECALC.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* ST_CXLRECALC.pgc - st 모듈 서비스 ST_CXLRECALC (one service = one file).
|
||||
* 정산 취소분 재계산: ac_cancel 누계를 매입 net 에서 차감해 정산 net 을
|
||||
* 재산정하고 (음수 방지 클램프) SETTLED 정산 레코드에 반영한다.
|
||||
*/
|
||||
#include "ST_CXLRECALC.h"
|
||||
|
||||
/* 35. ST_CXLRECALC - 취소 누계 반영 정산 net 재계산. */
|
||||
void ST_CXLRECALC(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_cxl, h_pnet, h_new;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_cxl FROM ac_cancel WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL SELECT net INTO :h_pnet FROM purchase WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
h_new = h_pnet - h_cxl;
|
||||
if (h_new < 0) h_new = 0; /* 과취소 방지 클램프 */
|
||||
EXEC SQL UPDATE settlement SET net = :h_new WHERE purchase_id = :h_pid AND status = 'SETTLED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_NET, h_new);
|
||||
setl(b, T_DELTA, -h_cxl);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_CYCLED1.h
Normal file
19
app/src/st/svc/ST_CYCLED1.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_CYCLED1.h - st 서비스 ST_CYCLED1 카피북 (copybook / record header).
|
||||
* D+1 정산주기: 당일 SETTLED 합계를 익영업일 지급으로 예약.
|
||||
*/
|
||||
#ifndef ST_CYCLED1_H
|
||||
#define ST_CYCLED1_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
char pay_date[16];
|
||||
long net_sum;
|
||||
} st_st_cycled1_rec_t;
|
||||
|
||||
void ST_CYCLED1(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CYCLED1_H */
|
||||
35
app/src/st/svc/ST_CYCLED1.pgc
Normal file
35
app/src/st/svc/ST_CYCLED1.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ST_CYCLED1.pgc - st 모듈 서비스 ST_CYCLED1 (one service = one file).
|
||||
* D+1 정산주기: 당일 SETTLED 정산 net 합계를 산출해 익영업일(pay_date=D+1)
|
||||
* 지급(SCHEDULED)으로 예약한다 (dbio).
|
||||
*/
|
||||
#include "ST_CYCLED1.h"
|
||||
|
||||
/* 38. ST_CYCLED1 - D+1 주기 지급 예약. */
|
||||
void ST_CYCLED1(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16], payd[16];
|
||||
long pay;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_sum;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(net),0) INTO :h_sum FROM settlement
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'SETTLED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_sum <= 0) { setl(b, T_RC, 1); OK(b); }
|
||||
if (acq_next_bizday(bizdate, payd) < 0) FAIL(b);
|
||||
pay = stdb_insert_payment(merch, h_sum, payd, "SCHEDULED", bizdate);
|
||||
if (pay < 0) FAIL(b);
|
||||
setl(b, T_ID1, pay);
|
||||
setl(b, T_NET, h_sum);
|
||||
Bchg(b, T_KEY1, 0, payd, 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_CYCLED2.h
Normal file
20
app/src/st/svc/ST_CYCLED2.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_CYCLED2.h - st 서비스 ST_CYCLED2 카피북 (copybook / record header).
|
||||
* D+2 정산주기: 확정(CONFIRMED)분을 2영업일 뒤 지급으로 예약.
|
||||
*/
|
||||
#ifndef ST_CYCLED2_H
|
||||
#define ST_CYCLED2_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
char pay_date[16];
|
||||
long confirmed_cnt;
|
||||
long net_sum;
|
||||
} st_st_cycled2_rec_t;
|
||||
|
||||
void ST_CYCLED2(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CYCLED2_H */
|
||||
37
app/src/st/svc/ST_CYCLED2.pgc
Normal file
37
app/src/st/svc/ST_CYCLED2.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ST_CYCLED2.pgc - st 모듈 서비스 ST_CYCLED2 (one service = one file).
|
||||
* D+2 정산주기: 당일 CONFIRMED 확정 정산만 집계해 2영업일 뒤(D+2, 주말 스킵)
|
||||
* 지급으로 예약한다. 확정 건이 없으면 RC=1 (dbio).
|
||||
*/
|
||||
#include "ST_CYCLED2.h"
|
||||
|
||||
/* 39. ST_CYCLED2 - D+2 주기 지급 예약 (확정분만). */
|
||||
void ST_CYCLED2(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16], d1[16], d2[16];
|
||||
long pay;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_sum;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_sum FROM settlement
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'CONFIRMED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_cnt == 0) { setl(b, T_RC, 1); setl(b, T_COUNT, 0); OK(b); }
|
||||
if (acq_next_bizday(bizdate, d1) < 0) FAIL(b);
|
||||
if (acq_next_bizday(d1, d2) < 0) FAIL(b); /* D+1 -> D+2, 주말 스킵 2회 */
|
||||
pay = stdb_insert_payment(merch, h_sum, d2, "SCHEDULED", bizdate);
|
||||
if (pay < 0) FAIL(b);
|
||||
setl(b, T_ID1, pay);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_NET, h_sum);
|
||||
Bchg(b, T_KEY1, 0, d2, 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_CYCLEMON.h
Normal file
20
app/src/st/svc/ST_CYCLEMON.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_CYCLEMON.h - st 서비스 ST_CYCLEMON 카피북 (copybook / record header).
|
||||
* 월간 정산주기: 해당 월 정산 합계를 월 1회 지급으로 예약.
|
||||
*/
|
||||
#ifndef ST_CYCLEMON_H
|
||||
#define ST_CYCLEMON_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char yyyymm[16];
|
||||
long month_cnt;
|
||||
long month_sum;
|
||||
long pay_id;
|
||||
} st_st_cyclemon_rec_t;
|
||||
|
||||
void ST_CYCLEMON(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CYCLEMON_H */
|
||||
39
app/src/st/svc/ST_CYCLEMON.pgc
Normal file
39
app/src/st/svc/ST_CYCLEMON.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* ST_CYCLEMON.pgc - st 모듈 서비스 ST_CYCLEMON (one service = one file).
|
||||
* 월간 정산주기: 대상 월(YYYY-MM)의 가맹점 정산 net 을 합산해 지급일 기준으로
|
||||
* 월 1회 지급 레코드를 직접 INSERT 한다. 합계 0 이하이면 RC=1.
|
||||
*/
|
||||
#include "ST_CYCLEMON.h"
|
||||
|
||||
/* 41. ST_CYCLEMON - 월간 통합 지급 예약 (직접 INSERT). */
|
||||
void ST_CYCLEMON(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16], ym[16], like[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_sum, h_pay;
|
||||
char h_merch[64], h_bizdate[16], h_like[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_KEY1, ym, sizeof(ym)); if (ym[0] == 0) strcpy(ym, "2026-07");
|
||||
snprintf(like, sizeof(like), "%s%%", ym);
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
strncpy(h_like, like, sizeof(h_like)-1); h_like[sizeof(h_like)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_sum FROM settlement
|
||||
WHERE merchant_id = :h_merch AND to_char(biz_date,'YYYY-MM-DD') LIKE :h_like;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_sum <= 0) { setl(b, T_RC, 1); setl(b, T_COUNT, h_cnt); OK(b); }
|
||||
EXEC SQL SELECT nextval('st_pay_seq') INTO :h_pay;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO st_payment (pay_id, merchant_id, net_amount, pay_date, status, biz_date)
|
||||
VALUES (:h_pay, :h_merch, :h_sum, :h_bizdate, 'SCHEDULED', :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_ID1, h_pay);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_CYCLEWEEK.h
Normal file
19
app/src/st/svc/ST_CYCLEWEEK.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_CYCLEWEEK.h - st 서비스 ST_CYCLEWEEK 카피북 (copybook / record header).
|
||||
* 주간 정산주기: 최근 7일 정산 합계를 주 1회 지급으로 예약.
|
||||
*/
|
||||
#ifndef ST_CYCLEWEEK_H
|
||||
#define ST_CYCLEWEEK_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char week_end[16];
|
||||
long week_cnt;
|
||||
long week_sum;
|
||||
} st_st_cycleweek_rec_t;
|
||||
|
||||
void ST_CYCLEWEEK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_CYCLEWEEK_H */
|
||||
36
app/src/st/svc/ST_CYCLEWEEK.pgc
Normal file
36
app/src/st/svc/ST_CYCLEWEEK.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ST_CYCLEWEEK.pgc - st 모듈 서비스 ST_CYCLEWEEK (one service = one file).
|
||||
* 주간 정산주기: 주 종료일 기준 직전 7일(취소 제외) 정산 net 을 합산해
|
||||
* 주 1회 지급으로 예약한다. 대상 없으면 RC=1 (dbio).
|
||||
*/
|
||||
#include "ST_CYCLEWEEK.h"
|
||||
|
||||
/* 40. ST_CYCLEWEEK - 주간(7일 윈도) 통합 지급 예약. */
|
||||
void ST_CYCLEWEEK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16], payd[16];
|
||||
long pay;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_sum;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_sum FROM settlement
|
||||
WHERE merchant_id = :h_merch AND status <> 'CANCELLED'
|
||||
AND biz_date BETWEEN :h_bizdate::date - 6 AND :h_bizdate::date;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_cnt == 0 || h_sum <= 0) { setl(b, T_RC, 1); OK(b); }
|
||||
if (acq_next_bizday(bizdate, payd) < 0) FAIL(b);
|
||||
pay = stdb_insert_payment(merch, h_sum, payd, "SCHEDULED", bizdate);
|
||||
if (pay < 0) FAIL(b);
|
||||
setl(b, T_ID1, pay);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_DAILYCLOSE.h
Normal file
20
app/src/st/svc/ST_DAILYCLOSE.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_DAILYCLOSE.h - st 서비스 ST_DAILYCLOSE 카피북 (copybook / record header).
|
||||
* 일마감: 정산/지급/조정 건수 집계 + 마감 원장(STCLOSE) 기록.
|
||||
*/
|
||||
#ifndef ST_DAILYCLOSE_H
|
||||
#define ST_DAILYCLOSE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long settle_cnt;
|
||||
long pay_cnt;
|
||||
long adj_cnt;
|
||||
long net_sum;
|
||||
} st_st_dailyclose_rec_t;
|
||||
|
||||
void ST_DAILYCLOSE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_DAILYCLOSE_H */
|
||||
36
app/src/st/svc/ST_DAILYCLOSE.pgc
Normal file
36
app/src/st/svc/ST_DAILYCLOSE.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ST_DAILYCLOSE.pgc - st 모듈 서비스 ST_DAILYCLOSE (one service = one file).
|
||||
* 정산 일마감: 당일 정산·지급·조정 건수를 각각 검증 집계하고 정산 net 총액으로
|
||||
* 마감 원장(STCLOSE)을 기록해 마감을 선언한다.
|
||||
*/
|
||||
#include "ST_DAILYCLOSE.h"
|
||||
|
||||
/* 60. ST_DAILYCLOSE - 정산 일마감 선언 (3원 집계 + 마감 원장). */
|
||||
void ST_DAILYCLOSE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_scnt, h_sum, h_pcnt, h_acnt;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(net),0) INTO :h_scnt, :h_sum
|
||||
FROM settlement WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL SELECT count(*) INTO :h_pcnt FROM st_payment WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL SELECT count(*) INTO :h_acnt FROM st_adjust WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (nextval('ledger_seq'), 0, 'STCLOSE', :h_sum, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_COUNT, h_scnt);
|
||||
setl(b, T_ARG1, h_pcnt);
|
||||
setl(b, T_ARG2, h_acnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_DEBTCOLLECT.h
Normal file
19
app/src/st/svc/ST_DEBTCOLLECT.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_DEBTCOLLECT.h - st 서비스 ST_DEBTCOLLECT 카피북 (copybook / record header).
|
||||
* 채권 회수 정산: 회수 입금액을 채권 잔액에 반영하고 원장 기록.
|
||||
*/
|
||||
#ifndef ST_DEBTCOLLECT_H
|
||||
#define ST_DEBTCOLLECT_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
long collected;
|
||||
long outstanding;
|
||||
} st_st_debtcollect_rec_t;
|
||||
|
||||
void ST_DEBTCOLLECT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_DEBTCOLLECT_H */
|
||||
40
app/src/st/svc/ST_DEBTCOLLECT.pgc
Normal file
40
app/src/st/svc/ST_DEBTCOLLECT.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* ST_DEBTCOLLECT.pgc - st 모듈 서비스 ST_DEBTCOLLECT (one service = one file).
|
||||
* 채권 회수 정산: 회수 입금액을 양수 조정(COLLECT)으로 기록하고 원장에 COLLECT
|
||||
* 엔트리를 남긴 뒤, 회수 후 잔여 채권액을 회신한다.
|
||||
*/
|
||||
#include "ST_DEBTCOLLECT.h"
|
||||
|
||||
/* 44. ST_DEBTCOLLECT - 채권 회수 입금 정산. */
|
||||
void ST_DEBTCOLLECT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
long adj, remain;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_col, h_out;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_col = getl(b, T_AMOUNT);
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
if (h_col <= 0) FAIL(b);
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(a.delta) FILTER (WHERE a.delta < 0),0) INTO :h_out
|
||||
FROM st_adjust a JOIN purchase p ON p.purchase_id = a.purchase_id
|
||||
WHERE p.merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
adj = stdb_insert_adjust(0, 0, h_col, "COLLECT", bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (nextval('ledger_seq'), 0, 'COLLECT', :h_col, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
remain = (-h_out) - h_col;
|
||||
if (remain < 0) remain = 0;
|
||||
setl(b, T_ADJ, adj);
|
||||
setl(b, T_DELTA, remain);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_DEPOSITCUT.h
Normal file
19
app/src/st/svc/ST_DEPOSITCUT.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_DEPOSITCUT.h - st 서비스 ST_DEPOSITCUT 카피북 (copybook / record header).
|
||||
* 보증금 차감: 예정 지급액에서 보증금 납부 예정액을 원천 차감.
|
||||
*/
|
||||
#ifndef ST_DEPOSITCUT_H
|
||||
#define ST_DEPOSITCUT_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
long deposit_due;
|
||||
long cut;
|
||||
} st_st_depositcut_rec_t;
|
||||
|
||||
void ST_DEPOSITCUT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_DEPOSITCUT_H */
|
||||
39
app/src/st/svc/ST_DEPOSITCUT.pgc
Normal file
39
app/src/st/svc/ST_DEPOSITCUT.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* ST_DEPOSITCUT.pgc - st 모듈 서비스 ST_DEPOSITCUT (one service = one file).
|
||||
* 보증금 차감: 보증금 납부 예정액과 SCHEDULED 지급 가용액 중 작은 금액을
|
||||
* 최초 지급 레코드에서 차감하고 음수 조정(DEPOSIT)으로 기록한다.
|
||||
*/
|
||||
#include "ST_DEPOSITCUT.h"
|
||||
|
||||
/* 42. ST_DEPOSITCUT - 지급액 보증금 원천 차감. */
|
||||
void ST_DEPOSITCUT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
long due = getl(b, T_AMT1), adj;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_avail, h_cut;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
if (due <= 0) due = 50000; /* 기본 보증금 납부 단위 */
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(net_amount),0) INTO :h_avail FROM st_payment
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'SCHEDULED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
h_cut = (due < h_avail) ? due : h_avail;
|
||||
if (h_cut <= 0) { setl(b, T_RC, 1); setl(b, T_DELTA, 0); OK(b); }
|
||||
EXEC SQL UPDATE st_payment SET net_amount = net_amount - :h_cut
|
||||
WHERE pay_id = (SELECT min(pay_id) FROM st_payment
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'SCHEDULED');
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
adj = stdb_insert_adjust(0, 0, -h_cut, "DEPOSIT", bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
setl(b, T_DELTA, -h_cut);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_DISPUTE.h
Normal file
19
app/src/st/svc/ST_DISPUTE.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_DISPUTE.h - st 서비스 ST_DISPUTE 카피북 (copybook / record header).
|
||||
* 정산 이의신청 처리: 지급 보류 + 이의 금액 조정 기록.
|
||||
*/
|
||||
#ifndef ST_DISPUTE_H
|
||||
#define ST_DISPUTE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long claimed;
|
||||
char reason[64];
|
||||
char merchant_id[64];
|
||||
} st_st_dispute_rec_t;
|
||||
|
||||
void ST_DISPUTE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_DISPUTE_H */
|
||||
35
app/src/st/svc/ST_DISPUTE.pgc
Normal file
35
app/src/st/svc/ST_DISPUTE.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ST_DISPUTE.pgc - st 모듈 서비스 ST_DISPUTE (one service = one file).
|
||||
* 정산 이의신청 처리: 대상 매입의 가맹점을 역추적해 예정 지급을 보류(HELD)로
|
||||
* 전환하고, 이의 금액을 DISPUTE 사유 조정으로 기록한다 (dbio).
|
||||
*/
|
||||
#include "ST_DISPUTE.h"
|
||||
|
||||
/* 49. ST_DISPUTE - 정산 이의신청 접수 (지급 보류 + 조정). */
|
||||
void ST_DISPUTE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], reason[64], rbuf[96], merch[64];
|
||||
long claimed = getl(b, T_DELTA), adj;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid;
|
||||
char h_merch[64];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_REASON, reason, sizeof(reason)); if (reason[0] == 0) strcpy(reason, "UNSPEC");
|
||||
EXEC SQL SELECT merchant_id INTO :h_merch FROM settlement
|
||||
WHERE purchase_id = :h_pid ORDER BY settlement_id LIMIT 1;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
strncpy(merch, h_merch, sizeof(merch)-1); merch[sizeof(merch)-1] = 0;
|
||||
if (stdb_update_payment_status(merch, "SCHEDULED", "HELD", bizdate) < 0) FAIL(b);
|
||||
snprintf(rbuf, sizeof(rbuf), "DISPUTE:%s", reason);
|
||||
adj = stdb_insert_adjust(0, h_pid, claimed, rbuf, bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
Bchg(b, T_MERCHANT, 0, merch, 0L);
|
||||
Bchg(b, T_STATUS, 0, "D", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_DTLSUM.h
Normal file
20
app/src/st/svc/ST_DTLSUM.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_DTLSUM.h - st 서비스 ST_DTLSUM 카피북 (copybook / record header).
|
||||
* 정산 상세 합계: 수수료 종류별 건수/합계/최소/최대/평균.
|
||||
*/
|
||||
#ifndef ST_DTLSUM_H
|
||||
#define ST_DTLSUM_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char fee_type[16];
|
||||
char biz_date[16];
|
||||
long cnt;
|
||||
long total;
|
||||
} st_st_dtlsum_rec_t;
|
||||
|
||||
void ST_DTLSUM(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_DTLSUM_H */
|
||||
37
app/src/st/svc/ST_DTLSUM.pgc
Normal file
37
app/src/st/svc/ST_DTLSUM.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ST_DTLSUM.pgc - st 모듈 서비스 ST_DTLSUM (one service = one file).
|
||||
* 정산 상세 합계: 가맹점+수수료종류+영업일 단위로 상세 라인의 건수·합계·
|
||||
* 최소·최대를 집계하고 평균을 계산해 회신한다. 조회 전용.
|
||||
*/
|
||||
#include "ST_DTLSUM.h"
|
||||
|
||||
/* 55. ST_DTLSUM - 정산 상세 다중 집계 (건수/합/min/max/평균). */
|
||||
void ST_DTLSUM(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], ftype[16], bizdate[16];
|
||||
long avg;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_sum, h_min, h_max;
|
||||
char h_merch[64], h_ftype[16], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_STR1, ftype, sizeof(ftype)); if (ftype[0] == 0) strcpy(ftype, "MDR");
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_ftype, ftype, sizeof(h_ftype)-1); h_ftype[sizeof(h_ftype)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(amount),0), coalesce(min(amount),0), coalesce(max(amount),0)
|
||||
INTO :h_cnt, :h_sum, :h_min, :h_max FROM st_settle_dtl
|
||||
WHERE merchant_id = :h_merch AND fee_type = :h_ftype AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
avg = (h_cnt > 0) ? h_sum / h_cnt : 0;
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
setl(b, T_AMT1, h_min);
|
||||
setl(b, T_AMT2, h_max);
|
||||
setl(b, T_AMT3, avg);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_EDIRECON.h
Normal file
20
app/src/st/svc/ST_EDIRECON.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_EDIRECON.h - st 서비스 ST_EDIRECON 카피북 (copybook / record header).
|
||||
* EDI 정산 대사: EDI 청구액 vs 가맹점 정산 집계 net 대사.
|
||||
*/
|
||||
#ifndef ST_EDIRECON_H
|
||||
#define ST_EDIRECON_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
long edi_cnt;
|
||||
long edi_sum;
|
||||
long settle_net;
|
||||
} st_st_edirecon_rec_t;
|
||||
|
||||
void ST_EDIRECON(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_EDIRECON_H */
|
||||
36
app/src/st/svc/ST_EDIRECON.pgc
Normal file
36
app/src/st/svc/ST_EDIRECON.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ST_EDIRECON.pgc - st 모듈 서비스 ST_EDIRECON (one service = one file).
|
||||
* EDI 정산 대사: 가맹점 당일 EDI 문서(ac_edi) 청구 합계와 정산 집계
|
||||
* (st_merch_settle) net 을 대사한다. 집계 미존재 시 0 으로 간주. 조회 전용.
|
||||
*/
|
||||
#include "ST_EDIRECON.h"
|
||||
|
||||
/* 71. ST_EDIRECON - EDI 청구 vs 정산 집계 대사. */
|
||||
void ST_EDIRECON(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_edi, h_net;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(amount),0) INTO :h_cnt, :h_edi
|
||||
FROM ac_edi WHERE merchant_id = :h_merch AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL SELECT net_amount INTO :h_net FROM st_merch_settle
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (sqlca.sqlcode == 100) h_net = 0; /* 집계 미존재: 0 대사 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_edi);
|
||||
setl(b, T_NET, h_net);
|
||||
setl(b, T_DELTA, h_edi - h_net);
|
||||
setl(b, T_RC, (h_edi == h_net) ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
22
app/src/st/svc/ST_FEEPREVIEW.h
Normal file
22
app/src/st/svc/ST_FEEPREVIEW.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* ST_FEEPREVIEW.h - st 서비스 ST_FEEPREVIEW 카피북 (copybook / record header).
|
||||
* 수수료 사전 미리보기: 가맹점 요율 기준 수수료/부가세/원천세/실수령 예상.
|
||||
*/
|
||||
#ifndef ST_FEEPREVIEW_H
|
||||
#define ST_FEEPREVIEW_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
long amount;
|
||||
long mdr_bps;
|
||||
long fee;
|
||||
long vat;
|
||||
long wht;
|
||||
long take_home;
|
||||
} st_st_feepreview_rec_t;
|
||||
|
||||
void ST_FEEPREVIEW(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_FEEPREVIEW_H */
|
||||
34
app/src/st/svc/ST_FEEPREVIEW.pgc
Normal file
34
app/src/st/svc/ST_FEEPREVIEW.pgc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* ST_FEEPREVIEW.pgc - st 모듈 서비스 ST_FEEPREVIEW (one service = one file).
|
||||
* 수수료 사전 미리보기: 가맹점 등록 요율(mdr_bps)로 수수료·부가세·원천세와
|
||||
* 실수령 예상액을 계산해 회신한다. DB 쓰기 없는 견적 서비스.
|
||||
*/
|
||||
#include "ST_FEEPREVIEW.h"
|
||||
|
||||
/* 51. ST_FEEPREVIEW - 정산 실수령 예상 견적. */
|
||||
void ST_FEEPREVIEW(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64];
|
||||
long amount = getl(b, T_AMOUNT), fee, vat, wht, net;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_bps;
|
||||
char h_merch[64];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
EXEC SQL SELECT mdr_bps INTO :h_bps FROM merchant WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
fee = acq_fee(amount, h_bps);
|
||||
vat = acq_vat(fee);
|
||||
wht = acq_wht_amt(fee, 2200);
|
||||
net = amount - fee - vat;
|
||||
setl(b, T_FEE, fee);
|
||||
setl(b, T_TAX, vat);
|
||||
setl(b, T_AMT1, wht);
|
||||
setl(b, T_NET, net);
|
||||
setl(b, T_RC, h_bps);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_FEERATIO.h
Normal file
19
app/src/st/svc/ST_FEERATIO.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_FEERATIO.h - st 서비스 ST_FEERATIO 카피북 (copybook / record header).
|
||||
* 수수료율 실효 검증: 실효 bps vs 계약 bps 편차 판정.
|
||||
*/
|
||||
#ifndef ST_FEERATIO_H
|
||||
#define ST_FEERATIO_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long eff_bps;
|
||||
long contract_bps;
|
||||
long diff_bps;
|
||||
} st_st_feeratio_rec_t;
|
||||
|
||||
void ST_FEERATIO(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_FEERATIO_H */
|
||||
32
app/src/st/svc/ST_FEERATIO.pgc
Normal file
32
app/src/st/svc/ST_FEERATIO.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ST_FEERATIO.pgc - st 모듈 서비스 ST_FEERATIO (one service = one file).
|
||||
* 수수료율 실효 검증: 매입-가맹점 조인 한 번으로 실제 부과 수수료의 실효
|
||||
* bps 를 역산하고 계약 요율과의 편차(±5bps 허용)를 판정한다. 조회 전용.
|
||||
*/
|
||||
#include "ST_FEERATIO.h"
|
||||
|
||||
/* 65. ST_FEERATIO - 실효 수수료율 vs 계약 요율 편차 검증. */
|
||||
void ST_FEERATIO(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long eff, diff, adiff;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_amount, h_fee, h_bps;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
EXEC SQL SELECT p.amount, p.fee, m.mdr_bps INTO :h_amount, :h_fee, :h_bps
|
||||
FROM purchase p JOIN merchant m ON m.merchant_id = p.merchant_id
|
||||
WHERE p.purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
if (h_amount <= 0) FAIL(b);
|
||||
eff = h_fee * 10000 / h_amount; /* 실효 bps 역산 */
|
||||
diff = eff - h_bps;
|
||||
adiff = (diff < 0) ? -diff : diff;
|
||||
setl(b, T_ARG1, eff);
|
||||
setl(b, T_ARG2, h_bps);
|
||||
setl(b, T_DELTA, diff);
|
||||
setl(b, T_RC, (adiff > 5) ? 1 : 0); /* 허용 편차 5bps 초과 시 이상 */
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_FXSETTLE.h
Normal file
20
app/src/st/svc/ST_FXSETTLE.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_FXSETTLE.h - st 서비스 ST_FXSETTLE 카피북 (copybook / record header).
|
||||
* 해외 매입 정산: ac_fx 원화 환산액 합산 + FX 정산 상세 기록.
|
||||
*/
|
||||
#ifndef ST_FXSETTLE_H
|
||||
#define ST_FXSETTLE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long settlement_id;
|
||||
long purchase_id;
|
||||
char merchant_id[64];
|
||||
long fx_cnt;
|
||||
long krw_total;
|
||||
} st_st_fxsettle_rec_t;
|
||||
|
||||
void ST_FXSETTLE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_FXSETTLE_H */
|
||||
32
app/src/st/svc/ST_FXSETTLE.pgc
Normal file
32
app/src/st/svc/ST_FXSETTLE.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ST_FXSETTLE.pgc - st 모듈 서비스 ST_FXSETTLE (one service = one file).
|
||||
* 해외 매입 정산: 매입에 걸린 외화 내역(ac_fx)의 원화 환산액을 합산해 FX
|
||||
* 정산 상세로 기록한다. 외화 내역 없으면 RC=1 (dbio).
|
||||
*/
|
||||
#include "ST_FXSETTLE.h"
|
||||
|
||||
/* 70. ST_FXSETTLE - 외화 환산액 정산 상세 기록. */
|
||||
void ST_FXSETTLE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
long sid = getl(b, T_SETTLE_ID), dtl;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_cnt, h_krw;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
EXEC SQL SELECT count(*), coalesce(sum(krw_amount),0) INTO :h_cnt, :h_krw
|
||||
FROM ac_fx WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_cnt == 0) { setl(b, T_RC, 1); setl(b, T_AMOUNT, 0); OK(b); }
|
||||
dtl = stdb_insert_fee_dtl(sid, h_pid, merch, "FX", h_krw, bizdate);
|
||||
if (dtl < 0) FAIL(b);
|
||||
setl(b, T_AMOUNT, h_krw);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_GRPSETTLE.h
Normal file
20
app/src/st/svc/ST_GRPSETTLE.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_GRPSETTLE.h - st 서비스 ST_GRPSETTLE 카피북 (copybook / record header).
|
||||
* 가맹점그룹 통합정산: 그룹 prefix 소속 가맹점 정산을 통합 지급.
|
||||
*/
|
||||
#ifndef ST_GRPSETTLE_H
|
||||
#define ST_GRPSETTLE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char group_prefix[16];
|
||||
char biz_date[16];
|
||||
long members;
|
||||
long group_total;
|
||||
long pay_id;
|
||||
} st_st_grpsettle_rec_t;
|
||||
|
||||
void ST_GRPSETTLE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_GRPSETTLE_H */
|
||||
46
app/src/st/svc/ST_GRPSETTLE.pgc
Normal file
46
app/src/st/svc/ST_GRPSETTLE.pgc
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* ST_GRPSETTLE.pgc - st 모듈 서비스 ST_GRPSETTLE (one service = one file).
|
||||
* 가맹점그룹 통합정산: 그룹 prefix(LIKE) 소속 가맹점별 정산 net 을 커서로
|
||||
* 합산해 그룹 대표 앞 통합 지급 1건으로 예약한다. 소속원 없으면 RC=1 (dbio).
|
||||
*/
|
||||
#include "ST_GRPSETTLE.h"
|
||||
|
||||
/* 48. ST_GRPSETTLE - 그룹 prefix 통합정산 지급. */
|
||||
void ST_GRPSETTLE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char prefix[16], bizdate[16], like[24];
|
||||
long members = 0, total = 0, pay;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_msum;
|
||||
char h_mid[64], h_like[24], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_KEY1, prefix, sizeof(prefix)); if (prefix[0] == 0) strcpy(prefix, "M0");
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
snprintf(like, sizeof(like), "%s%%", prefix);
|
||||
strncpy(h_like, like, sizeof(h_like)-1); h_like[sizeof(h_like)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL DECLARE grpset_c CURSOR FOR
|
||||
SELECT merchant_id, coalesce(sum(net),0) FROM settlement
|
||||
WHERE biz_date = :h_bizdate AND merchant_id LIKE :h_like
|
||||
GROUP BY merchant_id ORDER BY merchant_id;
|
||||
EXEC SQL OPEN grpset_c;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH grpset_c INTO :h_mid, :h_msum;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE grpset_c; FAIL(b); }
|
||||
members++;
|
||||
total += h_msum;
|
||||
}
|
||||
EXEC SQL CLOSE grpset_c;
|
||||
if (members == 0) { setl(b, T_RC, 1); OK(b); }
|
||||
pay = stdb_insert_payment(prefix, total, bizdate, "SCHEDULED", bizdate); /* 그룹 대표 지급 */
|
||||
if (pay < 0) FAIL(b);
|
||||
setl(b, T_ID1, pay);
|
||||
setl(b, T_COUNT, members);
|
||||
setl(b, T_GROSS, total);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
18
app/src/st/svc/ST_HOLDAMT.h
Normal file
18
app/src/st/svc/ST_HOLDAMT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ST_HOLDAMT.h - st 서비스 ST_HOLDAMT 카피북 (copybook / record header).
|
||||
* 금액 조건부 보류: 임계액 이상 예정 지급의 일괄 보류.
|
||||
*/
|
||||
#ifndef ST_HOLDAMT_H
|
||||
#define ST_HOLDAMT_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long threshold;
|
||||
long held_rows;
|
||||
} st_st_holdamt_rec_t;
|
||||
|
||||
void ST_HOLDAMT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_HOLDAMT_H */
|
||||
31
app/src/st/svc/ST_HOLDAMT.pgc
Normal file
31
app/src/st/svc/ST_HOLDAMT.pgc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* ST_HOLDAMT.pgc - st 모듈 서비스 ST_HOLDAMT (one service = one file).
|
||||
* 금액 조건부 보류: 임계액(threshold) 이상의 SCHEDULED 지급을 집합 UPDATE 로
|
||||
* 일괄 HELD 전환하고 보류 건수를 회신한다 (고액 지급 심사용).
|
||||
*/
|
||||
#include "ST_HOLDAMT.h"
|
||||
|
||||
/* 52. ST_HOLDAMT - 임계액 이상 지급 일괄 보류. */
|
||||
void ST_HOLDAMT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
long rows;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_thr;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_thr = getl(b, T_AMT1);
|
||||
if (h_thr <= 0) h_thr = 1000000; /* 기본 고액 기준 100만원 */
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL UPDATE st_payment SET status = 'HELD'
|
||||
WHERE status = 'SCHEDULED' AND biz_date = :h_bizdate AND net_amount >= :h_thr;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
rows = (long) sqlca.sqlerrd[2];
|
||||
setl(b, T_COUNT, rows);
|
||||
setl(b, T_RC, rows > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
18
app/src/st/svc/ST_ISSUERSTAT.h
Normal file
18
app/src/st/svc/ST_ISSUERSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ST_ISSUERSTAT.h - st 서비스 ST_ISSUERSTAT 카피북 (copybook / record header).
|
||||
* 발급사별 수수료 통계: 발급사 단위 매입 수수료 분해 집계.
|
||||
*/
|
||||
#ifndef ST_ISSUERSTAT_H
|
||||
#define ST_ISSUERSTAT_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long issuer_cnt;
|
||||
long fee_total;
|
||||
} st_st_issuerstat_rec_t;
|
||||
|
||||
void ST_ISSUERSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_ISSUERSTAT_H */
|
||||
41
app/src/st/svc/ST_ISSUERSTAT.pgc
Normal file
41
app/src/st/svc/ST_ISSUERSTAT.pgc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* ST_ISSUERSTAT.pgc - st 모듈 서비스 ST_ISSUERSTAT (one service = one file).
|
||||
* 발급사별 수수료 통계 세분: 당일 정산완료(S) 매입을 발급사(issuer) 단위로
|
||||
* 커서 순회하며 발급사 수와 수수료 총액을 집계한다. 조회 전용.
|
||||
*/
|
||||
#include "ST_ISSUERSTAT.h"
|
||||
|
||||
/* 68. ST_ISSUERSTAT - 발급사별 수수료 분해 통계. */
|
||||
void ST_ISSUERSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
long issuers = 0, feesum = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_fee;
|
||||
char h_issuer[32], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL DECLARE issuerstat_c CURSOR FOR
|
||||
SELECT issuer, coalesce(sum(fee),0) FROM purchase
|
||||
WHERE biz_date = :h_bizdate AND status = 'S'
|
||||
GROUP BY issuer ORDER BY issuer;
|
||||
EXEC SQL OPEN issuerstat_c;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH issuerstat_c INTO :h_issuer, :h_fee;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE issuerstat_c; FAIL(b); }
|
||||
issuers++;
|
||||
feesum += h_fee;
|
||||
}
|
||||
EXEC SQL CLOSE issuerstat_c;
|
||||
if (issuers == 0) { setl(b, T_RC, 1); OK(b); }
|
||||
setl(b, T_COUNT, issuers);
|
||||
setl(b, T_FEE, feesum);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_LEDGERSNAP.h
Normal file
19
app/src/st/svc/ST_LEDGERSNAP.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_LEDGERSNAP.h - st 서비스 ST_LEDGERSNAP 카피북 (copybook / record header).
|
||||
* 정산 스냅샷: 당일 정산 총액의 원장 스냅샷(STSNAP) 기록.
|
||||
*/
|
||||
#ifndef ST_LEDGERSNAP_H
|
||||
#define ST_LEDGERSNAP_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long snap_ledger_id;
|
||||
long settle_cnt;
|
||||
long net_sum;
|
||||
} st_st_ledgersnap_rec_t;
|
||||
|
||||
void ST_LEDGERSNAP(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_LEDGERSNAP_H */
|
||||
33
app/src/st/svc/ST_LEDGERSNAP.pgc
Normal file
33
app/src/st/svc/ST_LEDGERSNAP.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* ST_LEDGERSNAP.pgc - st 모듈 서비스 ST_LEDGERSNAP (one service = one file).
|
||||
* 정산 스냅샷: 당일 정산 건수·net 총액을 집계해 원장에 STSNAP 스냅샷 엔트리로
|
||||
* 기록하고 스냅샷 원장 ID 를 회신한다 (감사 추적용).
|
||||
*/
|
||||
#include "ST_LEDGERSNAP.h"
|
||||
|
||||
/* 75. ST_LEDGERSNAP - 당일 정산 총액 원장 스냅샷. */
|
||||
void ST_LEDGERSNAP(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_sum, h_lid;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_sum
|
||||
FROM settlement WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL SELECT nextval('ledger_seq') INTO :h_lid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (:h_lid, 0, 'STSNAP', :h_sum, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_ID1, h_lid);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_LIMITCHK.h
Normal file
20
app/src/st/svc/ST_LIMITCHK.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_LIMITCHK.h - st 서비스 ST_LIMITCHK 카피북 (copybook / record header).
|
||||
* 가맹점 한도 점검: 일 매입 누계 vs daily_limit 잔여 확인.
|
||||
*/
|
||||
#ifndef ST_LIMITCHK_H
|
||||
#define ST_LIMITCHK_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
long daily_limit;
|
||||
long used;
|
||||
long remain;
|
||||
} st_st_limitchk_rec_t;
|
||||
|
||||
void ST_LIMITCHK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_LIMITCHK_H */
|
||||
35
app/src/st/svc/ST_LIMITCHK.pgc
Normal file
35
app/src/st/svc/ST_LIMITCHK.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ST_LIMITCHK.pgc - st 모듈 서비스 ST_LIMITCHK (one service = one file).
|
||||
* 가맹점 한도 점검: 가맹점 일 한도(daily_limit)와 당일 매입 누계(취소 제외)를
|
||||
* 비교해 잔여 한도를 회신한다. 한도 초과 시 RC=1. 조회 전용.
|
||||
*/
|
||||
#include "ST_LIMITCHK.h"
|
||||
|
||||
/* 74. ST_LIMITCHK - 일 매입 한도 잔여 점검. */
|
||||
void ST_LIMITCHK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
long remain;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_limit, h_used;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT daily_limit INTO :h_limit FROM merchant WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_used FROM purchase
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status <> 'C';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
remain = h_limit - h_used;
|
||||
setl(b, T_AMT1, h_limit);
|
||||
setl(b, T_GROSS, h_used);
|
||||
setl(b, T_DELTA, remain);
|
||||
setl(b, T_RC, (remain < 0) ? 1 : 0);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
21
app/src/st/svc/ST_MERCHRATE.h
Normal file
21
app/src/st/svc/ST_MERCHRATE.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* ST_MERCHRATE.h - st 서비스 ST_MERCHRATE 카피북 (copybook / record header).
|
||||
* 가맹점 개별 요율 적용: merchant.mdr_bps 로 수수료 산출 + 상세 기록.
|
||||
*/
|
||||
#ifndef ST_MERCHRATE_H
|
||||
#define ST_MERCHRATE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long settlement_id;
|
||||
long purchase_id;
|
||||
char merchant_id[64];
|
||||
long amount;
|
||||
long merch_bps;
|
||||
long fee;
|
||||
} st_st_merchrate_rec_t;
|
||||
|
||||
void ST_MERCHRATE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_MERCHRATE_H */
|
||||
32
app/src/st/svc/ST_MERCHRATE.pgc
Normal file
32
app/src/st/svc/ST_MERCHRATE.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ST_MERCHRATE.pgc - st 모듈 서비스 ST_MERCHRATE (one service = one file).
|
||||
* 가맹점 개별 요율 적용: 구간요율표 대신 가맹점 마스터의 계약 요율(mdr_bps)로
|
||||
* 수수료를 산출하고 MDR 정산 상세로 기록한다 (dbio).
|
||||
*/
|
||||
#include "ST_MERCHRATE.h"
|
||||
|
||||
/* 56. ST_MERCHRATE - 가맹점 계약 요율 수수료 산출/기록. */
|
||||
void ST_MERCHRATE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
long sid = getl(b, T_SETTLE_ID), pid = getl(b, T_PURCHASE_ID);
|
||||
long amount = getl(b, T_AMOUNT), fee, dtl;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_bps;
|
||||
char h_merch[64];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
EXEC SQL SELECT mdr_bps INTO :h_bps FROM merchant WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
fee = acq_fee(amount, h_bps);
|
||||
dtl = stdb_insert_fee_dtl(sid, pid, merch, "MDR", fee, bizdate);
|
||||
if (dtl < 0) FAIL(b);
|
||||
setl(b, T_FEE, fee);
|
||||
setl(b, T_RC, h_bps);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_MINFEE.h
Normal file
20
app/src/st/svc/ST_MINFEE.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_MINFEE.h - st 서비스 ST_MINFEE 카피북 (copybook / record header).
|
||||
* 최저 수수료 보정: 최저액 미달 수수료의 부족분 보정 상세 기록.
|
||||
*/
|
||||
#ifndef ST_MINFEE_H
|
||||
#define ST_MINFEE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long settlement_id;
|
||||
long purchase_id;
|
||||
char merchant_id[64];
|
||||
long fee;
|
||||
long min_fee;
|
||||
} st_st_minfee_rec_t;
|
||||
|
||||
void ST_MINFEE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_MINFEE_H */
|
||||
31
app/src/st/svc/ST_MINFEE.pgc
Normal file
31
app/src/st/svc/ST_MINFEE.pgc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* ST_MINFEE.pgc - st 모듈 서비스 ST_MINFEE (one service = one file).
|
||||
* 최저 수수료 보정: 산출 수수료가 최저 수수료에 미달하면 부족분을 ADJ 정산
|
||||
* 상세로 추가 기록해 최저액을 보장한다 (dbio). 충족 시 변경 없음.
|
||||
*/
|
||||
#include "ST_MINFEE.h"
|
||||
|
||||
/* 59. ST_MINFEE - 최저 수수료 미달분 보정. */
|
||||
void ST_MINFEE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
long sid = getl(b, T_SETTLE_ID), pid = getl(b, T_PURCHASE_ID);
|
||||
long fee = getl(b, T_FEE), minfee = getl(b, T_ARG1), diff, dtl;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
if (minfee <= 0) minfee = 100; /* 기본 최저 수수료 100원 */
|
||||
if (fee >= minfee) {
|
||||
setl(b, T_FEE, fee);
|
||||
setl(b, T_DELTA, 0);
|
||||
OK(b);
|
||||
}
|
||||
diff = minfee - fee;
|
||||
dtl = stdb_insert_fee_dtl(sid, pid, merch, "ADJ", diff, bizdate);
|
||||
if (dtl < 0) FAIL(b);
|
||||
setl(b, T_FEE, minfee);
|
||||
setl(b, T_DELTA, diff);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
18
app/src/st/svc/ST_NEGSWEEP.h
Normal file
18
app/src/st/svc/ST_NEGSWEEP.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ST_NEGSWEEP.h - st 서비스 ST_NEGSWEEP 카피북 (copybook / record header).
|
||||
* 음수 정산 정리: 당일 음수 net 정산의 일괄 취소 전환.
|
||||
*/
|
||||
#ifndef ST_NEGSWEEP_H
|
||||
#define ST_NEGSWEEP_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long neg_sum;
|
||||
long swept;
|
||||
} st_st_negsweep_rec_t;
|
||||
|
||||
void ST_NEGSWEEP(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_NEGSWEEP_H */
|
||||
33
app/src/st/svc/ST_NEGSWEEP.pgc
Normal file
33
app/src/st/svc/ST_NEGSWEEP.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* ST_NEGSWEEP.pgc - st 모듈 서비스 ST_NEGSWEEP (one service = one file).
|
||||
* 음수 정산 정리: 당일 net 이 음수인 SETTLED 정산의 합계를 먼저 파악한 뒤
|
||||
* 집합 UPDATE 로 일괄 CANCELLED 전환한다. 처리 건수/음수 합계를 회신.
|
||||
*/
|
||||
#include "ST_NEGSWEEP.h"
|
||||
|
||||
/* 63. ST_NEGSWEEP - 음수 net 정산 일괄 취소. */
|
||||
void ST_NEGSWEEP(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
long rows;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_neg;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(net),0) INTO :h_neg FROM settlement
|
||||
WHERE biz_date = :h_bizdate AND net < 0 AND status = 'SETTLED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL UPDATE settlement SET status = 'CANCELLED'
|
||||
WHERE biz_date = :h_bizdate AND net < 0 AND status = 'SETTLED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
rows = (long) sqlca.sqlerrd[2];
|
||||
setl(b, T_COUNT, rows);
|
||||
setl(b, T_GROSS, h_neg);
|
||||
setl(b, T_RC, rows > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_PARTIAL.h
Normal file
20
app/src/st/svc/ST_PARTIAL.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_PARTIAL.h - st 서비스 ST_PARTIAL 카피북 (copybook / record header).
|
||||
* 부분정산: 매입 net 잔여 한도 내에서 일부 금액만 정산 확정.
|
||||
*/
|
||||
#ifndef ST_PARTIAL_H
|
||||
#define ST_PARTIAL_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
char merchant_id[64];
|
||||
long part_amount;
|
||||
long remain;
|
||||
char biz_date[16];
|
||||
} st_st_partial_rec_t;
|
||||
|
||||
void ST_PARTIAL(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_PARTIAL_H */
|
||||
44
app/src/st/svc/ST_PARTIAL.pgc
Normal file
44
app/src/st/svc/ST_PARTIAL.pgc
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* ST_PARTIAL.pgc - st 모듈 서비스 ST_PARTIAL (one service = one file).
|
||||
* 부분정산: 매입 net 에서 기정산 합계를 뺀 잔여 한도 내에서 요청 금액만큼
|
||||
* PARTIAL 상태의 정산 레코드를 추가 생성한다. 한도 초과/0 이하는 RC=1.
|
||||
*/
|
||||
#include "ST_PARTIAL.h"
|
||||
|
||||
/* 33. ST_PARTIAL - 부분정산 (잔여 한도 검증 후 PARTIAL 정산 생성). */
|
||||
void ST_PARTIAL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_sid, h_pnet, h_done, h_part;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
h_part = getl(b, T_AMOUNT);
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT net INTO :h_pnet FROM purchase WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
EXEC SQL SELECT coalesce(sum(net),0) INTO :h_done FROM settlement
|
||||
WHERE purchase_id = :h_pid AND status <> 'CANCELLED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_part <= 0 || h_part > h_pnet - h_done) {
|
||||
setl(b, T_RC, 1);
|
||||
setl(b, T_NET, h_pnet - h_done); /* 잔여 한도 통지 */
|
||||
OK(b);
|
||||
}
|
||||
EXEC SQL SELECT nextval('settlement_seq') INTO :h_sid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO settlement (settlement_id, purchase_id, merchant_id, net, biz_date, status)
|
||||
VALUES (:h_sid, :h_pid, :h_merch, :h_part, :h_bizdate, 'PARTIAL');
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_SETTLE_ID, h_sid);
|
||||
setl(b, T_NET, h_pnet - h_done - h_part);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_PAYRETRY.h
Normal file
19
app/src/st/svc/ST_PAYRETRY.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_PAYRETRY.h - st 서비스 ST_PAYRETRY 카피북 (copybook / record header).
|
||||
* 지급 재시도: 취소된 지급을 익영업일 재예약으로 복구.
|
||||
*/
|
||||
#ifndef ST_PAYRETRY_H
|
||||
#define ST_PAYRETRY_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
char retry_date[16];
|
||||
long retried;
|
||||
} st_st_payretry_rec_t;
|
||||
|
||||
void ST_PAYRETRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_PAYRETRY_H */
|
||||
34
app/src/st/svc/ST_PAYRETRY.pgc
Normal file
34
app/src/st/svc/ST_PAYRETRY.pgc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* ST_PAYRETRY.pgc - st 모듈 서비스 ST_PAYRETRY (one service = one file).
|
||||
* 지급 재시도: 이체 실패 등으로 CANCELLED 된 지급을 익영업일 지급일로 갱신해
|
||||
* SCHEDULED 재예약한다. 대상 없으면 RC=1.
|
||||
*/
|
||||
#include "ST_PAYRETRY.h"
|
||||
|
||||
/* 73. ST_PAYRETRY - 취소 지급 익영업일 재예약. */
|
||||
void ST_PAYRETRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16], retry[16];
|
||||
long rows;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_merch[64], h_bizdate[16], h_retry[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
if (acq_next_bizday(bizdate, retry) < 0) FAIL(b);
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
strncpy(h_retry, retry, sizeof(h_retry)-1); h_retry[sizeof(h_retry)-1] = 0;
|
||||
EXEC SQL UPDATE st_payment SET status = 'SCHEDULED', pay_date = :h_retry
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'CANCELLED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
rows = (long) sqlca.sqlerrd[2];
|
||||
if (rows == 0) { setl(b, T_RC, 1); setl(b, T_COUNT, 0); OK(b); }
|
||||
setl(b, T_COUNT, rows);
|
||||
Bchg(b, T_KEY1, 0, retry, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_PAYSTATUS.h
Normal file
19
app/src/st/svc/ST_PAYSTATUS.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_PAYSTATUS.h - st 서비스 ST_PAYSTATUS 카피북 (copybook / record header).
|
||||
* 지급 상태 조회: 가맹점 최신 지급 레코드의 상태/금액/지급일.
|
||||
*/
|
||||
#ifndef ST_PAYSTATUS_H
|
||||
#define ST_PAYSTATUS_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char status[16];
|
||||
long net_amount;
|
||||
char pay_date[16];
|
||||
} st_st_paystatus_rec_t;
|
||||
|
||||
void ST_PAYSTATUS(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_PAYSTATUS_H */
|
||||
35
app/src/st/svc/ST_PAYSTATUS.pgc
Normal file
35
app/src/st/svc/ST_PAYSTATUS.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ST_PAYSTATUS.pgc - st 모듈 서비스 ST_PAYSTATUS (one service = one file).
|
||||
* 지급 상태 조회: 가맹점의 가장 최근 지급 레코드에서 상태·금액·지급 예정일을
|
||||
* 조회해 회신한다. 지급 이력이 없으면 NONE/RC=1.
|
||||
*/
|
||||
#include "ST_PAYSTATUS.h"
|
||||
|
||||
/* 53. ST_PAYSTATUS - 가맹점 최신 지급 상태 조회. */
|
||||
void ST_PAYSTATUS(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_net;
|
||||
char h_merch[64], h_status[16], h_payd[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
EXEC SQL SELECT status, net_amount, to_char(pay_date,'YYYY-MM-DD')
|
||||
INTO :h_status, :h_net, :h_payd FROM st_payment
|
||||
WHERE merchant_id = :h_merch ORDER BY pay_id DESC LIMIT 1;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (sqlca.sqlcode == 100) {
|
||||
Bchg(b, T_STATUS, 0, "NONE", 0L);
|
||||
setl(b, T_RC, 1);
|
||||
OK(b);
|
||||
}
|
||||
Bchg(b, T_STATUS, 0, h_status, 0L);
|
||||
setl(b, T_NET, h_net);
|
||||
Bchg(b, T_KEY1, 0, h_payd, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
21
app/src/st/svc/ST_PROMOCALC.h
Normal file
21
app/src/st/svc/ST_PROMOCALC.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* ST_PROMOCALC.h - st 서비스 ST_PROMOCALC 카피북 (copybook / record header).
|
||||
* 프로모션/이벤트 정산: 이벤트 코드별 수수료 할인율 적용 + 할인 조정 기록.
|
||||
*/
|
||||
#ifndef ST_PROMOCALC_H
|
||||
#define ST_PROMOCALC_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long settlement_id;
|
||||
long purchase_id;
|
||||
char event_code[32];
|
||||
long fee;
|
||||
long promo_pct;
|
||||
long discount;
|
||||
} st_st_promocalc_rec_t;
|
||||
|
||||
void ST_PROMOCALC(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_PROMOCALC_H */
|
||||
29
app/src/st/svc/ST_PROMOCALC.pgc
Normal file
29
app/src/st/svc/ST_PROMOCALC.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* ST_PROMOCALC.pgc - st 모듈 서비스 ST_PROMOCALC (one service = one file).
|
||||
* 프로모션/이벤트 정산: 이벤트 코드와 할인율(%)을 받아 수수료 할인액을 계산하고
|
||||
* 양수 조정(가맹점 환급)으로 st_adjust 에 기록한다 (dbio).
|
||||
*/
|
||||
#include "ST_PROMOCALC.h"
|
||||
|
||||
/* 32. ST_PROMOCALC - 프로모션/이벤트 수수료 할인 정산. */
|
||||
void ST_PROMOCALC(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], event[32], reason[64];
|
||||
long sid = getl(b, T_SETTLE_ID), pid = getl(b, T_PURCHASE_ID);
|
||||
long fee = getl(b, T_FEE), pct = getl(b, T_ARG1), disc, adj;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_STR1, event, sizeof(event)); if (event[0] == 0) strcpy(event, "EVENT");
|
||||
if (pct <= 0 || pct > 100) pct = 30; /* 기본 30% 할인 */
|
||||
disc = fee * pct / 100;
|
||||
if (disc <= 0) { setl(b, T_RC, 1); setl(b, T_DELTA, 0); OK(b); }
|
||||
snprintf(reason, sizeof(reason), "PROMO:%s", event);
|
||||
adj = stdb_insert_adjust(sid, pid, disc, reason, bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
setl(b, T_DELTA, disc);
|
||||
setl(b, T_FEE, fee - disc);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_RATESIM.h
Normal file
20
app/src/st/svc/ST_RATESIM.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_RATESIM.h - st 서비스 ST_RATESIM 카피북 (copybook / record header).
|
||||
* 요율 시뮬레이션: 요율표 전 구간 순회 + 적용 구간 판정 + 예상 수수료 계산.
|
||||
*/
|
||||
#ifndef ST_RATESIM_H
|
||||
#define ST_RATESIM_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char fee_type[16];
|
||||
long amount;
|
||||
long band_count;
|
||||
long applied_bps;
|
||||
long sim_fee;
|
||||
} st_st_ratesim_rec_t;
|
||||
|
||||
void ST_RATESIM(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_RATESIM_H */
|
||||
40
app/src/st/svc/ST_RATESIM.pgc
Normal file
40
app/src/st/svc/ST_RATESIM.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* ST_RATESIM.pgc - st 모듈 서비스 ST_RATESIM (one service = one file).
|
||||
* 요율 시뮬레이션: 요율표(st_fee_rate)의 전 구간을 커서로 순회하며 입력 금액에
|
||||
* 적용될 구간(bps)을 판정하고 예상 수수료를 계산한다. 조회 전용(쓰기 없음).
|
||||
*/
|
||||
#include "ST_RATESIM.h"
|
||||
|
||||
/* 31. ST_RATESIM - 요율 시뮬레이션 (구간 판정 + 예상 수수료). */
|
||||
void ST_RATESIM(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char ftype[16];
|
||||
long amount = getl(b, T_AMOUNT), bands = 0, applied = 0, fee;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_min, h_bps;
|
||||
char h_ftype[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_STR1, ftype, sizeof(ftype)); if (ftype[0] == 0) strcpy(ftype, "MDR");
|
||||
strncpy(h_ftype, ftype, sizeof(h_ftype)-1); h_ftype[sizeof(h_ftype)-1] = 0;
|
||||
EXEC SQL DECLARE ratesim_c CURSOR FOR
|
||||
SELECT band_min, rate_bps FROM st_fee_rate WHERE fee_type = :h_ftype ORDER BY band_min;
|
||||
EXEC SQL OPEN ratesim_c;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH ratesim_c INTO :h_min, :h_bps;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE ratesim_c; FAIL(b); }
|
||||
bands++;
|
||||
if (h_min <= amount) applied = h_bps; /* band_min 오름차순: 마지막 매칭 구간이 적용 요율 */
|
||||
}
|
||||
EXEC SQL CLOSE ratesim_c;
|
||||
if (bands == 0) { setl(b, T_RC, -1); OK(b); }
|
||||
fee = acq_fee(amount, applied);
|
||||
setl(b, T_COUNT, bands);
|
||||
setl(b, T_RC, applied);
|
||||
setl(b, T_FEE, fee);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_RECVOFFSET.h
Normal file
19
app/src/st/svc/ST_RECVOFFSET.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_RECVOFFSET.h - st 서비스 ST_RECVOFFSET 카피북 (copybook / record header).
|
||||
* 미수금 상계: 누적 미수금(음수 조정)을 예정 지급액과 상계.
|
||||
*/
|
||||
#ifndef ST_RECVOFFSET_H
|
||||
#define ST_RECVOFFSET_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char biz_date[16];
|
||||
long receivable;
|
||||
long offset_amt;
|
||||
} st_st_recvoffset_rec_t;
|
||||
|
||||
void ST_RECVOFFSET(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_RECVOFFSET_H */
|
||||
41
app/src/st/svc/ST_RECVOFFSET.pgc
Normal file
41
app/src/st/svc/ST_RECVOFFSET.pgc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* ST_RECVOFFSET.pgc - st 모듈 서비스 ST_RECVOFFSET (one service = one file).
|
||||
* 미수금 상계: 매입 조인으로 가맹점의 누적 미수금(음수 조정 절대값)을 산출하고
|
||||
* 예정 지급 가용액과의 min 만큼 최근 지급 레코드에서 상계 차감한다.
|
||||
*/
|
||||
#include "ST_RECVOFFSET.h"
|
||||
|
||||
/* 43. ST_RECVOFFSET - 미수금-지급 상계 처리. */
|
||||
void ST_RECVOFFSET(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_recv, h_avail, h_off;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(-sum(a.delta),0) INTO :h_recv
|
||||
FROM st_adjust a JOIN purchase p ON p.purchase_id = a.purchase_id
|
||||
WHERE p.merchant_id = :h_merch AND a.delta < 0 AND a.biz_date <= :h_bizdate::date;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_recv <= 0) { setl(b, T_RC, 1); setl(b, T_AMOUNT, 0); OK(b); }
|
||||
EXEC SQL SELECT coalesce(sum(net_amount),0) INTO :h_avail FROM st_payment
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'SCHEDULED';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
h_off = (h_recv < h_avail) ? h_recv : h_avail;
|
||||
if (h_off <= 0) { setl(b, T_RC, 2); setl(b, T_AMOUNT, 0); OK(b); } /* 상계 재원 없음 */
|
||||
EXEC SQL UPDATE st_payment SET net_amount = net_amount - :h_off
|
||||
WHERE pay_id = (SELECT max(pay_id) FROM st_payment
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'SCHEDULED');
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_AMOUNT, h_off);
|
||||
setl(b, T_AMT1, h_recv - h_off); /* 잔여 미수금 */
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
17
app/src/st/svc/ST_REOPEN.h
Normal file
17
app/src/st/svc/ST_REOPEN.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* ST_REOPEN.h - st 서비스 ST_REOPEN 카피북 (copybook / record header).
|
||||
* 마감 해제: 당일 마감 원장(STCLOSE) 철회.
|
||||
*/
|
||||
#ifndef ST_REOPEN_H
|
||||
#define ST_REOPEN_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long removed;
|
||||
} st_st_reopen_rec_t;
|
||||
|
||||
void ST_REOPEN(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_REOPEN_H */
|
||||
27
app/src/st/svc/ST_REOPEN.pgc
Normal file
27
app/src/st/svc/ST_REOPEN.pgc
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* ST_REOPEN.pgc - st 모듈 서비스 ST_REOPEN (one service = one file).
|
||||
* 정산 마감 해제: 당일 마감 원장(STCLOSE)을 삭제해 마감을 철회한다.
|
||||
* 마감 원장이 없으면(미마감) RC=1 로 회신한다.
|
||||
*/
|
||||
#include "ST_REOPEN.h"
|
||||
|
||||
/* 61. ST_REOPEN - 정산 마감 철회 (STCLOSE 삭제). */
|
||||
void ST_REOPEN(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
long rows;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL DELETE FROM ledger WHERE entry_type = 'STCLOSE' AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
rows = (long) sqlca.sqlerrd[2];
|
||||
setl(b, T_COUNT, rows);
|
||||
setl(b, T_RC, rows > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_RERUN.h
Normal file
19
app/src/st/svc/ST_RERUN.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_RERUN.h - st 서비스 ST_RERUN 카피북 (copybook / record header).
|
||||
* 정산 재실행: 기존 정산 상세 삭제 후 매입 원본 기준으로 재생성.
|
||||
*/
|
||||
#ifndef ST_RERUN_H
|
||||
#define ST_RERUN_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long removed;
|
||||
long fee;
|
||||
char merchant_id[64];
|
||||
} st_st_rerun_rec_t;
|
||||
|
||||
void ST_RERUN(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_RERUN_H */
|
||||
32
app/src/st/svc/ST_RERUN.pgc
Normal file
32
app/src/st/svc/ST_RERUN.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ST_RERUN.pgc - st 모듈 서비스 ST_RERUN (one service = one file).
|
||||
* 정산 재실행: 해당 매입의 정산 상세를 전량 삭제하고 매입 원본(fee)을 기준으로
|
||||
* MDR 상세 라인을 다시 생성한다. 삭제 건수를 회신한다.
|
||||
*/
|
||||
#include "ST_RERUN.h"
|
||||
|
||||
/* 34. ST_RERUN - 정산 재실행 (상세 삭제 + 원본 기준 재생성). */
|
||||
void ST_RERUN(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long removed;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_amount, h_fee;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
EXEC SQL DELETE FROM st_settle_dtl WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
removed = (long) sqlca.sqlerrd[2];
|
||||
EXEC SQL SELECT amount, fee, merchant_id, to_char(biz_date,'YYYY-MM-DD')
|
||||
INTO :h_amount, :h_fee, :h_merch, :h_bizdate FROM purchase WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
EXEC SQL INSERT INTO st_settle_dtl (dtl_id, settlement_id, purchase_id, merchant_id, fee_type, amount, biz_date)
|
||||
VALUES (nextval('st_dtl_seq'), 0, :h_pid, :h_merch, 'MDR', :h_fee, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_COUNT, removed);
|
||||
setl(b, T_FEE, h_fee);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
20
app/src/st/svc/ST_RETRORATE.h
Normal file
20
app/src/st/svc/ST_RETRORATE.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ST_RETRORATE.h - st 서비스 ST_RETRORATE 카피북 (copybook / record header).
|
||||
* 요율 소급적용: 신규 bps 로 재계산한 수수료와 기계상분의 차액 조정.
|
||||
*/
|
||||
#ifndef ST_RETRORATE_H
|
||||
#define ST_RETRORATE_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
char fee_type[16];
|
||||
long new_bps;
|
||||
long old_fee;
|
||||
long new_fee;
|
||||
} st_st_retrorate_rec_t;
|
||||
|
||||
void ST_RETRORATE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_RETRORATE_H */
|
||||
40
app/src/st/svc/ST_RETRORATE.pgc
Normal file
40
app/src/st/svc/ST_RETRORATE.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* ST_RETRORATE.pgc - st 모듈 서비스 ST_RETRORATE (one service = one file).
|
||||
* 요율 소급적용: 신규 요율(bps)로 매입 금액의 수수료를 재계산하고, 기계상된
|
||||
* 정산 상세 합계와의 차액만큼 소급 조정(st_adjust)을 기록한다 (dbio).
|
||||
*/
|
||||
#include "ST_RETRORATE.h"
|
||||
|
||||
/* 36. ST_RETRORATE - 요율 소급적용 (차액 조정 기록). */
|
||||
void ST_RETRORATE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], ftype[16];
|
||||
long sid = getl(b, T_SETTLE_ID), newbps = getl(b, T_ARG1);
|
||||
long newfee, diff, adj;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_amount, h_old;
|
||||
char h_ftype[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_STR1, ftype, sizeof(ftype)); if (ftype[0] == 0) strcpy(ftype, "MDR");
|
||||
if (newbps <= 0) newbps = 25;
|
||||
strncpy(h_ftype, ftype, sizeof(h_ftype)-1); h_ftype[sizeof(h_ftype)-1] = 0;
|
||||
EXEC SQL SELECT amount INTO :h_amount FROM purchase WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_old FROM st_settle_dtl
|
||||
WHERE purchase_id = :h_pid AND fee_type = :h_ftype;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
newfee = acq_fee(h_amount, newbps);
|
||||
diff = newfee - h_old;
|
||||
if (diff == 0) { setl(b, T_RC, 0); setl(b, T_DELTA, 0); OK(b); }
|
||||
adj = stdb_insert_adjust(sid, h_pid, diff, "RETRO_RATE", bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
setl(b, T_DELTA, diff);
|
||||
setl(b, T_FEE, newfee);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
19
app/src/st/svc/ST_ROUNDING.h
Normal file
19
app/src/st/svc/ST_ROUNDING.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ST_ROUNDING.h - st 서비스 ST_ROUNDING 카피북 (copybook / record header).
|
||||
* 원단위 절사: 정산 net 10원 미만 절사 + 절사분 조정.
|
||||
*/
|
||||
#ifndef ST_ROUNDING_H
|
||||
#define ST_ROUNDING_H
|
||||
|
||||
#include "st_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long settlement_id;
|
||||
long net_before;
|
||||
long truncated;
|
||||
} st_st_rounding_rec_t;
|
||||
|
||||
void ST_ROUNDING(TPSVCINFO *p);
|
||||
|
||||
#endif /* ST_ROUNDING_H */
|
||||
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