다양화 Wave2: dbio 289 + common 120 고유화 + 프로그램 206개 EXEC SQL 심화

- dbio io(289): fetch/touch/total 시그니처 유지, SQL 바디를 JOIN/집계/커서/
  upsert/DELETE 등 구조로 고유화 → 289/289 고유
- common cu(120): 유틸 시그니처 유지, Luhn/CRC/Zeller/BIN레인지/amortization/
  netting 등 실 알고리즘으로 고유화 → 120/120 고유
- 심화: 실제 EXEC SQL 없던 프로그램에 SELECT/INSERT/UPDATE/커서+tx 추가
  → online+batch 530/530 전부 실제 SQL 보유
- 전 코퍼스 프로그램 939/939 고유, 전체 docker make -j4 = EXIT 0, 958 오브젝트
- 임시 생성기 제거, inventory.json loc 실측 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
forge-bot 2026-07-19 04:54:59 +00:00
parent c3a0259e95
commit 93c3cb74af
1111 changed files with 31539 additions and 17258 deletions

View file

@ -162,7 +162,7 @@ TX_SERVICE(AC_OL_0001, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 53 "app/online/ac_ol_0001.pgc"
#line 52 "app/online/ac_ol_0001.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -46,8 +46,7 @@ TX_SERVICE(AC_OL_0001, ctx)
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
EXEC SQL
SELECT status, amount, fee, merch_id, card_no, biz_date
EXEC SQL SELECT status, amount, fee, merch_id, card_no, biz_date
INTO :h_status, :h_amount, :h_fee, :h_merch_id, :h_card_no, :h_biz_date
FROM ac_ledger
WHERE key = :h_key;

View file

@ -172,7 +172,7 @@ TX_SERVICE(AC_OL_0002, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_limit_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 72 "app/online/ac_ol_0002.pgc"
#line 71 "app/online/ac_ol_0002.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -201,7 +201,7 @@ TX_SERVICE(AC_OL_0002, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_dup),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 98 "app/online/ac_ol_0002.pgc"
#line 96 "app/online/ac_ol_0002.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {

View file

@ -65,8 +65,7 @@ TX_SERVICE(AC_OL_0002, ctx)
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
strncpy(h_status, "A", sizeof(h_status));
EXEC SQL
SELECT fee_rate, limit_amt INTO :h_fee_rate, :h_limit_amt
EXEC SQL SELECT fee_rate, limit_amt INTO :h_fee_rate, :h_limit_amt
FROM merchant
WHERE merch_id = :h_merch_id
AND status = :h_status;
@ -92,8 +91,7 @@ TX_SERVICE(AC_OL_0002, ctx)
return;
}
EXEC SQL
SELECT count(*) INTO :h_dup
EXEC SQL SELECT count(*) INTO :h_dup
FROM ac_ledger
WHERE key = :h_key;

View file

@ -180,7 +180,7 @@ TX_SERVICE(AC_OL_0003, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_merch_active),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 72 "app/online/ac_ol_0003.pgc"
#line 71 "app/online/ac_ol_0003.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
@ -201,7 +201,7 @@ TX_SERVICE(AC_OL_0003, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_dup),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 90 "app/online/ac_ol_0003.pgc"
#line 88 "app/online/ac_ol_0003.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
@ -247,7 +247,7 @@ TX_SERVICE(AC_OL_0003, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_acq_type),(long)4,(long)1,(4)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 123 "app/online/ac_ol_0003.pgc"
#line 120 "app/online/ac_ol_0003.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {

View file

@ -65,8 +65,7 @@ TX_SERVICE(AC_OL_0003, ctx)
strncpy(h_merch_id, merch, sizeof(h_merch_id) - 1);
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
EXEC SQL
SELECT count(*) INTO :h_merch_active
EXEC SQL SELECT count(*) INTO :h_merch_active
FROM merchant
WHERE merch_id = :h_merch_id
AND status = 'A';
@ -84,8 +83,7 @@ TX_SERVICE(AC_OL_0003, ctx)
return;
}
EXEC SQL
SELECT count(*) INTO :h_dup
EXEC SQL SELECT count(*) INTO :h_dup
FROM ac_ledger
WHERE key = :h_key;
@ -115,8 +113,7 @@ TX_SERVICE(AC_OL_0003, ctx)
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[AC_OL_0003] tx_begin 경고");
EXEC SQL
INSERT INTO ac_ledger
EXEC SQL INSERT INTO ac_ledger
(key, merch_id, card_no, amount, biz_date, status, fee, acq_type)
VALUES
(:h_key, :h_merch_id, :h_card_no, :h_amount, :h_biz_date,

View file

@ -173,7 +173,7 @@ TX_SERVICE(AC_OL_0004, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_appr_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 59 "app/online/ac_ol_0004.pgc"
#line 58 "app/online/ac_ol_0004.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -234,7 +234,7 @@ TX_SERVICE(AC_OL_0004, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_appr_no),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 106 "app/online/ac_ol_0004.pgc"
#line 104 "app/online/ac_ol_0004.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {

View file

@ -52,8 +52,7 @@ TX_SERVICE(AC_OL_0004, ctx)
strncpy(h_appr_no, apprno, sizeof(h_appr_no) - 1);
h_appr_no[sizeof(h_appr_no) - 1] = '\0';
EXEC SQL
SELECT amount, merch_id, card_no, appr_status
EXEC SQL SELECT amount, merch_id, card_no, appr_status
INTO :h_amount, :h_merch_id, :h_card_no, :h_appr_status
FROM approval
WHERE approval_no = :h_appr_no;
@ -97,8 +96,7 @@ TX_SERVICE(AC_OL_0004, ctx)
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[AC_OL_0004] tx_begin 경고");
EXEC SQL
INSERT INTO ac_ledger
EXEC SQL INSERT INTO ac_ledger
(key, merch_id, card_no, amount, biz_date, status, fee,
acq_type, approval_no)
VALUES

View file

@ -151,7 +151,7 @@ TX_SERVICE(AC_OL_0005, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/online/ac_ol_0005.pgc"
#line 53 "app/online/ac_ol_0005.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -192,7 +192,7 @@ TX_SERVICE(AC_OL_0005, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 93 "app/online/ac_ol_0005.pgc"
#line 91 "app/online/ac_ol_0005.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {

View file

@ -47,8 +47,7 @@ TX_SERVICE(AC_OL_0005, ctx)
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
EXEC SQL
SELECT status, amount, biz_date
EXEC SQL SELECT status, amount, biz_date
INTO :h_status, :h_amount, :h_biz_date
FROM ac_ledger
WHERE key = :h_key;
@ -86,8 +85,7 @@ TX_SERVICE(AC_OL_0005, ctx)
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[AC_OL_0005] tx_begin 경고");
EXEC SQL
UPDATE ac_ledger
EXEC SQL UPDATE ac_ledger
SET status = :h_cancel_status,
upd_ts = now()
WHERE key = :h_key;

View file

@ -184,7 +184,7 @@ TX_SERVICE(AC_OL_0006, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 65 "app/online/ac_ol_0006.pgc"
#line 64 "app/online/ac_ol_0006.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -205,7 +205,7 @@ TX_SERVICE(AC_OL_0006, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_fee_rate),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 83 "app/online/ac_ol_0006.pgc"
#line 81 "app/online/ac_ol_0006.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -230,7 +230,7 @@ TX_SERVICE(AC_OL_0006, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 105 "app/online/ac_ol_0006.pgc"
#line 102 "app/online/ac_ol_0006.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {
@ -266,7 +266,7 @@ TX_SERVICE(AC_OL_0006, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 129 "app/online/ac_ol_0006.pgc"
#line 125 "app/online/ac_ol_0006.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {

View file

@ -58,8 +58,7 @@ TX_SERVICE(AC_OL_0006, ctx)
tx_log(TX_LOG_WARN, "[AC_OL_0006] tx_begin 경고");
}
EXEC SQL
SELECT amount, fee, merch_id, card_no, biz_date
EXEC SQL SELECT amount, fee, merch_id, card_no, biz_date
INTO :h_old_amount, :h_old_fee, :h_merch_id, :h_card_no, :h_biz_date
FROM ac_ledger
WHERE key = :h_key;
@ -77,8 +76,7 @@ TX_SERVICE(AC_OL_0006, ctx)
return;
}
EXEC SQL
SELECT fee_rate INTO :h_fee_rate
EXEC SQL SELECT fee_rate INTO :h_fee_rate
FROM merchant
WHERE merch_id = :h_merch_id;
@ -97,8 +95,7 @@ TX_SERVICE(AC_OL_0006, ctx)
h_new_fee = h_new_amount * h_fee_rate / 10000;
EXEC SQL
UPDATE ac_ledger
EXEC SQL UPDATE ac_ledger
SET amount = :h_new_amount,
fee = :h_new_fee,
upd_ts = now()
@ -120,8 +117,7 @@ TX_SERVICE(AC_OL_0006, ctx)
strcat(h_corr_key, "-C");
strncpy(h_status, AC_ST_DONE, sizeof(h_status));
EXEC SQL
INSERT INTO ac_ledger
EXEC SQL INSERT INTO ac_ledger
(key, merch_id, card_no, amount, biz_date, status, fee,
acq_type, orig_key)
VALUES

View file

@ -168,7 +168,7 @@ TX_SERVICE(AC_OL_0007, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 57 "app/online/ac_ol_0007.pgc"
#line 56 "app/online/ac_ol_0007.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -200,7 +200,7 @@ TX_SERVICE(AC_OL_0007, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 87 "app/online/ac_ol_0007.pgc"
#line 85 "app/online/ac_ol_0007.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {
@ -234,7 +234,7 @@ TX_SERVICE(AC_OL_0007, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 111 "app/online/ac_ol_0007.pgc"
#line 108 "app/online/ac_ol_0007.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {

View file

@ -50,8 +50,7 @@ TX_SERVICE(AC_OL_0007, ctx)
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
EXEC SQL
SELECT amount, merch_id, card_no, biz_date
EXEC SQL SELECT amount, merch_id, card_no, biz_date
INTO :h_orig_amount, :h_merch_id, :h_card_no, :h_biz_date
FROM ac_ledger
WHERE key = :h_key;
@ -80,8 +79,7 @@ TX_SERVICE(AC_OL_0007, ctx)
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[AC_OL_0007] tx_begin 경고");
EXEC SQL
UPDATE ac_ledger
EXEC SQL UPDATE ac_ledger
SET amount = :h_remaining,
upd_ts = now()
WHERE key = :h_key;
@ -102,8 +100,7 @@ TX_SERVICE(AC_OL_0007, ctx)
strcat(h_part_key, "-P");
strncpy(h_status, AC_ST_DONE, sizeof(h_status));
EXEC SQL
INSERT INTO ac_ledger
EXEC SQL INSERT INTO ac_ledger
(key, merch_id, card_no, amount, biz_date, status, fee,
acq_type, orig_key)
VALUES

View file

@ -220,7 +220,7 @@ TX_SERVICE(AC_OL_0008, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_int,&(h_install_month),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 103 "app/online/ac_ol_0008.pgc"
#line 102 "app/online/ac_ol_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK || sqlca.sqlerrd[2] != 1) {

View file

@ -94,8 +94,7 @@ TX_SERVICE(AC_OL_0008, ctx)
h_row_fee = row_amt * 25 / 10000; /* 할부 수수료 0.25% */
h_install_month = i;
EXEC SQL
INSERT INTO ac_ledger
EXEC SQL INSERT INTO ac_ledger
(key, merch_id, card_no, amount, biz_date, status, fee,
acq_type, install_month)
VALUES

View file

@ -171,7 +171,7 @@ TX_SERVICE(AC_OL_0025, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_totamt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 77 "app/online/ac_ol_0025.pgc"
#line 76 "app/online/ac_ol_0025.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
@ -195,7 +195,7 @@ TX_SERVICE(AC_OL_0025, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_oldest),(long)16,(long)1,(16)*sizeof(char),
ECPGt_short,&(h_oldest_ind),(long)1,(long)1,sizeof(short), ECPGt_EORT);}
#line 100 "app/online/ac_ol_0025.pgc"
#line 98 "app/online/ac_ol_0025.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {

View file

@ -69,8 +69,7 @@ TX_SERVICE(AC_OL_0025, ctx)
}
/* ---- 3. 미매입 접수건 집계 (건수 + 합계금액) ---- */
EXEC SQL
SELECT COUNT(*), COALESCE(SUM(amount), 0)
EXEC SQL SELECT COUNT(*), COALESCE(SUM(amount), 0)
INTO :h_cnt, :h_totamt
FROM ac_ledger
WHERE biz_date <= :h_biz_date
@ -92,8 +91,7 @@ TX_SERVICE(AC_OL_0025, ctx)
memset(h_oldest, 0, sizeof(h_oldest));
h_oldest_ind = -1;
EXEC SQL
SELECT MIN(key)
EXEC SQL SELECT MIN(key)
INTO :h_oldest:h_oldest_ind
FROM ac_ledger
WHERE biz_date <= :h_biz_date

View file

@ -170,7 +170,7 @@ TX_SERVICE(AC_OL_0027, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_totfee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 67 "app/online/ac_ol_0027.pgc"
#line 66 "app/online/ac_ol_0027.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {

View file

@ -59,8 +59,7 @@ TX_SERVICE(AC_OL_0027, ctx)
h_status_settled[sizeof(h_status_settled) - 1] = '\0';
/* ---- 2. 완료 + 정산완료 건 집계 ---- */
EXEC SQL
SELECT COUNT(*), COALESCE(SUM(amount), 0), COALESCE(SUM(fee), 0)
EXEC SQL SELECT COUNT(*), COALESCE(SUM(amount), 0), COALESCE(SUM(fee), 0)
INTO :h_cnt, :h_tot, :h_totfee
FROM ac_ledger
WHERE biz_date = :h_biz_date

View file

@ -174,7 +174,7 @@ TX_SERVICE(AC_OL_0029, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 70 "app/online/ac_ol_0029.pgc"
#line 69 "app/online/ac_ol_0029.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -63,8 +63,7 @@ TX_SERVICE(AC_OL_0029, ctx)
strncpy(h_claim_no, claimno, sizeof(h_claim_no) - 1);
/* ---- 3. 청구내역 단건 조회 ---- */
EXEC SQL
SELECT merch_id, biz_date, amount, file_seq, status
EXEC SQL SELECT merch_id, biz_date, amount, file_seq, status
INTO :h_merch_id, :h_biz_date, :h_amount, :h_file_seq, :h_status
FROM ac_claim
WHERE claim_no = :h_claim_no;

View file

@ -175,7 +175,7 @@ TX_SERVICE(AC_OL_0030, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_dupcnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 76 "app/online/ac_ol_0030.pgc"
#line 75 "app/online/ac_ol_0030.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
@ -223,7 +223,7 @@ TX_SERVICE(AC_OL_0030, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 118 "app/online/ac_ol_0030.pgc"
#line 116 "app/online/ac_ol_0030.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {

View file

@ -66,8 +66,7 @@ TX_SERVICE(AC_OL_0030, ctx)
h_status_fail[sizeof(h_status_fail) - 1] = '\0';
/* ---- 2. 중복 집합 크기 사전 확인 ---- */
EXEC SQL
SELECT COUNT(*)
EXEC SQL SELECT COUNT(*)
INTO :h_dupcnt
FROM ac_ledger
WHERE merch_id = :h_merch_id
@ -101,8 +100,7 @@ TX_SERVICE(AC_OL_0030, ctx)
return;
}
EXEC SQL
UPDATE ac_ledger
EXEC SQL UPDATE ac_ledger
SET status = :h_status_fail, upd_ts = now()
WHERE merch_id = :h_merch_id
AND card_no = :h_card_no

View file

@ -149,7 +149,7 @@ TX_SERVICE(AC_OL_0031, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 59 "app/online/ac_ol_0031.pgc"
#line 58 "app/online/ac_ol_0031.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -193,7 +193,7 @@ TX_SERVICE(AC_OL_0031, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 100 "app/online/ac_ol_0031.pgc"
#line 98 "app/online/ac_ol_0031.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {

View file

@ -52,8 +52,7 @@ TX_SERVICE(AC_OL_0031, ctx)
h_status_settled[sizeof(h_status_settled) - 1] = '\0';
/* ---- 2. 현재 상태 조회 ---- */
EXEC SQL
SELECT status
EXEC SQL SELECT status
INTO :h_status
FROM ac_ledger
WHERE key = :h_key;
@ -94,8 +93,7 @@ TX_SERVICE(AC_OL_0031, ctx)
return;
}
EXEC SQL
UPDATE ac_ledger
EXEC SQL UPDATE ac_ledger
SET hold_yn = :h_hold, upd_ts = now()
WHERE key = :h_key;

View file

@ -154,7 +154,7 @@ TX_SERVICE(AC_OL_0032, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_appr_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 60 "app/online/ac_ol_0032.pgc"
#line 59 "app/online/ac_ol_0032.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -188,7 +188,7 @@ TX_SERVICE(AC_OL_0032, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 89 "app/online/ac_ol_0032.pgc"
#line 87 "app/online/ac_ol_0032.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {

View file

@ -52,8 +52,7 @@ TX_SERVICE(AC_OL_0032, ctx)
h_status_done[sizeof(h_status_done) - 1] = '\0';
/* ---- 2. 신규 승인번호 유효성 확인 (정상승인 건만 매핑 허용) ---- */
EXEC SQL
SELECT amount
EXEC SQL SELECT amount
INTO :h_appr_amount
FROM approval
WHERE approval_no = :h_new_appr
@ -83,8 +82,7 @@ TX_SERVICE(AC_OL_0032, ctx)
return;
}
EXEC SQL
UPDATE ac_ledger
EXEC SQL UPDATE ac_ledger
SET approval_no = :h_new_appr, status = :h_status_done, upd_ts = now()
WHERE key = :h_key;

View file

@ -10,13 +10,15 @@
/*
* au_ol_0001.pgc - (AU_OL_0001) [tier=easy]
*
* TxCore TX_SERVICE . TXBUF au DBIO
* TXBUF . (ATMI void SVC(TPSVCINFO*) )
* (KEY) ,
* (au_limit) / SQL
* (avail = daily_limit - used_amt) . ( )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "au_core.h"
@ -89,13 +91,32 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 15 "app/online/au_ol_0001.pgc"
#line 17 "app/online/au_ol_0001.pgc"
TX_SERVICE(AU_OL_0001, ctx)
{
/* exec sql begin declare section */
#line 22 "app/online/au_ol_0001.pgc"
char h_merch_id [ 16 ] ;
#line 23 "app/online/au_ol_0001.pgc"
long h_daily_limit ;
#line 24 "app/online/au_ol_0001.pgc"
long h_used_amt ;
/* exec sql end declare section */
#line 25 "app/online/au_ol_0001.pgc"
au_rec_t rec;
char key[16];
char avail_won[32];
long avail;
int rc;
tx_log(TX_LOG_INFO, "[AU_OL_0001] 승인한도 단건조회 서비스 진입");
@ -115,11 +136,46 @@ TX_SERVICE(AU_OL_0001, ctx)
return;
}
/* 가맹점 승인한도 마스터 조회 (임베디드 SQL) */
strncpy(h_merch_id, rec.merch_id, sizeof(h_merch_id) - 1);
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
h_daily_limit = 0;
h_used_amt = 0;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select daily_limit , used_amt from au_limit where merch_id = $1 ",
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_daily_limit),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_used_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 59 "app/online/au_ol_0001.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[AU_OL_0001] 한도마스터 미등록 merch=%s", rec.merch_id);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("SELECT au_limit");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
avail = h_daily_limit - h_used_amt;
if (avail < 0)
avail = 0;
amount_format_won(avail, avail_won, sizeof(avail_won));
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "KEY", rec.key);
tx_buf_sets(ctx->out, "MERCHID", rec.merch_id);
tx_buf_setlong(ctx->out, "AMOUNT", rec.amount);
tx_buf_sets(ctx->out, "STATUS", rec.status);
tx_log(TX_LOG_INFO, "[AU_OL_0001] 조회완료 key=%s amount=%ld", key, rec.amount);
tx_buf_setlong(ctx->out, "DAILYLIMIT", h_daily_limit);
tx_buf_setlong(ctx->out, "USEDAMT", h_used_amt);
tx_buf_setlong(ctx->out, "AVAIL", avail);
tx_buf_sets(ctx->out, "AVAILWON", avail_won);
tx_log(TX_LOG_INFO, "[AU_OL_0001] 조회완료 key=%s amount=%ld 가용한도=%ld",
key, rec.amount, avail);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -2,13 +2,15 @@
/*
* au_ol_0001.pgc - 승인한도 온라인 서비스 (AU_OL_0001) [tier=easy]
*
* TxCore TX_SERVICE 엔트리. 요청 TXBUF 를 검증하고 au 표준 DBIO 를
* 통해 처리한 뒤 응답 TXBUF 를 구성한다. (ATMI void SVC(TPSVCINFO*) 대응)
* 처리키(KEY)로 승인원장을 조회하고, 해당 가맹점의 승인한도 마스터
* (au_limit)에서 일한도/기사용액을 임베디드 SQL 로 읽어 가용한도
* (avail = daily_limit - used_amt)를 산출해 함께 응답한다. (조회 전용)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "au_core.h"
@ -16,8 +18,16 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(AU_OL_0001, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_merch_id[16];
long h_daily_limit;
long h_used_amt;
EXEC SQL END DECLARE SECTION;
au_rec_t rec;
char key[16];
char avail_won[32];
long avail;
int rc;
tx_log(TX_LOG_INFO, "[AU_OL_0001] 승인한도 단건조회 서비스 진입");
@ -37,11 +47,41 @@ TX_SERVICE(AU_OL_0001, ctx)
return;
}
/* 가맹점 승인한도 마스터 조회 (임베디드 SQL) */
strncpy(h_merch_id, rec.merch_id, sizeof(h_merch_id) - 1);
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
h_daily_limit = 0;
h_used_amt = 0;
EXEC SQL SELECT daily_limit, used_amt
INTO :h_daily_limit, :h_used_amt
FROM au_limit
WHERE merch_id = :h_merch_id;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[AU_OL_0001] 한도마스터 미등록 merch=%s", rec.merch_id);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("SELECT au_limit");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
avail = h_daily_limit - h_used_amt;
if (avail < 0)
avail = 0;
amount_format_won(avail, avail_won, sizeof(avail_won));
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "KEY", rec.key);
tx_buf_sets(ctx->out, "MERCHID", rec.merch_id);
tx_buf_setlong(ctx->out, "AMOUNT", rec.amount);
tx_buf_sets(ctx->out, "STATUS", rec.status);
tx_log(TX_LOG_INFO, "[AU_OL_0001] 조회완료 key=%s amount=%ld", key, rec.amount);
tx_buf_setlong(ctx->out, "DAILYLIMIT", h_daily_limit);
tx_buf_setlong(ctx->out, "USEDAMT", h_used_amt);
tx_buf_setlong(ctx->out, "AVAIL", avail);
tx_buf_sets(ctx->out, "AVAILWON", avail_won);
tx_log(TX_LOG_INFO, "[AU_OL_0001] 조회완료 key=%s amount=%ld 가용한도=%ld",
key, rec.amount, avail);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -10,8 +10,10 @@
/*
* au_ol_0008.pgc - (tx_call) (AU_OL_0008) [tier=hard]
*
* TxCore TX_SERVICE . TXBUF SQL /
* DBIO / tx_call TXBUF .
* (au_limit) SQL ,
* (au_appr_req) (AU_ISSUER) tx_call
* . (used_amt)
* . .
*/
#include <stdio.h>
#include <string.h>
@ -90,32 +92,116 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 16 "app/online/au_ol_0008.pgc"
#line 18 "app/online/au_ol_0008.pgc"
TX_SERVICE(AU_OL_0008, ctx)
{
char key[16];
if (tx_buf_get(ctx->in, "KEY", key, sizeof(key)) != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] KEY 누락");
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
/* exec sql begin declare section */
#line 23 "app/online/au_ol_0008.pgc"
char h_key [ 16 ] ;
#line 24 "app/online/au_ol_0008.pgc"
char h_merch_id [ 16 ] ;
#line 25 "app/online/au_ol_0008.pgc"
char h_card_no [ 20 ] ;
#line 26 "app/online/au_ol_0008.pgc"
long h_amount ;
#line 27 "app/online/au_ol_0008.pgc"
long h_daily_limit ;
#line 28 "app/online/au_ol_0008.pgc"
long h_used_amt ;
/* exec sql end declare section */
#line 29 "app/online/au_ol_0008.pgc"
TXBUF *req;
char merch[16], card[20], resp[8];
long amount = 0;
char key[16], merch[16], card[20], resp[8];
long amount = 0, avail;
int rc;
tx_log(TX_LOG_INFO, "[AU_OL_0008] 승인요청 중계 진입");
if (tx_buf_get(ctx->in, "MERCHID", merch, sizeof(merch)) != TX_OK ||
if (tx_buf_get(ctx->in, "KEY", key, sizeof(key)) != TX_OK ||
tx_buf_get(ctx->in, "MERCHID", merch, sizeof(merch)) != TX_OK ||
tx_buf_get(ctx->in, "CARDNO", card, sizeof(card)) != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] 필수 필드 누락");
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
tx_buf_getlong(ctx->in, "AMOUNT", &amount);
strncpy(h_key, key, sizeof(h_key) - 1); h_key[sizeof(h_key) - 1] = '\0';
strncpy(h_merch_id, merch, sizeof(h_merch_id) - 1); h_merch_id[sizeof(h_merch_id) - 1] = '\0';
strncpy(h_card_no, card, sizeof(h_card_no) - 1); h_card_no[sizeof(h_card_no) - 1] = '\0';
h_amount = amount;
/* 1) 가맹점 승인한도 확인 */
h_daily_limit = 0;
h_used_amt = 0;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select daily_limit , used_amt from au_limit where merch_id = $1 ",
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_daily_limit),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_used_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 58 "app/online/au_ol_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT au_limit");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
avail = h_daily_limit - h_used_amt;
if (h_daily_limit > 0 && amount > avail) {
tx_log(TX_LOG_WARN, "[AU_OL_0008] 한도초과 merch=%s req=%ld avail=%ld",
merch, amount, avail);
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_INVALID);
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
/* 2) 승인요청 이력행 적재 (요청상태 'Q') */
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] 트랜잭션 시작 실패");
tx_return(ctx, TX_FAIL, ctx->out);
return;
}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into au_appr_req ( req_key , merch_id , card_no , req_amount , req_status ) values ( $1 , $2 , $3 , $4 , 'Q' )",
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_card_no),(long)20,(long)1,(20)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 83 "app/online/au_ol_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT au_appr_req");
tx_abort();
tx_return(ctx, TX_EDB, ctx->out);
return;
}
/* 3) 매입사 중계 (tx_call) */
req = tx_buf_alloc();
if (!req) {
tx_abort();
tx_return(ctx, TX_ENOMEM, ctx->out);
return;
}
@ -129,6 +215,7 @@ TX_SERVICE(AU_OL_0008, ctx)
tx_buf_free(req);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] 매입사 중계 실패 rc=%d(%s)", rc, tx_strerror(rc));
tx_abort();
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_return(ctx, rc, ctx->out);
@ -137,6 +224,37 @@ TX_SERVICE(AU_OL_0008, ctx)
if (tx_buf_get(ctx->out, "RESPCODE", resp, sizeof(resp)) != TX_OK)
strcpy(resp, RESP_OK);
tx_log(TX_LOG_INFO, "[AU_OL_0008] 중계 응답 key=%s resp=%s", key, resp);
/* 4) 승인 성공 시 요청상태 완료 + 기사용액 증액 */
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_appr_req set req_status = 'A' where req_key = $1 ",
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 121 "app/online/au_ol_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE au_appr_req");
tx_abort();
tx_return(ctx, TX_EDB, ctx->out);
return;
}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_limit set used_amt = used_amt + $1 where merch_id = $2 ",
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 131 "app/online/au_ol_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE au_limit used_amt");
tx_abort();
tx_return(ctx, TX_EDB, ctx->out);
return;
}
tx_commit();
tx_log(TX_LOG_INFO, "[AU_OL_0008] 중계 응답 key=%s resp=%s used+=%ld",
key, resp, amount);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -2,8 +2,10 @@
/*
* au_ol_0008.pgc - 승인요청 매입사 중계(tx_call) (AU_OL_0008) [tier=hard]
*
* TxCore TX_SERVICE 엔트리. 요청 TXBUF 를 검증하고 임베디드 SQL / 표준
* DBIO / tx_call 로 처리한 뒤 응답 TXBUF 를 구성한다.
* 요청 승인건에 대해 가맹점 승인한도(au_limit)를 임베디드 SQL 로 확인하고,
* 승인요청 이력행(au_appr_req)을 적재한 뒤 매입사(AU_ISSUER)로 tx_call
* 중계한다. 매입사 승인응답이 정상이면 가맹점 기사용액(used_amt)을 증액
* 반영한다. 원장 반영은 하나의 트랜잭션으로 처리한다.
*/
#include <stdio.h>
#include <string.h>
@ -17,27 +19,79 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(AU_OL_0008, ctx)
{
char key[16];
if (tx_buf_get(ctx->in, "KEY", key, sizeof(key)) != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] KEY 누락");
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
EXEC SQL BEGIN DECLARE SECTION;
char h_key[16];
char h_merch_id[16];
char h_card_no[20];
long h_amount;
long h_daily_limit;
long h_used_amt;
EXEC SQL END DECLARE SECTION;
TXBUF *req;
char merch[16], card[20], resp[8];
long amount = 0;
char key[16], merch[16], card[20], resp[8];
long amount = 0, avail;
int rc;
tx_log(TX_LOG_INFO, "[AU_OL_0008] 승인요청 중계 진입");
if (tx_buf_get(ctx->in, "MERCHID", merch, sizeof(merch)) != TX_OK ||
if (tx_buf_get(ctx->in, "KEY", key, sizeof(key)) != TX_OK ||
tx_buf_get(ctx->in, "MERCHID", merch, sizeof(merch)) != TX_OK ||
tx_buf_get(ctx->in, "CARDNO", card, sizeof(card)) != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] 필수 필드 누락");
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
tx_buf_getlong(ctx->in, "AMOUNT", &amount);
strncpy(h_key, key, sizeof(h_key) - 1); h_key[sizeof(h_key) - 1] = '\0';
strncpy(h_merch_id, merch, sizeof(h_merch_id) - 1); h_merch_id[sizeof(h_merch_id) - 1] = '\0';
strncpy(h_card_no, card, sizeof(h_card_no) - 1); h_card_no[sizeof(h_card_no) - 1] = '\0';
h_amount = amount;
/* 1) 가맹점 승인한도 확인 */
h_daily_limit = 0;
h_used_amt = 0;
EXEC SQL SELECT daily_limit, used_amt
INTO :h_daily_limit, :h_used_amt
FROM au_limit
WHERE merch_id = :h_merch_id;
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT au_limit");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
avail = h_daily_limit - h_used_amt;
if (h_daily_limit > 0 && amount > avail) {
tx_log(TX_LOG_WARN, "[AU_OL_0008] 한도초과 merch=%s req=%ld avail=%ld",
merch, amount, avail);
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_INVALID);
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
/* 2) 승인요청 이력행 적재 (요청상태 'Q') */
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] 트랜잭션 시작 실패");
tx_return(ctx, TX_FAIL, ctx->out);
return;
}
EXEC SQL INSERT INTO au_appr_req
(req_key, merch_id, card_no, req_amount, req_status)
VALUES
(:h_key, :h_merch_id, :h_card_no, :h_amount, 'Q');
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT au_appr_req");
tx_abort();
tx_return(ctx, TX_EDB, ctx->out);
return;
}
/* 3) 매입사 중계 (tx_call) */
req = tx_buf_alloc();
if (!req) {
tx_abort();
tx_return(ctx, TX_ENOMEM, ctx->out);
return;
}
@ -51,6 +105,7 @@ TX_SERVICE(AU_OL_0008, ctx)
tx_buf_free(req);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0008] 매입사 중계 실패 rc=%d(%s)", rc, tx_strerror(rc));
tx_abort();
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_return(ctx, rc, ctx->out);
@ -59,6 +114,31 @@ TX_SERVICE(AU_OL_0008, ctx)
if (tx_buf_get(ctx->out, "RESPCODE", resp, sizeof(resp)) != TX_OK)
strcpy(resp, RESP_OK);
tx_log(TX_LOG_INFO, "[AU_OL_0008] 중계 응답 key=%s resp=%s", key, resp);
/* 4) 승인 성공 시 요청상태 완료 + 기사용액 증액 */
EXEC SQL UPDATE au_appr_req
SET req_status = 'A'
WHERE req_key = :h_key;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE au_appr_req");
tx_abort();
tx_return(ctx, TX_EDB, ctx->out);
return;
}
EXEC SQL UPDATE au_limit
SET used_amt = used_amt + :h_amount
WHERE merch_id = :h_merch_id;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE au_limit used_amt");
tx_abort();
tx_return(ctx, TX_EDB, ctx->out);
return;
}
tx_commit();
tx_log(TX_LOG_INFO, "[AU_OL_0008] 중계 응답 key=%s resp=%s used+=%ld",
key, resp, amount);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -10,8 +10,10 @@
/*
* au_ol_0009.pgc - fallback( ) (AU_OL_0009) [tier=hard]
*
* TxCore TX_SERVICE . TXBUF SQL /
* DBIO / tx_call TXBUF .
* (au_center) SQL
* (AU_ISSUER), (AU_STANDIN) tx_call .
* tx_call ,
* (au_standin_log) .
*/
#include <stdio.h>
#include <string.h>
@ -90,24 +92,68 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 16 "app/online/au_ol_0009.pgc"
#line 18 "app/online/au_ol_0009.pgc"
TX_SERVICE(AU_OL_0009, ctx)
{
/* exec sql begin declare section */
#line 23 "app/online/au_ol_0009.pgc"
char h_center_id [ 8 ] ;
#line 24 "app/online/au_ol_0009.pgc"
char h_center_status [ 2 ] ;
#line 25 "app/online/au_ol_0009.pgc"
char h_key [ 16 ] ;
#line 26 "app/online/au_ol_0009.pgc"
long h_amount ;
/* exec sql end declare section */
#line 27 "app/online/au_ol_0009.pgc"
TXBUF *req;
char key[16];
long amount = 0;
int rc, standin = 0, primary_down;
tx_log(TX_LOG_INFO, "[AU_OL_0009] 대행승인 fallback 진입");
if (tx_buf_get(ctx->in, "KEY", key, sizeof(key)) != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0009] KEY 누락");
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
TXBUF *req;
long amount = 0;
int rc;
tx_log(TX_LOG_INFO, "[AU_OL_0009] 대행승인 fallback 진입");
tx_buf_getlong(ctx->in, "AMOUNT", &amount);
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
h_amount = amount;
/* 주센터 가동상태 조회 (center_id='PRIMARY') */
strcpy(h_center_id, "PRIMARY");
strcpy(h_center_status, "U");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select center_status from au_center where center_id = $1 ",
ECPGt_char,(h_center_id),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_center_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 53 "app/online/au_ol_0009.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT au_center");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
/* 상태 'U'(Up)=정상, 그 외는 장애로 간주 */
primary_down = (strncmp(h_center_status, "U", 1) != 0);
req = tx_buf_alloc();
if (!req) {
tx_return(ctx, TX_ENOMEM, ctx->out);
@ -116,15 +162,22 @@ TX_SERVICE(AU_OL_0009, ctx)
tx_buf_sets(req, "KEY", key);
tx_buf_setlong(req, "AMOUNT", amount);
rc = tx_call("AU_ISSUER", req, ctx->out);
if (rc != TX_OK) {
tx_log(TX_LOG_WARN, "[AU_OL_0009] 주센터 실패 rc=%d, 대행센터 전환", rc);
if (!primary_down) {
rc = tx_call("AU_ISSUER", req, ctx->out);
if (rc != TX_OK) {
tx_log(TX_LOG_WARN, "[AU_OL_0009] 주센터 응답실패 rc=%d, 대행 전환", rc);
primary_down = 1;
}
} else {
rc = TX_FAIL;
tx_log(TX_LOG_WARN, "[AU_OL_0009] 주센터 장애(status=%s), 대행 전환",
h_center_status);
}
if (primary_down) {
tx_buf_reset(ctx->out);
rc = tx_call("AU_STANDIN", req, ctx->out);
if (rc == TX_OK)
tx_buf_sets(ctx->out, "STANDIN", "Y");
} else {
tx_buf_sets(ctx->out, "STANDIN", "N");
standin = (rc == TX_OK);
}
tx_buf_free(req);
@ -134,6 +187,31 @@ TX_SERVICE(AU_OL_0009, ctx)
tx_return(ctx, rc, ctx->out);
return;
}
tx_log(TX_LOG_INFO, "[AU_OL_0009] fallback 처리완료 key=%s", key);
tx_buf_sets(ctx->out, "STANDIN", standin ? "Y" : "N");
/* 대행 처리분은 이력에 기록 */
if (standin) {
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[AU_OL_0009] tx_begin 경고");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into au_standin_log ( req_key , req_amount , center_status ) values ( $1 , $2 , $3 )",
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_center_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 105 "app/online/au_ol_0009.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT au_standin_log");
tx_abort();
} else {
tx_commit();
}
}
tx_log(TX_LOG_INFO, "[AU_OL_0009] fallback 처리완료 key=%s standin=%s",
key, standin ? "Y" : "N");
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -2,8 +2,10 @@
/*
* au_ol_0009.pgc - 대행승인 fallback(주센터 실패시 백업) (AU_OL_0009) [tier=hard]
*
* TxCore TX_SERVICE 엔트리. 요청 TXBUF 를 검증하고 임베디드 SQL / 표준
* DBIO / tx_call 로 처리한 뒤 응답 TXBUF 를 구성한다.
* 주센터(au_center) 가동상태를 임베디드 SQL 로 확인해 정상이면 주센터
* (AU_ISSUER)로, 장애면 곧바로 대행센터(AU_STANDIN)로 tx_call 한다.
* 주센터 tx_call 이 실패해도 대행센터로 전환하며, 대행 처리분은
* 대행승인 이력(au_standin_log)에 기록한다.
*/
#include <stdio.h>
#include <string.h>
@ -17,19 +19,46 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(AU_OL_0009, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_center_id[8];
char h_center_status[2];
char h_key[16];
long h_amount;
EXEC SQL END DECLARE SECTION;
TXBUF *req;
char key[16];
long amount = 0;
int rc, standin = 0, primary_down;
tx_log(TX_LOG_INFO, "[AU_OL_0009] 대행승인 fallback 진입");
if (tx_buf_get(ctx->in, "KEY", key, sizeof(key)) != TX_OK) {
tx_log(TX_LOG_ERROR, "[AU_OL_0009] KEY 누락");
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
TXBUF *req;
long amount = 0;
int rc;
tx_log(TX_LOG_INFO, "[AU_OL_0009] 대행승인 fallback 진입");
tx_buf_getlong(ctx->in, "AMOUNT", &amount);
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
h_amount = amount;
/* 주센터 가동상태 조회 (center_id='PRIMARY') */
strcpy(h_center_id, "PRIMARY");
strcpy(h_center_status, "U");
EXEC SQL SELECT center_status
INTO :h_center_status
FROM au_center
WHERE center_id = :h_center_id;
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT au_center");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
/* 상태 'U'(Up)=정상, 그 외는 장애로 간주 */
primary_down = (strncmp(h_center_status, "U", 1) != 0);
req = tx_buf_alloc();
if (!req) {
tx_return(ctx, TX_ENOMEM, ctx->out);
@ -38,15 +67,22 @@ TX_SERVICE(AU_OL_0009, ctx)
tx_buf_sets(req, "KEY", key);
tx_buf_setlong(req, "AMOUNT", amount);
rc = tx_call("AU_ISSUER", req, ctx->out);
if (rc != TX_OK) {
tx_log(TX_LOG_WARN, "[AU_OL_0009] 주센터 실패 rc=%d, 대행센터 전환", rc);
if (!primary_down) {
rc = tx_call("AU_ISSUER", req, ctx->out);
if (rc != TX_OK) {
tx_log(TX_LOG_WARN, "[AU_OL_0009] 주센터 응답실패 rc=%d, 대행 전환", rc);
primary_down = 1;
}
} else {
rc = TX_FAIL;
tx_log(TX_LOG_WARN, "[AU_OL_0009] 주센터 장애(status=%s), 대행 전환",
h_center_status);
}
if (primary_down) {
tx_buf_reset(ctx->out);
rc = tx_call("AU_STANDIN", req, ctx->out);
if (rc == TX_OK)
tx_buf_sets(ctx->out, "STANDIN", "Y");
} else {
tx_buf_sets(ctx->out, "STANDIN", "N");
standin = (rc == TX_OK);
}
tx_buf_free(req);
@ -56,6 +92,26 @@ TX_SERVICE(AU_OL_0009, ctx)
tx_return(ctx, rc, ctx->out);
return;
}
tx_log(TX_LOG_INFO, "[AU_OL_0009] fallback 처리완료 key=%s", key);
tx_buf_sets(ctx->out, "STANDIN", standin ? "Y" : "N");
/* 대행 처리분은 이력에 기록 */
if (standin) {
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[AU_OL_0009] tx_begin 경고");
EXEC SQL INSERT INTO au_standin_log
(req_key, req_amount, center_status)
VALUES
(:h_key, :h_amount, :h_center_status);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT au_standin_log");
tx_abort();
} else {
tx_commit();
}
}
tx_log(TX_LOG_INFO, "[AU_OL_0009] fallback 처리완료 key=%s standin=%s",
key, standin ? "Y" : "N");
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -12,11 +12,14 @@
*
* TxCore TX_SERVICE . TXBUF cl DBIO
* TXBUF . (ATMI void SVC(TPSVCINFO*) )
* (//)
* cl_ledger SELECT .
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cl_core.h"
@ -89,11 +92,32 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 15 "app/online/cl_ol_0001.pgc"
#line 18 "app/online/cl_ol_0001.pgc"
TX_SERVICE(CL_OL_0001, ctx)
{
/* exec sql begin declare section */
#line 23 "app/online/cl_ol_0001.pgc"
char h_key [ 16 ] ;
#line 24 "app/online/cl_ol_0001.pgc"
char h_card_no [ 24 ] ;
#line 25 "app/online/cl_ol_0001.pgc"
long h_fee ;
#line 26 "app/online/cl_ol_0001.pgc"
char h_upd_ts [ 24 ] ;
/* exec sql end declare section */
#line 27 "app/online/cl_ol_0001.pgc"
cl_rec_t rec;
char key[16];
int rc;
@ -115,11 +139,42 @@ TX_SERVICE(CL_OL_0001, ctx)
return;
}
/* 원장 확장필드 직접 조회 (카드번호/수수료/최종반영시각) */
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
h_card_no[0] = '\0';
h_upd_ts[0] = '\0';
h_fee = 0;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select card_no , fee , to_char ( upd_ts , 'YYYYMMDDHH24MISS' ) from cl_ledger where key = $1 ",
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_card_no),(long)24,(long)1,(24)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_upd_ts),(long)24,(long)1,(24)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 60 "app/online/cl_ol_0001.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[CL_OL_0001] 확장필드 원장 없음 key=%s", key);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0001 SELECT cl_ledger ext");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "KEY", rec.key);
tx_buf_sets(ctx->out, "MERCHID", rec.merch_id);
tx_buf_setlong(ctx->out, "AMOUNT", rec.amount);
tx_buf_sets(ctx->out, "STATUS", rec.status);
tx_log(TX_LOG_INFO, "[CL_OL_0001] 조회완료 key=%s amount=%ld", key, rec.amount);
tx_buf_sets(ctx->out, "CARDNO", h_card_no);
tx_buf_setlong(ctx->out, "FEE", h_fee);
tx_buf_sets(ctx->out, "UPDTS", h_upd_ts);
tx_log(TX_LOG_INFO, "[CL_OL_0001] 조회완료 key=%s amount=%ld fee=%ld",
key, rec.amount, h_fee);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,11 +4,14 @@
*
* TxCore TX_SERVICE 엔트리. 요청 TXBUF 를 검증하고 cl 표준 DBIO 를
* 통해 처리한 뒤 응답 TXBUF 를 구성한다. (ATMI void SVC(TPSVCINFO*) 대응)
* 단건 조회 결과에 더해 원장 확장필드(카드번호/수수료/최종반영시각)를
* cl_ledger 에서 직접 SELECT 하여 응답에 실어 감사표시를 지원한다.
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cl_core.h"
@ -16,6 +19,13 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CL_OL_0001, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_key[16];
char h_card_no[24];
long h_fee;
char h_upd_ts[24];
EXEC SQL END DECLARE SECTION;
cl_rec_t rec;
char key[16];
int rc;
@ -37,11 +47,35 @@ TX_SERVICE(CL_OL_0001, ctx)
return;
}
/* 원장 확장필드 직접 조회 (카드번호/수수료/최종반영시각) */
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
h_card_no[0] = '\0';
h_upd_ts[0] = '\0';
h_fee = 0;
EXEC SQL SELECT card_no, fee, to_char(upd_ts, 'YYYYMMDDHH24MISS')
INTO :h_card_no, :h_fee, :h_upd_ts
FROM cl_ledger
WHERE key = :h_key;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[CL_OL_0001] 확장필드 원장 없음 key=%s", key);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0001 SELECT cl_ledger ext");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "KEY", rec.key);
tx_buf_sets(ctx->out, "MERCHID", rec.merch_id);
tx_buf_setlong(ctx->out, "AMOUNT", rec.amount);
tx_buf_sets(ctx->out, "STATUS", rec.status);
tx_log(TX_LOG_INFO, "[CL_OL_0001] 조회완료 key=%s amount=%ld", key, rec.amount);
tx_buf_sets(ctx->out, "CARDNO", h_card_no);
tx_buf_setlong(ctx->out, "FEE", h_fee);
tx_buf_sets(ctx->out, "UPDTS", h_upd_ts);
tx_log(TX_LOG_INFO, "[CL_OL_0001] 조회완료 key=%s amount=%ld fee=%ld",
key, rec.amount, h_fee);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -12,7 +12,8 @@
*
* . (KEY) DBIO cl_rec_select
* , // (status='S')
* . (read-only )
* . · /
* cl_ledger (SELECT) .
*
* (Contract)
* :
@ -27,6 +28,8 @@
* STATUS (R/M/U/S)
* STATUSLABEL (///)
* CLOSED (Y= S / N= )
* SIBLINGCNT ·
* SIBLINGSUM ·
*
*
* R() M() S(/)
@ -37,12 +40,14 @@
* 1) TXBUF KEY
* 2) cl_rec_select ( RESP_INVALID)
* 3) status CL_ST_* /
* 4) TXBUF tx_return
* 4) · SELECT
* 5) TXBUF tx_return
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cl_core.h"
@ -115,11 +120,32 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 41 "app/online/cl_ol_0015.pgc"
#line 46 "app/online/cl_ol_0015.pgc"
TX_SERVICE(CL_OL_0015, ctx)
{
/* exec sql begin declare section */
#line 51 "app/online/cl_ol_0015.pgc"
char h_merch_id [ 16 ] ;
#line 52 "app/online/cl_ol_0015.pgc"
char h_biz_date [ 9 ] ;
#line 53 "app/online/cl_ol_0015.pgc"
long h_sib_cnt ;
#line 54 "app/online/cl_ol_0015.pgc"
long h_sib_sum ;
/* exec sql end declare section */
#line 55 "app/online/cl_ol_0015.pgc"
cl_rec_t rec;
char key[16];
char won[40];
@ -171,7 +197,33 @@ TX_SERVICE(CL_OL_0015, ctx)
/* 4. 스냅샷 요약행 여부 판정 (merch_id='*SNAP' 규약) */
is_snap = (strcmp(rec.merch_id, "*SNAP") == 0);
/* 5. 응답 구성 */
/* 5. 동일 가맹점·동일 영업일 형제 거래 집계 (read-only 맥락) */
strncpy(h_merch_id, rec.merch_id, sizeof(h_merch_id) - 1);
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
strncpy(h_biz_date, rec.biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
h_sib_cnt = 0;
h_sib_sum = 0;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) from cl_ledger where merch_id = $1 and biz_date = $2 ",
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_sib_cnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sib_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 120 "app/online/cl_ol_0015.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CL_OL_0015 sibling aggregate");
h_sib_cnt = 0;
h_sib_sum = 0;
}
/* 6. 응답 구성 */
amount_format_won(rec.amount, won, sizeof(won));
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_OK);
@ -185,15 +237,17 @@ TX_SERVICE(CL_OL_0015, ctx)
tx_buf_sets(ctx->out, "STATUSLABEL", st_label);
tx_buf_sets(ctx->out, "CLOSED", is_settled ? "Y" : "N");
tx_buf_sets(ctx->out, "SNAPSHOT", is_snap ? "Y" : "N");
tx_buf_setlong(ctx->out, "SIBLINGCNT", h_sib_cnt);
tx_buf_setlong(ctx->out, "SIBLINGSUM", h_sib_sum);
/* 6. 스냅샷 요약행은 집계행이므로 별도 안내 로깅 */
/* 7. 스냅샷 요약행은 집계행이므로 별도 안내 로깅 */
if (is_snap)
tx_log(TX_LOG_INFO,
"[CL_OL_0015] 스냅샷 요약행 조회 key=%s biz=%s Σ=%ld",
rec.key, rec.biz_date, rec.amount);
tx_log(TX_LOG_INFO,
"[CL_OL_0015] 상태조회 key=%s status=%s(%s) 마감여부=%s",
rec.key, rec.status, st_label, is_settled ? "Y" : "N");
"[CL_OL_0015] 상태조회 key=%s status=%s(%s) 마감여부=%s 형제=%ld건",
rec.key, rec.status, st_label, is_settled ? "Y" : "N", h_sib_cnt);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,7 +4,8 @@
*
* 마감 상태조회. 요청 처리키(KEY) 단건에 대해 표준 DBIO cl_rec_select 로
* 원장 레코드를 읽어, 상태코드/금액/영업일과 함께 마감여부(status='S')를
* 판정하여 응답한다. (read-only 단건 판정)
* 판정하여 응답한다. 아울러 동일 가맹점·동일 영업일의 형제 거래 건수/
* 금액합계를 cl_ledger 에서 직접 집계(SELECT)하여 맥락을 함께 제공한다.
*
* ── 서비스 계약(Contract) ────────────────────────────────────────────
* 입력 필드:
@ -19,6 +20,8 @@
* STATUS 상태코드(R/M/U/S)
* STATUSLABEL 상태 한글 라벨(접수/처리완료/불일치/정산완료)
* CLOSED 마감여부(Y=정산완료 S / N=그 외)
* SIBLINGCNT 동일 가맹점·영업일 형제 거래 건수
* SIBLINGSUM 동일 가맹점·영업일 형제 거래 금액합계
*
* ── 상태코드 정의 ────────────────────────────────────────────────────
* R(접수) → M(처리완료) → S(정산완료/마감확정)
@ -29,12 +32,14 @@
* 1) 요청 TXBUF 에서 KEY 추출 및 필수검증
* 2) cl_rec_select 로 단건 원장 조회 (없으면 RESP_INVALID)
* 3) status 를 CL_ST_* 상수와 비교하여 라벨/마감여부 산출
* 4) 응답 TXBUF 구성 후 tx_return
* 4) 동일 가맹점·영업일 형제 집계 SELECT
* 5) 응답 TXBUF 구성 후 tx_return
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cl_core.h"
@ -42,6 +47,13 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CL_OL_0015, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_merch_id[16];
char h_biz_date[9];
long h_sib_cnt;
long h_sib_sum;
EXEC SQL END DECLARE SECTION;
cl_rec_t rec;
char key[16];
char won[40];
@ -93,7 +105,27 @@ TX_SERVICE(CL_OL_0015, ctx)
/* 4. 스냅샷 요약행 여부 판정 (merch_id='*SNAP' 규약) */
is_snap = (strcmp(rec.merch_id, "*SNAP") == 0);
/* 5. 응답 구성 */
/* 5. 동일 가맹점·동일 영업일 형제 거래 집계 (read-only 맥락) */
strncpy(h_merch_id, rec.merch_id, sizeof(h_merch_id) - 1);
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
strncpy(h_biz_date, rec.biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
h_sib_cnt = 0;
h_sib_sum = 0;
EXEC SQL SELECT count(*), coalesce(sum(amount), 0)
INTO :h_sib_cnt, :h_sib_sum
FROM cl_ledger
WHERE merch_id = :h_merch_id
AND biz_date = :h_biz_date;
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CL_OL_0015 sibling aggregate");
h_sib_cnt = 0;
h_sib_sum = 0;
}
/* 6. 응답 구성 */
amount_format_won(rec.amount, won, sizeof(won));
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_OK);
@ -107,15 +139,17 @@ TX_SERVICE(CL_OL_0015, ctx)
tx_buf_sets(ctx->out, "STATUSLABEL", st_label);
tx_buf_sets(ctx->out, "CLOSED", is_settled ? "Y" : "N");
tx_buf_sets(ctx->out, "SNAPSHOT", is_snap ? "Y" : "N");
tx_buf_setlong(ctx->out, "SIBLINGCNT", h_sib_cnt);
tx_buf_setlong(ctx->out, "SIBLINGSUM", h_sib_sum);
/* 6. 스냅샷 요약행은 집계행이므로 별도 안내 로깅 */
/* 7. 스냅샷 요약행은 집계행이므로 별도 안내 로깅 */
if (is_snap)
tx_log(TX_LOG_INFO,
"[CL_OL_0015] 스냅샷 요약행 조회 key=%s biz=%s Σ=%ld",
rec.key, rec.biz_date, rec.amount);
tx_log(TX_LOG_INFO,
"[CL_OL_0015] 상태조회 key=%s status=%s(%s) 마감여부=%s",
rec.key, rec.status, st_label, is_settled ? "Y" : "N");
"[CL_OL_0015] 상태조회 key=%s status=%s(%s) 마감여부=%s 형제=%ld건",
rec.key, rec.status, st_label, is_settled ? "Y" : "N", h_sib_cnt);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -104,6 +104,23 @@ struct sqlca_t *ECPGget_sqlca(void);
TX_SERVICE(CL_OL_0017, ctx)
{
/* exec sql begin declare section */
#line 30 "app/online/cl_ol_0017.pgc"
char h_biz_date [ 9 ] ;
#line 31 "app/online/cl_ol_0017.pgc"
long h_db_total ;
#line 32 "app/online/cl_ol_0017.pgc"
long h_db_amt ;
/* exec sql end declare section */
#line 33 "app/online/cl_ol_0017.pgc"
char bizdate[16];
char reqid[32];
char oper[32];
@ -111,6 +128,7 @@ TX_SERVICE(CL_OL_0017, ctx)
char summary[TX_VAL_LEN];
long recv_cnt, done_cnt, fail_cnt, settled_cnt;
long total_cnt, processed_cnt, complete_rate;
long db_diff;
int valid;
tx_log(TX_LOG_INFO, "[CL_OL_0017] 일마감 검증 서비스 진입");
@ -155,6 +173,38 @@ TX_SERVICE(CL_OL_0017, ctx)
}
total_cnt = recv_cnt + done_cnt + fail_cnt + settled_cnt;
/*
* 3-1) DBIO .
* DBIO (total_cnt) (h_db_total)
* .
*/
strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
h_db_total = 0;
h_db_amt = 0;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) from cl_ledger where biz_date = $1 ",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_db_total),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_db_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 100 "app/online/cl_ol_0017.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CL_OL_0017 direct total");
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_return(ctx, TX_EDB, ctx->out);
return;
}
db_diff = total_cnt - h_db_total;
if (db_diff != 0)
tx_log(TX_LOG_WARN, "[CL_OL_0017] 집계 대사 불일치 dbio=%ld ledger=%ld",
total_cnt, h_db_total);
/* 4) 일마감 유효성 판정: 미마감 잔량이 0 이어야 유효 */
valid = (recv_cnt == 0) ? 1 : 0;
@ -184,6 +234,10 @@ TX_SERVICE(CL_OL_0017, ctx)
tx_buf_setlong(ctx->out, "FAILCNT", fail_cnt);
tx_buf_setlong(ctx->out, "SETTLEDCNT", settled_cnt);
tx_buf_setlong(ctx->out, "TOTALCNT", total_cnt);
tx_buf_setlong(ctx->out, "DBTOTAL", h_db_total);
tx_buf_setlong(ctx->out, "DBAMT", h_db_amt);
tx_buf_setlong(ctx->out, "DBDIFF", db_diff);
tx_buf_sets(ctx->out, "RECONMATCH", (db_diff == 0) ? "Y" : "N");
tx_buf_setlong(ctx->out, "PROCESSEDCNT", processed_cnt);
tx_buf_setlong(ctx->out, "COMPLETERATE", complete_rate);
tx_buf_sets(ctx->out, "NEXTBIZ", nextbiz);

