Phase 2c: 전 11모듈 per-service 레거시 구조 분해·확장 (실동작 유지)
- 10개 모듈(au py rc st lg cl mm vl mg cm)을 ac 템플릿대로 분해: svc/ 30 서비스 .pgc + 카피북 .h, 얇은 <mod>_svr 디스패처 dbio/ ~25 .pgc(+.h), batch/ ~17 .pgc, run/ ~17 .sh (모듈마다) - 파일: svc 330 + dbio 276 + batch 187 + run 187, 총 소스 1602본 - 서비스별 고유 실로직(정규화 md5), build.sh 자동발견(inline/split 양립) - 통합 검증: build DONE modules=11 servers=11 batches=187, 12서버 runok, 333 서비스 AVAIL, 매입체인 XA 커밋(status=S), prepared_xacts=0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c3b99a8b75
commit
fd8b418c6e
1404 changed files with 30322 additions and 5994 deletions
34
app/src/py/batch/py_account_batch.pgc
Normal file
34
app/src/py/batch/py_account_batch.pgc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* py_account_batch.pgc - py 계좌 현황 집계 (dbio 전용 배치, XA).
|
||||
*
|
||||
* Uses only the dbio layer (no direct EXEC SQL here) to read the active-account
|
||||
* balance total and count under ONE XA transaction. Usage: py_account_batch
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
#include "py_account_agg_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
long total, cnt;
|
||||
|
||||
(void)argc; (void)argv;
|
||||
|
||||
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; }
|
||||
|
||||
total = pydb_account_active_balance();
|
||||
if (total < 0) { fprintf(stderr, "py_account_batch balance FAIL\n"); tpabort(0); return 1; }
|
||||
cnt = pydb_account_active_count();
|
||||
if (cnt < 0) { fprintf(stderr, "py_account_batch count FAIL\n"); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_account_batch COMMIT: active_accounts=%ld total_balance=%ld\n", cnt, total);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
50
app/src/py/batch/py_adjust_apply_batch.pgc
Normal file
50
app/src/py/batch/py_adjust_apply_batch.pgc
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* py_adjust_apply_batch.pgc - py 조정 반영 (커서 + inline UPDATE, XA).
|
||||
*
|
||||
* Cursors the day's adjustments and applies each delta to the linked payout's
|
||||
* net with an inline UPDATE, under ONE XA transaction.
|
||||
* Usage: py_adjust_apply_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_pay, h_delta;
|
||||
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 pyaac CURSOR FOR
|
||||
SELECT payout_id, delta FROM py_adjust WHERE biz_date = :h_bizdate ORDER BY adj_id;
|
||||
EXEC SQL OPEN pyaac;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyaac INTO :h_pay, :h_delta;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyaac; tpabort(0); return 1; }
|
||||
EXEC SQL UPDATE py_payout SET net = net + :h_delta, updated_at = now() WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pyaac; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyaac;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_adjust_apply_batch COMMIT: bizdate=%s applied=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
38
app/src/py/batch/py_close_batch.pgc
Normal file
38
app/src/py/batch/py_close_batch.pgc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* py_close_batch.pgc - py 일마감 (단건 UPDATE 배치, XA).
|
||||
*
|
||||
* Flips the day's paid(P) payouts to closed(X) with ONE guarded UPDATE and
|
||||
* reports the affected count via sqlca.sqlerrd[2], all under ONE XA transaction.
|
||||
* Usage: py_close_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_aff;
|
||||
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 UPDATE py_payout SET status = 'X' WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_close_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_close_batch COMMIT: bizdate=%s closed(P->X)=%ld\n", bizdate, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
37
app/src/py/batch/py_daily_batch.pgc
Normal file
37
app/src/py/batch/py_daily_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* py_daily_batch.pgc - py 일일 지급 총계 (단건 집계 배치, XA).
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, an EXEC SQL aggregate runs on the biz_date, then tpcommit drives
|
||||
* XA 2PC. Usage: py_daily_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cnt, h_gross, h_fee, 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 SELECT count(*), coalesce(sum(amount),0), coalesce(sum(fee),0), coalesce(sum(net),0) INTO :h_cnt, :h_gross, :h_fee, :h_net FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_daily_batch 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(">>> py_daily_batch COMMIT: bizdate=%s payouts=%ld gross=%ld fee=%ld net=%ld\n", bizdate, h_cnt, h_gross, h_fee, h_net);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
55
app/src/py/batch/py_fee_recalc_batch.pgc
Normal file
55
app/src/py/batch/py_fee_recalc_batch.pgc
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* py_fee_recalc_batch.pgc - py 수수료 재계산 (커서 + 계산 + inline UPDATE, XA).
|
||||
*
|
||||
* Cursors the day's requested(R) payouts, recomputes fee (30bps) and net in C,
|
||||
* and writes them back with an inline UPDATE, under ONE XA transaction.
|
||||
* Usage: py_fee_recalc_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0, fee, net;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_pay, h_amt, h_fee, 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 pyfrc CURSOR FOR
|
||||
SELECT payout_id, amount FROM py_payout
|
||||
WHERE biz_date = :h_bizdate AND status = 'R'
|
||||
ORDER BY payout_id;
|
||||
EXEC SQL OPEN pyfrc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyfrc INTO :h_pay, :h_amt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyfrc; tpabort(0); return 1; }
|
||||
fee = h_amt * 30 / 10000;
|
||||
net = h_amt - fee;
|
||||
h_fee = fee; h_net = net;
|
||||
EXEC SQL UPDATE py_payout SET fee = :h_fee, net = :h_net, updated_at = now() WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pyfrc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyfrc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_fee_recalc_batch COMMIT: bizdate=%s recalced=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
39
app/src/py/batch/py_file_confirm_batch.pgc
Normal file
39
app/src/py/batch/py_file_confirm_batch.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* py_file_confirm_batch.pgc - py 지급파일 확정 (조회 후 UPDATE 배치, XA).
|
||||
*
|
||||
* Counts the day's generated(G) files, then flips them to confirmed(C) stamping
|
||||
* confirmed_at, under ONE XA transaction. Usage: py_file_confirm_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cnt, h_aff;
|
||||
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_cnt FROM py_file WHERE biz_date = :h_bizdate AND status = 'G';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "COUNT FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
EXEC SQL UPDATE py_file SET status = 'C', confirmed_at = now() WHERE biz_date = :h_bizdate AND status = 'G';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_file_confirm_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_file_confirm_batch COMMIT: bizdate=%s generated=%ld confirmed=%ld\n", bizdate, h_cnt, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
39
app/src/py/batch/py_ledger_batch.pgc
Normal file
39
app/src/py/batch/py_ledger_batch.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* py_ledger_batch.pgc - py 지급 원장 생성 (INSERT..SELECT 배치, XA).
|
||||
*
|
||||
* Bulk-inserts one XFER ledger row per paid(P) payout of the biz_date using a
|
||||
* single INSERT ... SELECT, under ONE XA transaction. Usage: py_ledger_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_rows;
|
||||
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 py_ledger (ledger_id, payout_id, entry_type, amount, biz_date)
|
||||
SELECT nextval('py_ledger_seq'), payout_id, 'XFER', net, biz_date
|
||||
FROM py_payout WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_ledger_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_rows = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_ledger_batch COMMIT: bizdate=%s xfer_rows=%ld\n", bizdate, h_rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
50
app/src/py/batch/py_merchsum_batch.pgc
Normal file
50
app/src/py/batch/py_merchsum_batch.pgc
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* py_merchsum_batch.pgc - py 가맹점 지급 집계 (커서 + dbio upsert 배치, XA).
|
||||
*
|
||||
* Cursors the day's paid(P) payouts and rolls a per-merchant summary via the
|
||||
* dbio upsert, under ONE XA transaction. Usage: py_merchsum_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
long h_pay, 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 pymsc CURSOR FOR
|
||||
SELECT payout_id, merchant_id, net FROM py_payout
|
||||
WHERE biz_date = :h_bizdate AND status = 'P'
|
||||
ORDER BY payout_id;
|
||||
EXEC SQL OPEN pymsc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pymsc INTO :h_pay, :h_merch, :h_net;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pymsc; tpabort(0); return 1; }
|
||||
if (pydb_upsert_summary(h_merch, bizdate, 1, h_net) < 0) { EXEC SQL CLOSE pymsc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pymsc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_merchsum_batch COMMIT: bizdate=%s rolled=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
40
app/src/py/batch/py_netoff_batch.pgc
Normal file
40
app/src/py/batch/py_netoff_batch.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* py_netoff_batch.pgc - py 일괄 상계 (단건 산술 UPDATE 배치, XA).
|
||||
*
|
||||
* Applies a flat offset amount to the net of every requested(R) payout of the
|
||||
* biz_date with a single arithmetic UPDATE, under ONE XA transaction.
|
||||
* Usage: py_netoff_batch [YYYY-MM-DD] [OFFSET]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_off, h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
h_off = (argc > 2) ? atol(argv[2]) : 100;
|
||||
|
||||
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 py_payout SET net = net - :h_off, updated_at = now()
|
||||
WHERE biz_date = :h_bizdate AND status = 'R';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_netoff_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_netoff_batch COMMIT: bizdate=%s offset=%ld affected=%ld\n", bizdate, h_off, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
50
app/src/py/batch/py_reject_report_batch.pgc
Normal file
50
app/src/py/batch/py_reject_report_batch.pgc
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* py_reject_report_batch.pgc - py 반려 현황 리포트 (읽기 전용 커서 누적 배치, XA).
|
||||
*
|
||||
* Cursors the day's rejected(J) payouts, accumulating count and amount in C
|
||||
* (no writes), under ONE XA transaction. Usage: py_reject_report_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0, total = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_pay, h_amt;
|
||||
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 pyjrc CURSOR FOR
|
||||
SELECT payout_id, amount FROM py_payout
|
||||
WHERE biz_date = :h_bizdate AND status = 'J'
|
||||
ORDER BY payout_id;
|
||||
EXEC SQL OPEN pyjrc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyjrc INTO :h_pay, :h_amt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyjrc; tpabort(0); return 1; }
|
||||
total += h_amt;
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyjrc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_reject_report_batch COMMIT: bizdate=%s rejects=%ld amount=%ld\n", bizdate, rows, total);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
39
app/src/py/batch/py_retry_batch.pgc
Normal file
39
app/src/py/batch/py_retry_batch.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* py_retry_batch.pgc - py 실패 지급 재시도 (단건 UPDATE 배치, XA).
|
||||
*
|
||||
* One guarded UPDATE flips the day's failed/held(J,H) payouts back to requested(R)
|
||||
* and bumps retry_count, reporting the affected count via sqlca.sqlerrd[2].
|
||||
* Usage: py_retry_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_aff;
|
||||
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 UPDATE py_payout SET status = 'R', retry_count = retry_count + 1, updated_at = now()
|
||||
WHERE biz_date = :h_bizdate AND status IN ('J', 'H');
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_retry_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_retry_batch COMMIT: bizdate=%s requeued=%ld\n", bizdate, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
53
app/src/py/batch/py_schedule_run_batch.pgc
Normal file
53
app/src/py/batch/py_schedule_run_batch.pgc
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* py_schedule_run_batch.pgc - py 예약 지급 실행 (커서 + dbio + inline UPDATE, XA).
|
||||
*
|
||||
* Cursors the day's pending(S) schedules; per row it flips the linked payout to
|
||||
* requested(R) via dbio and marks the schedule done(D) inline, under ONE XA
|
||||
* transaction. Usage: py_schedule_run_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *rundate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_rundate[16];
|
||||
long h_sched, h_pay;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_rundate, rundate, sizeof(h_rundate)-1); h_rundate[sizeof(h_rundate)-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 pyrsc CURSOR FOR
|
||||
SELECT schedule_id, payout_id FROM py_schedule
|
||||
WHERE run_date = :h_rundate AND status = 'S'
|
||||
ORDER BY schedule_id;
|
||||
EXEC SQL OPEN pyrsc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyrsc INTO :h_sched, :h_pay;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyrsc; tpabort(0); return 1; }
|
||||
if (pydb_update_status(h_pay, "R") < 0) { EXEC SQL CLOSE pyrsc; tpabort(0); return 1; }
|
||||
EXEC SQL UPDATE py_schedule SET status = 'D' WHERE schedule_id = :h_sched;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pyrsc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyrsc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_schedule_run_batch COMMIT: rundate=%s executed=%ld\n", rundate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
37
app/src/py/batch/py_settle_batch.pgc
Normal file
37
app/src/py/batch/py_settle_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* py_settle_batch.pgc - py 지급완료 정산 집계 (단건 집계 배치, XA).
|
||||
*
|
||||
* ATMI client: opens the ECPG XA RM, starts ONE global transaction, aggregates
|
||||
* paid(P) payouts for the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: py_settle_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
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 SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_net FROM py_payout WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_settle_batch 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(">>> py_settle_batch COMMIT: bizdate=%s paid=%ld net=%ld\n", bizdate, h_cnt, h_net);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
40
app/src/py/batch/py_stat_batch.pgc
Normal file
40
app/src/py/batch/py_stat_batch.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* py_stat_batch.pgc - py 집중 가맹점 통계 (GROUP BY HAVING 서브쿼리 배치, XA).
|
||||
*
|
||||
* Counts merchants whose daily payout amount clears a threshold using a single
|
||||
* GROUP BY ... HAVING subquery, under ONE XA transaction.
|
||||
* Usage: py_stat_batch [YYYY-MM-DD] [THRESHOLD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_thr, h_merchants;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
h_thr = (argc > 2) ? atol(argv[2]) : 1000000;
|
||||
|
||||
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_merchants FROM (
|
||||
SELECT merchant_id FROM py_payout WHERE biz_date = :h_bizdate
|
||||
GROUP BY merchant_id HAVING coalesce(sum(net),0) >= :h_thr) t;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_stat_batch 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(">>> py_stat_batch COMMIT: bizdate=%s threshold=%ld top_merchants=%ld\n", bizdate, h_thr, h_merchants);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
49
app/src/py/batch/py_summary_reset_batch.pgc
Normal file
49
app/src/py/batch/py_summary_reset_batch.pgc
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* py_summary_reset_batch.pgc - py 집계 리셋 (커서 DISTINCT + dbio upsert, XA).
|
||||
*
|
||||
* Cursors the DISTINCT merchants that traded on the biz_date and zeroes each
|
||||
* merchant's daily summary via the dbio ON CONFLICT reset, under ONE XA
|
||||
* transaction. Usage: py_summary_reset_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
#include "py_summary_upsert_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
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 pysrc CURSOR FOR
|
||||
SELECT DISTINCT merchant_id FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
EXEC SQL OPEN pysrc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pysrc INTO :h_merch;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pysrc; tpabort(0); return 1; }
|
||||
if (pydb_summary_reset(h_merch, bizdate) < 0) { EXEC SQL CLOSE pysrc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pysrc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_summary_reset_batch COMMIT: bizdate=%s merchants=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
14
app/src/py/dbio/py_account_agg_dbio.h
Normal file
14
app/src/py/dbio/py_account_agg_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_account_agg_dbio.h - py 모듈 DB 접근 계층 copybook (py_account_agg_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_ACCOUNT_AGG_DBIO_H
|
||||
#define PY_ACCOUNT_AGG_DBIO_H
|
||||
|
||||
typedef struct { long total_balance; long active_cnt; } py_account_agg_rec_t;
|
||||
|
||||
long pydb_account_active_balance(void);
|
||||
long pydb_account_active_count(void);
|
||||
|
||||
#endif /* PY_ACCOUNT_AGG_DBIO_H */
|
||||
29
app/src/py/dbio/py_account_agg_dbio.pgc
Normal file
29
app/src/py/dbio/py_account_agg_dbio.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* py_account_agg_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_account_agg_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_account_agg_dbio.h"
|
||||
|
||||
/* ACTIVE 계좌 잔액 총합 (무인자 집계). */
|
||||
long pydb_account_active_balance(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT coalesce(sum(balance),0) INTO :h_v FROM py_account WHERE status = 'ACTIVE';
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* ACTIVE 계좌 수 (무인자 집계). */
|
||||
long pydb_account_active_count(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_account WHERE status = 'ACTIVE';
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_account_minmax_dbio.h
Normal file
14
app/src/py/dbio/py_account_minmax_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_account_minmax_dbio.h - py 모듈 DB 접근 계층 copybook (py_account_minmax_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_ACCOUNT_MINMAX_DBIO_H
|
||||
#define PY_ACCOUNT_MINMAX_DBIO_H
|
||||
|
||||
typedef struct { long threshold; long top_balance; long low_cnt; } py_account_minmax_rec_t;
|
||||
|
||||
long pydb_account_top_balance(void);
|
||||
long pydb_account_low_count(long threshold);
|
||||
|
||||
#endif /* PY_ACCOUNT_MINMAX_DBIO_H */
|
||||
29
app/src/py/dbio/py_account_minmax_dbio.pgc
Normal file
29
app/src/py/dbio/py_account_minmax_dbio.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* py_account_minmax_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_account_minmax_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_account_minmax_dbio.h"
|
||||
|
||||
/* 최대 잔액 계좌의 잔액 (무인자). */
|
||||
long pydb_account_top_balance(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT coalesce(max(balance),0) INTO :h_v FROM py_account;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 임계 미만 잔액 계좌 수 (threshold 인자). */
|
||||
long pydb_account_low_count(long threshold)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_thr = threshold, h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_account WHERE balance < :h_thr;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_adjust_dbio.h
Normal file
14
app/src/py/dbio/py_adjust_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_adjust_dbio.h - py 모듈 DB 접근 계층 copybook (py_adjust_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_ADJUST_DBIO_H
|
||||
#define PY_ADJUST_DBIO_H
|
||||
|
||||
typedef struct { long payout_id; char biz_date[16]; long delta_sum; long cnt; } py_adjust_rec_t;
|
||||
|
||||
long pydb_adjust_delta_sum(long payout_id);
|
||||
long pydb_adjust_count(const char *bizdate);
|
||||
|
||||
#endif /* PY_ADJUST_DBIO_H */
|
||||
31
app/src/py/dbio/py_adjust_dbio.pgc
Normal file
31
app/src/py/dbio/py_adjust_dbio.pgc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* py_adjust_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_adjust_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_adjust_dbio.h"
|
||||
|
||||
/* 단일 지급건 조정 증감 누계 (payout_id 스칼라 키). */
|
||||
long pydb_adjust_delta_sum(long payout_id)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay = payout_id, h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT coalesce(sum(delta),0) INTO :h_v FROM py_adjust WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 당일 조정 건수. */
|
||||
long pydb_adjust_count(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_adjust WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
13
app/src/py/dbio/py_adjust_reason_dbio.h
Normal file
13
app/src/py/dbio/py_adjust_reason_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_adjust_reason_dbio.h - py 모듈 DB 접근 계층 copybook (py_adjust_reason_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_ADJUST_REASON_DBIO_H
|
||||
#define PY_ADJUST_REASON_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long reason_kinds; } py_adjust_reason_rec_t;
|
||||
|
||||
long pydb_adjust_reason_variety(const char *bizdate);
|
||||
|
||||
#endif /* PY_ADJUST_REASON_DBIO_H */
|
||||
20
app/src/py/dbio/py_adjust_reason_dbio.pgc
Normal file
20
app/src/py/dbio/py_adjust_reason_dbio.pgc
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* py_adjust_reason_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_adjust_reason_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_adjust_reason_dbio.h"
|
||||
|
||||
/* 당일 조정 사유 가짓수 (count DISTINCT reason). */
|
||||
long pydb_adjust_reason_variety(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(DISTINCT reason) INTO :h_v FROM py_adjust WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_adjust_reason_variety FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_file_agg_dbio.h
Normal file
14
app/src/py/dbio/py_file_agg_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_file_agg_dbio.h - py 모듈 DB 접근 계층 copybook (py_file_agg_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_FILE_AGG_DBIO_H
|
||||
#define PY_FILE_AGG_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long gen_cnt; long rec_sum; } py_file_agg_rec_t;
|
||||
|
||||
long pydb_file_generated_count(const char *bizdate);
|
||||
long pydb_file_record_sum(const char *bizdate);
|
||||
|
||||
#endif /* PY_FILE_AGG_DBIO_H */
|
||||
33
app/src/py/dbio/py_file_agg_dbio.pgc
Normal file
33
app/src/py/dbio/py_file_agg_dbio.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* py_file_agg_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_file_agg_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_file_agg_dbio.h"
|
||||
|
||||
/* 당일 생성(G) 상태 파일 건수 (2조건 필터 count). */
|
||||
long pydb_file_generated_count(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_file WHERE biz_date = :h_bizdate AND status = 'G';
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 당일 파일 레코드 수 합계. */
|
||||
long pydb_file_record_sum(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(record_count),0) INTO :h_v FROM py_file WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_file_dbio.h
Normal file
14
app/src/py/dbio/py_file_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_file_dbio.h - py 모듈 DB 접근 계층 copybook (py_file_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_FILE_DBIO_H
|
||||
#define PY_FILE_DBIO_H
|
||||
|
||||
typedef struct { long file_id; long total_amount; char status[8]; } py_file_rec_t;
|
||||
|
||||
long pydb_file_total(long file_id);
|
||||
int pydb_file_status(long file_id, char *out /* >= 2 bytes */);
|
||||
|
||||
#endif /* PY_FILE_DBIO_H */
|
||||
32
app/src/py/dbio/py_file_dbio.pgc
Normal file
32
app/src/py/dbio/py_file_dbio.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* py_file_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_file_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_file_dbio.h"
|
||||
|
||||
/* 지급 파일 총액 (단순 스칼라). */
|
||||
long pydb_file_total(long file_id)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_file = file_id, h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT coalesce(total_amount,0) INTO :h_v FROM py_file WHERE file_id = :h_file;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_file_total FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 지급 파일 상태 문자 회신. */
|
||||
int pydb_file_status(long file_id, char *out)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_file = file_id;
|
||||
char h_status[8];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT status INTO :h_status FROM py_file WHERE file_id = :h_file;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) { userlog("pydb_file_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
out[0] = h_status[0];
|
||||
out[1] = 0;
|
||||
return 0;
|
||||
}
|
||||
14
app/src/py/dbio/py_ledger_dbio.h
Normal file
14
app/src/py/dbio/py_ledger_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_ledger_dbio.h - py 모듈 DB 접근 계층 copybook (py_ledger_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_LEDGER_DBIO_H
|
||||
#define PY_LEDGER_DBIO_H
|
||||
|
||||
typedef struct { long ledger_id; long payout_id; char entry_type[16]; long amount; } py_ledger_rec_t;
|
||||
|
||||
long pydb_ledger_xfer_sum(const char *bizdate);
|
||||
long pydb_ledger_balance(long payout_id);
|
||||
|
||||
#endif /* PY_LEDGER_DBIO_H */
|
||||
45
app/src/py/dbio/py_ledger_dbio.pgc
Normal file
45
app/src/py/dbio/py_ledger_dbio.pgc
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* py_ledger_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_ledger_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_ledger_dbio.h"
|
||||
|
||||
/* XFER/ADJ 엔트리를 FILTER 로 한 번에 분리 집계하고 XFER 합 반환. */
|
||||
long pydb_ledger_xfer_sum(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_xfer = 0, h_adj = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT
|
||||
coalesce(sum(amount) FILTER (WHERE entry_type = 'XFER'), 0),
|
||||
coalesce(sum(amount) FILTER (WHERE entry_type = 'ADJ'), 0)
|
||||
INTO :h_xfer, :h_adj FROM py_ledger WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
if (h_adj < 0) return -1;
|
||||
return h_xfer;
|
||||
}
|
||||
|
||||
/* 단일 지급 원장 잔액 = XFER(-) 그 외(+), 커서 부호 누적. */
|
||||
long pydb_ledger_balance(long payout_id)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay = payout_id, h_amt, bal = 0;
|
||||
char h_type[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL DECLARE plbc CURSOR FOR
|
||||
SELECT entry_type, amount FROM py_ledger WHERE payout_id = :h_pay;
|
||||
EXEC SQL OPEN plbc;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
for (;;) {
|
||||
EXEC SQL FETCH plbc INTO :h_type, :h_amt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE plbc; return -1; }
|
||||
bal += (h_type[0] == 'X') ? -h_amt : h_amt;
|
||||
}
|
||||
EXEC SQL CLOSE plbc;
|
||||
return bal;
|
||||
}
|
||||
13
app/src/py/dbio/py_ledger_type_dbio.h
Normal file
13
app/src/py/dbio/py_ledger_type_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_ledger_type_dbio.h - py 모듈 DB 접근 계층 copybook (py_ledger_type_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_LEDGER_TYPE_DBIO_H
|
||||
#define PY_LEDGER_TYPE_DBIO_H
|
||||
|
||||
typedef struct { char entry_type[16]; char biz_date[16]; long total; } py_ledger_type_rec_t;
|
||||
|
||||
long pydb_ledger_type_total(const char *entry_type, const char *bizdate);
|
||||
|
||||
#endif /* PY_LEDGER_TYPE_DBIO_H */
|
||||
22
app/src/py/dbio/py_ledger_type_dbio.pgc
Normal file
22
app/src/py/dbio/py_ledger_type_dbio.pgc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* py_ledger_type_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_ledger_type_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_ledger_type_dbio.h"
|
||||
|
||||
/* 지정 엔트리 유형의 당일 원장 합계 (entry_type 인자). */
|
||||
long pydb_ledger_type_total(const char *entry_type, const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_type[16], h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_type, entry_type, sizeof(h_type)-1); h_type[sizeof(h_type)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_v FROM py_ledger
|
||||
WHERE entry_type = :h_type AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_ledger_type_total FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_payout_agg_dbio.h
Normal file
14
app/src/py/dbio/py_payout_agg_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_payout_agg_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_agg_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_AGG_DBIO_H
|
||||
#define PY_PAYOUT_AGG_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long gross; long cnt; } py_payout_agg_rec_t;
|
||||
|
||||
long pydb_payout_amount_sum(const char *bizdate);
|
||||
long pydb_payout_txn_count(const char *bizdate);
|
||||
|
||||
#endif /* PY_PAYOUT_AGG_DBIO_H */
|
||||
33
app/src/py/dbio/py_payout_agg_dbio.pgc
Normal file
33
app/src/py/dbio/py_payout_agg_dbio.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* py_payout_agg_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_agg_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_agg_dbio.h"
|
||||
|
||||
/* 당일 지급 총액. */
|
||||
long pydb_payout_amount_sum(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_v FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_payout_amount_sum FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 당일 지급 건수. */
|
||||
long pydb_payout_txn_count(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_payout_txn_count FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
13
app/src/py/dbio/py_payout_avg_dbio.h
Normal file
13
app/src/py/dbio/py_payout_avg_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_payout_avg_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_avg_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_AVG_DBIO_H
|
||||
#define PY_PAYOUT_AVG_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long total; long cnt; long avg; } py_payout_avg_rec_t;
|
||||
|
||||
long pydb_payout_avg_amount(const char *bizdate);
|
||||
|
||||
#endif /* PY_PAYOUT_AVG_DBIO_H */
|
||||
22
app/src/py/dbio/py_payout_avg_dbio.pgc
Normal file
22
app/src/py/dbio/py_payout_avg_dbio.pgc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* py_payout_avg_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_avg_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_avg_dbio.h"
|
||||
|
||||
/* 건당 평균 지급액 = sum(amount)/count(*) (0 나눗셈 가드). */
|
||||
long pydb_payout_avg_amount(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_sum = 0, h_cnt = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(amount),0), count(*) INTO :h_sum, :h_cnt
|
||||
FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
if (h_cnt <= 0) return 0;
|
||||
return h_sum / h_cnt;
|
||||
}
|
||||
13
app/src/py/dbio/py_payout_case_dbio.h
Normal file
13
app/src/py/dbio/py_payout_case_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_payout_case_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_case_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_CASE_DBIO_H
|
||||
#define PY_PAYOUT_CASE_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long threshold; long large_cnt; } py_payout_case_rec_t;
|
||||
|
||||
long pydb_payout_large_count(const char *bizdate, long threshold);
|
||||
|
||||
#endif /* PY_PAYOUT_CASE_DBIO_H */
|
||||
21
app/src/py/dbio/py_payout_case_dbio.pgc
Normal file
21
app/src/py/dbio/py_payout_case_dbio.pgc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* py_payout_case_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_case_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_case_dbio.h"
|
||||
|
||||
/* CASE 버킷 집계: 임계금액 이상 지급건 수를 sum(CASE ...) 로 산출. */
|
||||
long pydb_payout_large_count(const char *bizdate, long threshold)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_thr = threshold, h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(CASE WHEN amount >= :h_thr THEN 1 ELSE 0 END),0) INTO :h_v
|
||||
FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_payout_large_count FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_payout_channel_dbio.h
Normal file
14
app/src/py/dbio/py_payout_channel_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_payout_channel_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_channel_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_CHANNEL_DBIO_H
|
||||
#define PY_PAYOUT_CHANNEL_DBIO_H
|
||||
|
||||
typedef struct { char channel[16]; char biz_date[16]; long gross; } py_payout_channel_rec_t;
|
||||
|
||||
long pydb_payout_channel_variety(const char *bizdate);
|
||||
long pydb_payout_channel_gross(const char *channel, const char *bizdate);
|
||||
|
||||
#endif /* PY_PAYOUT_CHANNEL_DBIO_H */
|
||||
35
app/src/py/dbio/py_payout_channel_dbio.pgc
Normal file
35
app/src/py/dbio/py_payout_channel_dbio.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* py_payout_channel_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_channel_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_channel_dbio.h"
|
||||
|
||||
/* 당일 사용된 지급 채널 가짓수 (BULK/SPLIT/ADVANCE/...). */
|
||||
long pydb_payout_channel_variety(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(DISTINCT channel) INTO :h_v FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 지정 채널의 당일 지급 총액. */
|
||||
long pydb_payout_channel_gross(const char *channel, const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_ch[16], h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_ch, channel, sizeof(h_ch)-1); h_ch[sizeof(h_ch)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_v FROM py_payout
|
||||
WHERE channel = :h_ch AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
13
app/src/py/dbio/py_payout_join_dbio.h
Normal file
13
app/src/py/dbio/py_payout_join_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_payout_join_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_join_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_JOIN_DBIO_H
|
||||
#define PY_PAYOUT_JOIN_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long filed_net; } py_payout_join_rec_t;
|
||||
|
||||
long pydb_payout_filed_net(const char *bizdate);
|
||||
|
||||
#endif /* PY_PAYOUT_JOIN_DBIO_H */
|
||||
22
app/src/py/dbio/py_payout_join_dbio.pgc
Normal file
22
app/src/py/dbio/py_payout_join_dbio.pgc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* py_payout_join_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_join_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_join_dbio.h"
|
||||
|
||||
/* 2-테이블 JOIN: 생성(G)된 파일에 편성된 지급건의 순액 합. */
|
||||
long pydb_payout_filed_net(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(pp.net),0) INTO :h_v
|
||||
FROM py_payout pp JOIN py_file pf ON pp.file_id = pf.file_id
|
||||
WHERE pf.biz_date = :h_bizdate AND pf.status = 'G';
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_payout_filed_net FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_payout_merch_dbio.h
Normal file
14
app/src/py/dbio/py_payout_merch_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_payout_merch_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_merch_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_MERCH_DBIO_H
|
||||
#define PY_PAYOUT_MERCH_DBIO_H
|
||||
|
||||
typedef struct { char merchant_id[64]; long cnt; long gross; } py_payout_merch_rec_t;
|
||||
|
||||
long pydb_payout_merch_count(const char *merch);
|
||||
long pydb_payout_merch_gross(const char *merch);
|
||||
|
||||
#endif /* PY_PAYOUT_MERCH_DBIO_H */
|
||||
33
app/src/py/dbio/py_payout_merch_dbio.pgc
Normal file
33
app/src/py/dbio/py_payout_merch_dbio.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* py_payout_merch_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_merch_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_merch_dbio.h"
|
||||
|
||||
/* 가맹점 전체 지급 건수. */
|
||||
long pydb_payout_merch_count(const char *merch)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_merch[64];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_payout WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 가맹점 전체 지급 총액. */
|
||||
long pydb_payout_merch_gross(const char *merch)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_merch[64];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_v FROM py_payout WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_payout_minmax_dbio.h
Normal file
14
app/src/py/dbio/py_payout_minmax_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_payout_minmax_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_minmax_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_MINMAX_DBIO_H
|
||||
#define PY_PAYOUT_MINMAX_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long peak; long floor_amt; } py_payout_minmax_rec_t;
|
||||
|
||||
long pydb_payout_peak_amount(const char *bizdate);
|
||||
long pydb_payout_floor_amount(const char *bizdate);
|
||||
|
||||
#endif /* PY_PAYOUT_MINMAX_DBIO_H */
|
||||
33
app/src/py/dbio/py_payout_minmax_dbio.pgc
Normal file
33
app/src/py/dbio/py_payout_minmax_dbio.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* py_payout_minmax_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_minmax_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_minmax_dbio.h"
|
||||
|
||||
/* 당일 최대 지급액. */
|
||||
long pydb_payout_peak_amount(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(max(amount),0) INTO :h_v FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 당일 최소 지급액. */
|
||||
long pydb_payout_floor_amount(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(min(amount),0) INTO :h_v FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_payout_reject_dbio.h
Normal file
14
app/src/py/dbio/py_payout_reject_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_payout_reject_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_reject_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_REJECT_DBIO_H
|
||||
#define PY_PAYOUT_REJECT_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long payout_id; long reject_cnt; char reason[128]; } py_payout_reject_rec_t;
|
||||
|
||||
long pydb_payout_reject_count(const char *bizdate);
|
||||
int pydb_payout_reject_reason(long payout_id, char *out /* >= 128 bytes */);
|
||||
|
||||
#endif /* PY_PAYOUT_REJECT_DBIO_H */
|
||||
33
app/src/py/dbio/py_payout_reject_dbio.pgc
Normal file
33
app/src/py/dbio/py_payout_reject_dbio.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* py_payout_reject_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_reject_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_reject_dbio.h"
|
||||
|
||||
/* 당일 반려(J) 지급 건수. */
|
||||
long pydb_payout_reject_count(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_payout WHERE biz_date = :h_bizdate AND status = 'J';
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 단건 반려 사유 문자열 회신. */
|
||||
int pydb_payout_reject_reason(long payout_id, char *out)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay = payout_id;
|
||||
char h_reason[128];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT coalesce(reject_reason,'') INTO :h_reason FROM py_payout WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) { userlog("pydb_payout_reject_reason FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
strncpy(out, h_reason, 127); out[127] = 0;
|
||||
return 0;
|
||||
}
|
||||
13
app/src/py/dbio/py_payout_retry_dbio.h
Normal file
13
app/src/py/dbio/py_payout_retry_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_payout_retry_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_retry_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_RETRY_DBIO_H
|
||||
#define PY_PAYOUT_RETRY_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long retried; long failed; } py_payout_retry_rec_t;
|
||||
|
||||
long pydb_payout_retry_load(const char *bizdate);
|
||||
|
||||
#endif /* PY_PAYOUT_RETRY_DBIO_H */
|
||||
24
app/src/py/dbio/py_payout_retry_dbio.pgc
Normal file
24
app/src/py/dbio/py_payout_retry_dbio.pgc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* py_payout_retry_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_retry_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_retry_dbio.h"
|
||||
|
||||
/* FILTER 집계로 실패(J)건과 재시도 누계를 한 번에 뽑아 재시도 합을 반환. */
|
||||
long pydb_payout_retry_load(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_retry = 0, h_fail = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT
|
||||
coalesce(sum(retry_count),0),
|
||||
coalesce(count(*) FILTER (WHERE status = 'J'),0)
|
||||
INTO :h_retry, :h_fail FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
if (h_fail < 0) return -1;
|
||||
return h_retry;
|
||||
}
|
||||
13
app/src/py/dbio/py_payout_scan_dbio.h
Normal file
13
app/src/py/dbio/py_payout_scan_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_payout_scan_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_scan_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_SCAN_DBIO_H
|
||||
#define PY_PAYOUT_SCAN_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; char status[8]; long cnt; } py_payout_scan_rec_t;
|
||||
|
||||
long pydb_payout_paid_count(const char *bizdate);
|
||||
|
||||
#endif /* PY_PAYOUT_SCAN_DBIO_H */
|
||||
29
app/src/py/dbio/py_payout_scan_dbio.pgc
Normal file
29
app/src/py/dbio/py_payout_scan_dbio.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* py_payout_scan_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_scan_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_scan_dbio.h"
|
||||
|
||||
/* 상태별 건수를 커서로 순회하여 지급완료(P) 건수만 추출. */
|
||||
long pydb_payout_paid_count(const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_st[8];
|
||||
long h_cnt, paid = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL DECLARE pysc CURSOR FOR
|
||||
SELECT status, count(*) FROM py_payout WHERE biz_date = :h_bizdate GROUP BY status;
|
||||
EXEC SQL OPEN pysc;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pysc INTO :h_st, :h_cnt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pysc; return -1; }
|
||||
if (h_st[0] == 'P') paid = h_cnt;
|
||||
}
|
||||
EXEC SQL CLOSE pysc;
|
||||
return paid;
|
||||
}
|
||||
13
app/src/py/dbio/py_payout_subq_dbio.h
Normal file
13
app/src/py/dbio/py_payout_subq_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_payout_subq_dbio.h - py 모듈 DB 접근 계층 copybook (py_payout_subq_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_PAYOUT_SUBQ_DBIO_H
|
||||
#define PY_PAYOUT_SUBQ_DBIO_H
|
||||
|
||||
typedef struct { char run_date[16]; long scheduled_sum; } py_payout_subq_rec_t;
|
||||
|
||||
long pydb_payout_scheduled_sum(const char *rundate);
|
||||
|
||||
#endif /* PY_PAYOUT_SUBQ_DBIO_H */
|
||||
22
app/src/py/dbio/py_payout_subq_dbio.pgc
Normal file
22
app/src/py/dbio/py_payout_subq_dbio.pgc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* py_payout_subq_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_payout_subq_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_payout_subq_dbio.h"
|
||||
|
||||
/* 서브쿼리: 해당 실행일에 예약(S)된 지급건들의 순액 합. */
|
||||
long pydb_payout_scheduled_sum(const char *rundate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_rundate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_rundate, rundate, sizeof(h_rundate)-1); h_rundate[sizeof(h_rundate)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(sum(net),0) INTO :h_v FROM py_payout
|
||||
WHERE payout_id IN (SELECT payout_id FROM py_schedule
|
||||
WHERE run_date = :h_rundate AND status = 'S');
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_payout_scheduled_sum FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
14
app/src/py/dbio/py_schedule_dbio.h
Normal file
14
app/src/py/dbio/py_schedule_dbio.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* py_schedule_dbio.h - py 모듈 DB 접근 계층 copybook (py_schedule_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_SCHEDULE_DBIO_H
|
||||
#define PY_SCHEDULE_DBIO_H
|
||||
|
||||
typedef struct { char run_date[16]; long pending; } py_schedule_rec_t;
|
||||
|
||||
long pydb_schedule_pending_count(const char *rundate);
|
||||
long pydb_schedule_next_id(void);
|
||||
|
||||
#endif /* PY_SCHEDULE_DBIO_H */
|
||||
31
app/src/py/dbio/py_schedule_dbio.pgc
Normal file
31
app/src/py/dbio/py_schedule_dbio.pgc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* py_schedule_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_schedule_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_schedule_dbio.h"
|
||||
|
||||
/* 지정 실행일의 대기(S) 예약 건수. */
|
||||
long pydb_schedule_pending_count(const char *rundate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_rundate[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_rundate, rundate, sizeof(h_rundate)-1); h_rundate[sizeof(h_rundate)-1] = 0;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM py_schedule WHERE run_date = :h_rundate AND status = 'S';
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
|
||||
/* 예약 시퀀스 다음 값. */
|
||||
long pydb_schedule_next_id(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT nextval('py_schedule_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_schedule_next_id FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_id;
|
||||
}
|
||||
13
app/src/py/dbio/py_schedule_scan_dbio.h
Normal file
13
app/src/py/dbio/py_schedule_scan_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_schedule_scan_dbio.h - py 모듈 DB 접근 계층 copybook (py_schedule_scan_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_SCHEDULE_SCAN_DBIO_H
|
||||
#define PY_SCHEDULE_SCAN_DBIO_H
|
||||
|
||||
typedef struct { char run_date[16]; long due; } py_schedule_scan_rec_t;
|
||||
|
||||
long pydb_schedule_due_count(const char *rundate);
|
||||
|
||||
#endif /* PY_SCHEDULE_SCAN_DBIO_H */
|
||||
29
app/src/py/dbio/py_schedule_scan_dbio.pgc
Normal file
29
app/src/py/dbio/py_schedule_scan_dbio.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* py_schedule_scan_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_schedule_scan_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_schedule_scan_dbio.h"
|
||||
|
||||
/* 커서로 실행일 예약을 순회하며 대기(S) 상태 건만 집계. */
|
||||
long pydb_schedule_due_count(const char *rundate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_rundate[16], h_st[8];
|
||||
long h_pay, due = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_rundate, rundate, sizeof(h_rundate)-1); h_rundate[sizeof(h_rundate)-1] = 0;
|
||||
EXEC SQL DECLARE pydsc CURSOR FOR
|
||||
SELECT payout_id, status FROM py_schedule WHERE run_date = :h_rundate;
|
||||
EXEC SQL OPEN pydsc;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pydsc INTO :h_pay, :h_st;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pydsc; return -1; }
|
||||
if (h_st[0] == 'S') due++;
|
||||
}
|
||||
EXEC SQL CLOSE pydsc;
|
||||
return due;
|
||||
}
|
||||
13
app/src/py/dbio/py_summary_dbio.h
Normal file
13
app/src/py/dbio/py_summary_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_summary_dbio.h - py 모듈 DB 접근 계층 copybook (py_summary_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_SUMMARY_DBIO_H
|
||||
#define PY_SUMMARY_DBIO_H
|
||||
|
||||
typedef struct { char biz_date[16]; long threshold; long merchants; } py_summary_rec_t;
|
||||
|
||||
long pydb_summary_active_merchants(const char *bizdate, long threshold);
|
||||
|
||||
#endif /* PY_SUMMARY_DBIO_H */
|
||||
22
app/src/py/dbio/py_summary_dbio.pgc
Normal file
22
app/src/py/dbio/py_summary_dbio.pgc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* py_summary_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_summary_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_summary_dbio.h"
|
||||
|
||||
/* GROUP BY ... HAVING: 당일 지급총액이 임계 이상인 가맹점 수. */
|
||||
long pydb_summary_active_merchants(const char *bizdate, long threshold)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_thr = threshold, h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM (
|
||||
SELECT merchant_id FROM py_summary WHERE biz_date = :h_bizdate
|
||||
GROUP BY merchant_id HAVING sum(payout_amount) >= :h_thr) t;
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_summary_active_merchants FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
13
app/src/py/dbio/py_summary_upsert_dbio.h
Normal file
13
app/src/py/dbio/py_summary_upsert_dbio.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* py_summary_upsert_dbio.h - py 모듈 DB 접근 계층 copybook (py_summary_upsert_dbio, part of libpydbio.a).
|
||||
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
|
||||
* Return convention: 0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef PY_SUMMARY_UPSERT_DBIO_H
|
||||
#define PY_SUMMARY_UPSERT_DBIO_H
|
||||
|
||||
typedef struct { char merchant_id[64]; char biz_date[16]; } py_summary_upsert_rec_t;
|
||||
|
||||
int pydb_summary_reset(const char *merch, const char *bizdate);
|
||||
|
||||
#endif /* PY_SUMMARY_UPSERT_DBIO_H */
|
||||
23
app/src/py/dbio/py_summary_upsert_dbio.pgc
Normal file
23
app/src/py/dbio/py_summary_upsert_dbio.pgc
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* py_summary_upsert_dbio.pgc - py 모듈 DB 접근 함수 세트 (py_summary_upsert_dbio), archived into libpydbio.a.
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "py_summary_upsert_dbio.h"
|
||||
|
||||
/* ON CONFLICT upsert: 가맹점 당일 집계를 0으로 리셋(재집계 준비). */
|
||||
int pydb_summary_reset(const char *merch, const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
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 INSERT INTO py_summary (merchant_id, biz_date, payout_count, payout_amount)
|
||||
VALUES (:h_merch, :h_bizdate, 0, 0)
|
||||
ON CONFLICT (merchant_id, biz_date) DO UPDATE
|
||||
SET payout_count = 0, payout_amount = 0, updated_at = now();
|
||||
if (sqlca.sqlcode < 0) { userlog("pydb_summary_reset FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,53 +1,56 @@
|
|||
/*
|
||||
* py_svr.pgc - py (지급) MODULE SERVER.
|
||||
* py_svr.pgc - py (지급) MODULE SERVER (thin dispatcher).
|
||||
*
|
||||
* ONE binary that tpadvertise()s ALL ~30 online py services (the real Tuxedo
|
||||
* "one module server, many services" pattern). Every service is a distinct
|
||||
* 지급 operation with genuine EXEC SQL (directly, or via the linked libpydbio.a
|
||||
* dbio layer) and common math from libacqcommon.a.
|
||||
* The legacy "one module server, many services" pattern: this binary owns NO
|
||||
* business logic. Each of py's 30 online services now lives in its own file
|
||||
* (app/src/py/svc/<SVCNAME>.pgc) with its own copybook header
|
||||
* (app/src/py/svc/<SVCNAME>.h); those objects are archived into libpysvc.a and
|
||||
* linked into this server. Here we only:
|
||||
* - include every service copybook (for the extern prototypes),
|
||||
* - tpopen() the ECPG XA RM,
|
||||
* - tpadvertise() all services from a {name, fn} table,
|
||||
* - tpclose() at shutdown.
|
||||
*
|
||||
* XA: the connection is opened once by tpopen() (ECPG XA switch); there is NO
|
||||
* EXEC SQL CONNECT. Owner-writes discipline: services in this server never
|
||||
* tpcall each other; each owns its tables on this process's XA branch.
|
||||
* XA: the connection is opened once by tpopen() (ECPG XA switch libndrxxaecpg.so);
|
||||
* there is NO EXEC SQL CONNECT. Each tpcall runs on this process's XA branch.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include <ubf.h>
|
||||
#include <userlog.h>
|
||||
#include <ndebug.h>
|
||||
#include "acq.fd.h"
|
||||
#include "py_dbio.h"
|
||||
#include "acq_common.h"
|
||||
|
||||
/* ----- small UBF helpers ------------------------------------------------- */
|
||||
static long getl(UBFH *b, BFLDID f) { long v = 0; Bget(b, f, 0, (char *)&v, 0L); return v; }
|
||||
static void gets_(UBFH *b, BFLDID f, char *out, int cap)
|
||||
{ BFLDLEN l = cap; out[0] = 0; Bget(b, f, 0, out, &l); }
|
||||
static void setl(UBFH *b, BFLDID f, long v) { Bchg(b, f, 0, (char *)&v, 0L); }
|
||||
/* every py service's copybook header (declares its record struct + prototype) */
|
||||
#include "PAY_FILEGEN.h"
|
||||
#include "PAY_RESULT.h"
|
||||
#include "PAY_REPROC.h"
|
||||
#include "PAY_HOLD.h"
|
||||
#include "PAY_RELEASE.h"
|
||||
#include "PAY_CANCEL.h"
|
||||
#include "PAY_ACCTCHK.h"
|
||||
#include "PAY_SPLIT.h"
|
||||
#include "PAY_INT.h"
|
||||
#include "PAY_XFERLINK.h"
|
||||
#include "PAY_STATUS.h"
|
||||
#include "PAY_SCHEDULE.h"
|
||||
#include "PAY_MERCHSUM.h"
|
||||
#include "PAY_NETOFF.h"
|
||||
#include "PAY_ADVANCE.h"
|
||||
#include "PAY_RETRY.h"
|
||||
#include "PAY_APPROVE.h"
|
||||
#include "PAY_REJECT.h"
|
||||
#include "PAY_RECON.h"
|
||||
#include "PAY_STATEMENT.h"
|
||||
#include "PAY_FEEDED.h"
|
||||
#include "PAY_ADJUST.h"
|
||||
#include "PAY_BULK.h"
|
||||
#include "PAY_INQUIRY.h"
|
||||
#include "PAY_HISTORY.h"
|
||||
#include "PAY_REVERSE.h"
|
||||
#include "PAY_CONFIRM.h"
|
||||
#include "PAY_REMIT.h"
|
||||
#include "PAY_CLOSE.h"
|
||||
#include "PAY_SUMMARY.h"
|
||||
|
||||
#define FAIL(b) do { tpreturn(TPFAIL, 0, (char *)(b), 0L, 0L); return; } while (0)
|
||||
#define OK(b) do { tpreturn(TPSUCCESS, 0, (char *)(b), 0L, 0L); return; } while (0)
|
||||
|
||||
/* ----- service prototypes ------------------------------------------------ */
|
||||
void PAY_FILEGEN(TPSVCINFO *p); void PAY_RESULT(TPSVCINFO *p);
|
||||
void PAY_REPROC(TPSVCINFO *p); void PAY_HOLD(TPSVCINFO *p);
|
||||
void PAY_RELEASE(TPSVCINFO *p); void PAY_CANCEL(TPSVCINFO *p);
|
||||
void PAY_ACCTCHK(TPSVCINFO *p); void PAY_SPLIT(TPSVCINFO *p);
|
||||
void PAY_INT(TPSVCINFO *p); void PAY_XFERLINK(TPSVCINFO *p);
|
||||
void PAY_STATUS(TPSVCINFO *p); void PAY_SCHEDULE(TPSVCINFO *p);
|
||||
void PAY_MERCHSUM(TPSVCINFO *p); void PAY_NETOFF(TPSVCINFO *p);
|
||||
void PAY_ADVANCE(TPSVCINFO *p); void PAY_RETRY(TPSVCINFO *p);
|
||||
void PAY_APPROVE(TPSVCINFO *p); void PAY_REJECT(TPSVCINFO *p);
|
||||
void PAY_RECON(TPSVCINFO *p); void PAY_STATEMENT(TPSVCINFO *p);
|
||||
void PAY_FEEDED(TPSVCINFO *p); void PAY_ADJUST(TPSVCINFO *p);
|
||||
void PAY_BULK(TPSVCINFO *p); void PAY_INQUIRY(TPSVCINFO *p);
|
||||
void PAY_HISTORY(TPSVCINFO *p); void PAY_REVERSE(TPSVCINFO *p);
|
||||
void PAY_CONFIRM(TPSVCINFO *p); void PAY_REMIT(TPSVCINFO *p);
|
||||
void PAY_CLOSE(TPSVCINFO *p); void PAY_SUMMARY(TPSVCINFO *p);
|
||||
|
||||
/* ----- advertise table (this is what "scales to 30" cleanly) ------------- */
|
||||
/* ----- advertise table: {service name, function} (fn is extern from its file) */
|
||||
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
|
||||
{"PAY_FILEGEN", PAY_FILEGEN}, {"PAY_RESULT", PAY_RESULT},
|
||||
{"PAY_REPROC", PAY_REPROC}, {"PAY_HOLD", PAY_HOLD},
|
||||
|
|
@ -90,532 +93,4 @@ void tpsvrdone(void)
|
|||
userlog("py_svr: tpsvrdone");
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* 1. PAY_FILEGEN - 지급 파일 헤더 생성: 당일 승인(A) 지급건 집계 -> py_file. */
|
||||
/* ========================================================================= */
|
||||
void PAY_FILEGEN(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], fname[64];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_cnt, h_sum;
|
||||
char h_bizdate[16], h_fname[64];
|
||||
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 py_payout WHERE biz_date = :h_bizdate AND status = 'A';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
snprintf(fname, sizeof(fname), "PAYOUT_%s.dat", bizdate);
|
||||
strncpy(h_fname, fname, sizeof(h_fname)-1); h_fname[sizeof(h_fname)-1] = 0;
|
||||
EXEC SQL SELECT nextval('py_file_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO py_file (file_id, biz_date, file_name, record_count, total_amount, status)
|
||||
VALUES (:h_id, :h_bizdate, :h_fname, :h_cnt, :h_sum, 'G');
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_ID2, h_id);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
Bchg(b, T_STR1, 0, fname, 0L);
|
||||
userlog("PAY_FILEGEN file_id=%ld name=%s recs=%ld amt=%ld", h_id, fname, h_cnt, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 2. PAY_RESULT - 지급 결과 반영: 지급건 상태 P(지급완료). */
|
||||
void PAY_RESULT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long payout_id = getl(b, T_ID1);
|
||||
if (pydb_update_status(payout_id, "P") < 0) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, "P", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 3. PAY_REPROC - 재처리: 상태 R(요청)으로 되돌림. */
|
||||
void PAY_REPROC(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long payout_id = getl(b, T_ID1);
|
||||
if (pydb_update_status(payout_id, "R") < 0) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, "R", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 4. PAY_HOLD - 지급 보류. */
|
||||
void PAY_HOLD(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long payout_id = getl(b, T_ID1);
|
||||
if (pydb_update_status(payout_id, "H") < 0) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, "H", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 5. PAY_RELEASE - 보류 해제(요청 상태로). */
|
||||
void PAY_RELEASE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long payout_id = getl(b, T_ID1);
|
||||
if (pydb_update_status(payout_id, "R") < 0) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, "R", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 6. PAY_CANCEL - 지급 취소. */
|
||||
void PAY_CANCEL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], reason[128];
|
||||
long payout_id, amt, adj;
|
||||
payout_id = getl(b, T_ID1);
|
||||
amt = getl(b, T_AMOUNT);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_REASON, reason, sizeof(reason)); if (reason[0] == 0) strcpy(reason, "CANCEL");
|
||||
adj = pydb_insert_adjust(payout_id, -amt, reason, bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
if (pydb_update_status(payout_id, "C") < 0) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
Bchg(b, T_STATUS, 0, "C", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 7. PAY_ACCTCHK - 지급계좌 유효성 점검 (dbio). */
|
||||
void PAY_ACCTCHK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char acct[32], st[8];
|
||||
long bal = 0;
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
if (pydb_account_check(acct, st, &bal) < 0) { setl(b, T_RC, 1); FAIL(b); }
|
||||
setl(b, T_AMT1, bal);
|
||||
Bchg(b, T_STR1, 0, st, 0L);
|
||||
setl(b, T_RC, (strcmp(st, "ACTIVE") == 0) ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 8. PAY_SPLIT - 지급 분할: 금액을 N건으로 나눠 지급건 생성. */
|
||||
void PAY_SPLIT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], acct[32], bizdate[16];
|
||||
long n, amount, i, part, payout_id;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
amount = getl(b, T_AMOUNT);
|
||||
n = getl(b, T_COUNT); if (n < 1) n = 2;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
part = amount / n;
|
||||
for (i = 0; i < n; i++) {
|
||||
payout_id = pydb_next_payout_id();
|
||||
if (payout_id < 0) FAIL(b);
|
||||
if (pydb_insert_payout(payout_id, merch, acct, part, 0, part, "R", "SPLIT", bizdate) < 0) FAIL(b);
|
||||
}
|
||||
setl(b, T_COUNT, n);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 9. PAY_INT - 선지급 이자 계산 (일할, bps). */
|
||||
void PAY_INT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long principal, days, bps, interest;
|
||||
principal = getl(b, T_AMOUNT);
|
||||
days = getl(b, T_ARG1); if (days < 1) days = 1;
|
||||
bps = getl(b, T_ARG2); if (bps <= 0) bps = 15; /* 0.15%/일 */
|
||||
interest = principal * bps * days / 10000;
|
||||
setl(b, T_AMT1, interest);
|
||||
setl(b, T_NET, principal - interest);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 10. PAY_XFERLINK - 이체 연계 원장 기록(py_ledger). */
|
||||
void PAY_XFERLINK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay, h_amt;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1); h_amt = getl(b, T_AMOUNT);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
EXEC SQL INSERT INTO py_ledger (ledger_id, payout_id, entry_type, amount, biz_date)
|
||||
VALUES (nextval('py_ledger_seq'), :h_pay, 'XFER', :h_amt, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 11. PAY_STATUS - 지급 상태 조회 (dbio). */
|
||||
void PAY_STATUS(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long payout_id = getl(b, T_ID1);
|
||||
char st[4];
|
||||
if (pydb_get_status(payout_id, st) < 0) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, st, 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 12. PAY_SCHEDULE - 지급 예약 등록(py_schedule). */
|
||||
void PAY_SCHEDULE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char rundate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_pay;
|
||||
char h_rundate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1);
|
||||
gets_(b, T_BIZDATE, rundate, sizeof(rundate));
|
||||
strncpy(h_rundate, rundate, sizeof(h_rundate)-1); h_rundate[sizeof(h_rundate)-1] = 0;
|
||||
EXEC SQL SELECT nextval('py_schedule_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO py_schedule (schedule_id, payout_id, run_date, status)
|
||||
VALUES (:h_id, :h_pay, :h_rundate, 'S');
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_ID2, h_id);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 13. PAY_MERCHSUM - 가맹점 당일 지급 집계 upsert (dbio). */
|
||||
void PAY_MERCHSUM(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_amt;
|
||||
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_amt
|
||||
FROM py_payout WHERE merchant_id = :h_merch AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (pydb_upsert_summary(merch, bizdate, h_cnt, h_amt) < 0) FAIL(b);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_amt);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 14. PAY_NETOFF - 상계(net-off): 지급 금액에서 차감액 반영. */
|
||||
void PAY_NETOFF(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay, h_off, h_new;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1);
|
||||
h_off = getl(b, T_AMOUNT);
|
||||
EXEC SQL SELECT net INTO :h_new FROM py_payout WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
h_new = h_new - h_off;
|
||||
EXEC SQL UPDATE py_payout SET net = :h_new, updated_at = now() WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_NET, h_new);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 15. PAY_ADVANCE - 선지급(advance) 지급건 생성. */
|
||||
void PAY_ADVANCE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], acct[32], bizdate[16];
|
||||
long amount, fee, net, payout_id;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
amount = getl(b, T_AMOUNT);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
fee = acq_fee(amount, 100); /* 선지급 수수료 1% */
|
||||
net = amount - fee;
|
||||
payout_id = pydb_next_payout_id();
|
||||
if (payout_id < 0) FAIL(b);
|
||||
if (pydb_insert_payout(payout_id, merch, acct, amount, fee, net, "A", "ADVANCE", bizdate) < 0) FAIL(b);
|
||||
setl(b, T_ID1, payout_id);
|
||||
setl(b, T_FEE, fee);
|
||||
setl(b, T_NET, net);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 16. PAY_RETRY - 실패 지급 재시도(J/H -> R). */
|
||||
void PAY_RETRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1);
|
||||
EXEC SQL UPDATE py_payout SET status = 'R', retry_count = retry_count + 1, updated_at = now()
|
||||
WHERE payout_id = :h_pay AND status IN ('J', 'H');
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (sqlca.sqlcode == 100) { setl(b, T_RC, 1); FAIL(b); }
|
||||
setl(b, T_RC, 0);
|
||||
Bchg(b, T_STATUS, 0, "R", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 17. PAY_APPROVE - 지급 승인. */
|
||||
void PAY_APPROVE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long payout_id = getl(b, T_ID1);
|
||||
if (pydb_update_status(payout_id, "A") < 0) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, "A", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 18. PAY_REJECT - 지급 반려 + 사유 기록. */
|
||||
void PAY_REJECT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char reason[128];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay;
|
||||
char h_reason[128];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1);
|
||||
gets_(b, T_REASON, reason, sizeof(reason)); if (reason[0] == 0) strcpy(reason, "REJECT");
|
||||
strncpy(h_reason, reason, sizeof(h_reason)-1); h_reason[sizeof(h_reason)-1] = 0;
|
||||
EXEC SQL UPDATE py_payout SET status = 'J', reject_reason = :h_reason, updated_at = now()
|
||||
WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, "J", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 19. PAY_RECON - 지급-파일 대사: 파일에 편성된 건수/합계 확인. */
|
||||
void PAY_RECON(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_file, h_cnt, h_sum;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_file = getl(b, T_ID2);
|
||||
EXEC SQL SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_sum
|
||||
FROM py_payout WHERE file_id = :h_file;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 20. PAY_STATEMENT - 가맹점 지급 명세: 기간(당일) 지급 합계 집계. */
|
||||
void PAY_STATEMENT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_amt, h_fee, 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), coalesce(sum(fee),0), coalesce(sum(net),0)
|
||||
INTO :h_cnt, :h_amt, :h_fee, :h_net FROM py_payout
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_amt);
|
||||
setl(b, T_FEE, h_fee);
|
||||
setl(b, T_NET, h_net);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 21. PAY_FEEDED - 수수료 공제(fee deduction): net 재계산. */
|
||||
void PAY_FEEDED(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long amount, bps, fee, net;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay, h_fee, h_net;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1);
|
||||
amount = getl(b, T_AMOUNT);
|
||||
bps = getl(b, T_ARG1); if (bps <= 0) bps = 30;
|
||||
fee = acq_fee(amount, bps); net = amount - fee;
|
||||
h_fee = fee; h_net = net;
|
||||
EXEC SQL UPDATE py_payout SET fee = :h_fee, net = :h_net, updated_at = now()
|
||||
WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
setl(b, T_FEE, fee); setl(b, T_NET, net);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 22. PAY_ADJUST - 지급 조정 기록 + net 반영 (dbio + 직접 SQL). */
|
||||
void PAY_ADJUST(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], reason[128];
|
||||
long payout_id, delta, adj;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long e_pay, e_delta;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
payout_id = getl(b, T_ID1);
|
||||
delta = getl(b, T_DELTA);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_REASON, reason, sizeof(reason)); if (reason[0] == 0) strcpy(reason, "ADJ");
|
||||
adj = pydb_insert_adjust(payout_id, delta, reason, bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
e_pay = payout_id; e_delta = delta;
|
||||
EXEC SQL UPDATE py_payout SET net = net + :e_delta, updated_at = now()
|
||||
WHERE payout_id = :e_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 23. PAY_BULK - 대량 지급 생성: N건 반복 등록. */
|
||||
void PAY_BULK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], acct[32], bizdate[16];
|
||||
long n, amount, i, payout_id;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
amount = getl(b, T_AMOUNT);
|
||||
n = getl(b, T_COUNT); if (n < 1) n = 1;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
for (i = 0; i < n; i++) {
|
||||
payout_id = pydb_next_payout_id();
|
||||
if (payout_id < 0) FAIL(b);
|
||||
if (pydb_insert_payout(payout_id, merch, acct, amount, 0, amount, "R", "BULK", bizdate) < 0) FAIL(b);
|
||||
}
|
||||
setl(b, T_COUNT, n);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 24. PAY_INQUIRY - 지급 단건 상세 조회. */
|
||||
void PAY_INQUIRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], acct[32], st[8];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay, h_amt, h_fee, h_net;
|
||||
char h_merch[64], h_acct[32], h_status[8];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1);
|
||||
EXEC SQL SELECT merchant_id, account_no, amount, fee, net, status
|
||||
INTO :h_merch, :h_acct, :h_amt, :h_fee, :h_net, :h_status
|
||||
FROM py_payout WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
strncpy(merch, h_merch, sizeof(merch)-1); merch[sizeof(merch)-1] = 0;
|
||||
strncpy(acct, h_acct, sizeof(acct)-1); acct[sizeof(acct)-1] = 0;
|
||||
strncpy(st, h_status, sizeof(st)-1); st[sizeof(st)-1] = 0;
|
||||
Bchg(b, T_MERCHANT, 0, merch, 0L);
|
||||
Bchg(b, T_KEY1, 0, acct, 0L);
|
||||
Bchg(b, T_STATUS, 0, st, 0L);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
setl(b, T_FEE, h_fee);
|
||||
setl(b, T_NET, h_net);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 25. PAY_HISTORY - 가맹점 지급 이력 건수 조회. */
|
||||
void PAY_HISTORY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt;
|
||||
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 count(*) INTO :h_cnt FROM py_payout WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 26. PAY_REVERSE - 지급 역분개(reverse) + 계좌 잔액 원복. */
|
||||
void PAY_REVERSE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char acct[32];
|
||||
long payout_id = getl(b, T_ID1), amount = getl(b, T_AMOUNT);
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
if (pydb_update_status(payout_id, "V") < 0) FAIL(b);
|
||||
if (acct[0] && pydb_account_add(acct, amount) < 0) FAIL(b);
|
||||
Bchg(b, T_STATUS, 0, "V", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 27. PAY_CONFIRM - 지급 확정(confirm): 파일 상태 C(확정). */
|
||||
void PAY_CONFIRM(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_file;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_file = getl(b, T_ID2);
|
||||
EXEC SQL UPDATE py_file SET status = 'C', confirmed_at = now() WHERE file_id = :h_file;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 28. PAY_REMIT - 실지급 송금: 상태 P + 계좌 잔액 차감. */
|
||||
void PAY_REMIT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char acct[32], st[8];
|
||||
long payout_id, net, bal = 0;
|
||||
payout_id = getl(b, T_ID1);
|
||||
net = getl(b, T_NET);
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
if (pydb_account_check(acct, st, &bal) < 0) FAIL(b);
|
||||
if (bal < net) { setl(b, T_RC, 1); FAIL(b); }
|
||||
if (pydb_account_add(acct, -net) < 0) FAIL(b);
|
||||
if (pydb_update_status(payout_id, "P") < 0) FAIL(b);
|
||||
setl(b, T_RC, 0);
|
||||
Bchg(b, T_STATUS, 0, "P", 0L);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 29. PAY_CLOSE - 일마감: 당일 지급완료(P)건 상태 X(마감)로 일괄 전환. */
|
||||
void PAY_CLOSE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cnt;
|
||||
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 UPDATE py_payout SET status = 'X', updated_at = now()
|
||||
WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
h_cnt = sqlca.sqlerrd[2];
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* 30. PAY_SUMMARY - 가맹점 일별 지급 집계 조회(py_summary). */
|
||||
void PAY_SUMMARY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cnt, h_amt;
|
||||
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(payout_count,0), coalesce(payout_amount,0) INTO :h_cnt, :h_amt
|
||||
FROM py_summary WHERE merchant_id = :h_merch AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (sqlca.sqlcode == 100) { h_cnt = 0; h_amt = 0; }
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_amt);
|
||||
OK(b);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et smartindent: */
|
||||
|
|
|
|||
16
app/src/py/run/run_account.sh
Executable file
16
app/src/py/run/run_account.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_account.sh - 계좌 현황 집계 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_account.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_account.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_account_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_adjust.sh
Executable file
16
app/src/py/run/run_adjust.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_adjust.sh - 지급 조정 반영 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_adjust.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_adjust.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_adjust_apply_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_close.sh
Executable file
16
app/src/py/run/run_close.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_close.sh - 일마감(P->X) 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_close.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_close.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_close_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_confirm.sh
Executable file
16
app/src/py/run/run_confirm.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_confirm.sh - 지급 파일 확정 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_confirm.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_confirm.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_file_confirm_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_daily.sh
Executable file
16
app/src/py/run/run_daily.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_daily.sh - 일일 지급 총계 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_daily.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_daily.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_daily_batch "$BIZDATE"
|
||||
21
app/src/py/run/run_eod.sh
Executable file
21
app/src/py/run/run_eod.sh
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_eod.sh - 일마감(EOD): 지급 집계/정산 배치 일괄 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_eod.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_eod.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
for b in py_filegen_batch py_result_batch py_merchsum_batch py_ledger_batch \
|
||||
py_daily_batch py_settle_batch py_stat_batch py_reject_report_batch \
|
||||
py_file_confirm_batch py_close_batch; do
|
||||
echo "--- $b $BIZDATE ---"
|
||||
"/app/bin/$b" "$BIZDATE" || exit 1
|
||||
done
|
||||
16
app/src/py/run/run_fee.sh
Executable file
16
app/src/py/run/run_fee.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_fee.sh - 수수료 재계산 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_fee.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_fee.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_fee_recalc_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_filegen.sh
Executable file
16
app/src/py/run/run_filegen.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_filegen.sh - 지급 파일 생성 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_filegen.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_filegen.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_filegen_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_ledger.sh
Executable file
16
app/src/py/run/run_ledger.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_ledger.sh - 지급 원장 생성 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_ledger.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_ledger.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_ledger_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_merchsum.sh
Executable file
16
app/src/py/run/run_merchsum.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_merchsum.sh - 가맹점 지급 집계 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_merchsum.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_merchsum.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_merchsum_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_netoff.sh
Executable file
16
app/src/py/run/run_netoff.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_netoff.sh - 일괄 상계 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_netoff.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_netoff.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_netoff_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_reject.sh
Executable file
16
app/src/py/run/run_reject.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_reject.sh - 반려 현황 리포트 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_reject.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_reject.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_reject_report_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_result.sh
Executable file
16
app/src/py/run/run_result.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_result.sh - 지급 결과 반영 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_result.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_result.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_result_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_retry.sh
Executable file
16
app/src/py/run/run_retry.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_retry.sh - 실패 지급 재시도 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_retry.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_retry.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_retry_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_schedule.sh
Executable file
16
app/src/py/run/run_schedule.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_schedule.sh - 예약 지급 실행 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_schedule.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_schedule.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_schedule_run_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_settle.sh
Executable file
16
app/src/py/run/run_settle.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_settle.sh - 지급완료 정산 집계 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_settle.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_settle.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_settle_batch "$BIZDATE"
|
||||
16
app/src/py/run/run_stat.sh
Executable file
16
app/src/py/run/run_stat.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
## run_stat.sh - 집중 가맹점 통계 배치 실행.
|
||||
## 운영 스크립트: Enduro/X + ECPG/XA 런타임 환경을 설정하고 배치/서비스를 실행.
|
||||
## Usage: run_stat.sh [BIZDATE] [MERCH] [AMOUNT] [PID]
|
||||
##
|
||||
set -e
|
||||
. /app/conf/setapp.sh
|
||||
|
||||
BIZDATE="${1:-2026-07-19}"
|
||||
MERCH="${2:-M0001}"
|
||||
AMOUNT="${3:-1000000}"
|
||||
PID="${4:-1}"
|
||||
|
||||
echo "[run_stat.sh] BIZDATE=$BIZDATE MERCH=$MERCH AMOUNT=$AMOUNT"
|
||||
exec /app/bin/py_stat_batch "$BIZDATE"
|
||||
19
app/src/py/svc/PAY_ACCTCHK.h
Normal file
19
app/src/py/svc/PAY_ACCTCHK.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* PAY_ACCTCHK.h - py 서비스 PAY_ACCTCHK 카피북 (copybook / record header).
|
||||
* Request fields: T_KEY1(account_no)
|
||||
* Response fields: T_AMT1(balance), T_STR1(status), T_RC(0 active / 1 inactive)
|
||||
*/
|
||||
#ifndef PAY_ACCTCHK_H
|
||||
#define PAY_ACCTCHK_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char account_no[32];
|
||||
char status[8];
|
||||
long balance;
|
||||
} py_acctchk_rec_t;
|
||||
|
||||
void PAY_ACCTCHK(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_ACCTCHK_H */
|
||||
20
app/src/py/svc/PAY_ACCTCHK.pgc
Normal file
20
app/src/py/svc/PAY_ACCTCHK.pgc
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* PAY_ACCTCHK.pgc - py 모듈 서비스 PAY_ACCTCHK (one service = one file).
|
||||
* 지급계좌 유효성 점검: dbio 로 계좌 상태/잔액을 읽어 ACTIVE 여부를 회신.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_ACCTCHK.h"
|
||||
|
||||
void PAY_ACCTCHK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char acct[32], st[8];
|
||||
long bal = 0;
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
if (pydb_account_check(acct, st, &bal) < 0) { setl(b, T_RC, 1); FAIL(b); }
|
||||
setl(b, T_AMT1, bal);
|
||||
Bchg(b, T_STR1, 0, st, 0L);
|
||||
setl(b, T_RC, (strcmp(st, "ACTIVE") == 0) ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
21
app/src/py/svc/PAY_ADJUST.h
Normal file
21
app/src/py/svc/PAY_ADJUST.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* PAY_ADJUST.h - py 서비스 PAY_ADJUST 카피북 (copybook / record header).
|
||||
* Request fields: T_ID1(payout_id), T_DELTA, T_BIZDATE, T_REASON
|
||||
* Response fields: T_ADJ(adj_id)
|
||||
*/
|
||||
#ifndef PAY_ADJUST_H
|
||||
#define PAY_ADJUST_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long payout_id;
|
||||
long delta;
|
||||
long adj_id;
|
||||
char reason[128];
|
||||
char biz_date[16];
|
||||
} py_adjust_rec_t;
|
||||
|
||||
void PAY_ADJUST(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_ADJUST_H */
|
||||
29
app/src/py/svc/PAY_ADJUST.pgc
Normal file
29
app/src/py/svc/PAY_ADJUST.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* PAY_ADJUST.pgc - py 모듈 서비스 PAY_ADJUST (one service = one file).
|
||||
* 지급 조정: py_adjust 에 증감(delta)을 기록하고 지급건 net 에 즉시 반영.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_ADJUST.h"
|
||||
|
||||
void PAY_ADJUST(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], reason[128];
|
||||
long payout_id, delta, adj;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long e_pay, e_delta;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
payout_id = getl(b, T_ID1);
|
||||
delta = getl(b, T_DELTA);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_REASON, reason, sizeof(reason)); if (reason[0] == 0) strcpy(reason, "ADJ");
|
||||
adj = pydb_insert_adjust(payout_id, delta, reason, bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
e_pay = payout_id; e_delta = delta;
|
||||
EXEC SQL UPDATE py_payout SET net = net + :e_delta, updated_at = now()
|
||||
WHERE payout_id = :e_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
OK(b);
|
||||
}
|
||||
23
app/src/py/svc/PAY_ADVANCE.h
Normal file
23
app/src/py/svc/PAY_ADVANCE.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* PAY_ADVANCE.h - py 서비스 PAY_ADVANCE 카피북 (copybook / record header).
|
||||
* Request fields: T_MERCHANT, T_KEY1(account_no), T_AMOUNT, T_BIZDATE
|
||||
* Response fields: T_ID1(payout_id), T_FEE, T_NET
|
||||
*/
|
||||
#ifndef PAY_ADVANCE_H
|
||||
#define PAY_ADVANCE_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char account_no[32];
|
||||
long amount;
|
||||
long fee;
|
||||
long net;
|
||||
long payout_id;
|
||||
char biz_date[16];
|
||||
} py_advance_rec_t;
|
||||
|
||||
void PAY_ADVANCE(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_ADVANCE_H */
|
||||
27
app/src/py/svc/PAY_ADVANCE.pgc
Normal file
27
app/src/py/svc/PAY_ADVANCE.pgc
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* PAY_ADVANCE.pgc - py 모듈 서비스 PAY_ADVANCE (one service = one file).
|
||||
* 선지급(advance): 선지급 수수료(1%)를 공제한 지급건(ADVANCE 채널)을 생성.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_ADVANCE.h"
|
||||
|
||||
void PAY_ADVANCE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], acct[32], bizdate[16];
|
||||
long amount, fee, net, payout_id;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
amount = getl(b, T_AMOUNT);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
fee = acq_fee(amount, 100); /* 선지급 수수료 1% */
|
||||
net = amount - fee;
|
||||
payout_id = pydb_next_payout_id();
|
||||
if (payout_id < 0) FAIL(b);
|
||||
if (pydb_insert_payout(payout_id, merch, acct, amount, fee, net, "A", "ADVANCE", bizdate) < 0) FAIL(b);
|
||||
setl(b, T_ID1, payout_id);
|
||||
setl(b, T_FEE, fee);
|
||||
setl(b, T_NET, net);
|
||||
OK(b);
|
||||
}
|
||||
19
app/src/py/svc/PAY_APPROVE.h
Normal file
19
app/src/py/svc/PAY_APPROVE.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* PAY_APPROVE.h - py 서비스 PAY_APPROVE 카피북 (copybook / record header).
|
||||
* Request fields: T_ID1(payout_id)
|
||||
* Response fields: T_AMOUNT, T_STATUS, T_RC(0 approved / 1 no-op)
|
||||
*/
|
||||
#ifndef PAY_APPROVE_H
|
||||
#define PAY_APPROVE_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long payout_id;
|
||||
long amount;
|
||||
long affected;
|
||||
} py_approve_rec_t;
|
||||
|
||||
void PAY_APPROVE(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_APPROVE_H */
|
||||
27
app/src/py/svc/PAY_APPROVE.pgc
Normal file
27
app/src/py/svc/PAY_APPROVE.pgc
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* PAY_APPROVE.pgc - py 모듈 서비스 PAY_APPROVE (one service = one file).
|
||||
* 지급 승인: 금액을 먼저 조회한 뒤 요청(R) 상태만 승인(A)으로 전이하고 금액을
|
||||
* 함께 회신. SELECT amount + guarded UPDATE(status='R') + affected-count.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by py_svr.
|
||||
*/
|
||||
#include "PAY_APPROVE.h"
|
||||
|
||||
void PAY_APPROVE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay, h_amt, h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pay = getl(b, T_ID1);
|
||||
EXEC SQL SELECT coalesce(amount,0) INTO :h_amt FROM py_payout WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
EXEC SQL UPDATE py_payout SET status = 'A', updated_at = now()
|
||||
WHERE payout_id = :h_pay AND status = 'R';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
if (h_aff > 0) Bchg(b, T_STATUS, 0, "A", 0L);
|
||||
setl(b, T_RC, h_aff > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
21
app/src/py/svc/PAY_BULK.h
Normal file
21
app/src/py/svc/PAY_BULK.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* PAY_BULK.h - py 서비스 PAY_BULK 카피북 (copybook / record header).
|
||||
* Request fields: T_MERCHANT, T_KEY1(account_no), T_AMOUNT, T_COUNT(n), T_BIZDATE
|
||||
* Response fields: T_COUNT(created)
|
||||
*/
|
||||
#ifndef PAY_BULK_H
|
||||
#define PAY_BULK_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
char account_no[32];
|
||||
long amount;
|
||||
long count;
|
||||
char biz_date[16];
|
||||
} py_bulk_rec_t;
|
||||
|
||||
void PAY_BULK(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_BULK_H */
|
||||
26
app/src/py/svc/PAY_BULK.pgc
Normal file
26
app/src/py/svc/PAY_BULK.pgc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* PAY_BULK.pgc - py 모듈 서비스 PAY_BULK (one service = one file).
|
||||
* 대량 지급 생성: 동일 금액의 지급건(BULK 채널)을 N건 반복 등록.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_BULK.h"
|
||||
|
||||
void PAY_BULK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char merch[64], acct[32], bizdate[16];
|
||||
long n, amount, i, payout_id;
|
||||
gets_(b, T_MERCHANT, merch, sizeof(merch));
|
||||
gets_(b, T_KEY1, acct, sizeof(acct));
|
||||
amount = getl(b, T_AMOUNT);
|
||||
n = getl(b, T_COUNT); if (n < 1) n = 1;
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
for (i = 0; i < n; i++) {
|
||||
payout_id = pydb_next_payout_id();
|
||||
if (payout_id < 0) FAIL(b);
|
||||
if (pydb_insert_payout(payout_id, merch, acct, amount, 0, amount, "R", "BULK", bizdate) < 0) FAIL(b);
|
||||
}
|
||||
setl(b, T_COUNT, n);
|
||||
OK(b);
|
||||
}
|
||||
21
app/src/py/svc/PAY_CANCEL.h
Normal file
21
app/src/py/svc/PAY_CANCEL.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* PAY_CANCEL.h - py 서비스 PAY_CANCEL 카피북 (copybook / record header).
|
||||
* Request fields: T_ID1(payout_id), T_AMOUNT, T_BIZDATE, T_REASON
|
||||
* Response fields: T_ADJ(adj_id), T_STATUS
|
||||
*/
|
||||
#ifndef PAY_CANCEL_H
|
||||
#define PAY_CANCEL_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long payout_id;
|
||||
long amount;
|
||||
long adj_id;
|
||||
char reason[128];
|
||||
char biz_date[16];
|
||||
} py_cancel_rec_t;
|
||||
|
||||
void PAY_CANCEL(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_CANCEL_H */
|
||||
24
app/src/py/svc/PAY_CANCEL.pgc
Normal file
24
app/src/py/svc/PAY_CANCEL.pgc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* PAY_CANCEL.pgc - py 모듈 서비스 PAY_CANCEL (one service = one file).
|
||||
* 지급 취소: 취소 조정(-amount)을 py_adjust 에 기록하고 지급건 상태 C 로 전이.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_CANCEL.h"
|
||||
|
||||
void PAY_CANCEL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], reason[128];
|
||||
long payout_id, amt, adj;
|
||||
payout_id = getl(b, T_ID1);
|
||||
amt = getl(b, T_AMOUNT);
|
||||
gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
|
||||
gets_(b, T_REASON, reason, sizeof(reason)); if (reason[0] == 0) strcpy(reason, "CANCEL");
|
||||
adj = pydb_insert_adjust(payout_id, -amt, reason, bizdate);
|
||||
if (adj < 0) FAIL(b);
|
||||
if (pydb_update_status(payout_id, "C") < 0) FAIL(b);
|
||||
setl(b, T_ADJ, adj);
|
||||
Bchg(b, T_STATUS, 0, "C", 0L);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/py/svc/PAY_CLOSE.h
Normal file
18
app/src/py/svc/PAY_CLOSE.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* PAY_CLOSE.h - py 서비스 PAY_CLOSE 카피북 (copybook / record header).
|
||||
* Request fields: T_BIZDATE
|
||||
* Response fields: T_COUNT(closed)
|
||||
*/
|
||||
#ifndef PAY_CLOSE_H
|
||||
#define PAY_CLOSE_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char biz_date[16];
|
||||
long closed_count;
|
||||
} py_close_rec_t;
|
||||
|
||||
void PAY_CLOSE(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_CLOSE_H */
|
||||
25
app/src/py/svc/PAY_CLOSE.pgc
Normal file
25
app/src/py/svc/PAY_CLOSE.pgc
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* PAY_CLOSE.pgc - py 모듈 서비스 PAY_CLOSE (one service = one file).
|
||||
* 일마감: 당일 지급완료(P)건을 마감(X)으로 일괄 전환하고 전환 건수를 회신.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_CLOSE.h"
|
||||
|
||||
void PAY_CLOSE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cnt;
|
||||
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 UPDATE py_payout SET status = 'X', updated_at = now()
|
||||
WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
h_cnt = sqlca.sqlerrd[2];
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
OK(b);
|
||||
}
|
||||
17
app/src/py/svc/PAY_CONFIRM.h
Normal file
17
app/src/py/svc/PAY_CONFIRM.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* PAY_CONFIRM.h - py 서비스 PAY_CONFIRM 카피북 (copybook / record header).
|
||||
* Request fields: T_ID2(file_id)
|
||||
* Response fields: (none; flips py_file status to confirmed)
|
||||
*/
|
||||
#ifndef PAY_CONFIRM_H
|
||||
#define PAY_CONFIRM_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long file_id;
|
||||
} py_confirm_rec_t;
|
||||
|
||||
void PAY_CONFIRM(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_CONFIRM_H */
|
||||
19
app/src/py/svc/PAY_CONFIRM.pgc
Normal file
19
app/src/py/svc/PAY_CONFIRM.pgc
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* PAY_CONFIRM.pgc - py 모듈 서비스 PAY_CONFIRM (one service = one file).
|
||||
* 지급 확정(confirm): 지급 파일 상태를 확정(C)으로 전이하고 확정 시각 기록.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_CONFIRM.h"
|
||||
|
||||
void PAY_CONFIRM(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_file;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_file = getl(b, T_ID2);
|
||||
EXEC SQL UPDATE py_file SET status = 'C', confirmed_at = now() WHERE file_id = :h_file;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
OK(b);
|
||||
}
|
||||
21
app/src/py/svc/PAY_FEEDED.h
Normal file
21
app/src/py/svc/PAY_FEEDED.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* PAY_FEEDED.h - py 서비스 PAY_FEEDED 카피북 (copybook / record header).
|
||||
* Request fields: T_ID1(payout_id), T_AMOUNT, T_ARG1(bps)
|
||||
* Response fields: T_FEE, T_NET
|
||||
*/
|
||||
#ifndef PAY_FEEDED_H
|
||||
#define PAY_FEEDED_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long payout_id;
|
||||
long amount;
|
||||
long bps;
|
||||
long fee;
|
||||
long net;
|
||||
} py_feeded_rec_t;
|
||||
|
||||
void PAY_FEEDED(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_FEEDED_H */
|
||||
26
app/src/py/svc/PAY_FEEDED.pgc
Normal file
26
app/src/py/svc/PAY_FEEDED.pgc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* PAY_FEEDED.pgc - py 모듈 서비스 PAY_FEEDED (one service = one file).
|
||||
* 수수료 공제(fee deduction): bps 로 수수료를 산출해 fee/net 을 재계산·갱신.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_FEEDED.h"
|
||||
|
||||
void PAY_FEEDED(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long amount, bps, fee, net;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pay, h_fee, h_net;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
h_pay = getl(b, T_ID1);
|
||||
amount = getl(b, T_AMOUNT);
|
||||
bps = getl(b, T_ARG1); if (bps <= 0) bps = 30;
|
||||
fee = acq_fee(amount, bps); net = amount - fee;
|
||||
h_fee = fee; h_net = net;
|
||||
EXEC SQL UPDATE py_payout SET fee = :h_fee, net = :h_net, updated_at = now()
|
||||
WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) FAIL(b);
|
||||
setl(b, T_FEE, fee); setl(b, T_NET, net);
|
||||
OK(b);
|
||||
}
|
||||
21
app/src/py/svc/PAY_FILEGEN.h
Normal file
21
app/src/py/svc/PAY_FILEGEN.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* PAY_FILEGEN.h - py 서비스 PAY_FILEGEN 카피북 (copybook / record header).
|
||||
* Request fields: T_BIZDATE
|
||||
* Response fields: T_ID2(file_id), T_COUNT, T_GROSS, T_STR1(file_name)
|
||||
*/
|
||||
#ifndef PAY_FILEGEN_H
|
||||
#define PAY_FILEGEN_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long file_id;
|
||||
char biz_date[16];
|
||||
char file_name[64];
|
||||
long record_count;
|
||||
long total_amount;
|
||||
} py_filegen_rec_t;
|
||||
|
||||
void PAY_FILEGEN(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_FILEGEN_H */
|
||||
37
app/src/py/svc/PAY_FILEGEN.pgc
Normal file
37
app/src/py/svc/PAY_FILEGEN.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* PAY_FILEGEN.pgc - py 모듈 서비스 PAY_FILEGEN (one service = one file).
|
||||
* 지급 파일 헤더 생성: 당일 승인(A) 지급건 집계 -> py_file.
|
||||
* Moved verbatim from the former inline py_svr.pgc; runs on the caller's XA
|
||||
* branch (no EXEC SQL CONNECT). Advertised by py_svr at tpsvrinit.
|
||||
*/
|
||||
#include "PAY_FILEGEN.h"
|
||||
|
||||
void PAY_FILEGEN(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char bizdate[16], fname[64];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_cnt, h_sum;
|
||||
char h_bizdate[16], h_fname[64];
|
||||
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 py_payout WHERE biz_date = :h_bizdate AND status = 'A';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
snprintf(fname, sizeof(fname), "PAYOUT_%s.dat", bizdate);
|
||||
strncpy(h_fname, fname, sizeof(h_fname)-1); h_fname[sizeof(h_fname)-1] = 0;
|
||||
EXEC SQL SELECT nextval('py_file_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO py_file (file_id, biz_date, file_name, record_count, total_amount, status)
|
||||
VALUES (:h_id, :h_bizdate, :h_fname, :h_cnt, :h_sum, 'G');
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
setl(b, T_ID2, h_id);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
Bchg(b, T_STR1, 0, fname, 0L);
|
||||
userlog("PAY_FILEGEN file_id=%ld name=%s recs=%ld amt=%ld", h_id, fname, h_cnt, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/py/svc/PAY_HISTORY.h
Normal file
18
app/src/py/svc/PAY_HISTORY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* PAY_HISTORY.h - py 서비스 PAY_HISTORY 카피북 (copybook / record header).
|
||||
* Request fields: T_MERCHANT
|
||||
* Response fields: T_COUNT
|
||||
*/
|
||||
#ifndef PAY_HISTORY_H
|
||||
#define PAY_HISTORY_H
|
||||
|
||||
#include "py_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant_id[64];
|
||||
long history_count;
|
||||
} py_history_rec_t;
|
||||
|
||||
void PAY_HISTORY(TPSVCINFO *p);
|
||||
|
||||
#endif /* PAY_HISTORY_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