View file

@ -26,6 +26,12 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CL_OL_0017, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9];
long h_db_total;
long h_db_amt;
EXEC SQL END DECLARE SECTION;
char bizdate[16];
char reqid[32];
char oper[32];
@ -33,6 +39,7 @@ TX_SERVICE(CL_OL_0017, ctx)
char summary[TX_VAL_LEN];
long recv_cnt, done_cnt, fail_cnt, settled_cnt;
long total_cnt, processed_cnt, complete_rate;
long db_diff;
int valid;
tx_log(TX_LOG_INFO, "[CL_OL_0017] 일마감 검증 서비스 진입");
@ -77,6 +84,33 @@ TX_SERVICE(CL_OL_0017, ctx)
}
total_cnt = recv_cnt + done_cnt + fail_cnt + settled_cnt;
/*
* 3-1) 원장 직접 집계로 상태별 DBIO 합계를 교차검증한다.
* DBIO 채널 합계(total_cnt)와 원장 실집계(h_db_total)가
* 다르면 대사 불일치로 간주하여 감사 로그를 남긴다.
*/
strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
h_db_total = 0;
h_db_amt = 0;
EXEC SQL SELECT count(*), coalesce(sum(amount), 0)
INTO :h_db_total, :h_db_amt
FROM cl_ledger
WHERE biz_date = :h_biz_date;
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CL_OL_0017 direct total");
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_return(ctx, TX_EDB, ctx->out);
return;
}
db_diff = total_cnt - h_db_total;
if (db_diff != 0)
tx_log(TX_LOG_WARN, "[CL_OL_0017] 집계 대사 불일치 dbio=%ld ledger=%ld",
total_cnt, h_db_total);
/* 4) 일마감 유효성 판정: 미마감 잔량이 0 이어야 유효 */
valid = (recv_cnt == 0) ? 1 : 0;
@ -106,6 +140,10 @@ TX_SERVICE(CL_OL_0017, ctx)
tx_buf_setlong(ctx->out, "FAILCNT", fail_cnt);
tx_buf_setlong(ctx->out, "SETTLEDCNT", settled_cnt);
tx_buf_setlong(ctx->out, "TOTALCNT", total_cnt);
tx_buf_setlong(ctx->out, "DBTOTAL", h_db_total);
tx_buf_setlong(ctx->out, "DBAMT", h_db_amt);
tx_buf_setlong(ctx->out, "DBDIFF", db_diff);
tx_buf_sets(ctx->out, "RECONMATCH", (db_diff == 0) ? "Y" : "N");
tx_buf_setlong(ctx->out, "PROCESSEDCNT", processed_cnt);
tx_buf_setlong(ctx->out, "COMPLETERATE", complete_rate);
tx_buf_sets(ctx->out, "NEXTBIZ", nextbiz);

View file

@ -101,6 +101,31 @@ struct sqlca_t *ECPGget_sqlca(void);
TX_SERVICE(CL_OL_0019, ctx)
{
/* exec sql begin declare section */
#line 27 "app/online/cl_ol_0019.pgc"
char h_key [ 16 ] ;
#line 28 "app/online/cl_ol_0019.pgc"
char h_prev_st [ 2 ] ;
#line 29 "app/online/cl_ol_0019.pgc"
char h_new_st [ 2 ] ;
#line 30 "app/online/cl_ol_0019.pgc"
char h_oper [ 32 ] ;
#line 31 "app/online/cl_ol_0019.pgc"
char h_reqid [ 32 ] ;
/* exec sql end declare section */
#line 32 "app/online/cl_ol_0019.pgc"
cl_rec_t rec;
char key[16];
char reqid[32];
@ -181,6 +206,40 @@ TX_SERVICE(CL_OL_0019, ctx)
return;
}
/* 취소 승인 감사이력 적재 (동일 트랜잭션) */
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
strncpy(h_prev_st, CL_ST_FAIL, sizeof(h_prev_st));
strncpy(h_new_st, CL_ST_DONE, sizeof(h_new_st));
strncpy(h_oper, oper, sizeof(h_oper) - 1);
h_oper[sizeof(h_oper) - 1] = '\0';
strncpy(h_reqid, reqid, sizeof(h_reqid) - 1);
h_reqid[sizeof(h_reqid) - 1] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into cl_cancel_audit ( key , prev_status , new_status , oper , reqid , chg_ts ) values ( $1 , $2 , $3 , $4 , $5 , now ( ) )",
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_prev_st),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_new_st),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_oper),(long)32,(long)1,(32)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_reqid),(long)32,(long)1,(32)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 126 "app/online/cl_ol_0019.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0019 INSERT cl_cancel_audit");
tx_abort();
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_buf_sets(ctx->out, "APPROVED", "N");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
tx_commit();
/* 5) 승인 결과 응답 (원거래 요약 포함) */

View file

@ -23,6 +23,14 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CL_OL_0019, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_key[16];
char h_prev_st[2];
char h_new_st[2];
char h_oper[32];
char h_reqid[32];
EXEC SQL END DECLARE SECTION;
cl_rec_t rec;
char key[16];
char reqid[32];
@ -103,6 +111,30 @@ TX_SERVICE(CL_OL_0019, ctx)
return;
}
/* 취소 승인 감사이력 적재 (동일 트랜잭션) */
strncpy(h_key, key, sizeof(h_key) - 1);
h_key[sizeof(h_key) - 1] = '\0';
strncpy(h_prev_st, CL_ST_FAIL, sizeof(h_prev_st));
strncpy(h_new_st, CL_ST_DONE, sizeof(h_new_st));
strncpy(h_oper, oper, sizeof(h_oper) - 1);
h_oper[sizeof(h_oper) - 1] = '\0';
strncpy(h_reqid, reqid, sizeof(h_reqid) - 1);
h_reqid[sizeof(h_reqid) - 1] = '\0';
EXEC SQL INSERT INTO cl_cancel_audit
(key, prev_status, new_status, oper, reqid, chg_ts)
VALUES (:h_key, :h_prev_st, :h_new_st, :h_oper, :h_reqid, now());
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0019 INSERT cl_cancel_audit");
tx_abort();
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_buf_sets(ctx->out, "APPROVED", "N");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
tx_commit();
/* 5) 승인 결과 응답 (원거래 요약 포함) */

View file

@ -106,6 +106,27 @@ struct sqlca_t *ECPGget_sqlca(void);
TX_SERVICE(CL_OL_0023, ctx)
{
/* exec sql begin declare section */
#line 32 "app/online/cl_ol_0023.pgc"
char h_biz_date [ 9 ] ;
#line 33 "app/online/cl_ol_0023.pgc"
char h_st_done [ 2 ] ;
#line 34 "app/online/cl_ol_0023.pgc"
long h_db_used ;
#line 35 "app/online/cl_ol_0023.pgc"
char h_max_key [ 16 ] ;
/* exec sql end declare section */
#line 36 "app/online/cl_ol_0023.pgc"
char bizdate[16];
char reqid[32];
char channel[16];
@ -164,6 +185,36 @@ TX_SERVICE(CL_OL_0023, ctx)
* - (avail) (cap)
* 0 .
*/
/*
* 2-1) ( M) ,
* .
*/
strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_st_done, CL_ST_DONE, sizeof(h_st_done));
h_db_used = 0;
h_max_key[0] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( max ( key ) , '' ) from cl_ledger where biz_date = $1 and status = $2 ",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_st_done),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_db_used),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_max_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 110 "app/online/cl_ol_0023.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CL_OL_0023 direct used");
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_return(ctx, TX_EDB, ctx->out);
return;
}
next_no = done_cnt + 1;
avail = (cap > done_cnt) ? (cap - done_cnt) : 0;
usage_rate = (cap > 0) ? (done_cnt * 100 / cap) : 0;
@ -180,6 +231,8 @@ TX_SERVICE(CL_OL_0023, ctx)
tx_buf_sets(ctx->out, "REQID", reqid);
tx_buf_sets(ctx->out, "CHANNEL", channel);
tx_buf_setlong(ctx->out, "USEDCNT", done_cnt);
tx_buf_setlong(ctx->out, "DBUSED", h_db_used);
tx_buf_sets(ctx->out, "MAXKEY", h_max_key);
tx_buf_setlong(ctx->out, "RECVCNT", recv_cnt);
tx_buf_setlong(ctx->out, "SETTLEDCNT", settled_cnt);
tx_buf_setlong(ctx->out, "CAP", cap);

View file

@ -28,6 +28,13 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CL_OL_0023, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9];
char h_st_done[2];
long h_db_used;
char h_max_key[16];
EXEC SQL END DECLARE SECTION;
char bizdate[16];
char reqid[32];
char channel[16];
@ -86,6 +93,30 @@ TX_SERVICE(CL_OL_0023, ctx)
* - 가용 여력(avail)은 일 상한(cap)에서 소진수를 뺀 값이며
* 음수가 되지 않도록 0 하한으로 보정한다.
*/
/*
* 2-1) 원장 직접 집계로 소진수(마감완료 M)를 재확인하고, 이미 발급된
* 최대 처리키를 조회하여 채번 연속성의 근거로 삼는다.
*/
strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_st_done, CL_ST_DONE, sizeof(h_st_done));
h_db_used = 0;
h_max_key[0] = '\0';
EXEC SQL SELECT count(*), coalesce(max(key), '')
INTO :h_db_used, :h_max_key
FROM cl_ledger
WHERE biz_date = :h_biz_date
AND status = :h_st_done;
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CL_OL_0023 direct used");
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
tx_return(ctx, TX_EDB, ctx->out);
return;
}
next_no = done_cnt + 1;
avail = (cap > done_cnt) ? (cap - done_cnt) : 0;
usage_rate = (cap > 0) ? (done_cnt * 100 / cap) : 0;
@ -102,6 +133,8 @@ TX_SERVICE(CL_OL_0023, ctx)
tx_buf_sets(ctx->out, "REQID", reqid);
tx_buf_sets(ctx->out, "CHANNEL", channel);
tx_buf_setlong(ctx->out, "USEDCNT", done_cnt);
tx_buf_setlong(ctx->out, "DBUSED", h_db_used);
tx_buf_sets(ctx->out, "MAXKEY", h_max_key);
tx_buf_setlong(ctx->out, "RECVCNT", recv_cnt);
tx_buf_setlong(ctx->out, "SETTLEDCNT", settled_cnt);
tx_buf_setlong(ctx->out, "CAP", cap);

View file

@ -105,6 +105,39 @@ struct sqlca_t *ECPGget_sqlca(void);
TX_SERVICE(CL_OL_0025, ctx)
{
/* exec sql begin declare section */
#line 31 "app/online/cl_ol_0025.pgc"
char h_biz_date [ 9 ] ;
#line 32 "app/online/cl_ol_0025.pgc"
char h_severity [ 8 ] ;
#line 33 "app/online/cl_ol_0025.pgc"
char h_target [ 32 ] ;
#line 34 "app/online/cl_ol_0025.pgc"
char h_reqid [ 32 ] ;
#line 35 "app/online/cl_ol_0025.pgc"
long h_recv ;
#line 36 "app/online/cl_ol_0025.pgc"
long h_fail ;
#line 37 "app/online/cl_ol_0025.pgc"
char h_alert [ TX_VAL_LEN ] ;
/* exec sql end declare section */
#line 38 "app/online/cl_ol_0025.pgc"
char bizdate[16];
char reqid[32];
char target[32];
@ -112,6 +145,7 @@ TX_SERVICE(CL_OL_0025, ctx)
const char *severity;
long recv_cnt, fail_cnt, settled_cnt, done_cnt;
long pending, total_cnt;
long logged = 0;
int need_alert;
tx_log(TX_LOG_INFO, "[CL_OL_0025] 알림 재발송 서비스 진입");
@ -175,8 +209,58 @@ TX_SERVICE(CL_OL_0025, ctx)
"[마감알림/%s] %s 마감 정상완료(정산완료 %ld건) - 조치 불필요",
severity, bizdate, settled_cnt);
/*
* 4) . cl_alert_log
* , / .
*/
if (need_alert) {
strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_severity, severity, sizeof(h_severity) - 1);
h_severity[sizeof(h_severity) - 1] = '\0';
strncpy(h_target, target, sizeof(h_target) - 1);
h_target[sizeof(h_target) - 1] = '\0';
strncpy(h_reqid, reqid, sizeof(h_reqid) - 1);
h_reqid[sizeof(h_reqid) - 1] = '\0';
strncpy(h_alert, alert, sizeof(h_alert) - 1);
h_alert[sizeof(h_alert) - 1] = '\0';
h_recv = recv_cnt;
h_fail = fail_cnt;
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CL_OL_0025] tx_begin 경고");
} else {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into cl_alert_log ( biz_date , severity , recv_cnt , fail_cnt , target , reqid , alert_msg , sent_ts ) values ( $1 , $2 , $3 , $4 , $5 , $6 , $7 , now ( ) )",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_severity),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_recv),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_fail),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_target),(long)32,(long)1,(32)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_reqid),(long)32,(long)1,(32)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_alert),(long)TX_VAL_LEN,(long)1,(TX_VAL_LEN)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 136 "app/online/cl_ol_0025.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0025 INSERT cl_alert_log");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_OK);
tx_buf_setlong(ctx->out, "LOGGED", logged);
tx_buf_sets(ctx->out, "TYPE", "ALERT");
tx_buf_sets(ctx->out, "BIZDATE", bizdate);
tx_buf_sets(ctx->out, "REQID", reqid);

View file

@ -27,6 +27,16 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CL_OL_0025, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9];
char h_severity[8];
char h_target[32];
char h_reqid[32];
long h_recv;
long h_fail;
char h_alert[TX_VAL_LEN];
EXEC SQL END DECLARE SECTION;
char bizdate[16];
char reqid[32];
char target[32];
@ -34,6 +44,7 @@ TX_SERVICE(CL_OL_0025, ctx)
const char *severity;
long recv_cnt, fail_cnt, settled_cnt, done_cnt;
long pending, total_cnt;
long logged = 0;
int need_alert;
tx_log(TX_LOG_INFO, "[CL_OL_0025] 알림 재발송 서비스 진입");
@ -97,8 +108,46 @@ TX_SERVICE(CL_OL_0025, ctx)
"[마감알림/%s] %s 마감 정상완료(정산완료 %ld건) - 조치 불필요",
severity, bizdate, settled_cnt);
/*
* 4) 알림 발송 이력 적재. 알림이 필요한 경우에만 cl_alert_log 에
* 남기며, 발송 이력은 재발송 중복방지/감사추적의 근거가 된다.
*/
if (need_alert) {
strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_severity, severity, sizeof(h_severity) - 1);
h_severity[sizeof(h_severity) - 1] = '\0';
strncpy(h_target, target, sizeof(h_target) - 1);
h_target[sizeof(h_target) - 1] = '\0';
strncpy(h_reqid, reqid, sizeof(h_reqid) - 1);
h_reqid[sizeof(h_reqid) - 1] = '\0';
strncpy(h_alert, alert, sizeof(h_alert) - 1);
h_alert[sizeof(h_alert) - 1] = '\0';
h_recv = recv_cnt;
h_fail = fail_cnt;
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CL_OL_0025] tx_begin 경고");
} else {
EXEC SQL INSERT INTO cl_alert_log
(biz_date, severity, recv_cnt, fail_cnt,
target, reqid, alert_msg, sent_ts)
VALUES (:h_biz_date, :h_severity, :h_recv, :h_fail,
:h_target, :h_reqid, :h_alert, now());
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0025 INSERT cl_alert_log");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_OK);
tx_buf_setlong(ctx->out, "LOGGED", logged);
tx_buf_sets(ctx->out, "TYPE", "ALERT");
tx_buf_sets(ctx->out, "BIZDATE", bizdate);
tx_buf_sets(ctx->out, "REQID", reqid);

View file

@ -103,6 +103,31 @@ struct sqlca_t *ECPGget_sqlca(void);
TX_SERVICE(CL_OL_0031, ctx)
{
/* exec sql begin declare section */
#line 29 "app/online/cl_ol_0031.pgc"
char h_ss1 [ 16 ] ;
#line 30 "app/online/cl_ol_0031.pgc"
char h_ss2 [ 16 ] ;
#line 31 "app/online/cl_ol_0031.pgc"
long h_diff ;
#line 32 "app/online/cl_ol_0031.pgc"
char h_direction [ 8 ] ;
#line 33 "app/online/cl_ol_0031.pgc"
char h_reqid [ 32 ] ;
/* exec sql end declare section */
#line 34 "app/online/cl_ol_0031.pgc"
cl_rec_t rec1, rec2;
char ss1[16], ss2[16];
char reqid[32];
@ -111,6 +136,7 @@ TX_SERVICE(CL_OL_0031, ctx)
const char *direction;
long diff, cnt_diff, abs_diff;
long rate;
long persisted = 0;
int rc1, rc2;
tx_log(TX_LOG_INFO, "[CL_OL_0031] 마감 스냅샷 비교 서비스 진입");
@ -172,6 +198,43 @@ TX_SERVICE(CL_OL_0031, ctx)
"스냅샷 %s(%ld) -> %s(%ld) 변동 %ld원 (%s %ld%%)",
ss1, rec1.amount, ss2, rec2.amount, diff, direction, rate);
/* 5) 비교 결과를 cl_snap_diff 에 적재하여 감사이력으로 남긴다. */
strncpy(h_ss1, ss1, sizeof(h_ss1) - 1);
h_ss1[sizeof(h_ss1) - 1] = '\0';
strncpy(h_ss2, ss2, sizeof(h_ss2) - 1);
h_ss2[sizeof(h_ss2) - 1] = '\0';
strncpy(h_direction, direction, sizeof(h_direction) - 1);
h_direction[sizeof(h_direction) - 1] = '\0';
strncpy(h_reqid, reqid, sizeof(h_reqid) - 1);
h_reqid[sizeof(h_reqid) - 1] = '\0';
h_diff = diff;
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CL_OL_0031] tx_begin 경고");
} else {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into cl_snap_diff ( ss1_key , ss2_key , amt_diff , direction , reqid , cmp_ts ) values ( $1 , $2 , $3 , $4 , $5 , now ( ) )",
ECPGt_char,(h_ss1),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_ss2),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_diff),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_direction),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_reqid),(long)32,(long)1,(32)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 122 "app/online/cl_ol_0031.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0031 INSERT cl_snap_diff");
tx_abort();
} else {
persisted = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_OK);
tx_buf_sets(ctx->out, "SS1", ss1);
@ -187,6 +250,7 @@ TX_SERVICE(CL_OL_0031, ctx)
tx_buf_setlong(ctx->out, "CNTDIFF", cnt_diff);
tx_buf_setlong(ctx->out, "RATE", rate);
tx_buf_sets(ctx->out, "DIRECTION", direction);
tx_buf_setlong(ctx->out, "PERSISTED", persisted);
tx_buf_sets(ctx->out, "SUMMARY", summary);
tx_buf_sets(ctx->out, "MATCH", (diff == 0) ? "Y" : "N");
/* 유의미 변동 여부(절대변동이 기준의 1% 초과) */

View file

@ -25,6 +25,14 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CL_OL_0031, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_ss1[16];
char h_ss2[16];
long h_diff;
char h_direction[8];
char h_reqid[32];
EXEC SQL END DECLARE SECTION;
cl_rec_t rec1, rec2;
char ss1[16], ss2[16];
char reqid[32];
@ -33,6 +41,7 @@ TX_SERVICE(CL_OL_0031, ctx)
const char *direction;
long diff, cnt_diff, abs_diff;
long rate;
long persisted = 0;
int rc1, rc2;
tx_log(TX_LOG_INFO, "[CL_OL_0031] 마감 스냅샷 비교 서비스 진입");
@ -94,6 +103,33 @@ TX_SERVICE(CL_OL_0031, ctx)
"스냅샷 %s(%ld) -> %s(%ld) 변동 %ld원 (%s %ld%%)",
ss1, rec1.amount, ss2, rec2.amount, diff, direction, rate);
/* 5) 비교 결과를 cl_snap_diff 에 적재하여 감사이력으로 남긴다. */
strncpy(h_ss1, ss1, sizeof(h_ss1) - 1);
h_ss1[sizeof(h_ss1) - 1] = '\0';
strncpy(h_ss2, ss2, sizeof(h_ss2) - 1);
h_ss2[sizeof(h_ss2) - 1] = '\0';
strncpy(h_direction, direction, sizeof(h_direction) - 1);
h_direction[sizeof(h_direction) - 1] = '\0';
strncpy(h_reqid, reqid, sizeof(h_reqid) - 1);
h_reqid[sizeof(h_reqid) - 1] = '\0';
h_diff = diff;
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CL_OL_0031] tx_begin 경고");
} else {
EXEC SQL INSERT INTO cl_snap_diff
(ss1_key, ss2_key, amt_diff, direction, reqid, cmp_ts)
VALUES (:h_ss1, :h_ss2, :h_diff, :h_direction, :h_reqid, now());
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CL_OL_0031 INSERT cl_snap_diff");
tx_abort();
} else {
persisted = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "RESPCODE", RESP_OK);
tx_buf_sets(ctx->out, "SS1", ss1);
@ -109,6 +145,7 @@ TX_SERVICE(CL_OL_0031, ctx)
tx_buf_setlong(ctx->out, "CNTDIFF", cnt_diff);
tx_buf_setlong(ctx->out, "RATE", rate);
tx_buf_sets(ctx->out, "DIRECTION", direction);
tx_buf_setlong(ctx->out, "PERSISTED", persisted);
tx_buf_sets(ctx->out, "SUMMARY", summary);
tx_buf_sets(ctx->out, "MATCH", (diff == 0) ? "Y" : "N");
/* 유의미 변동 여부(절대변동이 기준의 1% 초과) */

View file

@ -152,7 +152,7 @@ TX_SERVICE(CM_OL_0001, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_int,&(h_sort),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 55 "app/online/cm_ol_0001.pgc"
#line 54 "app/online/cm_ol_0001.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -46,8 +46,7 @@ TX_SERVICE(CM_OL_0001, ctx)
strncpy(h_code, code, sizeof(h_code) - 1);
h_sort = 0;
EXEC SQL
SELECT code_name, attr_val, sort_no
EXEC SQL SELECT code_name, attr_val, sort_no
INTO :h_name, :h_attr, :h_sort
FROM cm_code
WHERE grp_cd = :h_grp

View file

@ -12,13 +12,15 @@
*
* (DATE, YYYYMMDD) date_next_business
* , //
* . DB .
* . (cm_holiday)
* (HOLIDAY=Y/N) .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0002.pgc"
#line 19 "app/online/cm_ol_0002.pgc"
/* 요일번호(0=일..6=토)를 한글 표기로 변환 */
@ -108,10 +110,28 @@ static const char *weekday_name(int wd)
TX_SERVICE(CM_OL_0002, ctx)
{
/* exec sql begin declare section */
#line 36 "app/online/cm_ol_0002.pgc"
char h_date [ 9 ] ;
#line 37 "app/online/cm_ol_0002.pgc"
char h_holi_nm [ 64 ] ;
#line 38 "app/online/cm_ol_0002.pgc"
long h_holi_cnt ;
/* exec sql end declare section */
#line 39 "app/online/cm_ol_0002.pgc"
char base_date[9];
char next_date[9];
int wd;
int weekend;
int is_holiday;
tx_log(TX_LOG_INFO, "[CM_OL_0002] 영업일 계산 서비스 진입");
@ -139,14 +159,40 @@ TX_SERVICE(CM_OL_0002, ctx)
return;
}
/* 지정 공휴일 여부 조회 (휴일 마스터) */
strncpy(h_date, base_date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
h_holi_cnt = 0;
h_holi_nm[0] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( max ( holi_nm ) , '' ) from cm_holiday where holi_date = $1 and use_yn = 'Y'",
ECPGt_char,(h_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_holi_cnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_holi_nm),(long)64,(long)1,(64)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 83 "app/online/cm_ol_0002.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CM_OL_0002 SELECT cm_holiday");
h_holi_cnt = 0;
h_holi_nm[0] = '\0';
}
is_holiday = (h_holi_cnt > 0) ? 1 : 0;
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", base_date);
tx_buf_sets(ctx->out, "NEXTBIZ", next_date);
tx_buf_setlong(ctx->out, "WEEKDAY", (long)wd);
tx_buf_sets(ctx->out, "WEEKDAYNM", weekday_name(wd));
tx_buf_sets(ctx->out, "WEEKEND", weekend ? "Y" : "N");
tx_buf_sets(ctx->out, "HOLIDAY", is_holiday ? "Y" : "N");
tx_buf_sets(ctx->out, "HOLINM", h_holi_nm);
tx_log(TX_LOG_INFO, "[CM_OL_0002] 계산완료 date=%s(%s) next=%s weekend=%s",
base_date, weekday_name(wd), next_date, weekend ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0002] 계산완료 date=%s(%s) next=%s weekend=%s holiday=%s",
base_date, weekday_name(wd), next_date, weekend ? "Y" : "N",
is_holiday ? "Y" : "N");
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,13 +4,15 @@
*
* 요청의 기준일자(DATE, YYYYMMDD)를 검증한 뒤 date_next_business 로
* 다음 영업일을 산출하고, 기준일의 요일번호/요일명/주말여부를 함께
* 응답한다. DB 접근이 없는 순수 유틸리티 로직.
* 응답한다. 아울러 휴일 마스터(cm_holiday)를 조회하여 기준일이 지정
* 공휴일인지(HOLIDAY=Y/N)와 휴일명을 응답에 반영한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -30,10 +32,17 @@ static const char *weekday_name(int wd)
TX_SERVICE(CM_OL_0002, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_date[9];
char h_holi_nm[64];
long h_holi_cnt;
EXEC SQL END DECLARE SECTION;
char base_date[9];
char next_date[9];
int wd;
int weekend;
int is_holiday;
tx_log(TX_LOG_INFO, "[CM_OL_0002] 영업일 계산 서비스 진입");
@ -61,14 +70,36 @@ TX_SERVICE(CM_OL_0002, ctx)
return;
}
/* 지정 공휴일 여부 조회 (휴일 마스터) */
strncpy(h_date, base_date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
h_holi_cnt = 0;
h_holi_nm[0] = '\0';
EXEC SQL SELECT count(*), coalesce(max(holi_nm), '')
INTO :h_holi_cnt, :h_holi_nm
FROM cm_holiday
WHERE holi_date = :h_date
AND use_yn = 'Y';
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CM_OL_0002 SELECT cm_holiday");
h_holi_cnt = 0;
h_holi_nm[0] = '\0';
}
is_holiday = (h_holi_cnt > 0) ? 1 : 0;
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", base_date);
tx_buf_sets(ctx->out, "NEXTBIZ", next_date);
tx_buf_setlong(ctx->out, "WEEKDAY", (long)wd);
tx_buf_sets(ctx->out, "WEEKDAYNM", weekday_name(wd));
tx_buf_sets(ctx->out, "WEEKEND", weekend ? "Y" : "N");
tx_buf_sets(ctx->out, "HOLIDAY", is_holiday ? "Y" : "N");
tx_buf_sets(ctx->out, "HOLINM", h_holi_nm);
tx_log(TX_LOG_INFO, "[CM_OL_0002] 계산완료 date=%s(%s) next=%s weekend=%s",
base_date, weekday_name(wd), next_date, weekend ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0002] 계산완료 date=%s(%s) next=%s weekend=%s holiday=%s",
base_date, weekday_name(wd), next_date, weekend ? "Y" : "N",
is_holiday ? "Y" : "N");
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -12,13 +12,15 @@
*
* (AMOUNT) amount_format_won /
* , amount_is_valid
* . DB .
* . (cm_amt_policy)
* (max_amt) (OVERPOLICY=Y/N) .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,16 +93,30 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0003.pgc"
#line 19 "app/online/cm_ol_0003.pgc"
TX_SERVICE(CM_OL_0003, ctx)
{
/* exec sql begin declare section */
#line 24 "app/online/cm_ol_0003.pgc"
char h_policy [ 16 ] ;
#line 25 "app/online/cm_ol_0003.pgc"
long h_max_amt ;
/* exec sql end declare section */
#line 26 "app/online/cm_ol_0003.pgc"
char amt_field[32];
char won_disp[48];
char plain_disp[32];
long amount = 0;
int valid;
int over_policy = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0003] 금액 포맷 유틸 서비스 진입");
@ -123,6 +139,28 @@ TX_SERVICE(CM_OL_0003, ctx)
/* 유효범위를 벗어나도 표기 자체는 제공하되 VALID=N 으로 통지 */
}
/* 정책 상한 조회 (정책구분 PARAM 우선, 없으면 DEFAULT) */
if (tx_buf_get(ctx->in, "POLICY", h_policy, sizeof(h_policy)) != TX_OK)
strncpy(h_policy, "DEFAULT", sizeof(h_policy) - 1);
h_policy[sizeof(h_policy) - 1] = '\0';
h_max_amt = 0;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select max_amt from cm_amt_policy where policy_cd = $1 and use_yn = 'Y'",
ECPGt_char,(h_policy),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_max_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 66 "app/online/cm_ol_0003.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_INFO, "[CM_OL_0003] 정책 미등록 policy=%s (상한검증 생략)", h_policy);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0003 SELECT cm_amt_policy");
} else if (h_max_amt > 0 && amount > h_max_amt) {
over_policy = 1;
}
amount_format_won(amount, won_disp, sizeof(won_disp));
if (amount_format(amount, plain_disp, sizeof(plain_disp)) != 0) {
strncpy(plain_disp, "0", sizeof(plain_disp) - 1);
@ -133,8 +171,10 @@ TX_SERVICE(CM_OL_0003, ctx)
tx_buf_sets(ctx->out, "WONDISP", won_disp);
tx_buf_sets(ctx->out, "PLAINDISP", plain_disp);
tx_buf_sets(ctx->out, "VALID", valid ? "Y" : "N");
tx_buf_setlong(ctx->out, "POLICYMAX", h_max_amt);
tx_buf_sets(ctx->out, "OVERPOLICY", over_policy ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0003] 포맷완료 amount=%ld disp=%s valid=%s",
amount, won_disp, valid ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0003] 포맷완료 amount=%ld disp=%s valid=%s over=%s",
amount, won_disp, valid ? "Y" : "N", over_policy ? "Y" : "N");
tx_return(ctx, valid ? TX_OK : TX_EINVAL, ctx->out);
}

View file

@ -4,13 +4,15 @@
*
* 요청의 입력금액(AMOUNT)을 amount_format_won 으로 천단위 콤마/원
* 표기 문자열로 변환하고, amount_is_valid 로 금액 유효범위 여부를
* 함께 응답한다. DB 접근이 없는 순수 유틸리티 로직.
* 함께 응답한다. 아울러 금액정책 마스터(cm_amt_policy)에서 표준 상한
* (max_amt)을 조회하여 정책상한 초과여부(OVERPOLICY=Y/N)를 통지한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -18,11 +20,17 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CM_OL_0003, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_policy[16];
long h_max_amt;
EXEC SQL END DECLARE SECTION;
char amt_field[32];
char won_disp[48];
char plain_disp[32];
long amount = 0;
int valid;
int over_policy = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0003] 금액 포맷 유틸 서비스 진입");
@ -45,6 +53,26 @@ TX_SERVICE(CM_OL_0003, ctx)
/* 유효범위를 벗어나도 표기 자체는 제공하되 VALID=N 으로 통지 */
}
/* 정책 상한 조회 (정책구분 PARAM 우선, 없으면 DEFAULT) */
if (tx_buf_get(ctx->in, "POLICY", h_policy, sizeof(h_policy)) != TX_OK)
strncpy(h_policy, "DEFAULT", sizeof(h_policy) - 1);
h_policy[sizeof(h_policy) - 1] = '\0';
h_max_amt = 0;
EXEC SQL SELECT max_amt
INTO :h_max_amt
FROM cm_amt_policy
WHERE policy_cd = :h_policy
AND use_yn = 'Y';
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_INFO, "[CM_OL_0003] 정책 미등록 policy=%s (상한검증 생략)", h_policy);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0003 SELECT cm_amt_policy");
} else if (h_max_amt > 0 && amount > h_max_amt) {
over_policy = 1;
}
amount_format_won(amount, won_disp, sizeof(won_disp));
if (amount_format(amount, plain_disp, sizeof(plain_disp)) != 0) {
strncpy(plain_disp, "0", sizeof(plain_disp) - 1);
@ -55,8 +83,10 @@ TX_SERVICE(CM_OL_0003, ctx)
tx_buf_sets(ctx->out, "WONDISP", won_disp);
tx_buf_sets(ctx->out, "PLAINDISP", plain_disp);
tx_buf_sets(ctx->out, "VALID", valid ? "Y" : "N");
tx_buf_setlong(ctx->out, "POLICYMAX", h_max_amt);
tx_buf_sets(ctx->out, "OVERPOLICY", over_policy ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0003] 포맷완료 amount=%ld disp=%s valid=%s",
amount, won_disp, valid ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0003] 포맷완료 amount=%ld disp=%s valid=%s over=%s",
amount, won_disp, valid ? "Y" : "N", over_policy ? "Y" : "N");
tx_return(ctx, valid ? TX_OK : TX_EINVAL, ctx->out);
}

View file

@ -12,13 +12,15 @@
*
* (///) ·
* , .
* DB .
* (cm_channel) /
* , · .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0004.pgc"
#line 19 "app/online/cm_ol_0004.pgc"
/* 전문종별 코드 → 표준 2자리 구분자 매핑 */
@ -105,6 +107,23 @@ static const char *header_kind_tag(const char *kind)
TX_SERVICE(CM_OL_0004, ctx)
{
/* exec sql begin declare section */
#line 33 "app/online/cm_ol_0004.pgc"
char h_channel [ 4 ] ;
#line 34 "app/online/cm_ol_0004.pgc"
char h_channel_nm [ 40 ] ;
#line 35 "app/online/cm_ol_0004.pgc"
char h_use_yn [ 2 ] ;
/* exec sql end declare section */
#line 36 "app/online/cm_ol_0004.pgc"
char msglen_f[8];
char kind[8];
char channel[4];
@ -153,6 +172,38 @@ TX_SERVICE(CM_OL_0004, ctx)
return;
}
/* 채널 마스터 조회 : 채널명/사용여부 확인 */
strncpy(h_channel, channel, sizeof(h_channel) - 1);
h_channel[sizeof(h_channel) - 1] = '\0';
h_channel_nm[0] = '\0';
strncpy(h_use_yn, "N", sizeof(h_use_yn));
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select channel_nm , use_yn from cm_channel where channel_cd = $1 ",
ECPGt_char,(h_channel),(long)4,(long)1,(4)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_channel_nm),(long)40,(long)1,(40)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_use_yn),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 95 "app/online/cm_ol_0004.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[CM_OL_0004] 미등록 채널 channel=%s", channel);
tx_return(ctx, TX_ENOENT, ctx->out);
return;
}
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0004 SELECT cm_channel");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
if (strcmp(h_use_yn, "Y") != 0) {
tx_log(TX_LOG_WARN, "[CM_OL_0004] 미사용 채널 channel=%s", channel);
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
/* 표준 공통헤더 = 길이(4) + 종별태그(2) + 채널(2) + 거래일시(14) */
snprintf(std_header, sizeof(std_header), "%04ld%2s%-2.2s%-14.14s",
msglen, tag, channel, datetime);
@ -161,8 +212,10 @@ TX_SERVICE(CM_OL_0004, ctx)
tx_buf_sets(ctx->out, "STDHEADER", std_header);
tx_buf_setlong(ctx->out, "MSGLEN", msglen);
tx_buf_sets(ctx->out, "KINDTAG", tag);
tx_buf_sets(ctx->out, "CHANNELNM", h_channel_nm);
tx_buf_setlong(ctx->out, "HDRLEN", (long)strlen(std_header));
tx_log(TX_LOG_INFO, "[CM_OL_0004] 헤더조립 완료 tag=%s header=[%s]", tag, std_header);
tx_log(TX_LOG_INFO, "[CM_OL_0004] 헤더조립 완료 tag=%s channel=%s(%s) header=[%s]",
tag, channel, h_channel_nm, std_header);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,13 +4,15 @@
*
* 요청의 공통헤더 원천 필드(전문길이/전문종별/채널/거래일시)를 파싱·
* 검증한 뒤, 고정 자리수의 표준 공통헤더 문자열로 재구성하여 응답한다.
* DB 접근이 없는 순수 전문 조립 로직.
* 채널코드는 채널 마스터(cm_channel)를 조회하여 채널명/사용여부를
* 확인하며, 미등록·미사용 채널이면 반려한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -27,6 +29,12 @@ static const char *header_kind_tag(const char *kind)
TX_SERVICE(CM_OL_0004, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_channel[4];
char h_channel_nm[40];
char h_use_yn[2];
EXEC SQL END DECLARE SECTION;
char msglen_f[8];
char kind[8];
char channel[4];
@ -75,6 +83,33 @@ TX_SERVICE(CM_OL_0004, ctx)
return;
}
/* 채널 마스터 조회 : 채널명/사용여부 확인 */
strncpy(h_channel, channel, sizeof(h_channel) - 1);
h_channel[sizeof(h_channel) - 1] = '\0';
h_channel_nm[0] = '\0';
strncpy(h_use_yn, "N", sizeof(h_use_yn));
EXEC SQL SELECT channel_nm, use_yn
INTO :h_channel_nm, :h_use_yn
FROM cm_channel
WHERE channel_cd = :h_channel;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[CM_OL_0004] 미등록 채널 channel=%s", channel);
tx_return(ctx, TX_ENOENT, ctx->out);
return;
}
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0004 SELECT cm_channel");
tx_return(ctx, TX_EDB, ctx->out);
return;
}
if (strcmp(h_use_yn, "Y") != 0) {
tx_log(TX_LOG_WARN, "[CM_OL_0004] 미사용 채널 channel=%s", channel);
tx_return(ctx, TX_EINVAL, ctx->out);
return;
}
/* 표준 공통헤더 = 길이(4) + 종별태그(2) + 채널(2) + 거래일시(14) */
snprintf(std_header, sizeof(std_header), "%04ld%2s%-2.2s%-14.14s",
msglen, tag, channel, datetime);
@ -83,8 +118,10 @@ TX_SERVICE(CM_OL_0004, ctx)
tx_buf_sets(ctx->out, "STDHEADER", std_header);
tx_buf_setlong(ctx->out, "MSGLEN", msglen);
tx_buf_sets(ctx->out, "KINDTAG", tag);
tx_buf_sets(ctx->out, "CHANNELNM", h_channel_nm);
tx_buf_setlong(ctx->out, "HDRLEN", (long)strlen(std_header));
tx_log(TX_LOG_INFO, "[CM_OL_0004] 헤더조립 완료 tag=%s header=[%s]", tag, std_header);
tx_log(TX_LOG_INFO, "[CM_OL_0004] 헤더조립 완료 tag=%s channel=%s(%s) header=[%s]",
tag, channel, h_channel_nm, std_header);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -159,7 +159,7 @@ TX_SERVICE(CM_OL_0005, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_action),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 62 "app/online/cm_ol_0005.pgc"
#line 61 "app/online/cm_ol_0005.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -53,8 +53,7 @@ TX_SERVICE(CM_OL_0005, ctx)
strncpy(h_errcd, errcd, sizeof(h_errcd) - 1);
strncpy(h_lang, lang, sizeof(h_lang) - 1);
EXEC SQL
SELECT msg_text, severity, action_cd
EXEC SQL SELECT msg_text, severity, action_cd
INTO :h_msgtext, :h_severity, :h_action
FROM cm_msg
WHERE err_cd = :h_errcd

View file

@ -162,7 +162,7 @@ TX_SERVICE(CM_OL_0006, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_prefix),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 64 "app/online/cm_ol_0006.pgc"
#line 63 "app/online/cm_ol_0006.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -190,7 +190,7 @@ TX_SERVICE(CM_OL_0006, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_seqkey),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 90 "app/online/cm_ol_0006.pgc"
#line 88 "app/online/cm_ol_0006.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {

View file

@ -56,8 +56,7 @@ TX_SERVICE(CM_OL_0006, ctx)
h_width = 0;
/* 순환최대치/자리수/접두어 확보 (행잠금) */
EXEC SQL
SELECT cur_val, max_val, seq_width, prefix
EXEC SQL SELECT cur_val, max_val, seq_width, prefix
INTO :h_seqval, :h_maxval, :h_width, :h_prefix
FROM cm_seq
WHERE seq_key = :h_seqkey
@ -83,8 +82,7 @@ TX_SERVICE(CM_OL_0006, ctx)
tx_log(TX_LOG_INFO, "[CM_OL_0006] 순번 순환 리셋 seqkey=%s", seqkey);
}
EXEC SQL
UPDATE cm_seq
EXEC SQL UPDATE cm_seq
SET cur_val = :h_seqval,
upd_ts = CURRENT_TIMESTAMP
WHERE seq_key = :h_seqkey;

View file

@ -180,7 +180,7 @@ TX_SERVICE(CM_OL_0007, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_logseq),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 84 "app/online/cm_ol_0007.pgc"
#line 83 "app/online/cm_ol_0007.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
@ -206,7 +206,7 @@ TX_SERVICE(CM_OL_0007, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_xid),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 100 "app/online/cm_ol_0007.pgc"
#line 98 "app/online/cm_ol_0007.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {

View file

@ -77,8 +77,7 @@ TX_SERVICE(CM_OL_0007, ctx)
}
/* 당일 로그일련번호 채번 (당일 최대치 +1) */
EXEC SQL
SELECT COALESCE(MAX(log_seq), 0) + 1
EXEC SQL SELECT COALESCE(MAX(log_seq), 0) + 1
INTO :h_logseq
FROM cm_log
WHERE biz_date = :h_bizdate;
@ -93,8 +92,7 @@ TX_SERVICE(CM_OL_0007, ctx)
h_logseq = 1;
}
EXEC SQL
INSERT INTO cm_log
EXEC SQL INSERT INTO cm_log
(biz_date, log_seq, log_level, module_id, log_msg, xid, reg_ts)
VALUES (:h_bizdate, :h_logseq, :h_level, :h_module, :h_message,
:h_xid, CURRENT_TIMESTAMP);

View file

@ -154,7 +154,7 @@ TX_SERVICE(CM_OL_0008, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_expired),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 58 "app/online/cm_ol_0008.pgc"
#line 57 "app/online/cm_ol_0008.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -48,8 +48,7 @@ TX_SERVICE(CM_OL_0008, ctx)
strncpy(h_sessid, sessid, sizeof(h_sessid) - 1);
/* 만료판정은 DB 현재시각과 비교하여 산출 */
EXEC SQL
SELECT user_id,
EXEC SQL SELECT user_id,
sess_status,
TO_CHAR(expire_ts, 'YYYYMMDDHH24MISS'),
CASE WHEN expire_ts < CURRENT_TIMESTAMP THEN 'Y' ELSE 'N' END

View file

@ -172,7 +172,7 @@ TX_SERVICE(CM_OL_0009, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_quotedate),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 77 "app/online/cm_ol_0009.pgc"
#line 76 "app/online/cm_ol_0009.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -66,8 +66,7 @@ TX_SERVICE(CM_OL_0009, ctx)
h_scale = 0;
/* 기준일 이하 최근 고시 1건 */
EXEC SQL
SELECT rate_scaled, rate_scale, quote_date
EXEC SQL SELECT rate_scaled, rate_scale, quote_date
INTO :h_scaled, :h_scale, :h_quotedate
FROM cm_rate
WHERE cur_cd = :h_cur

View file

@ -146,7 +146,7 @@ TX_SERVICE(CM_OL_0011, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_desc),(long)128,(long)1,(128)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 53 "app/online/cm_ol_0011.pgc"
#line 52 "app/online/cm_ol_0011.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -45,8 +45,7 @@ TX_SERVICE(CM_OL_0011, ctx)
memset(h_desc, 0, sizeof(h_desc));
strncpy(h_pkey, pkey, sizeof(h_pkey) - 1);
EXEC SQL
SELECT param_val, data_type, param_desc
EXEC SQL SELECT param_val, data_type, param_desc
INTO :h_pval, :h_dtype, :h_desc
FROM cm_param
WHERE param_key = :h_pkey

View file

@ -153,7 +153,7 @@ TX_SERVICE(CM_OL_0012, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_dst_name),(long)64,(long)1,(64)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 56 "app/online/cm_ol_0012.pgc"
#line 55 "app/online/cm_ol_0012.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -47,8 +47,7 @@ TX_SERVICE(CM_OL_0012, ctx)
strncpy(h_src_sys, src_sys, sizeof(h_src_sys) - 1);
strncpy(h_src_cd, src_cd, sizeof(h_src_cd) - 1);
EXEC SQL
SELECT dst_sys, dst_cd, dst_name
EXEC SQL SELECT dst_sys, dst_cd, dst_name
INTO :h_dst_sys, :h_dst_cd, :h_dst_name
FROM cm_code_map
WHERE src_sys = :h_src_sys

View file

@ -12,13 +12,15 @@
*
* (DATA) XOR (LRC)
* , (EXPECT, 16 2) (MATCH=Y/N)
* . . DB .
* . .
* (cm_lrc_log) .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0013.pgc"
#line 19 "app/online/cm_ol_0013.pgc"
/* 문자열 전 구간 바이트 XOR 로 LRC(종방향 중복검사) 계산 */
@ -108,12 +110,30 @@ static unsigned char lrc_calc(const char *data, int len)
TX_SERVICE(CM_OL_0013, ctx)
{
/* exec sql begin declare section */
#line 36 "app/online/cm_ol_0013.pgc"
long h_data_len ;
#line 37 "app/online/cm_ol_0013.pgc"
char h_lrc [ 4 ] ;
#line 38 "app/online/cm_ol_0013.pgc"
char h_match [ 4 ] ;
/* exec sql end declare section */
#line 39 "app/online/cm_ol_0013.pgc"
char data[256];
char expect[8];
unsigned char lrc;
unsigned int exp_val = 0;
char calc_hex[4];
int match;
long logged = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0013] 체크섬 검증 서비스 진입");
@ -138,9 +158,39 @@ TX_SERVICE(CM_OL_0013, ctx)
match = -1; /* 비교 미수행 */
}
/* 무결성 검증 이력 적재 */
h_data_len = (long)strlen(data);
strncpy(h_lrc, calc_hex, sizeof(h_lrc) - 1);
h_lrc[sizeof(h_lrc) - 1] = '\0';
strncpy(h_match, (match < 0) ? "NA" : (match ? "Y" : "N"), sizeof(h_match) - 1);
h_match[sizeof(h_match) - 1] = '\0';
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CM_OL_0013] tx_begin 경고");
} else {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into cm_lrc_log ( data_len , lrc_hex , match_yn , chk_ts ) values ( $1 , $2 , $3 , now ( ) )",
ECPGt_long,&(h_data_len),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_lrc),(long)4,(long)1,(4)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_match),(long)4,(long)1,(4)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 84 "app/online/cm_ol_0013.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0013 INSERT cm_lrc_log");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "LRC", calc_hex);
tx_buf_setlong(ctx->out, "LRCDEC", (long)lrc);
tx_buf_setlong(ctx->out, "LOGGED", logged);
if (match < 0) {
tx_buf_sets(ctx->out, "MATCH", "N/A");
tx_log(TX_LOG_INFO, "[CM_OL_0013] LRC 계산 lrc=%s (비교 미수행)", calc_hex);

View file

@ -4,13 +4,15 @@
*
* 요청의 원문(DATA) 에 대해 바이트 XOR 누적(LRC) 체크섬을 순수 로직으로
* 계산하고, 기대값(EXPECT, 16진 2자리) 과 비교하여 일치여부(MATCH=Y/N)를
* 응답한다. 대외 전문 무결성 검증 공통 루틴. DB 접근 없음.
* 응답한다. 대외 전문 무결성 검증 공통 루틴. 검증 결과는 무결성 감사
* 이력(cm_lrc_log)에 적재하여 사후 추적을 지원한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -30,12 +32,19 @@ static unsigned char lrc_calc(const char *data, int len)
TX_SERVICE(CM_OL_0013, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
long h_data_len;
char h_lrc[4];
char h_match[4];
EXEC SQL END DECLARE SECTION;
char data[256];
char expect[8];
unsigned char lrc;
unsigned int exp_val = 0;
char calc_hex[4];
int match;
long logged = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0013] 체크섬 검증 서비스 진입");
@ -60,9 +69,33 @@ TX_SERVICE(CM_OL_0013, ctx)
match = -1; /* 비교 미수행 */
}
/* 무결성 검증 이력 적재 */
h_data_len = (long)strlen(data);
strncpy(h_lrc, calc_hex, sizeof(h_lrc) - 1);
h_lrc[sizeof(h_lrc) - 1] = '\0';
strncpy(h_match, (match < 0) ? "NA" : (match ? "Y" : "N"), sizeof(h_match) - 1);
h_match[sizeof(h_match) - 1] = '\0';
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CM_OL_0013] tx_begin 경고");
} else {
EXEC SQL INSERT INTO cm_lrc_log
(data_len, lrc_hex, match_yn, chk_ts)
VALUES (:h_data_len, :h_lrc, :h_match, now());
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0013 INSERT cm_lrc_log");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "LRC", calc_hex);
tx_buf_setlong(ctx->out, "LRCDEC", (long)lrc);
tx_buf_setlong(ctx->out, "LOGGED", logged);
if (match < 0) {
tx_buf_sets(ctx->out, "MATCH", "N/A");
tx_log(TX_LOG_INFO, "[CM_OL_0013] LRC 계산 lrc=%s (비교 미수행)", calc_hex);

View file

@ -12,13 +12,15 @@
*
* (DATE, YYYYMMDD) date_is_valid
* YYYY.MM.DD +
* . / . DB .
* . / .
* (cm_holiday) / .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0014.pgc"
#line 19 "app/online/cm_ol_0014.pgc"
TX_SERVICE(CM_OL_0014, ctx)
@ -99,10 +101,29 @@ TX_SERVICE(CM_OL_0014, ctx)
static const char *WDAY_KR[7] = {
"일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"
};
/* exec sql begin declare section */
#line 28 "app/online/cm_ol_0014.pgc"
char h_date [ 9 ] ;
#line 29 "app/online/cm_ol_0014.pgc"
char h_holi_nm [ 64 ] ;
#line 30 "app/online/cm_ol_0014.pgc"
char h_holi_type [ 4 ] ;
/* exec sql end declare section */
#line 31 "app/online/cm_ol_0014.pgc"
char date[16];
char dotted[16];
char display[48];
char display[80];
int wd;
int is_holiday;
tx_log(TX_LOG_INFO, "[CM_OL_0014] 날짜 포맷 변환 서비스 진입");
@ -130,7 +151,37 @@ TX_SERVICE(CM_OL_0014, ctx)
return;
}
snprintf(display, sizeof(display), "%s (%s)", dotted, WDAY_KR[wd]);
/* 휴일 마스터에서 휴일명/휴일구분 조회 */
strncpy(h_date, date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
h_holi_nm[0] = '\0';
h_holi_type[0] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select holi_nm , holi_type from cm_holiday where holi_date = $1 and use_yn = 'Y'",
ECPGt_char,(h_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_holi_nm),(long)64,(long)1,(64)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_holi_type),(long)4,(long)1,(4)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 75 "app/online/cm_ol_0014.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
is_holiday = 0;
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0014 SELECT cm_holiday");
is_holiday = 0;
h_holi_nm[0] = '\0';
h_holi_type[0] = '\0';
} else {
is_holiday = 1;
}
if (is_holiday)
snprintf(display, sizeof(display), "%s (%s, %s)", dotted, WDAY_KR[wd], h_holi_nm);
else
snprintf(display, sizeof(display), "%s (%s)", dotted, WDAY_KR[wd]);
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", date);
@ -138,6 +189,9 @@ TX_SERVICE(CM_OL_0014, ctx)
tx_buf_sets(ctx->out, "WDAYNM", WDAY_KR[wd]);
tx_buf_setlong(ctx->out, "WDAY", (long)wd);
tx_buf_sets(ctx->out, "DISPLAY", display);
tx_buf_sets(ctx->out, "HOLIDAY", is_holiday ? "Y" : "N");
tx_buf_sets(ctx->out, "HOLINM", h_holi_nm);
tx_buf_sets(ctx->out, "HOLITYPE", h_holi_type);
tx_log(TX_LOG_INFO, "[CM_OL_0014] 변환완료 %s -> %s", date, display);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,13 +4,15 @@
*
* 요청의 영업일(DATE, YYYYMMDD)을 date_is_valid 로 검증한 뒤
* YYYY.MM.DD 표기 + 한글 요일명을 포함한 표시문자열로 변환하여
* 응답한다. 화면/리포트 공통 날짜표기 루틴. DB 접근 없음.
* 응답한다. 화면/리포트 공통 날짜표기 루틴. 추가로 휴일 마스터
* (cm_holiday)에서 휴일명/휴일구분을 조회하여 표시문자열에 반영한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -21,10 +23,18 @@ TX_SERVICE(CM_OL_0014, ctx)
static const char *WDAY_KR[7] = {
"일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"
};
EXEC SQL BEGIN DECLARE SECTION;
char h_date[9];
char h_holi_nm[64];
char h_holi_type[4];
EXEC SQL END DECLARE SECTION;
char date[16];
char dotted[16];
char display[48];
char display[80];
int wd;
int is_holiday;
tx_log(TX_LOG_INFO, "[CM_OL_0014] 날짜 포맷 변환 서비스 진입");
@ -52,7 +62,33 @@ TX_SERVICE(CM_OL_0014, ctx)
return;
}
snprintf(display, sizeof(display), "%s (%s)", dotted, WDAY_KR[wd]);
/* 휴일 마스터에서 휴일명/휴일구분 조회 */
strncpy(h_date, date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
h_holi_nm[0] = '\0';
h_holi_type[0] = '\0';
EXEC SQL SELECT holi_nm, holi_type
INTO :h_holi_nm, :h_holi_type
FROM cm_holiday
WHERE holi_date = :h_date
AND use_yn = 'Y';
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
is_holiday = 0;
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0014 SELECT cm_holiday");
is_holiday = 0;
h_holi_nm[0] = '\0';
h_holi_type[0] = '\0';
} else {
is_holiday = 1;
}
if (is_holiday)
snprintf(display, sizeof(display), "%s (%s, %s)", dotted, WDAY_KR[wd], h_holi_nm);
else
snprintf(display, sizeof(display), "%s (%s)", dotted, WDAY_KR[wd]);
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", date);
@ -60,6 +96,9 @@ TX_SERVICE(CM_OL_0014, ctx)
tx_buf_sets(ctx->out, "WDAYNM", WDAY_KR[wd]);
tx_buf_setlong(ctx->out, "WDAY", (long)wd);
tx_buf_sets(ctx->out, "DISPLAY", display);
tx_buf_sets(ctx->out, "HOLIDAY", is_holiday ? "Y" : "N");
tx_buf_sets(ctx->out, "HOLINM", h_holi_nm);
tx_buf_sets(ctx->out, "HOLITYPE", h_holi_type);
tx_log(TX_LOG_INFO, "[CM_OL_0014] 변환완료 %s -> %s", date, display);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -12,13 +12,15 @@
*
* (DATE) cm DBIO(cm_rec_count/cm_rec_sum)
* (///)
* . / .
* . cm_ledger (SELECT) //
* DBIO .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,14 +93,36 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0015.pgc"
#line 19 "app/online/cm_ol_0015.pgc"
TX_SERVICE(CM_OL_0015, ctx)
{
/* exec sql begin declare section */
#line 24 "app/online/cm_ol_0015.pgc"
char h_date [ 9 ] ;
#line 25 "app/online/cm_ol_0015.pgc"
long h_db_cnt ;
#line 26 "app/online/cm_ol_0015.pgc"
long h_db_amt ;
#line 27 "app/online/cm_ol_0015.pgc"
long h_db_fee ;
/* exec sql end declare section */
#line 28 "app/online/cm_ol_0015.pgc"
char date[16];
long c_recv, c_done, c_fail, c_settled, c_total;
long sum_amt = 0;
long recon_diff;
int rc;
tx_log(TX_LOG_INFO, "[CM_OL_0015] 통계 공통 조회 서비스 진입");
@ -134,6 +158,33 @@ TX_SERVICE(CM_OL_0015, ctx)
sum_amt = 0;
}
/* 원장 직접 집계 (건수/금액/수수료 합계) 로 DBIO 결과 교차검증 */
strncpy(h_date, date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
h_db_cnt = 0;
h_db_amt = 0;
h_db_fee = 0;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) , coalesce ( sum ( fee ) , 0 ) from cm_ledger where biz_date = $1 ",
ECPGt_char,(h_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_db_cnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_db_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_db_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 79 "app/online/cm_ol_0015.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CM_OL_0015 direct aggregate");
h_db_cnt = 0;
h_db_amt = 0;
h_db_fee = 0;
}
recon_diff = c_total - h_db_cnt;
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", date);
tx_buf_setlong(ctx->out, "CNTRECV", c_recv);
@ -142,8 +193,13 @@ TX_SERVICE(CM_OL_0015, ctx)
tx_buf_setlong(ctx->out, "CNTSETTLED", c_settled);
tx_buf_setlong(ctx->out, "CNTTOTAL", c_total);
tx_buf_setlong(ctx->out, "SUMAMT", sum_amt);
tx_buf_setlong(ctx->out, "DBCOUNT", h_db_cnt);
tx_buf_setlong(ctx->out, "DBAMT", h_db_amt);
tx_buf_setlong(ctx->out, "SUMFEE", h_db_fee);
tx_buf_setlong(ctx->out, "RECONDIFF", recon_diff);
tx_buf_sets(ctx->out, "RECONMATCH", (recon_diff == 0) ? "Y" : "N");
tx_log(TX_LOG_INFO,
"[CM_OL_0015] 집계완료 date=%s 총건=%ld 완료=%ld 합계=%ld",
date, c_total, c_done, sum_amt);
"[CM_OL_0015] 집계완료 date=%s 총건=%ld 완료=%ld 합계=%ld 수수료=%ld",
date, c_total, c_done, sum_amt, h_db_fee);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,13 +4,15 @@
*
* 요청의 영업일(DATE)에 대해 cm 표준 DBIO(cm_rec_count/cm_rec_sum)를
* 조합하여 상태별 건수(접수/완료/실패/정산)와 총 거래금액을 집계해
* 응답한다. 일마감/모니터링 대시보드용 공통 집계 서비스.
* 응답한다. 아울러 cm_ledger 원장을 직접 집계(SELECT)하여 총건수/금액/
* 수수료합계를 산출하고 DBIO 집계와 교차검증한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -18,9 +20,17 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CM_OL_0015, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_date[9];
long h_db_cnt;
long h_db_amt;
long h_db_fee;
EXEC SQL END DECLARE SECTION;
char date[16];
long c_recv, c_done, c_fail, c_settled, c_total;
long sum_amt = 0;
long recon_diff;
int rc;
tx_log(TX_LOG_INFO, "[CM_OL_0015] 통계 공통 조회 서비스 진입");
@ -56,6 +66,26 @@ TX_SERVICE(CM_OL_0015, ctx)
sum_amt = 0;
}
/* 원장 직접 집계 (건수/금액/수수료 합계) 로 DBIO 결과 교차검증 */
strncpy(h_date, date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
h_db_cnt = 0;
h_db_amt = 0;
h_db_fee = 0;
EXEC SQL SELECT count(*), coalesce(sum(amount), 0), coalesce(sum(fee), 0)
INTO :h_db_cnt, :h_db_amt, :h_db_fee
FROM cm_ledger
WHERE biz_date = :h_date;
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("CM_OL_0015 direct aggregate");
h_db_cnt = 0;
h_db_amt = 0;
h_db_fee = 0;
}
recon_diff = c_total - h_db_cnt;
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", date);
tx_buf_setlong(ctx->out, "CNTRECV", c_recv);
@ -64,8 +94,13 @@ TX_SERVICE(CM_OL_0015, ctx)
tx_buf_setlong(ctx->out, "CNTSETTLED", c_settled);
tx_buf_setlong(ctx->out, "CNTTOTAL", c_total);
tx_buf_setlong(ctx->out, "SUMAMT", sum_amt);
tx_buf_setlong(ctx->out, "DBCOUNT", h_db_cnt);
tx_buf_setlong(ctx->out, "DBAMT", h_db_amt);
tx_buf_setlong(ctx->out, "SUMFEE", h_db_fee);
tx_buf_setlong(ctx->out, "RECONDIFF", recon_diff);
tx_buf_sets(ctx->out, "RECONMATCH", (recon_diff == 0) ? "Y" : "N");
tx_log(TX_LOG_INFO,
"[CM_OL_0015] 집계완료 date=%s 총건=%ld 완료=%ld 합계=%ld",
date, c_total, c_done, sum_amt);
"[CM_OL_0015] 집계완료 date=%s 총건=%ld 완료=%ld 합계=%ld 수수료=%ld",
date, c_total, c_done, sum_amt, h_db_fee);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -150,7 +150,7 @@ TX_SERVICE(CM_OL_0016, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 51 "app/online/cm_ol_0016.pgc"
#line 50 "app/online/cm_ol_0016.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -44,8 +44,7 @@ TX_SERVICE(CM_OL_0016, ctx)
strncpy(h_batch_id, batch_id, sizeof(h_batch_id) - 1);
h_run_cnt = 0;
EXEC SQL
SELECT last_run_dt, run_status, run_cnt, biz_date
EXEC SQL SELECT last_run_dt, run_status, run_cnt, biz_date
INTO :h_last_run, :h_run_status, :h_run_cnt, :h_biz_date
FROM cm_batch_ctl
WHERE batch_id = :h_batch_id;

View file

@ -147,7 +147,7 @@ TX_SERVICE(CM_OL_0018, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&(h_holi_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 60 "app/online/cm_ol_0018.pgc"
#line 59 "app/online/cm_ol_0018.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
@ -162,7 +162,7 @@ TX_SERVICE(CM_OL_0018, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_holi_name),(long)64,(long)1,(64)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 73 "app/online/cm_ol_0018.pgc"
#line 71 "app/online/cm_ol_0018.pgc"
if (sqlca.sqlcode != TX_SQL_OK)
strncpy(h_holi_name, "공휴일", sizeof(h_holi_name) - 1);

View file

@ -53,8 +53,7 @@ TX_SERVICE(CM_OL_0018, ctx)
strncpy(h_date, date, sizeof(h_date) - 1);
h_holi_cnt = 0;
EXEC SQL
SELECT COUNT(*)
EXEC SQL SELECT COUNT(*)
INTO :h_holi_cnt
FROM cm_holiday
WHERE holi_date = :h_date;
@ -66,8 +65,7 @@ TX_SERVICE(CM_OL_0018, ctx)
}
if (h_holi_cnt > 0) {
is_holiday = 1;
EXEC SQL
SELECT holi_name
EXEC SQL SELECT holi_name
INTO :h_holi_name
FROM cm_holiday
WHERE holi_date = :h_date;

View file

@ -12,13 +12,15 @@
*
* (DATE, YYYYMMDD) date_weekday
* (0= ~ 6=) (~) /
* / . . DB .
* / . (cm_biz_calendar)
* (BIZDAY=Y/N) .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0019.pgc"
#line 19 "app/online/cm_ol_0019.pgc"
TX_SERVICE(CM_OL_0019, ctx)
@ -99,10 +101,29 @@ TX_SERVICE(CM_OL_0019, ctx)
static const char *WDAY_SHORT[7] = {
"", "", "", "", "", "", ""
};
/* exec sql begin declare section */
#line 28 "app/online/cm_ol_0019.pgc"
char h_date [ 9 ] ;
#line 29 "app/online/cm_ol_0019.pgc"
char h_biz_yn [ 2 ] ;
#line 30 "app/online/cm_ol_0019.pgc"
char h_remark [ 64 ] ;
/* exec sql end declare section */
#line 31 "app/online/cm_ol_0019.pgc"
char date[16];
char label[8];
int wd;
int weekend;
int biz_day;
tx_log(TX_LOG_INFO, "[CM_OL_0019] 요일 계산 서비스 진입");
@ -129,13 +150,38 @@ TX_SERVICE(CM_OL_0019, ctx)
weekend = (wd == 0 || wd == 6) ? 1 : 0;
snprintf(label, sizeof(label), "%s요일", WDAY_SHORT[wd]);
/* 영업일 달력 조회 : 등록이 있으면 그 값을 우선, 없으면 주말 반대로 */
strncpy(h_date, date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
strncpy(h_biz_yn, weekend ? "N" : "Y", sizeof(h_biz_yn));
h_remark[0] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select biz_yn , coalesce ( remark , '' ) from cm_biz_calendar where cal_date = $1 ",
ECPGt_char,(h_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_biz_yn),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_remark),(long)64,(long)1,(64)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 73 "app/online/cm_ol_0019.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_DEBUG, "[CM_OL_0019] 달력 미등록 date=%s (요일기준 판정)", date);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0019 SELECT cm_biz_calendar");
}
biz_day = (strcmp(h_biz_yn, "Y") == 0) ? 1 : 0;
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", date);
tx_buf_setlong(ctx->out, "WDAY", (long)wd);
tx_buf_sets(ctx->out, "WDAYNM", WDAY_SHORT[wd]);
tx_buf_sets(ctx->out, "WDAYLABEL", label);
tx_buf_sets(ctx->out, "WEEKEND", weekend ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0019] 계산완료 date=%s 요일=%s 주말=%s",
date, label, weekend ? "Y" : "N");
tx_buf_sets(ctx->out, "BIZDAY", biz_day ? "Y" : "N");
tx_buf_sets(ctx->out, "REMARK", h_remark);
tx_log(TX_LOG_INFO, "[CM_OL_0019] 계산완료 date=%s 요일=%s 주말=%s 영업일=%s",
date, label, weekend ? "Y" : "N", biz_day ? "Y" : "N");
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,13 +4,15 @@
*
* 요청의 일자(DATE, YYYYMMDD)에 대해 date_weekday 로 요일 인덱스
* (0=일 ~ 6=토)를 구하고 한글 요일명(일~토)으로 매핑하여 요일 인덱스/
* 요일명/주말여부를 응답한다. 순수 로직 요일 산출 공통 서비스. DB 접근 없음.
* 요일명/주말여부를 응답한다. 추가로 영업일 달력(cm_biz_calendar)을
* 조회하여 해당일이 영업일(BIZDAY=Y/N)인지와 비고를 응답한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -21,10 +23,18 @@ TX_SERVICE(CM_OL_0019, ctx)
static const char *WDAY_SHORT[7] = {
"일", "월", "화", "수", "목", "금", "토"
};
EXEC SQL BEGIN DECLARE SECTION;
char h_date[9];
char h_biz_yn[2];
char h_remark[64];
EXEC SQL END DECLARE SECTION;
char date[16];
char label[8];
int wd;
int weekend;
int biz_day;
tx_log(TX_LOG_INFO, "[CM_OL_0019] 요일 계산 서비스 진입");
@ -51,13 +61,33 @@ TX_SERVICE(CM_OL_0019, ctx)
weekend = (wd == 0 || wd == 6) ? 1 : 0;
snprintf(label, sizeof(label), "%s요일", WDAY_SHORT[wd]);
/* 영업일 달력 조회 : 등록이 있으면 그 값을 우선, 없으면 주말 반대로 */
strncpy(h_date, date, sizeof(h_date) - 1);
h_date[sizeof(h_date) - 1] = '\0';
strncpy(h_biz_yn, weekend ? "N" : "Y", sizeof(h_biz_yn));
h_remark[0] = '\0';
EXEC SQL SELECT biz_yn, coalesce(remark, '')
INTO :h_biz_yn, :h_remark
FROM cm_biz_calendar
WHERE cal_date = :h_date;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_DEBUG, "[CM_OL_0019] 달력 미등록 date=%s (요일기준 판정)", date);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0019 SELECT cm_biz_calendar");
}
biz_day = (strcmp(h_biz_yn, "Y") == 0) ? 1 : 0;
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "DATE", date);
tx_buf_setlong(ctx->out, "WDAY", (long)wd);
tx_buf_sets(ctx->out, "WDAYNM", WDAY_SHORT[wd]);
tx_buf_sets(ctx->out, "WDAYLABEL", label);
tx_buf_sets(ctx->out, "WEEKEND", weekend ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0019] 계산완료 date=%s 요일=%s 주말=%s",
date, label, weekend ? "Y" : "N");
tx_buf_sets(ctx->out, "BIZDAY", biz_day ? "Y" : "N");
tx_buf_sets(ctx->out, "REMARK", h_remark);
tx_log(TX_LOG_INFO, "[CM_OL_0019] 계산완료 date=%s 요일=%s 주말=%s 영업일=%s",
date, label, weekend ? "Y" : "N", biz_day ? "Y" : "N");
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -12,13 +12,14 @@
*
* (AMOUNT) // ()
* (: 123000000 -> "일억이천삼백만") . /
* . DB .
* (ATMI void SVC(TPSVCINFO*) )
* . (cm_amt_hangeul_log)
* . (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -91,7 +92,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 17 "app/online/cm_ol_0020.pgc"
#line 18 "app/online/cm_ol_0020.pgc"
/* 0~9999 한 절(節)을 천/백/십 단위 한글로 변환하여 out 에 누적 */
@ -122,12 +123,26 @@ static void hangeul_group(int val, char *out, int outlen)
TX_SERVICE(CM_OL_0020, ctx)
{
static const char *GUNIT[4] = { "", "", "", "" };
/* exec sql begin declare section */
#line 50 "app/online/cm_ol_0020.pgc"
long h_amount ;
#line 51 "app/online/cm_ol_0020.pgc"
char h_hangeul [ 128 ] ;
/* exec sql end declare section */
#line 52 "app/online/cm_ol_0020.pgc"
char hangeul[128];
char won_fmt[48];
long amount = 0;
long n;
long logged = 0;
int neg = 0;
int g;
int groups[4];
int i;
@ -170,10 +185,36 @@ TX_SERVICE(CM_OL_0020, ctx)
/* 교차표시용: 콤마 구분 숫자표기 */
amount_format_won(amount, won_fmt, sizeof(won_fmt));
/* 변환 결과 증서 감사이력 적재 */
h_amount = amount;
strncpy(h_hangeul, hangeul, sizeof(h_hangeul) - 1);
h_hangeul[sizeof(h_hangeul) - 1] = '\0';
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CM_OL_0020] tx_begin 경고");
} else {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into cm_amt_hangeul_log ( amount , hangeul_txt , conv_ts ) values ( $1 , $2 , now ( ) )",
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_hangeul),(long)128,(long)1,(128)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 112 "app/online/cm_ol_0020.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0020 INSERT cm_amt_hangeul_log");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_setlong(ctx->out, "AMOUNT", amount);
tx_buf_sets(ctx->out, "HANGEUL", hangeul);
tx_buf_sets(ctx->out, "WON", won_fmt);
tx_buf_setlong(ctx->out, "LOGGED", logged);
tx_log(TX_LOG_INFO, "[CM_OL_0020] 변환완료 amount=%ld -> %s", amount, hangeul);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,13 +4,14 @@
*
* 요청의 금액(AMOUNT)을 만/억/조 단위 절(節)로 분해하여 한글 금액표기
* (예: 123000000 -> "일억이천삼백만")로 변환하여 응답한다. 증서/전표
* 출력용 순수 로직 변환 서비스. DB 접근 없음.
* (ATMI void SVC(TPSVCINFO*) 대응)
* 출력용 변환 서비스. 변환 결과는 증서 발급 감사이력(cm_amt_hangeul_log)
* 에 적재하여 발급 근거로 남긴다. (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -44,12 +45,18 @@ static void hangeul_group(int val, char *out, int outlen)
TX_SERVICE(CM_OL_0020, ctx)
{
static const char *GUNIT[4] = { "", "만", "억", "조" };
EXEC SQL BEGIN DECLARE SECTION;
long h_amount;
char h_hangeul[128];
EXEC SQL END DECLARE SECTION;
char hangeul[128];
char won_fmt[48];
long amount = 0;
long n;
long logged = 0;
int neg = 0;
int g;
int groups[4];
int i;
@ -92,10 +99,32 @@ TX_SERVICE(CM_OL_0020, ctx)
/* 교차표시용: 콤마 구분 숫자표기 */
amount_format_won(amount, won_fmt, sizeof(won_fmt));
/* 변환 결과 증서 감사이력 적재 */
h_amount = amount;
strncpy(h_hangeul, hangeul, sizeof(h_hangeul) - 1);
h_hangeul[sizeof(h_hangeul) - 1] = '\0';
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CM_OL_0020] tx_begin 경고");
} else {
EXEC SQL INSERT INTO cm_amt_hangeul_log
(amount, hangeul_txt, conv_ts)
VALUES (:h_amount, :h_hangeul, now());
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0020 INSERT cm_amt_hangeul_log");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_setlong(ctx->out, "AMOUNT", amount);
tx_buf_sets(ctx->out, "HANGEUL", hangeul);
tx_buf_sets(ctx->out, "WON", won_fmt);
tx_buf_setlong(ctx->out, "LOGGED", logged);
tx_log(TX_LOG_INFO, "[CM_OL_0020] 변환완료 amount=%ld -> %s", amount, hangeul);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -157,7 +157,7 @@ TX_SERVICE(CM_OL_0021, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_base),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 64 "app/online/cm_ol_0021.pgc"
#line 63 "app/online/cm_ol_0021.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -56,8 +56,7 @@ TX_SERVICE(CM_OL_0021, ctx)
h_rate = 0;
h_scale = 0;
EXEC SQL
SELECT rate, rate_scale, base_cd
EXEC SQL SELECT rate, rate_scale, base_cd
INTO :h_rate, :h_scale, :h_base
FROM cm_rate
WHERE cur_cd = :h_cur

View file

@ -12,12 +12,15 @@
*
* (CARDNO) 6/ 4
* '*' 릿 .
* DB . (ATMI void SVC(TPSVCINFO*) )
* 6(BIN) BIN (mm_card_bin)
* / .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -90,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 16 "app/online/cm_ol_0022.pgc"
#line 19 "app/online/cm_ol_0022.pgc"
/* 카드번호 문자열에서 숫자만 추출해 dst 로 복사, 유효 자릿수 반환 */
@ -110,11 +113,29 @@ static int cm_digits_only(const char *src, char *dst, int dstlen)
TX_SERVICE(CM_OL_0022, ctx)
{
/* exec sql begin declare section */
#line 39 "app/online/cm_ol_0022.pgc"
char h_bin [ 7 ] ;
#line 40 "app/online/cm_ol_0022.pgc"
char h_issuer_cd [ 8 ] ;
#line 41 "app/online/cm_ol_0022.pgc"
char h_brand [ 16 ] ;
/* exec sql end declare section */
#line 42 "app/online/cm_ol_0022.pgc"
char cardno[32];
char digits[24];
char masked[24];
int len;
int i;
int bin_found = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0022] 카드번호 마스킹 서비스 진입");
@ -141,10 +162,39 @@ TX_SERVICE(CM_OL_0022, ctx)
}
masked[len] = '\0';
/* 앞 6자리 BIN 으로 카드사/브랜드 조회 */
memcpy(h_bin, digits, 6);
h_bin[6] = '\0';
h_issuer_cd[0] = '\0';
h_brand[0] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select issuer_cd , brand_nm from mm_card_bin where bin = $1 ",
ECPGt_char,(h_bin),(long)7,(long)1,(7)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_issuer_cd),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_brand),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 85 "app/online/cm_ol_0022.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_INFO, "[CM_OL_0022] 미등록 BIN bin=%s", h_bin);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0022 SELECT mm_card_bin");
} else {
bin_found = 1;
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "MASKED", masked);
tx_buf_setlong(ctx->out, "DIGITS", (long)len);
tx_buf_sets(ctx->out, "BIN", h_bin);
tx_buf_sets(ctx->out, "ISSUER", h_issuer_cd);
tx_buf_sets(ctx->out, "BRAND", h_brand);
tx_buf_sets(ctx->out, "BINFOUND", bin_found ? "Y" : "N");
tx_buf_sets(ctx->out, "RESULT", "OK");
tx_log(TX_LOG_INFO, "[CM_OL_0022] 마스킹 완료 masked=%s len=%d", masked, len);
tx_log(TX_LOG_INFO, "[CM_OL_0022] 마스킹 완료 masked=%s len=%d issuer=%s",
masked, len, h_issuer_cd);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,12 +4,15 @@
*
* 요청의 카드번호(CARDNO)에서 숫자만 추출하여 앞 6자리/뒤 4자리만
* 노출하고 가운데를 '*' 로 치환한 마스킹 결과와 자릿수를 응답한다.
* DB 접근 없는 순수 로직 서비스. (ATMI void SVC(TPSVCINFO*) 대응)
* 아울러 앞 6자리(BIN)로 카드 BIN 마스터(mm_card_bin)를 조회하여
* 카드사코드/브랜드를 응답에 함께 실어 준다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -32,11 +35,18 @@ static int cm_digits_only(const char *src, char *dst, int dstlen)
TX_SERVICE(CM_OL_0022, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bin[7];
char h_issuer_cd[8];
char h_brand[16];
EXEC SQL END DECLARE SECTION;
char cardno[32];
char digits[24];
char masked[24];
int len;
int i;
int bin_found = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0022] 카드번호 마스킹 서비스 진입");
@ -63,10 +73,34 @@ TX_SERVICE(CM_OL_0022, ctx)
}
masked[len] = '\0';
/* 앞 6자리 BIN 으로 카드사/브랜드 조회 */
memcpy(h_bin, digits, 6);
h_bin[6] = '\0';
h_issuer_cd[0] = '\0';
h_brand[0] = '\0';
EXEC SQL SELECT issuer_cd, brand_nm
INTO :h_issuer_cd, :h_brand
FROM mm_card_bin
WHERE bin = :h_bin;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_INFO, "[CM_OL_0022] 미등록 BIN bin=%s", h_bin);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0022 SELECT mm_card_bin");
} else {
bin_found = 1;
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "MASKED", masked);
tx_buf_setlong(ctx->out, "DIGITS", (long)len);
tx_buf_sets(ctx->out, "BIN", h_bin);
tx_buf_sets(ctx->out, "ISSUER", h_issuer_cd);
tx_buf_sets(ctx->out, "BRAND", h_brand);
tx_buf_sets(ctx->out, "BINFOUND", bin_found ? "Y" : "N");
tx_buf_sets(ctx->out, "RESULT", "OK");
tx_log(TX_LOG_INFO, "[CM_OL_0022] 마스킹 완료 masked=%s len=%d", masked, len);
tx_log(TX_LOG_INFO, "[CM_OL_0022] 마스킹 완료 masked=%s len=%d issuer=%s",
masked, len, h_issuer_cd);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -138,7 +138,7 @@ TX_SERVICE(CM_OL_0023, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_char,(h_name),(long)64,(long)1,(64)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 51 "app/online/cm_ol_0023.pgc"
#line 50 "app/online/cm_ol_0023.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -42,8 +42,7 @@ TX_SERVICE(CM_OL_0023, ctx)
strncpy(h_grp, grp, sizeof(h_grp) - 1);
strncpy(h_code, code, sizeof(h_code) - 1);
EXEC SQL
SELECT code_name
EXEC SQL SELECT code_name
INTO :h_name
FROM cm_code
WHERE grp_cd = :h_grp

View file

@ -144,7 +144,7 @@ TX_SERVICE(CM_OL_0024, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_maxval),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 50 "app/online/cm_ol_0024.pgc"
#line 49 "app/online/cm_ol_0024.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -43,8 +43,7 @@ TX_SERVICE(CM_OL_0024, ctx)
h_maxval = 0;
/* 현재값만 읽고 갱신하지 않는다 (미리보기) */
EXEC SQL
SELECT cur_val, inc_by, max_val
EXEC SQL SELECT cur_val, inc_by, max_val
INTO :h_curval, :h_incby, :h_maxval
FROM cm_seq
WHERE seq_key = :h_seqkey;

View file

@ -139,7 +139,7 @@ TX_SERVICE(CM_OL_0025, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_updts),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 50 "app/online/cm_ol_0025.pgc"
#line 49 "app/online/cm_ol_0025.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {

View file

@ -43,8 +43,7 @@ TX_SERVICE(CM_OL_0025, ctx)
memset(&h_updts, 0, sizeof(h_updts));
strncpy(h_pkey, pkey, sizeof(h_pkey) - 1);
EXEC SQL
SELECT param_val, TO_CHAR(upd_ts, 'YYYYMMDDHH24MISS')
EXEC SQL SELECT param_val, TO_CHAR(upd_ts, 'YYYYMMDDHH24MISS')
INTO :h_pval, :h_updts
FROM cm_param
WHERE param_key = :h_pkey;

View file

@ -158,7 +158,7 @@ TX_SERVICE(CM_OL_0026, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_ver),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 71 "app/online/cm_ol_0026.pgc"
#line 70 "app/online/cm_ol_0026.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
@ -188,7 +188,7 @@ TX_SERVICE(CM_OL_0026, ctx)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_ckey),(long)32,(long)1,(32)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 99 "app/online/cm_ol_0026.pgc"
#line 97 "app/online/cm_ol_0026.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {

View file

@ -64,8 +64,7 @@ TX_SERVICE(CM_OL_0026, ctx)
h_ver = 0;
/* 현재 캐시버전 조회 */
EXEC SQL
SELECT cache_ver
EXEC SQL SELECT cache_ver
INTO :h_ver
FROM cm_param
WHERE param_key = :h_ckey;
@ -92,8 +91,7 @@ TX_SERVICE(CM_OL_0026, ctx)
return;
}
EXEC SQL
UPDATE cm_param
EXEC SQL UPDATE cm_param
SET cache_ver = :newver,
upd_ts = SYSTIMESTAMP
WHERE param_key = :h_ckey;

View file

@ -11,13 +11,15 @@
* cm_ol_0027.pgc - (CM_OL_0027) [tier=medium]
*
* (NUMBER: / ) Luhn(10)
* (VALID=Y/N) . DB .
* (VALID=Y/N) .
* (cm_luhn_audit) .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -90,7 +92,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 16 "app/online/cm_ol_0027.pgc"
#line 18 "app/online/cm_ol_0027.pgc"
/* 숫자만 추출 후 자릿수 반환 */
@ -133,11 +135,33 @@ static int cm_luhn_mod(const char *digits, int len, int offset)
TX_SERVICE(CM_OL_0027, ctx)
{
/* exec sql begin declare section */
#line 61 "app/online/cm_ol_0027.pgc"
char h_bin [ 7 ] ;
#line 62 "app/online/cm_ol_0027.pgc"
long h_num_len ;
#line 63 "app/online/cm_ol_0027.pgc"
char h_valid [ 2 ] ;
#line 64 "app/online/cm_ol_0027.pgc"
long h_checkdigit ;
/* exec sql end declare section */
#line 65 "app/online/cm_ol_0027.pgc"
char number[40];
char digits[36];
int len;
int valid;
int checkdigit;
long logged = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0027] 체크디짓 검증 서비스 진입");
@ -160,10 +184,42 @@ TX_SERVICE(CM_OL_0027, ctx)
/* 본체(마지막 자리 제외)에 대해 산출되는 정상 체크디짓 */
checkdigit = (10 - cm_luhn_mod(digits, len - 1, 0)) % 10;
/* 검증 시도·결과 감사이력 적재 (BIN 은 앞 6자리, 부족 시 있는 만큼) */
memset(h_bin, 0, sizeof(h_bin));
memcpy(h_bin, digits, (len >= 6) ? 6 : len);
h_num_len = (long)len;
strncpy(h_valid, valid ? "Y" : "N", sizeof(h_valid));
h_checkdigit = (long)checkdigit;
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CM_OL_0027] tx_begin 경고");
} else {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into cm_luhn_audit ( bin6 , num_len , valid_yn , check_digit , chk_ts ) values ( $1 , $2 , $3 , $4 , now ( ) )",
ECPGt_char,(h_bin),(long)7,(long)1,(7)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_num_len),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_valid),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_checkdigit),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 107 "app/online/cm_ol_0027.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0027 INSERT cm_luhn_audit");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_setlong(ctx->out, "DIGITS", (long)len);
tx_buf_sets(ctx->out, "VALID", valid ? "Y" : "N");
tx_buf_setlong(ctx->out, "CHECKDIGIT", (long)checkdigit);
tx_buf_setlong(ctx->out, "LOGGED", logged);
tx_log(TX_LOG_INFO, "[CM_OL_0027] 검증완료 len=%d valid=%s cd=%d",
len, valid ? "Y" : "N", checkdigit);
tx_return(ctx, TX_OK, ctx->out);

View file

@ -3,13 +3,15 @@
* cm_ol_0027.pgc - 체크디짓 검증 서비스 (CM_OL_0027) [tier=medium]
*
* 입력 번호(NUMBER: 카드/계좌 등)에 Luhn(모드10) 알고리즘을 적용하여
* 유효성(VALID=Y/N)과 계산된 체크디짓을 응답한다. DB 접근 없는 순수 로직.
* 유효성(VALID=Y/N)과 계산된 체크디짓을 응답한다. 검증 시도와 결과는
* 무결성 감사이력(cm_luhn_audit)에 적재하여 사후 추적을 지원한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -55,11 +57,19 @@ static int cm_luhn_mod(const char *digits, int len, int offset)
TX_SERVICE(CM_OL_0027, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bin[7];
long h_num_len;
char h_valid[2];
long h_checkdigit;
EXEC SQL END DECLARE SECTION;
char number[40];
char digits[36];
int len;
int valid;
int checkdigit;
long logged = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0027] 체크디짓 검증 서비스 진입");
@ -82,10 +92,34 @@ TX_SERVICE(CM_OL_0027, ctx)
/* 본체(마지막 자리 제외)에 대해 산출되는 정상 체크디짓 */
checkdigit = (10 - cm_luhn_mod(digits, len - 1, 0)) % 10;
/* 검증 시도·결과 감사이력 적재 (BIN 은 앞 6자리, 부족 시 있는 만큼) */
memset(h_bin, 0, sizeof(h_bin));
memcpy(h_bin, digits, (len >= 6) ? 6 : len);
h_num_len = (long)len;
strncpy(h_valid, valid ? "Y" : "N", sizeof(h_valid));
h_checkdigit = (long)checkdigit;
if (tx_begin() != TX_OK) {
tx_log(TX_LOG_WARN, "[CM_OL_0027] tx_begin 경고");
} else {
EXEC SQL INSERT INTO cm_luhn_audit
(bin6, num_len, valid_yn, check_digit, chk_ts)
VALUES (:h_bin, :h_num_len, :h_valid, :h_checkdigit, now());
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0027 INSERT cm_luhn_audit");
tx_abort();
} else {
logged = (long)sqlca.sqlerrd[2];
tx_commit();
}
}
tx_buf_reset(ctx->out);
tx_buf_setlong(ctx->out, "DIGITS", (long)len);
tx_buf_sets(ctx->out, "VALID", valid ? "Y" : "N");
tx_buf_setlong(ctx->out, "CHECKDIGIT", (long)checkdigit);
tx_buf_setlong(ctx->out, "LOGGED", logged);
tx_log(TX_LOG_INFO, "[CM_OL_0027] 검증완료 len=%d valid=%s cd=%d",
len, valid ? "Y" : "N", checkdigit);
tx_return(ctx, TX_OK, ctx->out);

View file

@ -12,12 +12,15 @@
*
* (HHMMSS 6) HH:MM:SS
* ( 0~23, / 0~59) .
* DB . (ATMI void SVC(TPSVCINFO*) )
* (cm_time_policy) (cutoff_secs)
* (AFTERCUTOFF=Y/N) .
* (ATMI void SVC(TPSVCINFO*) )
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -90,11 +93,24 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
#line 16 "app/online/cm_ol_0028.pgc"
#line 19 "app/online/cm_ol_0028.pgc"
TX_SERVICE(CM_OL_0028, ctx)
{
/* exec sql begin declare section */
#line 24 "app/online/cm_ol_0028.pgc"
char h_policy [ 16 ] ;
#line 25 "app/online/cm_ol_0028.pgc"
long h_cutoff ;
/* exec sql end declare section */
#line 26 "app/online/cm_ol_0028.pgc"
char hms[16];
char formatted[16];
int hh;
@ -102,6 +118,7 @@ TX_SERVICE(CM_OL_0028, ctx)
int ss;
int i;
long secs;
int after_cutoff = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0028] 시간 포맷 변환 서비스 진입");
@ -138,10 +155,35 @@ TX_SERVICE(CM_OL_0028, ctx)
sprintf(formatted, "%02d:%02d:%02d", hh, mm, ss);
secs = (long)hh * 3600 + (long)mm * 60 + ss;
/* 시간정책 조회 : 마감시각(초). 정책구분 미지정 시 CUTOFF 기본 */
if (tx_buf_get(ctx->in, "POLICY", h_policy, sizeof(h_policy)) != TX_OK)
strncpy(h_policy, "CUTOFF", sizeof(h_policy) - 1);
h_policy[sizeof(h_policy) - 1] = '\0';
h_cutoff = -1;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select cutoff_secs from cm_time_policy where policy_cd = $1 and use_yn = 'Y'",
ECPGt_char,(h_policy),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_cutoff),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 82 "app/online/cm_ol_0028.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_INFO, "[CM_OL_0028] 시간정책 미등록 policy=%s", h_policy);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0028 SELECT cm_time_policy");
} else if (h_cutoff >= 0 && secs > h_cutoff) {
after_cutoff = 1;
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "HMS", hms);
tx_buf_sets(ctx->out, "FORMATTED", formatted);
tx_buf_setlong(ctx->out, "SECONDS", secs);
tx_log(TX_LOG_INFO, "[CM_OL_0028] 변환완료 %s -> %s (%ld초)", hms, formatted, secs);
tx_buf_setlong(ctx->out, "CUTOFF", h_cutoff);
tx_buf_sets(ctx->out, "AFTERCUTOFF", after_cutoff ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0028] 변환완료 %s -> %s (%ld초) cutoff=%ld",
hms, formatted, secs, h_cutoff);
tx_return(ctx, TX_OK, ctx->out);
}

View file

@ -4,12 +4,15 @@
*
* 입력 시각(HHMMSS 6자리)을 HH:MM:SS 로 변환하고 각 필드의 범위를
* 검증(시 0~23, 분/초 0~59)하여 포맷 결과와 총 경과초를 응답한다.
* DB 접근 없는 순수 로직 서비스. (ATMI void SVC(TPSVCINFO*) 대응)
* 아울러 시간정책 마스터(cm_time_policy)에서 마감시각(cutoff_secs)을
* 조회하여 입력 시각의 마감초과 여부(AFTERCUTOFF=Y/N)를 통지한다.
* (ATMI void SVC(TPSVCINFO*) 대응)
*/
#include <stdio.h>
#include <string.h>
#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"
@ -17,6 +20,11 @@ EXEC SQL INCLUDE sqlca;
TX_SERVICE(CM_OL_0028, ctx)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_policy[16];
long h_cutoff;
EXEC SQL END DECLARE SECTION;
char hms[16];
char formatted[16];
int hh;
@ -24,6 +32,7 @@ TX_SERVICE(CM_OL_0028, ctx)
int ss;
int i;
long secs;
int after_cutoff = 0;
tx_log(TX_LOG_INFO, "[CM_OL_0028] 시간 포맷 변환 서비스 진입");
@ -60,10 +69,33 @@ TX_SERVICE(CM_OL_0028, ctx)
sprintf(formatted, "%02d:%02d:%02d", hh, mm, ss);
secs = (long)hh * 3600 + (long)mm * 60 + ss;
/* 시간정책 조회 : 마감시각(초). 정책구분 미지정 시 CUTOFF 기본 */
if (tx_buf_get(ctx->in, "POLICY", h_policy, sizeof(h_policy)) != TX_OK)
strncpy(h_policy, "CUTOFF", sizeof(h_policy) - 1);
h_policy[sizeof(h_policy) - 1] = '\0';
h_cutoff = -1;
EXEC SQL SELECT cutoff_secs
INTO :h_cutoff
FROM cm_time_policy
WHERE policy_cd = :h_policy
AND use_yn = 'Y';
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_INFO, "[CM_OL_0028] 시간정책 미등록 policy=%s", h_policy);
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("CM_OL_0028 SELECT cm_time_policy");
} else if (h_cutoff >= 0 && secs > h_cutoff) {
after_cutoff = 1;
}
tx_buf_reset(ctx->out);
tx_buf_sets(ctx->out, "HMS", hms);
tx_buf_sets(ctx->out, "FORMATTED", formatted);
tx_buf_setlong(ctx->out, "SECONDS", secs);
tx_log(TX_LOG_INFO, "[CM_OL_0028] 변환완료 %s -> %s (%ld초)", hms, formatted, secs);
tx_buf_setlong(ctx->out, "CUTOFF", h_cutoff);
tx_buf_sets(ctx->out, "AFTERCUTOFF", after_cutoff ? "Y" : "N");
tx_log(TX_LOG_INFO, "[CM_OL_0028] 변환완료 %s -> %s (%ld초) cutoff=%ld",
hms, formatted, secs, h_cutoff);
tx_return(ctx, TX_OK, ctx->out);
}

Some files were not shown because too many files have changed in this diff Show more