다양화: 530개 online/batch 프로그램을 모듈별 고유 실업무 로직으로 재작성

- 템플릿 클론(정규화 후 0줄 상이) → 전 코퍼스 530/530 고유 바디
- 11개 모듈(mg/au/ac/rc/vl/st/py/lg/mm/cm/cl) 각 파일이 distinct한
  매입·대사·정산·수수료·지급·원장·마감·마스터·정합성·전문게이트웨이·공통 업무
- TxCore(ATMI 유사) + ECPG(EXEC SQL) 관용구, 프레임워크/헤더/DBIO API/파일ID·경로 유지
- 전체 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 01:37:54 +00:00
parent b96cf702ee
commit c3a0259e95
1027 changed files with 68915 additions and 40962 deletions

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0001.pgc" #line 1 "app/batch/ac_bt_0001.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0001.pgc - ( + ) [tier=easy] * ac_bt_0001.pgc - ( ) [tier=easy]
* *
* (status='R') * (status='R')
* ('M')/('U') . main . * ('M')/('U') ,
* / . main .
* *
* : ac_bt_0001 <YYYYMMDD> [db@host] * : ac_bt_0001 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0001.pgc" #line 20 "app/batch/ac_bt_0001.pgc"
static int run_ac_bt_0001(const char *biz_date) static int run_ac_bt_0001(const char *biz_date)
@ -104,42 +105,48 @@ static int run_ac_bt_0001(const char *biz_date)
#line 24 "app/batch/ac_bt_0001.pgc" #line 25 "app/batch/ac_bt_0001.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0001.pgc" #line 26 "app/batch/ac_bt_0001.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0001.pgc" #line 27 "app/batch/ac_bt_0001.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0001.pgc" #line 28 "app/batch/ac_bt_0001.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0001.pgc" #line 29 "app/batch/ac_bt_0001.pgc"
long h_fee ;
#line 30 "app/batch/ac_bt_0001.pgc"
char h_new_status [ 2 ] ; char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0001.pgc" #line 31 "app/batch/ac_bt_0001.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, done = 0, unmatch = 0, errcnt = 0;
long sum_amount = 0, sum_fee = 0;
char buf_amt[32], buf_fee[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0001 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0001 cursor for select key , merch_id , amount , fee from ac_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/ac_bt_0001.pgc" #line 46 "app/batch/ac_bt_0001.pgc"
#line 42 "app/batch/ac_bt_0001.pgc" #line 46 "app/batch/ac_bt_0001.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0001 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0001 cursor for select key , merch_id , amount , fee from ac_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0001.pgc" #line 48 "app/batch/ac_bt_0001.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0001"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0001");
@ -156,8 +163,10 @@ static int run_ac_bt_0001(const char *biz_date)
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0001.pgc" #line 58 "app/batch/ac_bt_0001.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -174,6 +183,8 @@ static int run_ac_bt_0001(const char *biz_date)
if (amount_is_valid(h_amount)) { if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; done++;
sum_amount += h_amount;
sum_fee += h_fee;
} else { } else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++; unmatch++;
@ -187,7 +198,7 @@ static int run_ac_bt_0001(const char *biz_date)
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0001", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0001", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0001.pgc" #line 88 "app/batch/ac_bt_0001.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +206,22 @@ static int run_ac_bt_0001(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0001] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", amount_format_won(sum_fee, buf_fee, sizeof(buf_fee));
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0001] ==========\n"); tx_log(TX_LOG_INFO,
"[ac_bt_0001] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld 매입금액=%ld 수수료=%ld",
biz_date, total, done, unmatch, errcnt, sum_amount, sum_fee);
printf("========== 매입 배치마감 결과 [ac_bt_0001] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf(" 총매입금액 : %s\n", buf_amt);
printf(" 총수수료 : %s\n", buf_fee);
printf("=====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0001.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0001.pgc - 매입 배치마감 (일마감 상태전이) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 접수(status='R') 건을 커서로 순회하며 금액 유효성에
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 따라 완료('M')/불일치('U') 로 상태를 전이하고, 완료 건에 대해
* 총매입금액/총수수료를 집계한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0001 <YYYYMMDD> [db@host] * 실행: ac_bt_0001 <YYYYMMDD> [db@host]
*/ */
@ -25,17 +26,20 @@ static int run_ac_bt_0001(const char *biz_date)
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
long h_amount; long h_amount;
long h_fee;
char h_new_status[2]; char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, done = 0, unmatch = 0, errcnt = 0;
long sum_amount = 0, sum_fee = 0;
char buf_amt[32], buf_fee[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0001 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0001 CURSOR FOR
SELECT key, merch_id, amount SELECT key, merch_id, amount, fee
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'R'
@ -51,7 +55,7 @@ static int run_ac_bt_0001(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0001] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0001] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0001 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0001 INTO :h_key, :h_merch_id, :h_amount, :h_fee;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -67,6 +71,8 @@ static int run_ac_bt_0001(const char *biz_date)
if (amount_is_valid(h_amount)) { if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; done++;
sum_amount += h_amount;
sum_fee += h_fee;
} else { } else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++; unmatch++;
@ -86,17 +92,22 @@ static int run_ac_bt_0001(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0001] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", amount_format_won(sum_fee, buf_fee, sizeof(buf_fee));
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0001] ==========\n"); tx_log(TX_LOG_INFO,
"[ac_bt_0001] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld 매입금액=%ld 수수료=%ld",
biz_date, total, done, unmatch, errcnt, sum_amount, sum_fee);
printf("========== 매입 배치마감 결과 [ac_bt_0001] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf(" 총매입금액 : %s\n", buf_amt);
printf(" 총수수료 : %s\n", buf_fee);
printf("=====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,10 @@
#line 1 "app/batch/ac_bt_0002.pgc" #line 1 "app/batch/ac_bt_0002.pgc"
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0002.pgc - ( + ) [tier=medium] * ac_bt_0002.pgc - [tier=medium]
* *
* (status='R') * (status='U')
* ('M')/('U') . main . * (ac_claim, status='X') /. main .
* *
* : ac_bt_0002 <YYYYMMDD> [db@host] * : ac_bt_0002 <YYYYMMDD> [db@host]
*/ */
@ -104,6 +104,8 @@ static int run_ac_bt_0002(const char *biz_date)
#line 24 "app/batch/ac_bt_0002.pgc" #line 24 "app/batch/ac_bt_0002.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
@ -118,28 +120,35 @@ static int run_ac_bt_0002(const char *biz_date)
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0002.pgc" #line 28 "app/batch/ac_bt_0002.pgc"
char h_new_status [ 2 ] ; char h_claim_no [ 20 ] ;
/* exec sql end declare section */
#line 29 "app/batch/ac_bt_0002.pgc" #line 29 "app/batch/ac_bt_0002.pgc"
int h_file_seq ;
#line 30 "app/batch/ac_bt_0002.pgc"
char h_status [ 2 ] ;
/* exec sql end declare section */
#line 31 "app/batch/ac_bt_0002.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, extracted = 0, errcnt = 0;
int rc; long sum_amount = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0002 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0002 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'U' order by key */
#line 42 "app/batch/ac_bt_0002.pgc" #line 45 "app/batch/ac_bt_0002.pgc"
#line 42 "app/batch/ac_bt_0002.pgc" #line 45 "app/batch/ac_bt_0002.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0002 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0002 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'U' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0002.pgc" #line 47 "app/batch/ac_bt_0002.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0002"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0002");
@ -149,6 +158,9 @@ static int run_ac_bt_0002(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0002] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0002] tx_begin 경고");
strncpy(h_status, "X", sizeof(h_status));
h_status[sizeof(h_status) - 1] = '\0';
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0002", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0002", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
@ -157,7 +169,7 @@ static int run_ac_bt_0002(const char *biz_date)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0002.pgc" #line 60 "app/batch/ac_bt_0002.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -169,25 +181,40 @@ static int run_ac_bt_0002(const char *biz_date)
} }
total++; total++;
h_file_seq = 0;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 미매입목록 파일번호(claim_no) 는 원거래키 기반으로 채번한다 */
if (amount_is_valid(h_amount)) { snprintf(h_claim_no, sizeof(h_claim_no), "UNM%s", h_key);
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ac_claim ( claim_no , merch_id , biz_date , amount , file_seq , status ) values ( $1 , $2 , $3 , $4 , $5 , $6 )",
if (rc != TX_OK) { ECPGt_char,(h_claim_no),(long)20,(long)1,(20)*sizeof(char),
tx_log(TX_LOG_ERROR, "[ac_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc); 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_biz_date),(long)9,(long)1,(9)*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_int,&(h_file_seq),(long)1,(long)1,sizeof(int),
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_EOIT, ECPGt_EORT);}
#line 79 "app/batch/ac_bt_0002.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0002");
tx_log(TX_LOG_ERROR, "[ac_bt_0002] 미매입 추출 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
extracted++;
sum_amount += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0002", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0002", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0002.pgc" #line 92 "app/batch/ac_bt_0002.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +222,19 @@ static int run_ac_bt_0002(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0002] ==========\n"); tx_log(TX_LOG_INFO,
"[ac_bt_0002] 요약 date=%s 대상=%ld 추출=%ld 오류=%ld 금액=%ld",
biz_date, total, extracted, errcnt, sum_amount);
printf("========== 미매입 추출 결과 [ac_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 추출 건수 : %ld\n", extracted);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf(" 추출 총액 : %s\n", buf_amt);
printf("====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,9 @@
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0002.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=medium] * ac_bt_0002.pgc - 매입 추출 배치 [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 불일치(status='U') 건을 커서로 순회하며 미매입목록
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * (ac_claim, status='X') 으로 추출/적재한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0002 <YYYYMMDD> [db@host] * 실행: ac_bt_0002 <YYYYMMDD> [db@host]
*/ */
@ -25,11 +25,14 @@ static int run_ac_bt_0002(const char *biz_date)
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2]; char h_claim_no[20];
int h_file_seq;
char h_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, extracted = 0, errcnt = 0;
int rc; long sum_amount = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
@ -38,7 +41,7 @@ static int run_ac_bt_0002(const char *biz_date)
SELECT key, merch_id, amount SELECT key, merch_id, amount
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'U'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0002; EXEC SQL OPEN cur_ac_bt_0002;
@ -50,6 +53,9 @@ static int run_ac_bt_0002(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0002] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0002] tx_begin 경고");
strncpy(h_status, "X", sizeof(h_status));
h_status[sizeof(h_status) - 1] = '\0';
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0002 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0002 INTO :h_key, :h_merch_id, :h_amount;
@ -62,21 +68,25 @@ static int run_ac_bt_0002(const char *biz_date)
} }
total++; total++;
h_file_seq = 0;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 미매입목록 파일번호(claim_no) 는 원거래키 기반으로 채번한다 */
if (amount_is_valid(h_amount)) { snprintf(h_claim_no, sizeof(h_claim_no), "UNM%s", h_key);
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); EXEC SQL INSERT INTO ac_claim
if (rc != TX_OK) { (claim_no, merch_id, biz_date, amount, file_seq, status)
tx_log(TX_LOG_ERROR, "[ac_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc); VALUES
(:h_claim_no, :h_merch_id, :h_biz_date, :h_amount, :h_file_seq, :h_status);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0002");
tx_log(TX_LOG_ERROR, "[ac_bt_0002] 미매입 추출 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
extracted++;
sum_amount += h_amount;
} }
EXEC SQL CLOSE cur_ac_bt_0002; EXEC SQL CLOSE cur_ac_bt_0002;
@ -86,17 +96,19 @@ static int run_ac_bt_0002(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0002] ==========\n"); tx_log(TX_LOG_INFO,
"[ac_bt_0002] 요약 date=%s 대상=%ld 추출=%ld 오류=%ld 금액=%ld",
biz_date, total, extracted, errcnt, sum_amount);
printf("========== 미매입 추출 결과 [ac_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 추출 건수 : %ld\n", extracted);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf(" 추출 총액 : %s\n", buf_amt);
printf("====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0003.pgc" #line 1 "app/batch/ac_bt_0003.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0003.pgc - ( + ) [tier=easy] * ac_bt_0003.pgc - [tier=easy]
* *
* (status='R') * (status='U')
* ('M')/('U') . main . * ('M') .
* (). main .
* *
* : ac_bt_0003 <YYYYMMDD> [db@host] * : ac_bt_0003 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0003.pgc" #line 20 "app/batch/ac_bt_0003.pgc"
static int run_ac_bt_0003(const char *biz_date) static int run_ac_bt_0003(const char *biz_date)
@ -105,41 +106,41 @@ static int run_ac_bt_0003(const char *biz_date)
#line 24 "app/batch/ac_bt_0003.pgc" #line 25 "app/batch/ac_bt_0003.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0003.pgc" #line 26 "app/batch/ac_bt_0003.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0003.pgc" #line 27 "app/batch/ac_bt_0003.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0003.pgc" #line 28 "app/batch/ac_bt_0003.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0003.pgc" #line 29 "app/batch/ac_bt_0003.pgc"
char h_new_status [ 2 ] ; char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0003.pgc" #line 30 "app/batch/ac_bt_0003.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, reprocessed = 0, still_fail = 0, errcnt = 0;
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0003 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0003 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'U' order by key */
#line 42 "app/batch/ac_bt_0003.pgc" #line 43 "app/batch/ac_bt_0003.pgc"
#line 42 "app/batch/ac_bt_0003.pgc" #line 43 "app/batch/ac_bt_0003.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0003 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0003 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'U' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0003.pgc" #line 45 "app/batch/ac_bt_0003.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0003"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0003");
@ -157,7 +158,7 @@ static int run_ac_bt_0003(const char *biz_date)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0003.pgc" #line 55 "app/batch/ac_bt_0003.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -170,24 +171,26 @@ static int run_ac_bt_0003(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 업무규칙: 금액 유효성 재검증 - 유효하면 재처리 성공 */
if (amount_is_valid(h_amount)) { if (!amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); still_fail++;
done++; tx_log(TX_LOG_WARN, "[ac_bt_0003] 재처리 보류 key=%s amount=%ld", h_key, h_amount);
} else { continue;
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
rc = ac_rec_update_status(h_key, h_new_status); rc = ac_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[ac_bt_0003] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[ac_bt_0003] 재처리 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
reprocessed++;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0003", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0003", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0003.pgc" #line 85 "app/batch/ac_bt_0003.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +199,16 @@ static int run_ac_bt_0003(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0003] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0003] 요약 date=%s 대상=%ld 재처리성공=%ld 재실패=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, reprocessed, still_fail, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0003] ==========\n"); printf("========== 미매입 재처리 결과 [ac_bt_0003] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 재처리성공(M) : %ld\n", reprocessed);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 재실패(U) : %ld\n", still_fail);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0003.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0003.pgc - 매입 재처리 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 불일치(status='U') 건을 커서로 순회하며 금액 유효성을
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 재검증하여 완료('M') 로 재전이한다. 여전히 유효하지 않으면 상태를
* 그대로 둔다(재실패). 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0003 <YYYYMMDD> [db@host] * 실행: ac_bt_0003 <YYYYMMDD> [db@host]
*/ */
@ -28,7 +29,7 @@ static int run_ac_bt_0003(const char *biz_date)
char h_new_status[2]; char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, reprocessed = 0, still_fail = 0, errcnt = 0;
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
@ -38,7 +39,7 @@ static int run_ac_bt_0003(const char *biz_date)
SELECT key, merch_id, amount SELECT key, merch_id, amount
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'U'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0003; EXEC SQL OPEN cur_ac_bt_0003;
@ -63,20 +64,22 @@ static int run_ac_bt_0003(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 업무규칙: 금액 유효성 재검증 - 유효하면 재처리 성공 */
if (amount_is_valid(h_amount)) { if (!amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); still_fail++;
done++; tx_log(TX_LOG_WARN, "[ac_bt_0003] 재처리 보류 key=%s amount=%ld", h_key, h_amount);
} else { continue;
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
rc = ac_rec_update_status(h_key, h_new_status); rc = ac_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[ac_bt_0003] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[ac_bt_0003] 재처리 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
reprocessed++;
} }
EXEC SQL CLOSE cur_ac_bt_0003; EXEC SQL CLOSE cur_ac_bt_0003;
@ -87,16 +90,16 @@ static int run_ac_bt_0003(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0003] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0003] 요약 date=%s 대상=%ld 재처리성공=%ld 재실패=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, reprocessed, still_fail, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0003] ==========\n"); printf("========== 미매입 재처리 결과 [ac_bt_0003] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 재처리성공(M) : %ld\n", reprocessed);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 재실패(U) : %ld\n", still_fail);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0004.pgc" #line 1 "app/batch/ac_bt_0004.pgc"
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0004.pgc - ( + ) [tier=medium] * ac_bt_0004.pgc - EDI [tier=medium]
* *
* (status='R') * (status='M') SEQ
* ('M')/('U') . main . * ac_claim(status='C') .
* main .
* *
* : ac_bt_0004 <YYYYMMDD> [db@host] * : ac_bt_0004 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0004.pgc" #line 20 "app/batch/ac_bt_0004.pgc"
static int run_ac_bt_0004(const char *biz_date) static int run_ac_bt_0004(const char *biz_date)
@ -104,42 +105,52 @@ static int run_ac_bt_0004(const char *biz_date)
#line 24 "app/batch/ac_bt_0004.pgc" #line 25 "app/batch/ac_bt_0004.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0004.pgc" #line 26 "app/batch/ac_bt_0004.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0004.pgc" #line 27 "app/batch/ac_bt_0004.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0004.pgc" #line 28 "app/batch/ac_bt_0004.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0004.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */
#line 29 "app/batch/ac_bt_0004.pgc" #line 29 "app/batch/ac_bt_0004.pgc"
char h_claim_no [ 20 ] ;
#line 30 "app/batch/ac_bt_0004.pgc"
int h_file_seq ;
#line 31 "app/batch/ac_bt_0004.pgc"
char h_status [ 2 ] ;
/* exec sql end declare section */
#line 32 "app/batch/ac_bt_0004.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, lines = 0, errcnt = 0;
int rc; long sum_amount = 0;
int file_seq = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0004 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0004 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'M' order by key */
#line 42 "app/batch/ac_bt_0004.pgc" #line 47 "app/batch/ac_bt_0004.pgc"
#line 42 "app/batch/ac_bt_0004.pgc" #line 47 "app/batch/ac_bt_0004.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0004 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0004 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'M' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0004.pgc" #line 49 "app/batch/ac_bt_0004.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0004"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0004");
@ -149,6 +160,9 @@ static int run_ac_bt_0004(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0004] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0004] tx_begin 경고");
strncpy(h_status, "C", sizeof(h_status));
h_status[sizeof(h_status) - 1] = '\0';
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0004", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0004", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
@ -157,7 +171,7 @@ static int run_ac_bt_0004(const char *biz_date)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0004.pgc" #line 62 "app/batch/ac_bt_0004.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -169,25 +183,40 @@ static int run_ac_bt_0004(const char *biz_date)
} }
total++; total++;
file_seq++;
h_file_seq = file_seq;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ snprintf(h_claim_no, sizeof(h_claim_no), "CLM%s", h_key);
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ac_claim ( claim_no , merch_id , biz_date , amount , file_seq , status ) values ( $1 , $2 , $3 , $4 , $5 , $6 )",
if (rc != TX_OK) { ECPGt_char,(h_claim_no),(long)20,(long)1,(20)*sizeof(char),
tx_log(TX_LOG_ERROR, "[ac_bt_0004] 상태전이 실패 key=%s rc=%d", h_key, rc); 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_biz_date),(long)9,(long)1,(9)*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_int,&(h_file_seq),(long)1,(long)1,sizeof(int),
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_EOIT, ECPGt_EORT);}
#line 81 "app/batch/ac_bt_0004.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0004");
tx_log(TX_LOG_ERROR, "[ac_bt_0004] 청구라인 생성 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
lines++;
sum_amount += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0004", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0004", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0004.pgc" #line 94 "app/batch/ac_bt_0004.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +224,20 @@ static int run_ac_bt_0004(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0004] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0004] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0004] 요약 date=%s 대상=%ld 청구건수=%ld 오류=%ld 금액=%ld 최종SEQ=%d",
printf(" 대상 건수 : %ld\n", total); biz_date, total, lines, errcnt, sum_amount, file_seq);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== EDI 매입청구 파일생성 결과 [ac_bt_0004] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 청구 건수 : %ld\n", lines);
printf(" 오류 건수 : %ld\n", errcnt);
printf(" 청구 총액 : %s\n", buf_amt);
printf(" 파일SEQ 최종 : %d\n", file_seq);
printf("==============================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0004.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=medium] * ac_bt_0004.pgc - EDI 매입청구 파일생성 배치 [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 완료(status='M') 건을 커서로 순회하며 청구파일 SEQ 를
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 채번하여 ac_claim(status='C') 에 청구 라인으로 적재한다.
* 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0004 <YYYYMMDD> [db@host] * 실행: ac_bt_0004 <YYYYMMDD> [db@host]
*/ */
@ -25,11 +26,15 @@ static int run_ac_bt_0004(const char *biz_date)
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2]; char h_claim_no[20];
int h_file_seq;
char h_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, lines = 0, errcnt = 0;
int rc; long sum_amount = 0;
int file_seq = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
@ -38,7 +43,7 @@ static int run_ac_bt_0004(const char *biz_date)
SELECT key, merch_id, amount SELECT key, merch_id, amount
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'M'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0004; EXEC SQL OPEN cur_ac_bt_0004;
@ -50,6 +55,9 @@ static int run_ac_bt_0004(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0004] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0004] tx_begin 경고");
strncpy(h_status, "C", sizeof(h_status));
h_status[sizeof(h_status) - 1] = '\0';
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0004 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0004 INTO :h_key, :h_merch_id, :h_amount;
@ -62,21 +70,25 @@ static int run_ac_bt_0004(const char *biz_date)
} }
total++; total++;
file_seq++;
h_file_seq = file_seq;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ snprintf(h_claim_no, sizeof(h_claim_no), "CLM%s", h_key);
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); EXEC SQL INSERT INTO ac_claim
if (rc != TX_OK) { (claim_no, merch_id, biz_date, amount, file_seq, status)
tx_log(TX_LOG_ERROR, "[ac_bt_0004] 상태전이 실패 key=%s rc=%d", h_key, rc); VALUES
(:h_claim_no, :h_merch_id, :h_biz_date, :h_amount, :h_file_seq, :h_status);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0004");
tx_log(TX_LOG_ERROR, "[ac_bt_0004] 청구라인 생성 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
lines++;
sum_amount += h_amount;
} }
EXEC SQL CLOSE cur_ac_bt_0004; EXEC SQL CLOSE cur_ac_bt_0004;
@ -86,17 +98,20 @@ static int run_ac_bt_0004(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0004] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0004] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0004] 요약 date=%s 대상=%ld 청구건수=%ld 오류=%ld 금액=%ld 최종SEQ=%d",
printf(" 대상 건수 : %ld\n", total); biz_date, total, lines, errcnt, sum_amount, file_seq);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== EDI 매입청구 파일생성 결과 [ac_bt_0004] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 청구 건수 : %ld\n", lines);
printf(" 오류 건수 : %ld\n", errcnt);
printf(" 청구 총액 : %s\n", buf_amt);
printf(" 파일SEQ 최종 : %d\n", file_seq);
printf("==============================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0005.pgc" #line 1 "app/batch/ac_bt_0005.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0005.pgc - ( + ) [tier=easy] * ac_bt_0005.pgc - [tier=easy]
* *
* (status='R') * (ac_stage)
* ('M')/('U') . main . * (ac_ledger, status='R') . 1%
* . main .
* *
* : ac_bt_0005 <YYYYMMDD> [db@host] * : ac_bt_0005 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0005.pgc" #line 20 "app/batch/ac_bt_0005.pgc"
static int run_ac_bt_0005(const char *biz_date) static int run_ac_bt_0005(const char *biz_date)
@ -104,42 +105,51 @@ static int run_ac_bt_0005(const char *biz_date)
#line 24 "app/batch/ac_bt_0005.pgc" #line 25 "app/batch/ac_bt_0005.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0005.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0005.pgc" #line 26 "app/batch/ac_bt_0005.pgc"
char h_merch_id [ 16 ] ; char h_stg_key [ 16 ] ;
#line 27 "app/batch/ac_bt_0005.pgc" #line 27 "app/batch/ac_bt_0005.pgc"
long h_amount ; char h_merch_id [ 16 ] ;
#line 28 "app/batch/ac_bt_0005.pgc" #line 28 "app/batch/ac_bt_0005.pgc"
char h_new_status [ 2 ] ; char h_card_no [ 20 ] ;
/* exec sql end declare section */
#line 29 "app/batch/ac_bt_0005.pgc" #line 29 "app/batch/ac_bt_0005.pgc"
long h_amount ;
#line 30 "app/batch/ac_bt_0005.pgc"
long h_fee ;
#line 31 "app/batch/ac_bt_0005.pgc"
char h_status [ 2 ] ;
/* exec sql end declare section */
#line 32 "app/batch/ac_bt_0005.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, loaded = 0, errcnt = 0;
int rc; long sum_amount = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0005 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0005 cursor for select stg_key , merch_id , card_no , amount from ac_stage where biz_date = $1 order by stg_key */
#line 42 "app/batch/ac_bt_0005.pgc" #line 45 "app/batch/ac_bt_0005.pgc"
#line 42 "app/batch/ac_bt_0005.pgc" #line 45 "app/batch/ac_bt_0005.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0005 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0005 cursor for select stg_key , merch_id , card_no , amount from ac_stage where biz_date = $1 order by stg_key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0005.pgc" #line 47 "app/batch/ac_bt_0005.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0005"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0005");
@ -149,15 +159,20 @@ static int run_ac_bt_0005(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0005] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0005] tx_begin 경고");
strncpy(h_status, AC_ST_RECV, sizeof(h_status));
h_status[sizeof(h_status) - 1] = '\0';
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0005", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0005", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_stg_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0005.pgc" #line 60 "app/batch/ac_bt_0005.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -169,25 +184,39 @@ static int run_ac_bt_0005(const char *biz_date)
} }
total++; total++;
h_fee = h_amount / 100;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ac_ledger ( key , merch_id , card_no , amount , biz_date , status , fee ) values ( $1 , $2 , $3 , $4 , $5 , $6 , $7 )",
if (amount_is_valid(h_amount)) { ECPGt_char,(h_stg_key),(long)16,(long)1,(16)*sizeof(char),
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
done++; ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
} else { ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); ECPGt_char,(h_card_no),(long)20,(long)1,(20)*sizeof(char),
unmatch++; 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_biz_date),(long)9,(long)1,(9)*sizeof(char),
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_long,&(h_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 76 "app/batch/ac_bt_0005.pgc"
rc = ac_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
tx_log(TX_LOG_ERROR, "[ac_bt_0005] 상태전이 실패 key=%s rc=%d", h_key, rc); TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0005");
tx_log(TX_LOG_ERROR, "[ac_bt_0005] 적재 실패 key=%s", h_stg_key);
errcnt++; errcnt++;
continue;
} }
loaded++;
sum_amount += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0005", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0005", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0005.pgc" #line 89 "app/batch/ac_bt_0005.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +224,19 @@ static int run_ac_bt_0005(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0005] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0005] ==========\n"); tx_log(TX_LOG_INFO,
"[ac_bt_0005] 요약 date=%s 대상=%ld 적재=%ld 오류=%ld 금액=%ld",
biz_date, total, loaded, errcnt, sum_amount);
printf("========== 대량 매입 적재 결과 [ac_bt_0005] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 적재 건수 : %ld\n", loaded);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf(" 적재 총액 : %s\n", buf_amt);
printf("======================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0005.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0005.pgc - 대량 매입 적재 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 가적재(ac_stage) 건을 커서로 순회하며 매입원장
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * (ac_ledger, status='R') 으로 적재한다. 수수료는 거래금액의 1%로
* 임시 산정한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0005 <YYYYMMDD> [db@host] * 실행: ac_bt_0005 <YYYYMMDD> [db@host]
*/ */
@ -22,24 +23,26 @@ static int run_ac_bt_0005(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_stg_key[16];
char h_merch_id[16]; char h_merch_id[16];
char h_card_no[20];
long h_amount; long h_amount;
char h_new_status[2]; long h_fee;
char h_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, loaded = 0, errcnt = 0;
int rc; long sum_amount = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0005 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0005 CURSOR FOR
SELECT key, merch_id, amount SELECT stg_key, merch_id, card_no, amount
FROM ac_ledger FROM ac_stage
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' ORDER BY stg_key;
ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0005; EXEC SQL OPEN cur_ac_bt_0005;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -50,8 +53,11 @@ static int run_ac_bt_0005(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0005] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0005] tx_begin 경고");
strncpy(h_status, AC_ST_RECV, sizeof(h_status));
h_status[sizeof(h_status) - 1] = '\0';
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0005 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0005 INTO :h_stg_key, :h_merch_id, :h_card_no, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -62,21 +68,22 @@ static int run_ac_bt_0005(const char *biz_date)
} }
total++; total++;
h_fee = h_amount / 100;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ EXEC SQL INSERT INTO ac_ledger
if (amount_is_valid(h_amount)) { (key, merch_id, card_no, amount, biz_date, status, fee)
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); VALUES
done++; (:h_stg_key, :h_merch_id, :h_card_no, :h_amount, :h_biz_date, :h_status, :h_fee);
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); if (sqlca.sqlcode != TX_SQL_OK) {
if (rc != TX_OK) { TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0005");
tx_log(TX_LOG_ERROR, "[ac_bt_0005] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[ac_bt_0005] 적재 실패 key=%s", h_stg_key);
errcnt++; errcnt++;
continue;
} }
loaded++;
sum_amount += h_amount;
} }
EXEC SQL CLOSE cur_ac_bt_0005; EXEC SQL CLOSE cur_ac_bt_0005;
@ -86,17 +93,19 @@ static int run_ac_bt_0005(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amount, buf_amt, sizeof(buf_amt));
"[ac_bt_0005] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0005] ==========\n"); tx_log(TX_LOG_INFO,
"[ac_bt_0005] 요약 date=%s 대상=%ld 적재=%ld 오류=%ld 금액=%ld",
biz_date, total, loaded, errcnt, sum_amount);
printf("========== 대량 매입 적재 결과 [ac_bt_0005] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 적재 건수 : %ld\n", loaded);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf(" 적재 총액 : %s\n", buf_amt);
printf("======================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0006.pgc" #line 1 "app/batch/ac_bt_0006.pgc"
/* @tier hard @module ac @transform acquire-batch */ /* @tier hard @module ac @transform acquire-batch */
/* /*
* ac_bt_0006.pgc - ( + ) [tier=hard] * ac_bt_0006.pgc - [tier=hard]
* *
* (status='R') * (status='M') (merch_id)
* ('M')/('U') . main . * (ac_stat) . (corp_cd )
* . main .
* *
* : ac_bt_0006 <YYYYMMDD> [db@host] * : ac_bt_0006 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0006.pgc" #line 20 "app/batch/ac_bt_0006.pgc"
static int run_ac_bt_0006(const char *biz_date) static int run_ac_bt_0006(const char *biz_date)
@ -103,43 +104,40 @@ static int run_ac_bt_0006(const char *biz_date)
#line 24 "app/batch/ac_bt_0006.pgc"
char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0006.pgc" #line 25 "app/batch/ac_bt_0006.pgc"
char h_key [ 16 ] ; char h_biz_date [ 9 ] ;
#line 26 "app/batch/ac_bt_0006.pgc" #line 26 "app/batch/ac_bt_0006.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0006.pgc" #line 27 "app/batch/ac_bt_0006.pgc"
long h_amount ; long h_cnt ;
#line 28 "app/batch/ac_bt_0006.pgc" #line 28 "app/batch/ac_bt_0006.pgc"
char h_new_status [ 2 ] ; long h_sum ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0006.pgc" #line 29 "app/batch/ac_bt_0006.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, grand_cnt = 0, errcnt = 0;
int rc; long grand_total = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0006 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0006 cursor for select merch_id , count ( * ) , sum ( amount ) from ac_ledger where biz_date = $1 and status = 'M' group by merch_id order by merch_id */
#line 42 "app/batch/ac_bt_0006.pgc" #line 44 "app/batch/ac_bt_0006.pgc"
#line 42 "app/batch/ac_bt_0006.pgc" #line 44 "app/batch/ac_bt_0006.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0006 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0006 cursor for select merch_id , count ( * ) , sum ( amount ) from ac_ledger where biz_date = $1 and status = 'M' group by merch_id order by merch_id",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0006.pgc" #line 46 "app/batch/ac_bt_0006.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0006"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0006");
@ -151,13 +149,13 @@ static int run_ac_bt_0006(const char *biz_date)
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0006", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0006", ECPGt_EOIT,
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_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_cnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0006.pgc" #line 56 "app/batch/ac_bt_0006.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,26 +166,32 @@ static int run_ac_bt_0006(const char *biz_date)
break; break;
} }
total++; { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ac_stat ( biz_date , corp_cd , tot_cnt , tot_amt ) values ( $1 , $2 , $3 , $4 )",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*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_long,&(h_cnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 69 "app/batch/ac_bt_0006.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); if (sqlca.sqlcode != TX_SQL_OK) {
if (rc != TX_OK) { TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0006");
tx_log(TX_LOG_ERROR, "[ac_bt_0006] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[ac_bt_0006] 집계 적재 실패 merch_id=%s", h_merch_id);
errcnt++; errcnt++;
continue;
} }
merchants++;
grand_cnt += h_cnt;
grand_total += h_sum;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0006", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0006", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0006.pgc" #line 83 "app/batch/ac_bt_0006.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +199,19 @@ static int run_ac_bt_0006(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(grand_total, buf_amt, sizeof(buf_amt));
"[ac_bt_0006] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0006] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0006] 요약 date=%s 가맹점수=%ld 총건수=%ld 오류=%ld 총금액=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, merchants, grand_cnt, errcnt, grand_total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 가맹점별 매입집계 결과 [ac_bt_0006] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 가맹점 수 : %ld\n", merchants);
printf(" 총 매입건수 : %ld\n", grand_cnt);
printf(" 오류 건수 : %ld\n", errcnt);
printf(" 총 매입금액 : %s\n", buf_amt);
printf("==========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier hard @module ac @transform acquire-batch */ /* @tier hard @module ac @transform acquire-batch */
/* /*
* ac_bt_0006.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=hard] * ac_bt_0006.pgc - 가맹점별 매입집계 배치 [tier=hard]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 완료(status='M') 건을 가맹점(merch_id) 별로 집계하여
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 통계(ac_stat) 에 적재한다. 가맹점별 통계키(corp_cd 컬럼)는 가맹점
* 번호를 그대로 사용한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0006 <YYYYMMDD> [db@host] * 실행: ac_bt_0006 <YYYYMMDD> [db@host]
*/ */
@ -22,24 +23,25 @@ static int run_ac_bt_0006(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
long h_amount; long h_cnt;
char h_new_status[2]; long h_sum;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, grand_cnt = 0, errcnt = 0;
int rc; long grand_total = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0006 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0006 CURSOR FOR
SELECT key, merch_id, amount SELECT merch_id, count(*), sum(amount)
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'M'
ORDER BY key; GROUP BY merch_id
ORDER BY merch_id;
EXEC SQL OPEN cur_ac_bt_0006; EXEC SQL OPEN cur_ac_bt_0006;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -51,7 +53,7 @@ static int run_ac_bt_0006(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0006] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0006] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0006 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0006 INTO :h_merch_id, :h_cnt, :h_sum;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,22 +63,21 @@ static int run_ac_bt_0006(const char *biz_date)
break; break;
} }
total++; EXEC SQL INSERT INTO ac_stat
(biz_date, corp_cd, tot_cnt, tot_amt)
VALUES
(:h_biz_date, :h_merch_id, :h_cnt, :h_sum);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) {
if (amount_is_valid(h_amount)) { TX_DBIO_LOG_ERR("INSERT cur_ac_bt_0006");
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); tx_log(TX_LOG_ERROR, "[ac_bt_0006] 집계 적재 실패 merch_id=%s", h_merch_id);
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[ac_bt_0006] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
merchants++;
grand_cnt += h_cnt;
grand_total += h_sum;
} }
EXEC SQL CLOSE cur_ac_bt_0006; EXEC SQL CLOSE cur_ac_bt_0006;
@ -86,17 +87,19 @@ static int run_ac_bt_0006(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(grand_total, buf_amt, sizeof(buf_amt));
"[ac_bt_0006] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0006] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0006] 요약 date=%s 가맹점수=%ld 총건수=%ld 오류=%ld 총금액=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, merchants, grand_cnt, errcnt, grand_total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 가맹점별 매입집계 결과 [ac_bt_0006] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 가맹점 수 : %ld\n", merchants);
printf(" 총 매입건수 : %ld\n", grand_cnt);
printf(" 오류 건수 : %ld\n", errcnt);
printf(" 총 매입금액 : %s\n", buf_amt);
printf("==========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0007.pgc" #line 1 "app/batch/ac_bt_0007.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0007.pgc - ( + ) [tier=easy] * ac_bt_0007.pgc - [tier=easy]
* *
* (status='R') * BIN 2
* ('M')/('U') . main . * (corp_cd) .
* ('94'=KB, '95'=SH, '96'=HN, =ETC). main .
* *
* : ac_bt_0007 <YYYYMMDD> [db@host] * : ac_bt_0007 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0007.pgc" #line 20 "app/batch/ac_bt_0007.pgc"
static int run_ac_bt_0007(const char *biz_date) static int run_ac_bt_0007(const char *biz_date)
@ -103,40 +104,37 @@ static int run_ac_bt_0007(const char *biz_date)
#line 24 "app/batch/ac_bt_0007.pgc" #line 25 "app/batch/ac_bt_0007.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0007.pgc" #line 26 "app/batch/ac_bt_0007.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0007.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0007.pgc" #line 27 "app/batch/ac_bt_0007.pgc"
long h_amount ; char h_card_no [ 20 ] ;
#line 28 "app/batch/ac_bt_0007.pgc" #line 28 "app/batch/ac_bt_0007.pgc"
char h_new_status [ 2 ] ; char h_corp_cd [ 4 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0007.pgc" #line 29 "app/batch/ac_bt_0007.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0;
int rc; long cnt_kb = 0, cnt_sh = 0, cnt_hn = 0, cnt_etc = 0;
char bin2[3];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0007 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0007 cursor for select key , card_no from ac_ledger where biz_date = $1 order by key */
#line 42 "app/batch/ac_bt_0007.pgc" #line 42 "app/batch/ac_bt_0007.pgc"
#line 42 "app/batch/ac_bt_0007.pgc" #line 42 "app/batch/ac_bt_0007.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0007 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0007 cursor for select key , card_no from ac_ledger where biz_date = $1 order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0007.pgc" #line 44 "app/batch/ac_bt_0007.pgc"
@ -153,9 +151,7 @@ static int run_ac_bt_0007(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0007", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0007", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), 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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0007.pgc" #line 54 "app/batch/ac_bt_0007.pgc"
@ -170,24 +166,48 @@ static int run_ac_bt_0007(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 업무규칙: 카드번호 BIN 앞 2자리로 카드사 판별 */
if (amount_is_valid(h_amount)) { bin2[0] = h_card_no[0];
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); bin2[1] = h_card_no[1];
done++; bin2[2] = '\0';
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); if (strcmp(bin2, "94") == 0) {
if (rc != TX_OK) { strncpy(h_corp_cd, "KB", sizeof(h_corp_cd));
tx_log(TX_LOG_ERROR, "[ac_bt_0007] 상태전이 실패 key=%s rc=%d", h_key, rc); cnt_kb++;
} else if (strcmp(bin2, "95") == 0) {
strncpy(h_corp_cd, "SH", sizeof(h_corp_cd));
cnt_sh++;
} else if (strcmp(bin2, "96") == 0) {
strncpy(h_corp_cd, "HN", sizeof(h_corp_cd));
cnt_hn++;
} else {
strncpy(h_corp_cd, "ETC", sizeof(h_corp_cd));
cnt_etc++;
}
h_corp_cd[sizeof(h_corp_cd) - 1] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update ac_ledger set corp_cd = $1 where key = $2 ",
ECPGt_char,(h_corp_cd),(long)4,(long)1,(4)*sizeof(char),
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 88 "app/batch/ac_bt_0007.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE cur_ac_bt_0007");
tx_log(TX_LOG_ERROR, "[ac_bt_0007] 분류 반영 실패 key=%s", h_key);
errcnt++;
continue;
}
if (sqlca.sqlerrd[2] == 0) {
tx_log(TX_LOG_WARN, "[ac_bt_0007] 대상없음 key=%s", h_key);
errcnt++; errcnt++;
} }
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0007", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0007", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0007.pgc" #line 102 "app/batch/ac_bt_0007.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +216,18 @@ static int run_ac_bt_0007(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0007] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0007] 요약 date=%s 대상=%ld KB=%ld SH=%ld HN=%ld ETC=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, cnt_kb, cnt_sh, cnt_hn, cnt_etc, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0007] ==========\n"); printf("========== 카드사별 매입분류 결과 [ac_bt_0007] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" KB : %ld\n", cnt_kb);
printf(" 불일치(U) : %ld\n", unmatch); printf(" SH : %ld\n", cnt_sh);
printf(" HN : %ld\n", cnt_hn);
printf(" ETC : %ld\n", cnt_etc);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("==========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0007.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0007.pgc - 카드사별 매입분류 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일 전체 매입 건을 커서로 순회하며 카드번호 BIN 앞 2자리로
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 카드사(corp_cd) 를 판별하여 매입원장에 반영한다.
* ('94'=KB, '95'=SH, '96'=HN, 그 외=ETC). 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0007 <YYYYMMDD> [db@host] * 실행: ac_bt_0007 <YYYYMMDD> [db@host]
*/ */
@ -23,22 +24,21 @@ static int run_ac_bt_0007(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_card_no[20];
long h_amount; char h_corp_cd[4];
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0;
int rc; long cnt_kb = 0, cnt_sh = 0, cnt_hn = 0, cnt_etc = 0;
char bin2[3];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0007 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0007 CURSOR FOR
SELECT key, merch_id, amount SELECT key, card_no
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0007; EXEC SQL OPEN cur_ac_bt_0007;
@ -51,7 +51,7 @@ static int run_ac_bt_0007(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0007] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0007] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0007 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0007 INTO :h_key, :h_card_no;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -63,18 +63,38 @@ static int run_ac_bt_0007(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 업무규칙: 카드번호 BIN 앞 2자리로 카드사 판별 */
if (amount_is_valid(h_amount)) { bin2[0] = h_card_no[0];
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); bin2[1] = h_card_no[1];
done++; bin2[2] = '\0';
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); if (strcmp(bin2, "94") == 0) {
if (rc != TX_OK) { strncpy(h_corp_cd, "KB", sizeof(h_corp_cd));
tx_log(TX_LOG_ERROR, "[ac_bt_0007] 상태전이 실패 key=%s rc=%d", h_key, rc); cnt_kb++;
} else if (strcmp(bin2, "95") == 0) {
strncpy(h_corp_cd, "SH", sizeof(h_corp_cd));
cnt_sh++;
} else if (strcmp(bin2, "96") == 0) {
strncpy(h_corp_cd, "HN", sizeof(h_corp_cd));
cnt_hn++;
} else {
strncpy(h_corp_cd, "ETC", sizeof(h_corp_cd));
cnt_etc++;
}
h_corp_cd[sizeof(h_corp_cd) - 1] = '\0';
EXEC SQL UPDATE ac_ledger
SET corp_cd = :h_corp_cd
WHERE key = :h_key;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE cur_ac_bt_0007");
tx_log(TX_LOG_ERROR, "[ac_bt_0007] 분류 반영 실패 key=%s", h_key);
errcnt++;
continue;
}
if (sqlca.sqlerrd[2] == 0) {
tx_log(TX_LOG_WARN, "[ac_bt_0007] 대상없음 key=%s", h_key);
errcnt++; errcnt++;
} }
} }
@ -87,16 +107,18 @@ static int run_ac_bt_0007(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0007] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0007] 요약 date=%s 대상=%ld KB=%ld SH=%ld HN=%ld ETC=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, cnt_kb, cnt_sh, cnt_hn, cnt_etc, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0007] ==========\n"); printf("========== 카드사별 매입분류 결과 [ac_bt_0007] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" KB : %ld\n", cnt_kb);
printf(" 불일치(U) : %ld\n", unmatch); printf(" SH : %ld\n", cnt_sh);
printf(" HN : %ld\n", cnt_hn);
printf(" ETC : %ld\n", cnt_etc);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("==========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0008.pgc" #line 1 "app/batch/ac_bt_0008.pgc"
/* @tier hard @module ac @transform acquire-batch */ /* @tier hard @module ac @transform acquire-batch */
/* /*
* ac_bt_0008.pgc - ( + ) [tier=hard] * ac_bt_0008.pgc - () [tier=hard]
* *
* (status='R') * (status='M') (merchant.fee_rate)
* ('M')/('U') . main . * ( * / 10000),
* . main .
* *
* : ac_bt_0008 <YYYYMMDD> [db@host] * : ac_bt_0008 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0008.pgc" #line 20 "app/batch/ac_bt_0008.pgc"
static int run_ac_bt_0008(const char *biz_date) static int run_ac_bt_0008(const char *biz_date)
@ -104,42 +105,46 @@ static int run_ac_bt_0008(const char *biz_date)
#line 24 "app/batch/ac_bt_0008.pgc" #line 25 "app/batch/ac_bt_0008.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0008.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0008.pgc" #line 26 "app/batch/ac_bt_0008.pgc"
char h_merch_id [ 16 ] ; char h_key [ 16 ] ;
#line 27 "app/batch/ac_bt_0008.pgc" #line 27 "app/batch/ac_bt_0008.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0008.pgc" #line 28 "app/batch/ac_bt_0008.pgc"
char h_new_status [ 2 ] ; long h_old_fee ;
/* exec sql end declare section */
#line 29 "app/batch/ac_bt_0008.pgc" #line 29 "app/batch/ac_bt_0008.pgc"
long h_fee_rate ;
#line 30 "app/batch/ac_bt_0008.pgc"
long h_new_fee ;
/* exec sql end declare section */
#line 31 "app/batch/ac_bt_0008.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, adjusted = 0, errcnt = 0;
int rc; long delta_sum = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0008 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0008 cursor for select l . key , l . amount , l . fee , m . fee_rate from ac_ledger l join merchant m on l . merch_id = m . merch_id where l . biz_date = $1 and l . status = 'M' order by l . key */
#line 42 "app/batch/ac_bt_0008.pgc" #line 45 "app/batch/ac_bt_0008.pgc"
#line 42 "app/batch/ac_bt_0008.pgc" #line 45 "app/batch/ac_bt_0008.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0008 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0008 cursor for select l . key , l . amount , l . fee , m . fee_rate from ac_ledger l join merchant m on l . merch_id = m . merch_id where l . biz_date = $1 and l . status = 'M' order by l . key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0008.pgc" #line 47 "app/batch/ac_bt_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0008"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0008");
@ -153,11 +158,13 @@ static int run_ac_bt_0008(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0008", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0008", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_old_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_fee_rate),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0008.pgc" #line 57 "app/batch/ac_bt_0008.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -170,24 +177,35 @@ static int run_ac_bt_0008(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 업무규칙: 신규수수료 = 금액 * 수수료율(bp) / 10000 */
if (amount_is_valid(h_amount)) { h_new_fee = h_amount * h_fee_rate / 10000;
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update ac_ledger set fee = $1 where key = $2 ",
} else { ECPGt_long,&(h_new_fee),(long)1,(long)1,sizeof(long),
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
unmatch++; ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 74 "app/batch/ac_bt_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE cur_ac_bt_0008");
tx_log(TX_LOG_ERROR, "[ac_bt_0008] 수수료 조정 실패 key=%s", h_key);
errcnt++;
continue;
}
if (sqlca.sqlerrd[2] == 0) {
tx_log(TX_LOG_WARN, "[ac_bt_0008] 대상없음 key=%s", h_key);
errcnt++;
continue;
} }
rc = ac_rec_update_status(h_key, h_new_status); adjusted++;
if (rc != TX_OK) { delta_sum += (h_new_fee - h_old_fee);
tx_log(TX_LOG_ERROR, "[ac_bt_0008] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0008", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0008", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0008.pgc" #line 92 "app/batch/ac_bt_0008.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +214,16 @@ static int run_ac_bt_0008(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0008] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0008] 요약 date=%s 대상=%ld 조정건수=%ld 오류=%ld 증감액=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, adjusted, errcnt, delta_sum);
printf("========== 매입 배치 결과 [ac_bt_0008] ==========\n"); printf("========== 매입 수수료 조정 결과 [ac_bt_0008] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 조정 건수 : %ld\n", adjusted);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 총 수수료 증감 : %ld\n", delta_sum);
printf("=============================================\n"); printf("=========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier hard @module ac @transform acquire-batch */ /* @tier hard @module ac @transform acquire-batch */
/* /*
* ac_bt_0008.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=hard] * ac_bt_0008.pgc - 매입 수수료 조정(재계산) 배치 [tier=hard]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 완료(status='M') 건을 가맹점 수수료율(merchant.fee_rate)
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 과 조인하여 수수료를 재계산(금액 * 수수료율 / 10000)하고, 기존 수수료
* 와의 증감분을 집계한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0008 <YYYYMMDD> [db@host] * 실행: ac_bt_0008 <YYYYMMDD> [db@host]
*/ */
@ -23,23 +24,25 @@ static int run_ac_bt_0008(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2]; long h_old_fee;
long h_fee_rate;
long h_new_fee;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, adjusted = 0, errcnt = 0;
int rc; long delta_sum = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0008 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0008 CURSOR FOR
SELECT key, merch_id, amount SELECT l.key, l.amount, l.fee, m.fee_rate
FROM ac_ledger FROM ac_ledger l
WHERE biz_date = :h_biz_date JOIN merchant m ON l.merch_id = m.merch_id
AND status = 'R' WHERE l.biz_date = :h_biz_date
ORDER BY key; AND l.status = 'M'
ORDER BY l.key;
EXEC SQL OPEN cur_ac_bt_0008; EXEC SQL OPEN cur_ac_bt_0008;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -51,7 +54,7 @@ static int run_ac_bt_0008(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0008] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0008] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0008 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0008 INTO :h_key, :h_amount, :h_old_fee, :h_fee_rate;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -63,20 +66,27 @@ static int run_ac_bt_0008(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* 업무규칙: 신규수수료 = 금액 * 수수료율(bp) / 10000 */
if (amount_is_valid(h_amount)) { h_new_fee = h_amount * h_fee_rate / 10000;
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; EXEC SQL UPDATE ac_ledger
} else { SET fee = :h_new_fee
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); WHERE key = :h_key;
unmatch++;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE cur_ac_bt_0008");
tx_log(TX_LOG_ERROR, "[ac_bt_0008] 수수료 조정 실패 key=%s", h_key);
errcnt++;
continue;
}
if (sqlca.sqlerrd[2] == 0) {
tx_log(TX_LOG_WARN, "[ac_bt_0008] 대상없음 key=%s", h_key);
errcnt++;
continue;
} }
rc = ac_rec_update_status(h_key, h_new_status); adjusted++;
if (rc != TX_OK) { delta_sum += (h_new_fee - h_old_fee);
tx_log(TX_LOG_ERROR, "[ac_bt_0008] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_ac_bt_0008; EXEC SQL CLOSE cur_ac_bt_0008;
@ -87,16 +97,16 @@ static int run_ac_bt_0008(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0008] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0008] 요약 date=%s 대상=%ld 조정건수=%ld 오류=%ld 증감액=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, adjusted, errcnt, delta_sum);
printf("========== 매입 배치 결과 [ac_bt_0008] ==========\n"); printf("========== 매입 수수료 조정 결과 [ac_bt_0008] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 조정 건수 : %ld\n", adjusted);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 총 수수료 증감 : %ld\n", delta_sum);
printf("=============================================\n"); printf("=========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0009.pgc" #line 1 "app/batch/ac_bt_0009.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0009.pgc - ( + ) [tier=easy] * ac_bt_0009.pgc - [tier=easy]
* *
* (status='R') * (cur_code<>'KRW')
* ('M')/('U') . main . * (fx_rate) .
* main .
* *
* : ac_bt_0009 <YYYYMMDD> [db@host] * : ac_bt_0009 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0009.pgc" #line 20 "app/batch/ac_bt_0009.pgc"
static int run_ac_bt_0009(const char *biz_date) static int run_ac_bt_0009(const char *biz_date)
@ -104,42 +105,47 @@ static int run_ac_bt_0009(const char *biz_date)
#line 24 "app/batch/ac_bt_0009.pgc" #line 25 "app/batch/ac_bt_0009.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0009.pgc" #line 26 "app/batch/ac_bt_0009.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0009.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0009.pgc" #line 27 "app/batch/ac_bt_0009.pgc"
long h_amount ; char h_cur_code [ 5 ] ;
#line 28 "app/batch/ac_bt_0009.pgc" #line 28 "app/batch/ac_bt_0009.pgc"
char h_new_status [ 2 ] ; long h_fx_amount ;
/* exec sql end declare section */
#line 29 "app/batch/ac_bt_0009.pgc" #line 29 "app/batch/ac_bt_0009.pgc"
long h_base_rate ;
#line 30 "app/batch/ac_bt_0009.pgc"
long h_krw ;
/* exec sql end declare section */
#line 31 "app/batch/ac_bt_0009.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, converted = 0, norate = 0, errcnt = 0;
int rc; long sum_krw = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0009 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0009 cursor for select key , cur_code , fx_amount from ac_ledger where biz_date = $1 and cur_code is not null and cur_code <> 'KRW' order by key */
#line 42 "app/batch/ac_bt_0009.pgc" #line 46 "app/batch/ac_bt_0009.pgc"
#line 42 "app/batch/ac_bt_0009.pgc" #line 46 "app/batch/ac_bt_0009.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0009 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0009 cursor for select key , cur_code , fx_amount from ac_ledger where biz_date = $1 and cur_code is not null and cur_code <> 'KRW' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0009.pgc" #line 48 "app/batch/ac_bt_0009.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0009"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0009");
@ -153,11 +159,11 @@ static int run_ac_bt_0009(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0009", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0009", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_cur_code),(long)5,(long)1,(5)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_fx_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0009.pgc" #line 58 "app/batch/ac_bt_0009.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -170,24 +176,56 @@ static int run_ac_bt_0009(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select base_rate from fx_rate where cur_code = $1 and rate_date = $2 ",
if (amount_is_valid(h_amount)) { ECPGt_char,(h_cur_code),(long)5,(long)1,(5)*sizeof(char),
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
done++; ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
} else { ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); ECPGt_long,&(h_base_rate),(long)1,(long)1,sizeof(long),
unmatch++; ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 74 "app/batch/ac_bt_0009.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[ac_bt_0009] 환율없음 key=%s cur=%s", h_key, h_cur_code);
norate++;
continue;
}
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("SELECT fx_rate");
errcnt++;
continue;
} }
rc = ac_rec_update_status(h_key, h_new_status); /* 업무규칙: 원화환산액 = 외화금액 * 기준환율 / 10000 */
if (rc != TX_OK) { h_krw = h_fx_amount * h_base_rate / 10000;
tx_log(TX_LOG_ERROR, "[ac_bt_0009] 상태전이 실패 key=%s rc=%d", h_key, rc);
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update ac_ledger set amount = $1 where key = $2 ",
ECPGt_long,&(h_krw),(long)1,(long)1,sizeof(long),
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 92 "app/batch/ac_bt_0009.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE cur_ac_bt_0009");
tx_log(TX_LOG_ERROR, "[ac_bt_0009] 환산 반영 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
if (sqlca.sqlerrd[2] == 0) {
tx_log(TX_LOG_WARN, "[ac_bt_0009] 대상없음 key=%s", h_key);
errcnt++;
continue;
}
converted++;
sum_krw += h_krw;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0009", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0009", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0009.pgc" #line 110 "app/batch/ac_bt_0009.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +233,20 @@ static int run_ac_bt_0009(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_krw, buf_amt, sizeof(buf_amt));
"[ac_bt_0009] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0009] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0009] 요약 date=%s 대상=%ld 환산=%ld 환율없음=%ld 오류=%ld 금액=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, total, converted, norate, errcnt, sum_krw);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 해외매입 환산 결과 [ac_bt_0009] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 환산 건수 : %ld\n", converted);
printf(" 환율없음 : %ld\n", norate);
printf(" 오류 건수 : %ld\n", errcnt);
printf(" 총 환산금액 : %s\n", buf_amt);
printf("=====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0009.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0009.pgc - 해외매입 환산 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 외화(cur_code<>'KRW') 매입 건을 커서로 순회하며
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 통화별 당일 기준환율(fx_rate)로 원화 환산하여 매입원장에 반영한다.
* 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0009 <YYYYMMDD> [db@host] * 실행: ac_bt_0009 <YYYYMMDD> [db@host]
*/ */
@ -23,22 +24,25 @@ static int run_ac_bt_0009(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_cur_code[5];
long h_amount; long h_fx_amount;
char h_new_status[2]; long h_base_rate;
long h_krw;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, converted = 0, norate = 0, errcnt = 0;
int rc; long sum_krw = 0;
char buf_amt[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0009 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0009 CURSOR FOR
SELECT key, merch_id, amount SELECT key, cur_code, fx_amount
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND cur_code IS NOT NULL
AND cur_code <> 'KRW'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0009; EXEC SQL OPEN cur_ac_bt_0009;
@ -51,7 +55,7 @@ static int run_ac_bt_0009(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0009] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0009] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0009 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0009 INTO :h_key, :h_cur_code, :h_fx_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -63,20 +67,44 @@ static int run_ac_bt_0009(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ EXEC SQL SELECT base_rate
if (amount_is_valid(h_amount)) { INTO :h_base_rate
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); FROM fx_rate
done++; WHERE cur_code = :h_cur_code
} else { AND rate_date = :h_biz_date;
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++; if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
tx_log(TX_LOG_WARN, "[ac_bt_0009] 환율없음 key=%s cur=%s", h_key, h_cur_code);
norate++;
continue;
}
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("SELECT fx_rate");
errcnt++;
continue;
} }
rc = ac_rec_update_status(h_key, h_new_status); /* 업무규칙: 원화환산액 = 외화금액 * 기준환율 / 10000 */
if (rc != TX_OK) { h_krw = h_fx_amount * h_base_rate / 10000;
tx_log(TX_LOG_ERROR, "[ac_bt_0009] 상태전이 실패 key=%s rc=%d", h_key, rc);
EXEC SQL UPDATE ac_ledger
SET amount = :h_krw
WHERE key = :h_key;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE cur_ac_bt_0009");
tx_log(TX_LOG_ERROR, "[ac_bt_0009] 환산 반영 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
if (sqlca.sqlerrd[2] == 0) {
tx_log(TX_LOG_WARN, "[ac_bt_0009] 대상없음 key=%s", h_key);
errcnt++;
continue;
}
converted++;
sum_krw += h_krw;
} }
EXEC SQL CLOSE cur_ac_bt_0009; EXEC SQL CLOSE cur_ac_bt_0009;
@ -86,17 +114,20 @@ static int run_ac_bt_0009(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_krw, buf_amt, sizeof(buf_amt));
"[ac_bt_0009] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0009] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0009] 요약 date=%s 대상=%ld 환산=%ld 환율없음=%ld 오류=%ld 금액=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, total, converted, norate, errcnt, sum_krw);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 해외매입 환산 결과 [ac_bt_0009] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 환산 건수 : %ld\n", converted);
printf(" 환율없음 : %ld\n", norate);
printf(" 오류 건수 : %ld\n", errcnt);
printf(" 총 환산금액 : %s\n", buf_amt);
printf("=====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,12 @@
#line 1 "app/batch/ac_bt_0010.pgc" #line 1 "app/batch/ac_bt_0010.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0010.pgc - ( + ) [tier=easy] * ac_bt_0010.pgc - [tier=easy]
* *
* (status='R') * (acq_type='INST', install_month>=2,
* ('M')/('U') . main . * orig_key IS NULL) () .
* orig_key ,
* () 1 . main .
* *
* : ac_bt_0010 <YYYYMMDD> [db@host] * : ac_bt_0010 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +95,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0010.pgc" #line 21 "app/batch/ac_bt_0010.pgc"
static int run_ac_bt_0010(const char *biz_date) static int run_ac_bt_0010(const char *biz_date)
@ -104,42 +106,72 @@ static int run_ac_bt_0010(const char *biz_date)
#line 24 "app/batch/ac_bt_0010.pgc" #line 26 "app/batch/ac_bt_0010.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0010.pgc" #line 27 "app/batch/ac_bt_0010.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0010.pgc" #line 28 "app/batch/ac_bt_0010.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0010.pgc" #line 29 "app/batch/ac_bt_0010.pgc"
char h_card_no [ 20 ] ;
#line 30 "app/batch/ac_bt_0010.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0010.pgc" #line 31 "app/batch/ac_bt_0010.pgc"
char h_new_status [ 2 ] ; int h_install_month ;
#line 32 "app/batch/ac_bt_0010.pgc"
char h_child_key [ 16 ] ;
#line 33 "app/batch/ac_bt_0010.pgc"
long h_child_amount ;
#line 34 "app/batch/ac_bt_0010.pgc"
char h_status [ 2 ] ;
#line 35 "app/batch/ac_bt_0010.pgc"
char h_acq_type [ 9 ] ;
#line 36 "app/batch/ac_bt_0010.pgc"
char h_orig_key [ 16 ] ;
#line 37 "app/batch/ac_bt_0010.pgc"
long h_fee ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0010.pgc" #line 38 "app/batch/ac_bt_0010.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long parents = 0, children = 0, errcnt = 0;
int rc; long monthly, remainder;
int m;
char keybuf[16];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0010 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0010 cursor for select key , merch_id , card_no , amount , install_month from ac_ledger where biz_date = $1 and acq_type = 'INST' and install_month >= 2 and orig_key is null order by key */
#line 42 "app/batch/ac_bt_0010.pgc" #line 55 "app/batch/ac_bt_0010.pgc"
#line 42 "app/batch/ac_bt_0010.pgc" #line 55 "app/batch/ac_bt_0010.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0010 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0010 cursor for select key , merch_id , card_no , amount , install_month from ac_ledger where biz_date = $1 and acq_type = 'INST' and install_month >= 2 and orig_key is null order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0010.pgc" #line 57 "app/batch/ac_bt_0010.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0010"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0010");
@ -155,9 +187,13 @@ static int run_ac_bt_0010(const char *biz_date)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long),
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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0010.pgc" #line 68 "app/batch/ac_bt_0010.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,26 +204,70 @@ static int run_ac_bt_0010(const char *biz_date)
break; break;
} }
total++; parents++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_install_month < 2) {
if (amount_is_valid(h_amount)) { tx_log(TX_LOG_WARN, "[ac_bt_0010] 회차수 이상 key=%s month=%d, 건너뜀",
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); h_key, h_install_month);
done++; continue;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
rc = ac_rec_update_status(h_key, h_new_status); monthly = h_amount / h_install_month;
if (rc != TX_OK) { remainder = h_amount - (monthly * h_install_month);
tx_log(TX_LOG_ERROR, "[ac_bt_0010] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; strncpy(h_orig_key, h_key, sizeof(h_orig_key) - 1);
h_orig_key[sizeof(h_orig_key) - 1] = '\0';
strncpy(h_acq_type, "INST", sizeof(h_acq_type) - 1);
h_acq_type[sizeof(h_acq_type) - 1] = '\0';
strncpy(h_status, AC_ST_RECV, sizeof(h_status));
h_fee = 0;
for (m = 1; m <= h_install_month; m++) {
snprintf(keybuf, sizeof(keybuf), "%.12s-%02d", h_key, m);
strncpy(h_child_key, keybuf, sizeof(h_child_key) - 1);
h_child_key[sizeof(h_child_key) - 1] = '\0';
h_child_amount = monthly;
if (m == 1)
h_child_amount += remainder;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ac_ledger ( key , merch_id , card_no , amount , biz_date , status , fee , install_month , acq_type , orig_key ) values ( $1 , $2 , $3 , $4 , $5 , $6 , $7 , $8 , $9 , $10 )",
ECPGt_char,(h_child_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_child_amount),(long)1,(long)1,sizeof(long),
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_char,(h_status),(long)2,(long)1,(2)*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_int,&(h_install_month),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_acq_type),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_orig_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 111 "app/batch/ac_bt_0010.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT ac_bt_0010 child");
tx_log(TX_LOG_ERROR, "[ac_bt_0010] 자매입행 생성 실패 key=%s m=%d",
h_key, m);
errcnt++;
continue;
}
children++;
} }
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0010", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0010", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0010.pgc" #line 124 "app/batch/ac_bt_0010.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +276,15 @@ static int run_ac_bt_0010(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0010] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0010] 요약 date=%s 원거래=%ld 전개행=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, parents, children, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0010] ==========\n"); printf("========== 할부매입 전개 결과 [ac_bt_0010] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 원거래 건수 : %ld\n", parents);
printf(" 완료(M) : %ld\n", done); printf(" 전개 행수 : %ld\n", children);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf("======================================================\n");
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,11 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0010.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0010.pgc - 할부매입 전개 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일에 접수된 할부매입 원거래(acq_type='INST', install_month>=2,
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * orig_key IS NULL) 를 회차별로 전개하여 자매입행(자녀행)을 생성한다.
* 각 자녀행은 원거래를 orig_key 로 참조하며, 금액은 회차수로 균등 분할하고
* 나머지(단수)는 1회차에 합산한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0010 <YYYYMMDD> [db@host] * 실행: ac_bt_0010 <YYYYMMDD> [db@host]
*/ */
@ -24,21 +26,32 @@ static int run_ac_bt_0010(const char *biz_date)
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
char h_card_no[20];
long h_amount; long h_amount;
char h_new_status[2]; int h_install_month;
char h_child_key[16];
long h_child_amount;
char h_status[2];
char h_acq_type[9];
char h_orig_key[16];
long h_fee;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long parents = 0, children = 0, errcnt = 0;
int rc; long monthly, remainder;
int m;
char keybuf[16];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0010 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0010 CURSOR FOR
SELECT key, merch_id, amount SELECT key, merch_id, card_no, amount, install_month
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND acq_type = 'INST'
AND install_month >= 2
AND orig_key IS NULL
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0010; EXEC SQL OPEN cur_ac_bt_0010;
@ -51,7 +64,8 @@ static int run_ac_bt_0010(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0010] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0010] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0010 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0010
INTO :h_key, :h_merch_id, :h_card_no, :h_amount, :h_install_month;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,21 +75,49 @@ static int run_ac_bt_0010(const char *biz_date)
break; break;
} }
total++; parents++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_install_month < 2) {
if (amount_is_valid(h_amount)) { tx_log(TX_LOG_WARN, "[ac_bt_0010] 회차수 이상 key=%s month=%d, 건너뜀",
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); h_key, h_install_month);
done++; continue;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
rc = ac_rec_update_status(h_key, h_new_status); monthly = h_amount / h_install_month;
if (rc != TX_OK) { remainder = h_amount - (monthly * h_install_month);
tx_log(TX_LOG_ERROR, "[ac_bt_0010] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; strncpy(h_orig_key, h_key, sizeof(h_orig_key) - 1);
h_orig_key[sizeof(h_orig_key) - 1] = '\0';
strncpy(h_acq_type, "INST", sizeof(h_acq_type) - 1);
h_acq_type[sizeof(h_acq_type) - 1] = '\0';
strncpy(h_status, AC_ST_RECV, sizeof(h_status));
h_fee = 0;
for (m = 1; m <= h_install_month; m++) {
snprintf(keybuf, sizeof(keybuf), "%.12s-%02d", h_key, m);
strncpy(h_child_key, keybuf, sizeof(h_child_key) - 1);
h_child_key[sizeof(h_child_key) - 1] = '\0';
h_child_amount = monthly;
if (m == 1)
h_child_amount += remainder;
EXEC SQL INSERT INTO ac_ledger
(key, merch_id, card_no, amount, biz_date, status, fee,
install_month, acq_type, orig_key)
VALUES
(:h_child_key, :h_merch_id, :h_card_no, :h_child_amount,
:h_biz_date, :h_status, :h_fee, :h_install_month,
:h_acq_type, :h_orig_key);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT ac_bt_0010 child");
tx_log(TX_LOG_ERROR, "[ac_bt_0010] 자매입행 생성 실패 key=%s m=%d",
h_key, m);
errcnt++;
continue;
}
children++;
} }
} }
@ -87,16 +129,15 @@ static int run_ac_bt_0010(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0010] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0010] 요약 date=%s 원거래=%ld 전개행=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, parents, children, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0010] ==========\n"); printf("========== 할부매입 전개 결과 [ac_bt_0010] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 원거래 건수 : %ld\n", parents);
printf(" 완료(M) : %ld\n", done); printf(" 전개 행수 : %ld\n", children);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf("======================================================\n");
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,12 @@
#line 1 "app/batch/ac_bt_0011.pgc" #line 1 "app/batch/ac_bt_0011.pgc"
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0011.pgc - ( + ) [tier=medium] * ac_bt_0011.pgc - - [tier=medium]
* *
* (status='R') * (status='R') (approval)
* ('M')/('U') . main . * .
* ('U'), ('M')
* . main .
* *
* : ac_bt_0011 <YYYYMMDD> [db@host] * : ac_bt_0011 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +95,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0011.pgc" #line 21 "app/batch/ac_bt_0011.pgc"
static int run_ac_bt_0011(const char *biz_date) static int run_ac_bt_0011(const char *biz_date)
@ -104,42 +106,47 @@ static int run_ac_bt_0011(const char *biz_date)
#line 24 "app/batch/ac_bt_0011.pgc" #line 26 "app/batch/ac_bt_0011.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0011.pgc" #line 27 "app/batch/ac_bt_0011.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0011.pgc" #line 28 "app/batch/ac_bt_0011.pgc"
char h_merch_id [ 16 ] ; char h_approval_no [ 17 ] ;
#line 27 "app/batch/ac_bt_0011.pgc" #line 29 "app/batch/ac_bt_0011.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0011.pgc" #line 30 "app/batch/ac_bt_0011.pgc"
long h_appr_amount ;
#line 31 "app/batch/ac_bt_0011.pgc"
char h_new_status [ 2 ] ; char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0011.pgc" #line 32 "app/batch/ac_bt_0011.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, matched = 0, unmatch = 0, errcnt = 0;
long diff_sum = 0;
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0011 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0011 cursor for select key , approval_no , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/ac_bt_0011.pgc" #line 46 "app/batch/ac_bt_0011.pgc"
#line 42 "app/batch/ac_bt_0011.pgc" #line 46 "app/batch/ac_bt_0011.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0011 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0011 cursor for select key , approval_no , amount from ac_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0011.pgc" #line 48 "app/batch/ac_bt_0011.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0011"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0011");
@ -153,11 +160,11 @@ static int run_ac_bt_0011(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0011", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0011", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_approval_no),(long)17,(long)1,(17)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0011.pgc" #line 58 "app/batch/ac_bt_0011.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -170,12 +177,29 @@ static int run_ac_bt_0011(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select amount from approval where approval_no = $1 ",
if (amount_is_valid(h_amount)) { ECPGt_char,(h_approval_no),(long)17,(long)1,(17)*sizeof(char),
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 73 "app/batch/ac_bt_0011.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
/* 승인정보 없음: 전액 불일치로 처리 */
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
diff_sum += labs(h_amount);
unmatch++;
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("SELECT ac_bt_0011 approval");
errcnt++;
continue;
} else if (h_amount == h_appr_amount) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; matched++;
} else { } else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
diff_sum += labs(h_amount - h_appr_amount);
unmatch++; unmatch++;
} }
@ -187,7 +211,7 @@ static int run_ac_bt_0011(const char *biz_date)
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0011", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0011", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0011.pgc" #line 100 "app/batch/ac_bt_0011.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +220,17 @@ static int run_ac_bt_0011(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0011] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0011] 요약 date=%s 대상=%ld 일치=%ld 불일치=%ld 불일치금액=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, matched, unmatch, diff_sum, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0011] ==========\n"); printf("========== 매입-승인 대사연계 결과 [ac_bt_0011] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 대사일치(M) : %ld\n", matched);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 불일치 금액합 : %ld\n", diff_sum);
printf("=============================================\n"); printf(" 오류 건수 : %ld\n", errcnt);
printf("============================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,11 @@
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0011.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=medium] * ac_bt_0011.pgc - 매입-승인 대사연계 배치 [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 접수(status='R') 매입행을 커서로 순회하며 승인(approval)
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 테이블의 동일 승인번호 금액과 대사한다. 승인정보가 없거나 금액이
* 상이하면 불일치('U'), 금액이 일치하면 완료('M') 로 상태를 전이하고
* 불일치 금액합을 집계한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0011 <YYYYMMDD> [db@host] * 실행: ac_bt_0011 <YYYYMMDD> [db@host]
*/ */
@ -23,19 +25,21 @@ static int run_ac_bt_0011(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_approval_no[17];
long h_amount; long h_amount;
long h_appr_amount;
char h_new_status[2]; char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, matched = 0, unmatch = 0, errcnt = 0;
long diff_sum = 0;
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0011 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0011 CURSOR FOR
SELECT key, merch_id, amount SELECT key, approval_no, amount
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'R'
@ -51,7 +55,7 @@ static int run_ac_bt_0011(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0011] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0011] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0011 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0011 INTO :h_key, :h_approval_no, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -63,12 +67,26 @@ static int run_ac_bt_0011(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ EXEC SQL SELECT amount
if (amount_is_valid(h_amount)) { INTO :h_appr_amount
FROM approval
WHERE approval_no = :h_approval_no;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) {
/* 승인정보 없음: 전액 불일치로 처리 */
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
diff_sum += labs(h_amount);
unmatch++;
} else if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("SELECT ac_bt_0011 approval");
errcnt++;
continue;
} else if (h_amount == h_appr_amount) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; matched++;
} else { } else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
diff_sum += labs(h_amount - h_appr_amount);
unmatch++; unmatch++;
} }
@ -87,16 +105,17 @@ static int run_ac_bt_0011(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0011] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0011] 요약 date=%s 대상=%ld 일치=%ld 불일치=%ld 불일치금액=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, matched, unmatch, diff_sum, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0011] ==========\n"); printf("========== 매입-승인 대사연계 결과 [ac_bt_0011] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 대사일치(M) : %ld\n", matched);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 불일치 금액합 : %ld\n", diff_sum);
printf("=============================================\n"); printf(" 오류 건수 : %ld\n", errcnt);
printf("============================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0012.pgc" #line 1 "app/batch/ac_bt_0012.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0012.pgc - ( + ) [tier=easy] * ac_bt_0012.pgc - [tier=easy]
* *
* (status='R') * (status='M') (merchant)
* ('M')/('U') . main . * ,
* . main .
* *
* : ac_bt_0012 <YYYYMMDD> [db@host] * : ac_bt_0012 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0012.pgc" #line 20 "app/batch/ac_bt_0012.pgc"
static int run_ac_bt_0012(const char *biz_date) static int run_ac_bt_0012(const char *biz_date)
@ -105,41 +106,42 @@ static int run_ac_bt_0012(const char *biz_date)
#line 24 "app/batch/ac_bt_0012.pgc" #line 25 "app/batch/ac_bt_0012.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0012.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0012.pgc" #line 26 "app/batch/ac_bt_0012.pgc"
char h_merch_id [ 16 ] ; char h_key [ 16 ] ;
#line 27 "app/batch/ac_bt_0012.pgc" #line 27 "app/batch/ac_bt_0012.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0012.pgc" #line 28 "app/batch/ac_bt_0012.pgc"
char h_new_status [ 2 ] ; long h_withhold_rate ;
/* exec sql end declare section */
#line 29 "app/batch/ac_bt_0012.pgc" #line 29 "app/batch/ac_bt_0012.pgc"
long h_withhold ;
/* exec sql end declare section */
#line 30 "app/batch/ac_bt_0012.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0;
int rc; long withhold_sum = 0;
char wonbuf[64];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0012 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0012 cursor for select l . key , l . amount , m . withhold_rate from ac_ledger l join merchant m on m . merch_id = l . merch_id where l . biz_date = $1 and l . status = 'M' order by l . key */
#line 42 "app/batch/ac_bt_0012.pgc" #line 45 "app/batch/ac_bt_0012.pgc"
#line 42 "app/batch/ac_bt_0012.pgc" #line 45 "app/batch/ac_bt_0012.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0012 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0012 cursor for select l . key , l . amount , m . withhold_rate from ac_ledger l join merchant m on m . merch_id = l . merch_id where l . biz_date = $1 and l . status = 'M' order by l . key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0012.pgc" #line 47 "app/batch/ac_bt_0012.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0012"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0012");
@ -153,11 +155,11 @@ static int run_ac_bt_0012(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0012", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0012", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_withhold_rate),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0012.pgc" #line 57 "app/batch/ac_bt_0012.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -170,24 +172,29 @@ static int run_ac_bt_0012(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* withhold_rate 는 만분율(1/10000) 단위 */
if (amount_is_valid(h_amount)) { h_withhold = (h_amount * h_withhold_rate) / 10000;
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update ac_ledger set withhold_amt = $1 where key = $2 ",
} else { ECPGt_long,&(h_withhold),(long)1,(long)1,sizeof(long),
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
unmatch++; ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 74 "app/batch/ac_bt_0012.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0012 withhold_amt");
tx_log(TX_LOG_ERROR, "[ac_bt_0012] 원천징수 반영 실패 key=%s", h_key);
errcnt++;
continue;
} }
rc = ac_rec_update_status(h_key, h_new_status); withhold_sum += h_withhold;
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[ac_bt_0012] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0012", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0012", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0012.pgc" #line 86 "app/batch/ac_bt_0012.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +202,18 @@ static int run_ac_bt_0012(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(withhold_sum, wonbuf, sizeof(wonbuf));
"[ac_bt_0012] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0012] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0012] 요약 date=%s 대상=%ld 원천징수합계=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, total, withhold_sum, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 매입 원천징수 결과 [ac_bt_0012] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 원천징수 합계 : %ld (%s)\n", withhold_sum, wonbuf);
printf(" 오류 건수 : %ld\n", errcnt);
printf("======================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0012.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0012.pgc - 매입 원천징수 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일에 처리완료(status='M') 된 매입행을 가맹점(merchant) 과
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 조인하여 가맹점별 원천징수율을 적용, 원천징수액을 계산해 원장에
* 반영한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0012 <YYYYMMDD> [db@host] * 실행: ac_bt_0012 <YYYYMMDD> [db@host]
*/ */
@ -23,23 +24,25 @@ static int run_ac_bt_0012(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2]; long h_withhold_rate;
long h_withhold;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0;
int rc; long withhold_sum = 0;
char wonbuf[64];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0012 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0012 CURSOR FOR
SELECT key, merch_id, amount SELECT l.key, l.amount, m.withhold_rate
FROM ac_ledger FROM ac_ledger l
WHERE biz_date = :h_biz_date JOIN merchant m ON m.merch_id = l.merch_id
AND status = 'R' WHERE l.biz_date = :h_biz_date
ORDER BY key; AND l.status = 'M'
ORDER BY l.key;
EXEC SQL OPEN cur_ac_bt_0012; EXEC SQL OPEN cur_ac_bt_0012;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -51,7 +54,7 @@ static int run_ac_bt_0012(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0012] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0012] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0012 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0012 INTO :h_key, :h_amount, :h_withhold_rate;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -63,20 +66,21 @@ static int run_ac_bt_0012(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* withhold_rate 는 만분율(1/10000) 단위 */
if (amount_is_valid(h_amount)) { h_withhold = (h_amount * h_withhold_rate) / 10000;
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++; EXEC SQL UPDATE ac_ledger
} else { SET withhold_amt = :h_withhold
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); WHERE key = :h_key;
unmatch++;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0012 withhold_amt");
tx_log(TX_LOG_ERROR, "[ac_bt_0012] 원천징수 반영 실패 key=%s", h_key);
errcnt++;
continue;
} }
rc = ac_rec_update_status(h_key, h_new_status); withhold_sum += h_withhold;
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[ac_bt_0012] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_ac_bt_0012; EXEC SQL CLOSE cur_ac_bt_0012;
@ -86,17 +90,18 @@ static int run_ac_bt_0012(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(withhold_sum, wonbuf, sizeof(wonbuf));
"[ac_bt_0012] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0012] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[ac_bt_0012] 요약 date=%s 대상=%ld 원천징수합계=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, total, withhold_sum, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 매입 원천징수 결과 [ac_bt_0012] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 원천징수 합계 : %ld (%s)\n", withhold_sum, wonbuf);
printf(" 오류 건수 : %ld\n", errcnt);
printf("======================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0013.pgc" #line 1 "app/batch/ac_bt_0013.pgc"
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0013.pgc - ( + ) [tier=medium] * ac_bt_0013.pgc - ( ) [tier=medium]
* *
* (status='R') * /(status IN ('M','S'))
* ('M')/('U') . main . * (corp_cd) ac_stat ,
* . main .
* *
* : ac_bt_0013 <YYYYMMDD> [db@host] * : ac_bt_0013 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0013.pgc" #line 20 "app/batch/ac_bt_0013.pgc"
static int run_ac_bt_0013(const char *biz_date) static int run_ac_bt_0013(const char *biz_date)
@ -105,41 +106,41 @@ static int run_ac_bt_0013(const char *biz_date)
#line 24 "app/batch/ac_bt_0013.pgc" #line 25 "app/batch/ac_bt_0013.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0013.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0013.pgc" #line 26 "app/batch/ac_bt_0013.pgc"
char h_merch_id [ 16 ] ; char h_corp_cd [ 5 ] ;
#line 27 "app/batch/ac_bt_0013.pgc" #line 27 "app/batch/ac_bt_0013.pgc"
long h_amount ; long h_cnt ;
#line 28 "app/batch/ac_bt_0013.pgc" #line 28 "app/batch/ac_bt_0013.pgc"
char h_new_status [ 2 ] ; long h_amt_sum ;
/* exec sql end declare section */
#line 29 "app/batch/ac_bt_0013.pgc" #line 29 "app/batch/ac_bt_0013.pgc"
long h_fee_sum ;
/* exec sql end declare section */
#line 30 "app/batch/ac_bt_0013.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long corp_rows = 0, errcnt = 0;
int rc; long grand_cnt = 0, grand_amt = 0, grand_fee = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0013 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0013 cursor for select corp_cd , count ( * ) , sum ( amount ) , sum ( fee ) from ac_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by corp_cd order by corp_cd */
#line 42 "app/batch/ac_bt_0013.pgc" #line 44 "app/batch/ac_bt_0013.pgc"
#line 42 "app/batch/ac_bt_0013.pgc" #line 44 "app/batch/ac_bt_0013.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0013 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0013 cursor for select corp_cd , count ( * ) , sum ( amount ) , sum ( fee ) from ac_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by corp_cd order by corp_cd",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0013.pgc" #line 46 "app/batch/ac_bt_0013.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0013"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0013");
@ -149,15 +150,22 @@ static int run_ac_bt_0013(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0013] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0013] tx_begin 경고");
printf("========== 매입 통계(카드사별) 결과 [ac_bt_0013] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" ---------------------------------------------------------\n");
printf(" %-6s %10s %16s %14s\n", "카드사", "건수", "매입금액", "수수료");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0013", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0013", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_corp_cd),(long)5,(long)1,(5)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_long,&(h_cnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amt_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_fee_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0013.pgc" #line 62 "app/batch/ac_bt_0013.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,26 +176,35 @@ static int run_ac_bt_0013(const char *biz_date)
break; break;
} }
total++; { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ac_stat ( biz_date , corp_cd , tot_cnt , tot_amt ) values ( $1 , $2 , $3 , $4 )",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_corp_cd),(long)5,(long)1,(5)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_cnt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amt_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 75 "app/batch/ac_bt_0013.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); if (sqlca.sqlcode != TX_SQL_OK) {
if (rc != TX_OK) { TX_DBIO_LOG_ERR("INSERT ac_bt_0013 ac_stat");
tx_log(TX_LOG_ERROR, "[ac_bt_0013] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[ac_bt_0013] 통계 적재 실패 corp_cd=%s", h_corp_cd);
errcnt++; errcnt++;
continue;
} }
printf(" %-6s %10ld %16ld %14ld\n", h_corp_cd, h_cnt, h_amt_sum, h_fee_sum);
corp_rows++;
grand_cnt += h_cnt;
grand_amt += h_amt_sum;
grand_fee += h_fee_sum;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0013", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0013", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0013.pgc" #line 92 "app/batch/ac_bt_0013.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +213,16 @@ static int run_ac_bt_0013(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0013] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0013] 요약 date=%s 카드사수=%ld 총건수=%ld 총금액=%ld 총수수료=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, corp_rows, grand_cnt, grand_amt, grand_fee, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0013] ==========\n"); printf(" ---------------------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 카드사 수 : %ld\n", corp_rows);
printf(" 대상 건수 : %ld\n", total); printf(" 총 건수 : %ld\n", grand_cnt);
printf(" 완료(M) : %ld\n", done); printf(" 총 매입금액 : %ld\n", grand_amt);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 총 수수료 : %ld\n", grand_fee);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=============================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0013.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=medium] * ac_bt_0013.pgc - 매입 통계(카드사별 집계) 배치 [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일에 처리완료/정산완료(status IN ('M','S')) 된 매입행을
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 카드사코드(corp_cd) 별로 집계하여 ac_stat 테이블에 적재하고,
* 전체 합계를 산출한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0013 <YYYYMMDD> [db@host] * 실행: ac_bt_0013 <YYYYMMDD> [db@host]
*/ */
@ -22,24 +23,25 @@ static int run_ac_bt_0013(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_corp_cd[5];
char h_merch_id[16]; long h_cnt;
long h_amount; long h_amt_sum;
char h_new_status[2]; long h_fee_sum;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long corp_rows = 0, errcnt = 0;
int rc; long grand_cnt = 0, grand_amt = 0, grand_fee = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0013 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0013 CURSOR FOR
SELECT key, merch_id, amount SELECT corp_cd, count(*), sum(amount), sum(fee)
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status IN ('M', 'S')
ORDER BY key; GROUP BY corp_cd
ORDER BY corp_cd;
EXEC SQL OPEN cur_ac_bt_0013; EXEC SQL OPEN cur_ac_bt_0013;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -50,8 +52,14 @@ static int run_ac_bt_0013(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0013] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0013] tx_begin 경고");
printf("========== 매입 통계(카드사별) 결과 [ac_bt_0013] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" ---------------------------------------------------------\n");
printf(" %-6s %10s %16s %14s\n", "카드사", "건수", "매입금액", "수수료");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0013 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0013
INTO :h_corp_cd, :h_cnt, :h_amt_sum, :h_fee_sum;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,22 +69,24 @@ static int run_ac_bt_0013(const char *biz_date)
break; break;
} }
total++; EXEC SQL INSERT INTO ac_stat
(biz_date, corp_cd, tot_cnt, tot_amt)
VALUES
(:h_biz_date, :h_corp_cd, :h_cnt, :h_amt_sum);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) {
if (amount_is_valid(h_amount)) { TX_DBIO_LOG_ERR("INSERT ac_bt_0013 ac_stat");
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); tx_log(TX_LOG_ERROR, "[ac_bt_0013] 통계 적재 실패 corp_cd=%s", h_corp_cd);
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[ac_bt_0013] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
printf(" %-6s %10ld %16ld %14ld\n", h_corp_cd, h_cnt, h_amt_sum, h_fee_sum);
corp_rows++;
grand_cnt += h_cnt;
grand_amt += h_amt_sum;
grand_fee += h_fee_sum;
} }
EXEC SQL CLOSE cur_ac_bt_0013; EXEC SQL CLOSE cur_ac_bt_0013;
@ -87,16 +97,16 @@ static int run_ac_bt_0013(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0013] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0013] 요약 date=%s 카드사수=%ld 총건수=%ld 총금액=%ld 총수수료=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, corp_rows, grand_cnt, grand_amt, grand_fee, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0013] ==========\n"); printf(" ---------------------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 카드사 수 : %ld\n", corp_rows);
printf(" 대상 건수 : %ld\n", total); printf(" 총 건수 : %ld\n", grand_cnt);
printf(" 완료(M) : %ld\n", done); printf(" 총 매입금액 : %ld\n", grand_amt);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 총 수수료 : %ld\n", grand_fee);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=============================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,12 @@
#line 1 "app/batch/ac_bt_0014.pgc" #line 1 "app/batch/ac_bt_0014.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0014.pgc - ( + ) [tier=easy] * ac_bt_0014.pgc - [tier=easy]
* *
* (status='R') * (status='M')
* ('M')/('U') . main . * (-) , settle
* ('S') .
* main .
* *
* : ac_bt_0014 <YYYYMMDD> [db@host] * : ac_bt_0014 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +95,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0014.pgc" #line 21 "app/batch/ac_bt_0014.pgc"
static int run_ac_bt_0014(const char *biz_date) static int run_ac_bt_0014(const char *biz_date)
@ -104,42 +106,54 @@ static int run_ac_bt_0014(const char *biz_date)
#line 24 "app/batch/ac_bt_0014.pgc" #line 26 "app/batch/ac_bt_0014.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0014.pgc" #line 27 "app/batch/ac_bt_0014.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0014.pgc" #line 28 "app/batch/ac_bt_0014.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0014.pgc" #line 29 "app/batch/ac_bt_0014.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0014.pgc" #line 30 "app/batch/ac_bt_0014.pgc"
char h_new_status [ 2 ] ; long h_fee ;
#line 31 "app/batch/ac_bt_0014.pgc"
long h_settle_amt ;
#line 32 "app/batch/ac_bt_0014.pgc"
char h_settle_no [ 20 ] ;
#line 33 "app/batch/ac_bt_0014.pgc"
char h_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0014.pgc" #line 34 "app/batch/ac_bt_0014.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0, seq = 0;
int rc; long settle_sum = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0014 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0014 cursor for select key , merch_id , amount , fee from ac_ledger where biz_date = $1 and status = 'M' order by key */
#line 42 "app/batch/ac_bt_0014.pgc" #line 47 "app/batch/ac_bt_0014.pgc"
#line 42 "app/batch/ac_bt_0014.pgc" #line 47 "app/batch/ac_bt_0014.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0014 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0014 cursor for select key , merch_id , amount , fee from ac_ledger where biz_date = $1 and status = 'M' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0014.pgc" #line 49 "app/batch/ac_bt_0014.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0014"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0014");
@ -156,8 +170,10 @@ static int run_ac_bt_0014(const char *biz_date)
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0014.pgc" #line 60 "app/batch/ac_bt_0014.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -169,25 +185,55 @@ static int run_ac_bt_0014(const char *biz_date)
} }
total++; total++;
seq++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ h_settle_amt = h_amount - h_fee;
if (amount_is_valid(h_amount)) { snprintf(h_settle_no, sizeof(h_settle_no), "ST%s%05ld", h_biz_date, seq);
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); strncpy(h_status, AC_ST_SETTLED, sizeof(h_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into settle ( settle_no , merch_id , biz_date , settle_amt , status ) values ( $1 , $2 , $3 , $4 , $5 )",
if (rc != TX_OK) { ECPGt_char,(h_settle_no),(long)20,(long)1,(20)*sizeof(char),
tx_log(TX_LOG_ERROR, "[ac_bt_0014] 상태전이 실패 key=%s rc=%d", h_key, rc); 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_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_settle_amt),(long)1,(long)1,sizeof(long),
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_EOIT, ECPGt_EORT);}
#line 80 "app/batch/ac_bt_0014.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT ac_bt_0014 settle");
tx_log(TX_LOG_ERROR, "[ac_bt_0014] 정산 적재 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update ac_ledger set status = $1 , settle_no = $2 where key = $3 ",
ECPGt_char,(h_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_settle_no),(long)20,(long)1,(20)*sizeof(char),
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 91 "app/batch/ac_bt_0014.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0014 ac_ledger");
tx_log(TX_LOG_ERROR, "[ac_bt_0014] 원장 상태전이 실패 key=%s", h_key);
errcnt++;
continue;
}
settle_sum += h_settle_amt;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0014", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0014", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0014.pgc" #line 103 "app/batch/ac_bt_0014.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +242,15 @@ static int run_ac_bt_0014(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0014] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0014] 요약 date=%s 대상=%ld 정산금액합=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, settle_sum, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0014] ==========\n"); printf("========== 매입 정산연계 결과 [ac_bt_0014] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 정산 금액 합계 : %ld\n", settle_sum);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf("======================================================\n");
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,11 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0014.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0014.pgc - 매입 정산연계 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일에 처리완료(status='M') 된 매입행을 커서로 순회하며
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 정산금액(매입금액-수수료) 을 산출, 정산번호를 채번하여 settle
* 테이블에 적재하고 원장 상태를 정산완료('S') 로 전이한다.
* 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0014 <YYYYMMDD> [db@host] * 실행: ac_bt_0014 <YYYYMMDD> [db@host]
*/ */
@ -25,20 +27,23 @@ static int run_ac_bt_0014(const char *biz_date)
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2]; long h_fee;
long h_settle_amt;
char h_settle_no[20];
char h_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0, seq = 0;
int rc; long settle_sum = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0014 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0014 CURSOR FOR
SELECT key, merch_id, amount SELECT key, merch_id, amount, fee
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'M'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0014; EXEC SQL OPEN cur_ac_bt_0014;
@ -51,7 +56,8 @@ static int run_ac_bt_0014(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0014] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0014] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0014 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0014
INTO :h_key, :h_merch_id, :h_amount, :h_fee;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -62,21 +68,36 @@ static int run_ac_bt_0014(const char *biz_date)
} }
total++; total++;
seq++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ h_settle_amt = h_amount - h_fee;
if (amount_is_valid(h_amount)) { snprintf(h_settle_no, sizeof(h_settle_no), "ST%s%05ld", h_biz_date, seq);
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); strncpy(h_status, AC_ST_SETTLED, sizeof(h_status));
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = ac_rec_update_status(h_key, h_new_status); EXEC SQL INSERT INTO settle
if (rc != TX_OK) { (settle_no, merch_id, biz_date, settle_amt, status)
tx_log(TX_LOG_ERROR, "[ac_bt_0014] 상태전이 실패 key=%s rc=%d", h_key, rc); VALUES
(:h_settle_no, :h_merch_id, :h_biz_date, :h_settle_amt, :h_status);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT ac_bt_0014 settle");
tx_log(TX_LOG_ERROR, "[ac_bt_0014] 정산 적재 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
EXEC SQL UPDATE ac_ledger
SET status = :h_status, settle_no = :h_settle_no
WHERE key = :h_key;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0014 ac_ledger");
tx_log(TX_LOG_ERROR, "[ac_bt_0014] 원장 상태전이 실패 key=%s", h_key);
errcnt++;
continue;
}
settle_sum += h_settle_amt;
} }
EXEC SQL CLOSE cur_ac_bt_0014; EXEC SQL CLOSE cur_ac_bt_0014;
@ -87,16 +108,15 @@ static int run_ac_bt_0014(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0014] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0014] 요약 date=%s 대상=%ld 정산금액합=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, settle_sum, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0014] ==========\n"); printf("========== 매입 정산연계 결과 [ac_bt_0014] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 정산 금액 합계 : %ld\n", settle_sum);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf("======================================================\n");
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0015.pgc" #line 1 "app/batch/ac_bt_0015.pgc"
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0015.pgc - ( + ) [tier=medium] * ac_bt_0015.pgc - ( ) [tier=medium]
* *
* (status='R') * () , (status='R')
* ('M')/('U') . main . * biz_date .
* (: 0). main .
* *
* : ac_bt_0015 <YYYYMMDD> [db@host] * : ac_bt_0015 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0015.pgc" #line 20 "app/batch/ac_bt_0015.pgc"
static int run_ac_bt_0015(const char *biz_date) static int run_ac_bt_0015(const char *biz_date)
@ -102,44 +103,50 @@ static int run_ac_bt_0015(const char *biz_date)
#line 24 "app/batch/ac_bt_0015.pgc" #line 25 "app/batch/ac_bt_0015.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0015.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0015.pgc" #line 26 "app/batch/ac_bt_0015.pgc"
char h_merch_id [ 16 ] ; char h_new_date [ 9 ] ;
#line 27 "app/batch/ac_bt_0015.pgc" #line 27 "app/batch/ac_bt_0015.pgc"
long h_amount ; char h_key [ 16 ] ;
#line 28 "app/batch/ac_bt_0015.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0015.pgc" #line 28 "app/batch/ac_bt_0015.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, shifted = 0, kept = 0, errcnt = 0;
int rc; int is_weekend;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
memset(h_new_date, 0, sizeof(h_new_date));
is_weekend = date_is_weekend(biz_date);
if (is_weekend) {
if (!date_next_business(biz_date, h_new_date)) {
tx_log(TX_LOG_WARN,
"[ac_bt_0015] 차영업일 계산 실패 date=%s, 이월 취소", biz_date);
is_weekend = 0;
} else {
tx_log(TX_LOG_INFO, "[ac_bt_0015] 휴일 감지 date=%s -> 차영업일=%s",
biz_date, h_new_date);
}
}
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0015 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0015 cursor for select key from ac_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/ac_bt_0015.pgc" #line 55 "app/batch/ac_bt_0015.pgc"
#line 42 "app/batch/ac_bt_0015.pgc" #line 55 "app/batch/ac_bt_0015.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0015 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0015 cursor for select key from ac_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0015.pgc" #line 57 "app/batch/ac_bt_0015.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0015"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0015");
@ -152,12 +159,8 @@ static int run_ac_bt_0015(const char *biz_date)
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0015", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0015", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), 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_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0015.pgc" #line 67 "app/batch/ac_bt_0015.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -170,24 +173,31 @@ static int run_ac_bt_0015(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (!is_weekend) {
if (amount_is_valid(h_amount)) { kept++;
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); continue;
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
rc = ac_rec_update_status(h_key, h_new_status); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update ac_ledger set biz_date = $1 where key = $2 ",
if (rc != TX_OK) { ECPGt_char,(h_new_date),(long)9,(long)1,(9)*sizeof(char),
tx_log(TX_LOG_ERROR, "[ac_bt_0015] 상태전이 실패 key=%s rc=%d", h_key, rc); 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 86 "app/batch/ac_bt_0015.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0015 biz_date");
tx_log(TX_LOG_ERROR, "[ac_bt_0015] 이월 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
shifted++;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0015", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0015", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0015.pgc" #line 98 "app/batch/ac_bt_0015.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +206,19 @@ static int run_ac_bt_0015(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0015] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0015] 요약 date=%s 휴일여부=%d 대상=%ld 이월=%ld 유지=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, is_weekend, total, shifted, kept, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0015] ==========\n"); printf("========== 매입일자 변경(휴일 이월) 결과 [ac_bt_0015] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 휴일 여부 : %s\n", is_weekend ? "휴일" : "평일");
printf(" 완료(M) : %ld\n", done); if (is_weekend)
printf(" 불일치(U) : %ld\n", unmatch); printf(" 차영업일 : %s\n", h_new_date);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 대상 건수 : %ld\n", total);
printf("=============================================\n"); printf(" 이월 건수 : %ld\n", shifted);
printf(" 유지 건수 : %ld\n", kept);
printf(" 오류 건수 : %ld\n", errcnt);
printf("==================================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier medium @module ac @transform acquire-batch */ /* @tier medium @module ac @transform acquire-batch */
/* /*
* ac_bt_0015.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=medium] * ac_bt_0015.pgc - 매입일자 변경(휴일 이월) 배치 [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일이 휴일(주말) 인 경우, 해당 일자의 접수(status='R') 건들의
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * biz_date 를 차영업일로 일괄 이월한다. 평일이면 이월 없이 대상 건수만
* 유지 건으로 집계한다(가드: 평일이면 이월 0건). 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0015 <YYYYMMDD> [db@host] * 실행: ac_bt_0015 <YYYYMMDD> [db@host]
*/ */
@ -22,20 +23,32 @@ static int run_ac_bt_0015(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_new_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, shifted = 0, kept = 0, errcnt = 0;
int rc; int is_weekend;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
memset(h_new_date, 0, sizeof(h_new_date));
is_weekend = date_is_weekend(biz_date);
if (is_weekend) {
if (!date_next_business(biz_date, h_new_date)) {
tx_log(TX_LOG_WARN,
"[ac_bt_0015] 차영업일 계산 실패 date=%s, 이월 취소", biz_date);
is_weekend = 0;
} else {
tx_log(TX_LOG_INFO, "[ac_bt_0015] 휴일 감지 date=%s -> 차영업일=%s",
biz_date, h_new_date);
}
}
EXEC SQL DECLARE cur_ac_bt_0015 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0015 CURSOR FOR
SELECT key, merch_id, amount SELECT key
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'R'
@ -51,7 +64,7 @@ static int run_ac_bt_0015(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0015] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0015] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0015 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0015 INTO :h_key;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -63,20 +76,23 @@ static int run_ac_bt_0015(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (!is_weekend) {
if (amount_is_valid(h_amount)) { kept++;
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); continue;
done++;
} else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
rc = ac_rec_update_status(h_key, h_new_status); EXEC SQL UPDATE ac_ledger
if (rc != TX_OK) { SET biz_date = :h_new_date
tx_log(TX_LOG_ERROR, "[ac_bt_0015] 상태전이 실패 key=%s rc=%d", h_key, rc); WHERE key = :h_key;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0015 biz_date");
tx_log(TX_LOG_ERROR, "[ac_bt_0015] 이월 실패 key=%s", h_key);
errcnt++; errcnt++;
continue;
} }
shifted++;
} }
EXEC SQL CLOSE cur_ac_bt_0015; EXEC SQL CLOSE cur_ac_bt_0015;
@ -87,16 +103,19 @@ static int run_ac_bt_0015(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0015] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0015] 요약 date=%s 휴일여부=%d 대상=%ld 이월=%ld 유지=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, is_weekend, total, shifted, kept, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0015] ==========\n"); printf("========== 매입일자 변경(휴일 이월) 결과 [ac_bt_0015] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 휴일 여부 : %s\n", is_weekend ? "휴일" : "평일");
printf(" 완료(M) : %ld\n", done); if (is_weekend)
printf(" 불일치(U) : %ld\n", unmatch); printf(" 차영업일 : %s\n", h_new_date);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 대상 건수 : %ld\n", total);
printf("=============================================\n"); printf(" 이월 건수 : %ld\n", shifted);
printf(" 유지 건수 : %ld\n", kept);
printf(" 오류 건수 : %ld\n", errcnt);
printf("==================================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/ac_bt_0016.pgc" #line 1 "app/batch/ac_bt_0016.pgc"
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0016.pgc - ( + ) [tier=easy] * ac_bt_0016.pgc - [tier=easy]
* *
* (status='R') * (status='M')
* ('M')/('U') . main . * ('LG', 100 ) / ('MD', 10 ) / ('SM', )
* acq_type . main .
* *
* : ac_bt_0016 <YYYYMMDD> [db@host] * : ac_bt_0016 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0016.pgc" #line 20 "app/batch/ac_bt_0016.pgc"
static int run_ac_bt_0016(const char *biz_date) static int run_ac_bt_0016(const char *biz_date)
@ -103,40 +104,36 @@ static int run_ac_bt_0016(const char *biz_date)
#line 24 "app/batch/ac_bt_0016.pgc" #line 25 "app/batch/ac_bt_0016.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0016.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0016.pgc" #line 26 "app/batch/ac_bt_0016.pgc"
char h_merch_id [ 16 ] ; char h_key [ 16 ] ;
#line 27 "app/batch/ac_bt_0016.pgc" #line 27 "app/batch/ac_bt_0016.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/ac_bt_0016.pgc" #line 28 "app/batch/ac_bt_0016.pgc"
char h_new_status [ 2 ] ; char h_new_type [ 9 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0016.pgc" #line 29 "app/batch/ac_bt_0016.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, lg_cnt = 0, md_cnt = 0, sm_cnt = 0, errcnt = 0;
int rc; const char *cls;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0016 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0016 cursor for select key , amount from ac_ledger where biz_date = $1 and status = 'M' order by key */
#line 42 "app/batch/ac_bt_0016.pgc" #line 42 "app/batch/ac_bt_0016.pgc"
#line 42 "app/batch/ac_bt_0016.pgc" #line 42 "app/batch/ac_bt_0016.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0016 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0016 cursor for select key , amount from ac_ledger where biz_date = $1 and status = 'M' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0016.pgc" #line 44 "app/batch/ac_bt_0016.pgc"
@ -153,8 +150,6 @@ static int run_ac_bt_0016(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0016", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0016", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0016.pgc" #line 54 "app/batch/ac_bt_0016.pgc"
@ -170,24 +165,37 @@ static int run_ac_bt_0016(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_amount >= 1000000L) {
if (amount_is_valid(h_amount)) { cls = "LG";
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); lg_cnt++;
done++; } else if (h_amount >= 100000L) {
cls = "MD";
md_cnt++;
} else { } else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); cls = "SM";
unmatch++; sm_cnt++;
} }
rc = ac_rec_update_status(h_key, h_new_status); strncpy(h_new_type, cls, sizeof(h_new_type) - 1);
if (rc != TX_OK) { h_new_type[sizeof(h_new_type) - 1] = '\0';
tx_log(TX_LOG_ERROR, "[ac_bt_0016] 상태전이 실패 key=%s rc=%d", h_key, rc);
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update ac_ledger set acq_type = $1 where key = $2 ",
ECPGt_char,(h_new_type),(long)9,(long)1,(9)*sizeof(char),
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 82 "app/batch/ac_bt_0016.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0016 acq_type");
tx_log(TX_LOG_ERROR, "[ac_bt_0016] 재분류 실패 key=%s", h_key);
errcnt++; errcnt++;
} }
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0016", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0016", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0016.pgc" #line 91 "app/batch/ac_bt_0016.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +204,17 @@ static int run_ac_bt_0016(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0016] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0016] 요약 date=%s 대상=%ld 대형=%ld 중형=%ld 소형=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, lg_cnt, md_cnt, sm_cnt, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0016] ==========\n"); printf("========== 매입 재분류 결과 [ac_bt_0016] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 대형(LG) : %ld\n", lg_cnt);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 중형(MD) : %ld\n", md_cnt);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 소형(SM) : %ld\n", sm_cnt);
printf("=============================================\n"); printf(" 오류 건수 : %ld\n", errcnt);
printf("====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module ac @transform acquire-batch */ /* @tier easy @module ac @transform acquire-batch */
/* /*
* ac_bt_0016.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=easy] * ac_bt_0016.pgc - 매입 재분류 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일에 처리완료(status='M') 된 매입행을 금액 구간에 따라
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 대형('LG', 100만원 이상) / 중형('MD', 10만원 이상) / 소형('SM', 그 외)
* 으로 재분류하여 acq_type 을 갱신한다. 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0016 <YYYYMMDD> [db@host] * 실행: ac_bt_0016 <YYYYMMDD> [db@host]
*/ */
@ -23,22 +24,21 @@ static int run_ac_bt_0016(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2]; char h_new_type[9];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, lg_cnt = 0, md_cnt = 0, sm_cnt = 0, errcnt = 0;
int rc; const char *cls;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0016 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0016 CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'M'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_ac_bt_0016; EXEC SQL OPEN cur_ac_bt_0016;
@ -51,7 +51,7 @@ static int run_ac_bt_0016(const char *biz_date)
tx_log(TX_LOG_WARN, "[ac_bt_0016] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0016] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0016 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0016 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -63,18 +63,27 @@ static int run_ac_bt_0016(const char *biz_date)
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_amount >= 1000000L) {
if (amount_is_valid(h_amount)) { cls = "LG";
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); lg_cnt++;
done++; } else if (h_amount >= 100000L) {
cls = "MD";
md_cnt++;
} else { } else {
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status)); cls = "SM";
unmatch++; sm_cnt++;
} }
rc = ac_rec_update_status(h_key, h_new_status); strncpy(h_new_type, cls, sizeof(h_new_type) - 1);
if (rc != TX_OK) { h_new_type[sizeof(h_new_type) - 1] = '\0';
tx_log(TX_LOG_ERROR, "[ac_bt_0016] 상태전이 실패 key=%s rc=%d", h_key, rc);
EXEC SQL UPDATE ac_ledger
SET acq_type = :h_new_type
WHERE key = :h_key;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE ac_bt_0016 acq_type");
tx_log(TX_LOG_ERROR, "[ac_bt_0016] 재분류 실패 key=%s", h_key);
errcnt++; errcnt++;
} }
} }
@ -87,16 +96,17 @@ static int run_ac_bt_0016(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0016] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0016] 요약 date=%s 대상=%ld 대형=%ld 중형=%ld 소형=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, total, lg_cnt, md_cnt, sm_cnt, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0016] ==========\n"); printf("========== 매입 재분류 결과 [ac_bt_0016] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 대형(LG) : %ld\n", lg_cnt);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 중형(MD) : %ld\n", md_cnt);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 소형(SM) : %ld\n", sm_cnt);
printf("=============================================\n"); printf(" 오류 건수 : %ld\n", errcnt);
printf("====================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,15 @@
#line 1 "app/batch/ac_bt_0017.pgc" #line 1 "app/batch/ac_bt_0017.pgc"
/* @tier hard @module ac @transform acquire-batch */ /* @tier hard @module ac @transform acquire-batch */
/* /*
* ac_bt_0017.pgc - ( + ) [tier=hard] * ac_bt_0017.pgc - [tier=hard]
* *
* (status='R') * (status='S')
* ('M')/('U') . main . * (- ) .
* - 0 .
* - (AC_BT_0017_MIN_TRANSFER)
* ( ).
* - settle ('T') .
* main .
* *
* : ac_bt_0017 <YYYYMMDD> [db@host] * : ac_bt_0017 <YYYYMMDD> [db@host]
*/ */
@ -93,9 +98,17 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/ac_bt_0017.pgc" #line 24 "app/batch/ac_bt_0017.pgc"
#define AC_BT_0017_MIN_TRANSFER 1000L
/*
* 'T' settle ,
* ac_core.h AC_ST_* (ac_ledger ) .
*/
#define AC_BT_0017_SETTLE_ST_XFER "T"
static int run_ac_bt_0017(const char *biz_date) static int run_ac_bt_0017(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
@ -105,41 +118,42 @@ static int run_ac_bt_0017(const char *biz_date)
#line 24 "app/batch/ac_bt_0017.pgc" #line 37 "app/batch/ac_bt_0017.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/ac_bt_0017.pgc" #line 38 "app/batch/ac_bt_0017.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/ac_bt_0017.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/ac_bt_0017.pgc" #line 39 "app/batch/ac_bt_0017.pgc"
long h_amount ; long h_net ;
#line 28 "app/batch/ac_bt_0017.pgc" #line 40 "app/batch/ac_bt_0017.pgc"
char h_new_status [ 2 ] ; char h_settle_no [ 20 ] ;
#line 41 "app/batch/ac_bt_0017.pgc"
char h_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/ac_bt_0017.pgc" #line 42 "app/batch/ac_bt_0017.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, transferred = 0, held = 0, skipped = 0, errcnt = 0;
int rc; long seq = 0;
long grand_net = 0, held_sum = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_ac_bt_0017 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_ac_bt_0017 cursor for select merch_id , sum ( amount - fee ) as net from ac_ledger where biz_date = $1 and status = 'S' group by merch_id order by merch_id */
#line 42 "app/batch/ac_bt_0017.pgc" #line 57 "app/batch/ac_bt_0017.pgc"
#line 42 "app/batch/ac_bt_0017.pgc" #line 57 "app/batch/ac_bt_0017.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0017 cursor for select key , merch_id , amount from ac_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_ac_bt_0017 cursor for select merch_id , sum ( amount - fee ) as net from ac_ledger where biz_date = $1 and status = 'S' group by merch_id order by merch_id",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/ac_bt_0017.pgc" #line 59 "app/batch/ac_bt_0017.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0017"); TX_DBIO_LOG_ERR("OPEN cur_ac_bt_0017");
@ -149,15 +163,17 @@ static int run_ac_bt_0017(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0017] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0017] tx_begin 경고");
printf("========== 매입 이체연계 결과 [ac_bt_0017] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" ------------------------------------------------------\n");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0017", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_ac_bt_0017", ECPGt_EOIT,
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_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_net),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/ac_bt_0017.pgc" #line 73 "app/batch/ac_bt_0017.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,26 +184,56 @@ static int run_ac_bt_0017(const char *biz_date)
break; break;
} }
total++; merchants++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_net <= 0) {
if (amount_is_valid(h_amount)) { tx_log(TX_LOG_WARN, "[ac_bt_0017] 순지급액 이하 제외 merch_id=%s net=%ld",
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); h_merch_id, h_net);
done++; skipped++;
} else { continue;
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
rc = ac_rec_update_status(h_key, h_new_status); if (h_net < AC_BT_0017_MIN_TRANSFER) {
if (rc != TX_OK) { tx_log(TX_LOG_INFO, "[ac_bt_0017] 최소이체금액 미만 보류 merch_id=%s net=%ld",
tx_log(TX_LOG_ERROR, "[ac_bt_0017] 상태전이 실패 key=%s rc=%d", h_key, rc); h_merch_id, h_net);
held++;
held_sum += h_net;
continue;
}
seq++;
snprintf(h_settle_no, sizeof(h_settle_no), "TR%s%05ld", h_biz_date, seq);
strncpy(h_status, AC_BT_0017_SETTLE_ST_XFER, sizeof(h_status));
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into settle ( settle_no , merch_id , biz_date , settle_amt , status ) values ( $1 , $2 , $3 , $4 , $5 )",
ECPGt_char,(h_settle_no),(long)20,(long)1,(20)*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_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_net),(long)1,(long)1,sizeof(long),
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_EOIT, ECPGt_EORT);}
#line 107 "app/batch/ac_bt_0017.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT ac_bt_0017 settle");
tx_log(TX_LOG_ERROR, "[ac_bt_0017] 이체지시 생성 실패 merch_id=%s", h_merch_id);
errcnt++; errcnt++;
continue;
} }
printf(" %-16s 이체번호=%-17s 이체금액=%ld\n", h_merch_id, h_settle_no, h_net);
transferred++;
grand_net += h_net;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0017", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_ac_bt_0017", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/ac_bt_0017.pgc" #line 122 "app/batch/ac_bt_0017.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +242,18 @@ static int run_ac_bt_0017(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0017] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0017] 요약 date=%s 가맹점=%ld 이체=%ld 이체총액=%ld 보류=%ld 보류액=%ld 제외=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, merchants, transferred, grand_net, held, held_sum, skipped, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0017] ==========\n"); printf(" ------------------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 대상 가맹점수 : %ld\n", merchants);
printf(" 대상 건수 : %ld\n", total); printf(" 이체 건수 : %ld\n", transferred);
printf(" 완료(M) : %ld\n", done); printf(" 이체 총액 : %ld\n", grand_net);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 보류 건수 : %ld\n", held);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 보류 금액합 : %ld\n", held_sum);
printf("=============================================\n"); printf(" 제외 건수 : %ld\n", skipped);
printf(" 오류 건수 : %ld\n", errcnt);
printf("========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,14 @@
/* @tier hard @module ac @transform acquire-batch */ /* @tier hard @module ac @transform acquire-batch */
/* /*
* ac_bt_0017.pgc - 매입 배치 (커서 순회 + 상태전이) [tier=hard] * ac_bt_0017.pgc - 매입 이체연계 배치 [tier=hard]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일에 정산완료(status='S') 된 매입행을 가맹점별로 집계하여
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 순지급액(매입금액-수수료 합계) 을 산출하고 이체지시를 생성한다.
* - 순지급액이 0원 이하이면 이체 대상에서 제외한다.
* - 순지급액이 최소이체금액(AC_BT_0017_MIN_TRANSFER) 미만이면 보류 처리하고
* 다음 영업일로 넘긴다(이체지시 미생성).
* - 그 외에는 이체번호를 채번하여 settle 테이블에 이체지시('T') 로 적재한다.
* 배치 main 엔트리 포함.
* *
* 실행: ac_bt_0017 <YYYYMMDD> [db@host] * 실행: ac_bt_0017 <YYYYMMDD> [db@host]
*/ */
@ -18,28 +23,38 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
#define AC_BT_0017_MIN_TRANSFER 1000L
/*
* 이체상태 'T' 는 settle 테이블 전용 로컬 상태코드이며,
* ac_core.h 의 AC_ST_* (ac_ledger 상태) 와는 별개의 값이다.
*/
#define AC_BT_0017_SETTLE_ST_XFER "T"
static int run_ac_bt_0017(const char *biz_date) static int run_ac_bt_0017(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
long h_amount; long h_net;
char h_new_status[2]; char h_settle_no[20];
char h_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, transferred = 0, held = 0, skipped = 0, errcnt = 0;
int rc; long seq = 0;
long grand_net = 0, held_sum = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_ac_bt_0017 CURSOR FOR EXEC SQL DECLARE cur_ac_bt_0017 CURSOR FOR
SELECT key, merch_id, amount SELECT merch_id, sum(amount - fee) AS net
FROM ac_ledger FROM ac_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'S'
ORDER BY key; GROUP BY merch_id
ORDER BY merch_id;
EXEC SQL OPEN cur_ac_bt_0017; EXEC SQL OPEN cur_ac_bt_0017;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -50,8 +65,12 @@ static int run_ac_bt_0017(const char *biz_date)
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[ac_bt_0017] tx_begin 경고"); tx_log(TX_LOG_WARN, "[ac_bt_0017] tx_begin 경고");
printf("========== 매입 이체연계 결과 [ac_bt_0017] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" ------------------------------------------------------\n");
for (;;) { for (;;) {
EXEC SQL FETCH cur_ac_bt_0017 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_ac_bt_0017 INTO :h_merch_id, :h_net;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,22 +80,43 @@ static int run_ac_bt_0017(const char *biz_date)
break; break;
} }
total++; merchants++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_net <= 0) {
if (amount_is_valid(h_amount)) { tx_log(TX_LOG_WARN, "[ac_bt_0017] 순지급액 이하 제외 merch_id=%s net=%ld",
strncpy(h_new_status, AC_ST_DONE, sizeof(h_new_status)); h_merch_id, h_net);
done++; skipped++;
} else { continue;
strncpy(h_new_status, AC_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
rc = ac_rec_update_status(h_key, h_new_status); if (h_net < AC_BT_0017_MIN_TRANSFER) {
if (rc != TX_OK) { tx_log(TX_LOG_INFO, "[ac_bt_0017] 최소이체금액 미만 보류 merch_id=%s net=%ld",
tx_log(TX_LOG_ERROR, "[ac_bt_0017] 상태전이 실패 key=%s rc=%d", h_key, rc); h_merch_id, h_net);
held++;
held_sum += h_net;
continue;
}
seq++;
snprintf(h_settle_no, sizeof(h_settle_no), "TR%s%05ld", h_biz_date, seq);
strncpy(h_status, AC_BT_0017_SETTLE_ST_XFER, sizeof(h_status));
EXEC SQL INSERT INTO settle
(settle_no, merch_id, biz_date, settle_amt, status)
VALUES
(:h_settle_no, :h_merch_id, :h_biz_date, :h_net, :h_status);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT ac_bt_0017 settle");
tx_log(TX_LOG_ERROR, "[ac_bt_0017] 이체지시 생성 실패 merch_id=%s", h_merch_id);
errcnt++; errcnt++;
continue;
} }
printf(" %-16s 이체번호=%-17s 이체금액=%ld\n", h_merch_id, h_settle_no, h_net);
transferred++;
grand_net += h_net;
} }
EXEC SQL CLOSE cur_ac_bt_0017; EXEC SQL CLOSE cur_ac_bt_0017;
@ -87,16 +127,18 @@ static int run_ac_bt_0017(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[ac_bt_0017] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[ac_bt_0017] 요약 date=%s 가맹점=%ld 이체=%ld 이체총액=%ld 보류=%ld 보류액=%ld 제외=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, merchants, transferred, grand_net, held, held_sum, skipped, errcnt);
printf("========== 매입 배치 결과 [ac_bt_0017] ==========\n"); printf(" ------------------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 대상 가맹점수 : %ld\n", merchants);
printf(" 대상 건수 : %ld\n", total); printf(" 이체 건수 : %ld\n", transferred);
printf(" 완료(M) : %ld\n", done); printf(" 이체 총액 : %ld\n", grand_net);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 보류 건수 : %ld\n", held);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 보류 금액합 : %ld\n", held_sum);
printf("=============================================\n"); printf(" 제외 건수 : %ld\n", skipped);
printf(" 오류 건수 : %ld\n", errcnt);
printf("========================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,12 +8,9 @@
#line 1 "app/batch/au_bt_0002.pgc" #line 1 "app/batch/au_bt_0002.pgc"
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0002.pgc - ( + ) [tier=medium] * au_bt_0002.pgc - ( M -> S) [tier=medium]
* *
* (status='R') * main . : au_bt_0002 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0002 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,7 +90,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0002.pgc" #line 16 "app/batch/au_bt_0002.pgc"
static int run_au_bt_0002(const char *biz_date) static int run_au_bt_0002(const char *biz_date)
@ -101,112 +98,72 @@ static int run_au_bt_0002(const char *biz_date)
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0002.pgc" #line 21 "app/batch/au_bt_0002.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/au_bt_0002.pgc" #line 22 "app/batch/au_bt_0002.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/au_bt_0002.pgc" #line 23 "app/batch/au_bt_0002.pgc"
char h_merch_id [ 16 ] ; long h_amount , h_fee ;
#line 27 "app/batch/au_bt_0002.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0002.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0002.pgc" #line 24 "app/batch/au_bt_0002.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, settled = 0, errcnt = 0, sum = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0002 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_settle cursor for select key , amount , fee from au_ledger where biz_date = $1 and status = 'M' order by key */
#line 42 "app/batch/au_bt_0002.pgc" #line 33 "app/batch/au_bt_0002.pgc"
#line 42 "app/batch/au_bt_0002.pgc" #line 33 "app/batch/au_bt_0002.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_settle cursor for select key , amount , fee from au_ledger where biz_date = $1 and status = 'M' order by key",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0002 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0002.pgc" #line 34 "app/batch/au_bt_0002.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_settle"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0002");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0002] tx_begin 경고");
if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0002] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0002", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_settle", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0002.pgc" #line 39 "app/batch/au_bt_0002.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0002");
errcnt++;
break;
}
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("FETCH cur_settle"); errcnt++; break; }
total++; total++;
sum += h_amount - h_fee;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_ledger set status = 'S' , upd_ts = now ( ) where 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 45 "app/batch/au_bt_0002.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; }
if (amount_is_valid(h_amount)) { else settled++;
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_settle", ECPGt_EOIT, ECPGt_EORT);}
#line 49 "app/batch/au_bt_0002.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0002", ECPGt_EOIT, ECPGt_EORT);} if (errcnt == 0) tx_commit(); else tx_abort();
#line 82 "app/batch/au_bt_0002.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
printf("===== 승인 정산반영 [au_bt_0002] =====\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상(M) : %ld\n", total);
printf(" 정산(S) : %ld\n", settled);
printf(" 순정산액 : %ld\n", sum);
printf(" 오류 : %ld\n", errcnt);
tx_log(TX_LOG_INFO, "[au_bt_0002] 정산 date=%s 대상=%ld 정산=%ld", biz_date, total, settled);
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -217,31 +174,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0002] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0002] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0002(biz_date); rc = run_au_bt_0002(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0002.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=medium] * au_bt_0002.pgc - 승인원장 정산반영 배치 (승인완료 M -> 정산 S) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0002 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0002 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -23,81 +20,42 @@ static int run_au_bt_0002(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16]; long h_amount, h_fee;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, settled = 0, errcnt = 0, sum = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0002 CURSOR FOR EXEC SQL DECLARE cur_settle CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount, fee FROM au_ledger
FROM au_ledger WHERE biz_date = :h_biz_date AND status = 'M'
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_settle;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_settle"); return TX_EDB; }
EXEC SQL OPEN cur_au_bt_0002; if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0002] tx_begin 경고");
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0002");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0002] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0002 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_settle INTO :h_key, :h_amount, :h_fee;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("FETCH cur_settle"); errcnt++; break; }
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0002");
errcnt++;
break;
}
total++; total++;
sum += h_amount - h_fee;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ EXEC SQL UPDATE au_ledger SET status = 'S', upd_ts = now()
if (amount_is_valid(h_amount)) { WHERE key = :h_key;
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; }
done++; else settled++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_settle;
if (errcnt == 0) tx_commit(); else tx_abort();
EXEC SQL CLOSE cur_au_bt_0002; printf("===== 승인 정산반영 [au_bt_0002] =====\n");
printf(" 영업일 : %s\n", biz_date);
if (errcnt == 0) printf(" 대상(M) : %ld\n", total);
tx_commit(); printf(" 정산(S) : %ld\n", settled);
else printf(" 순정산액 : %ld\n", sum);
tx_abort(); printf(" 오류 : %ld\n", errcnt);
tx_log(TX_LOG_INFO, "[au_bt_0002] 정산 date=%s 대상=%ld 정산=%ld", biz_date, total, settled);
tx_log(TX_LOG_INFO,
"[au_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -108,31 +66,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0002] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0002] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0002(biz_date); rc = run_au_bt_0002(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0002] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0003.pgc" #line 1 "app/batch/au_bt_0003.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0003.pgc - ( + ) [tier=easy] * au_bt_0003.pgc - ( /) [tier=medium]
* *
* (status='R') * main . : au_bt_0003 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0003 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,56 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0003.pgc" #line 16 "app/batch/au_bt_0003.pgc"
static int run_au_bt_0003(const char *biz_date) static int run_au_bt_0003(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0003.pgc" #line 21 "app/batch/au_bt_0003.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_st [ 2 ] ;
#line 25 "app/batch/au_bt_0003.pgc" #line 22 "app/batch/au_bt_0003.pgc"
char h_key [ 16 ] ; int h_cnt ;
#line 26 "app/batch/au_bt_0003.pgc" #line 23 "app/batch/au_bt_0003.pgc"
char h_merch_id [ 16 ] ; long h_sum ;
#line 27 "app/batch/au_bt_0003.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0003.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0003.pgc" #line 24 "app/batch/au_bt_0003.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; const char *codes = "RMUS";
int rc; const char *names[] = { "접수", "승인", "거절", "정산" };
int i;
long grand = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ printf("===== 승인 일별통계 [au_bt_0003] date=%s =====\n", biz_date);
/* declare cur_au_bt_0003 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ for (i = 0; codes[i]; i++) {
#line 42 "app/batch/au_bt_0003.pgc" h_st[0] = codes[i]; h_st[1] = '\0';
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) from au_ledger where biz_date = $1 and status = $2 ",
#line 42 "app/batch/au_bt_0003.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0003 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0003.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0003");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0003] tx_begin 경고");
for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0003", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_st),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0003.pgc" #line 38 "app/batch/au_bt_0003.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("통계"); return TX_EDB; }
if (sqlca.sqlcode == TX_SQL_NOTFOUND) printf(" %s(%c) : %6d 건 %15ld 원\n", names[i], codes[i], h_cnt, h_sum);
break; grand += h_sum;
if (sqlca.sqlcode != TX_SQL_OK) { tx_log(TX_LOG_INFO, "[au_bt_0003] %c cnt=%d sum=%ld", codes[i], h_cnt, h_sum);
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0003");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0003] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
printf(" 합계금액 : %ld 원\n", grand);
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0003", ECPGt_EOIT, ECPGt_EORT);} return TX_OK;
#line 82 "app/batch/au_bt_0003.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0003] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0003] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +149,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0003] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0003] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0003(biz_date); rc = run_au_bt_0003(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0003.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0003.pgc - 승인 일별 통계집계 배치 (상태별 건수/금액) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0003 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0003 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,31 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0003(const char *biz_date) static int run_au_bt_0003(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_st[2];
char h_key[16]; int h_cnt;
char h_merch_id[16]; long h_sum;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; const char *codes = "RMUS";
int rc; const char *names[] = { "접수", "승인", "거절", "정산" };
int i;
long grand = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0003 CURSOR FOR printf("===== 승인 일별통계 [au_bt_0003] date=%s =====\n", biz_date);
SELECT key, merch_id, amount for (i = 0; codes[i]; i++) {
FROM au_ledger h_st[0] = codes[i]; h_st[1] = '\0';
WHERE biz_date = :h_biz_date EXEC SQL SELECT count(*), coalesce(sum(amount), 0)
AND status = 'R' INTO :h_cnt, :h_sum
ORDER BY key; FROM au_ledger WHERE biz_date = :h_biz_date AND status = :h_st;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("통계"); return TX_EDB; }
EXEC SQL OPEN cur_au_bt_0003; printf(" %s(%c) : %6d 건 %15ld 원\n", names[i], codes[i], h_cnt, h_sum);
if (sqlca.sqlcode != TX_SQL_OK) { grand += h_sum;
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0003"); tx_log(TX_LOG_INFO, "[au_bt_0003] %c cnt=%d sum=%ld", codes[i], h_cnt, h_sum);
return TX_EDB;
} }
printf(" 합계금액 : %ld 원\n", grand);
if (tx_begin() != TX_OK) return TX_OK;
tx_log(TX_LOG_WARN, "[au_bt_0003] tx_begin 경고");
for (;;) {
EXEC SQL FETCH cur_au_bt_0003 INTO :h_key, :h_merch_id, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0003");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0003] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
EXEC SQL CLOSE cur_au_bt_0003;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0003] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0003] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +52,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0003] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0003] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0003(biz_date); rc = run_au_bt_0003(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0003] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -8,12 +8,9 @@
#line 1 "app/batch/au_bt_0004.pgc" #line 1 "app/batch/au_bt_0004.pgc"
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0004.pgc - ( + ) [tier=medium] * au_bt_0004.pgc - ( U -> R) [tier=medium]
* *
* (status='R') * main . : au_bt_0004 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0004 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,120 +90,69 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0004.pgc" #line 16 "app/batch/au_bt_0004.pgc"
static int run_au_bt_0004(const char *biz_date) static int run_au_bt_0004(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0004.pgc" #line 21 "app/batch/au_bt_0004.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_key [ 16 ] ;
#line 25 "app/batch/au_bt_0004.pgc" #line 22 "app/batch/au_bt_0004.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/au_bt_0004.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0004.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/au_bt_0004.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0004.pgc" #line 23 "app/batch/au_bt_0004.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, requeued = 0, skipped = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0004 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_retry cursor for select key , amount from au_ledger where biz_date = $1 and status = 'U' order by key */
#line 42 "app/batch/au_bt_0004.pgc" #line 32 "app/batch/au_bt_0004.pgc"
#line 42 "app/batch/au_bt_0004.pgc" #line 32 "app/batch/au_bt_0004.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_retry cursor for select key , amount from au_ledger where biz_date = $1 and status = 'U' order by key",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0004 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0004.pgc" #line 33 "app/batch/au_bt_0004.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_retry"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0004");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0004] tx_begin 경고");
if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0004] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0004", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_retry", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0004.pgc" #line 38 "app/batch/au_bt_0004.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0004");
errcnt++;
break;
}
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
total++; total++;
if (!amount_is_valid(h_amount)) { skipped++; continue; } /* 금액오류는 재처리 제외 */
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_ledger set status = 'R' , upd_ts = now ( ) where 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 44 "app/batch/au_bt_0004.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) errcnt++; else requeued++;
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0004] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_retry", ECPGt_EOIT, ECPGt_EORT);}
#line 47 "app/batch/au_bt_0004.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0004", ECPGt_EOIT, ECPGt_EORT);} if (errcnt == 0) tx_commit(); else tx_abort();
#line 82 "app/batch/au_bt_0004.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0004] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0004] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
printf("===== 승인 재처리 [au_bt_0004] =====\n");
printf(" 대상(U)=%ld 재접수=%ld 제외=%ld 오류=%ld\n", total, requeued, skipped, errcnt);
tx_log(TX_LOG_INFO, "[au_bt_0004] 재처리 date=%s 재접수=%ld", biz_date, requeued);
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -217,31 +163,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0004] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0004] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0004(biz_date); rc = run_au_bt_0004(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0004.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=medium] * au_bt_0004.pgc - 승인 실패건 재처리 배치 (거절 U -> 재접수 R) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0004 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0004 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,83 +18,38 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0004(const char *biz_date) static int run_au_bt_0004(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_key[16];
char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, requeued = 0, skipped = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0004 CURSOR FOR EXEC SQL DECLARE cur_retry CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount FROM au_ledger
FROM au_ledger WHERE biz_date = :h_biz_date AND status = 'U'
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_retry;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_retry"); return TX_EDB; }
EXEC SQL OPEN cur_au_bt_0004; if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0004] tx_begin 경고");
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0004");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0004] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0004 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_retry INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0004");
errcnt++;
break;
}
total++; total++;
if (!amount_is_valid(h_amount)) { skipped++; continue; } /* 금액오류는 재처리 제외 */
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ EXEC SQL UPDATE au_ledger SET status = 'R', upd_ts = now()
if (amount_is_valid(h_amount)) { WHERE key = :h_key;
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); if (sqlca.sqlcode != TX_SQL_OK) errcnt++; else requeued++;
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0004] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_retry;
if (errcnt == 0) tx_commit(); else tx_abort();
EXEC SQL CLOSE cur_au_bt_0004; printf("===== 승인 재처리 [au_bt_0004] =====\n");
printf(" 대상(U)=%ld 재접수=%ld 제외=%ld 오류=%ld\n", total, requeued, skipped, errcnt);
if (errcnt == 0) tx_log(TX_LOG_INFO, "[au_bt_0004] 재처리 date=%s 재접수=%ld", biz_date, requeued);
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0004] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0004] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -108,31 +60,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0004] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0004] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0004(biz_date); rc = run_au_bt_0004(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0004] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0005.pgc" #line 1 "app/batch/au_bt_0005.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier hard @module au @transform authorization-batch */
/* /*
* au_bt_0005.pgc - ( + ) [tier=easy] * au_bt_0005.pgc - ( ) [tier=hard]
* *
* (status='R') * main . : au_bt_0005 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0005 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,70 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0005.pgc" #line 16 "app/batch/au_bt_0005.pgc"
static int run_au_bt_0005(const char *biz_date) static int run_au_bt_0005(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0005.pgc" #line 21 "app/batch/au_bt_0005.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_card [ 20 ] ;
#line 25 "app/batch/au_bt_0005.pgc" #line 22 "app/batch/au_bt_0005.pgc"
char h_key [ 16 ] ; int h_cnt ;
#line 26 "app/batch/au_bt_0005.pgc" #line 23 "app/batch/au_bt_0005.pgc"
char h_merch_id [ 16 ] ; long h_sum ;
#line 27 "app/batch/au_bt_0005.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0005.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0005.pgc" #line 24 "app/batch/au_bt_0005.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long cards = 0, flagged = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0005 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_fraud cursor for select card_no , count ( * ) , sum ( amount ) from au_ledger where biz_date = $1 group by card_no having count ( * ) >= 10 or sum ( amount ) >= 30000000 order by sum ( amount ) desc */
#line 42 "app/batch/au_bt_0005.pgc" #line 36 "app/batch/au_bt_0005.pgc"
#line 42 "app/batch/au_bt_0005.pgc" #line 36 "app/batch/au_bt_0005.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_fraud cursor for select card_no , count ( * ) , sum ( amount ) from au_ledger where biz_date = $1 group by card_no having count ( * ) >= 10 or sum ( amount ) >= 30000000 order by sum ( amount ) desc",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0005 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0005.pgc" #line 37 "app/batch/au_bt_0005.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_fraud"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0005");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0005] tx_begin 경고");
printf("===== 이상거래 탐지 [au_bt_0005] date=%s =====\n", biz_date);
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0005", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_fraud", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_card),(long)20,(long)1,(20)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0005.pgc" #line 42 "app/batch/au_bt_0005.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; cards++;
if (sqlca.sqlcode != TX_SQL_OK) { flagged++;
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0005"); printf(" [의심] card=%s 건수=%d 합계=%ld\n", h_card, h_cnt, h_sum);
errcnt++; tx_log(TX_LOG_WARN, "[au_bt_0005] 이상거래 card=%s cnt=%d sum=%ld", h_card, h_cnt, h_sum);
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0005] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_fraud", ECPGt_EOIT, ECPGt_EORT);}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0005", ECPGt_EOIT, ECPGt_EORT);} #line 50 "app/batch/au_bt_0005.pgc"
#line 82 "app/batch/au_bt_0005.pgc"
if (errcnt == 0) printf(" 탐지 카드수 : %ld\n", flagged);
tx_commit(); (void)cards;
else return TX_OK;
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0005] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0005] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +163,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0005] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0005] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0005(biz_date); rc = run_au_bt_0005(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier hard @module au @transform authorization-batch */
/* /*
* au_bt_0005.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0005.pgc - 이상거래 탐지 배치 (카드별 임계 초과 플래그) [tier=hard]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0005 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0005 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,40 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0005(const char *biz_date) static int run_au_bt_0005(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_card[20];
char h_key[16]; int h_cnt;
char h_merch_id[16]; long h_sum;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long cards = 0, flagged = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0005 CURSOR FOR EXEC SQL DECLARE cur_fraud CURSOR FOR
SELECT key, merch_id, amount SELECT card_no, count(*), sum(amount)
FROM au_ledger FROM au_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' GROUP BY card_no
ORDER BY key; HAVING count(*) >= 10 OR sum(amount) >= 30000000
ORDER BY sum(amount) DESC;
EXEC SQL OPEN cur_au_bt_0005; EXEC SQL OPEN cur_fraud;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_fraud"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0005");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0005] tx_begin 경고");
printf("===== 이상거래 탐지 [au_bt_0005] date=%s =====\n", biz_date);
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0005 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_fraud INTO :h_card, :h_cnt, :h_sum;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; cards++;
if (sqlca.sqlcode != TX_SQL_OK) { flagged++;
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0005"); printf(" [의심] card=%s 건수=%d 합계=%ld\n", h_card, h_cnt, h_sum);
errcnt++; tx_log(TX_LOG_WARN, "[au_bt_0005] 이상거래 card=%s cnt=%d sum=%ld", h_card, h_cnt, h_sum);
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0005] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_fraud;
EXEC SQL CLOSE cur_au_bt_0005; printf(" 탐지 카드수 : %ld\n", flagged);
(void)cards;
if (errcnt == 0) return TX_OK;
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0005] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0005] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +61,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0005] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0005] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0005(biz_date); rc = run_au_bt_0005(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0005] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -8,12 +8,9 @@
#line 1 "app/batch/au_bt_0006.pgc" #line 1 "app/batch/au_bt_0006.pgc"
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0006.pgc - ( + ) [tier=medium] * au_bt_0006.pgc - ( ) [tier=medium]
* *
* (status='R') * main . : au_bt_0006 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0006 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,120 +90,72 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0006.pgc" #line 16 "app/batch/au_bt_0006.pgc"
static int run_au_bt_0006(const char *biz_date) static int run_au_bt_0006(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0006.pgc" #line 21 "app/batch/au_bt_0006.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_key [ 16 ] , h_merch [ 16 ] ;
#line 25 "app/batch/au_bt_0006.pgc" #line 22 "app/batch/au_bt_0006.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/au_bt_0006.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0006.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/au_bt_0006.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0006.pgc" #line 23 "app/batch/au_bt_0006.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, restored = 0, errcnt = 0, sum = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0006 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_restore cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'U' and amount > 0 order by merch_id , key */
#line 42 "app/batch/au_bt_0006.pgc" #line 32 "app/batch/au_bt_0006.pgc"
#line 42 "app/batch/au_bt_0006.pgc" #line 32 "app/batch/au_bt_0006.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_restore cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'U' and amount > 0 order by merch_id , key",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0006 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0006.pgc" #line 33 "app/batch/au_bt_0006.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_restore"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0006");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0006] tx_begin 경고");
if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0006] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0006", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_restore", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0006.pgc" #line 38 "app/batch/au_bt_0006.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0006");
errcnt++;
break;
}
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
total++; total++;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_ledger set fee = 0 , upd_ts = now ( ) where 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 42 "app/batch/au_bt_0006.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; continue; }
if (amount_is_valid(h_amount)) { restored++;
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); sum += h_amount;
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0006] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_restore", ECPGt_EOIT, ECPGt_EORT);}
#line 47 "app/batch/au_bt_0006.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0006", ECPGt_EOIT, ECPGt_EORT);} if (errcnt == 0) tx_commit(); else tx_abort();
#line 82 "app/batch/au_bt_0006.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0006] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0006] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
printf("===== 한도복원 [au_bt_0006] 대상=%ld 복원=%ld 복원액=%ld =====\n",
total, restored, sum);
tx_log(TX_LOG_INFO, "[au_bt_0006] 한도복원 date=%s 복원=%ld", biz_date, restored);
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -217,31 +166,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0006] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0006] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0006(biz_date); rc = run_au_bt_0006(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0006.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=medium] * au_bt_0006.pgc - 한도 복원 배치 (취소건 한도 원복) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0006 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0006 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,83 +18,38 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0006(const char *biz_date) static int run_au_bt_0006(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_key[16], h_merch[16];
char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, restored = 0, errcnt = 0, sum = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0006 CURSOR FOR EXEC SQL DECLARE cur_restore CURSOR FOR
SELECT key, merch_id, amount SELECT key, merch_id, amount FROM au_ledger
FROM au_ledger WHERE biz_date = :h_biz_date AND status = 'U' AND amount > 0
WHERE biz_date = :h_biz_date ORDER BY merch_id, key;
AND status = 'R' EXEC SQL OPEN cur_restore;
ORDER BY key; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_restore"); return TX_EDB; }
EXEC SQL OPEN cur_au_bt_0006;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0006");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0006] tx_begin 경고");
if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0006] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0006 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_restore INTO :h_key, :h_merch, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0006");
errcnt++;
break;
}
total++; total++;
EXEC SQL UPDATE au_ledger SET fee = 0, upd_ts = now() WHERE key = :h_key;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; continue; }
if (amount_is_valid(h_amount)) { restored++;
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); sum += h_amount;
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0006] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_restore;
if (errcnt == 0) tx_commit(); else tx_abort();
EXEC SQL CLOSE cur_au_bt_0006; printf("===== 한도복원 [au_bt_0006] 대상=%ld 복원=%ld 복원액=%ld =====\n",
total, restored, sum);
if (errcnt == 0) tx_log(TX_LOG_INFO, "[au_bt_0006] 한도복원 date=%s 복원=%ld", biz_date, restored);
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0006] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0006] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -108,31 +60,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0006] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0006] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0006(biz_date); rc = run_au_bt_0006(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0006] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0007.pgc" #line 1 "app/batch/au_bt_0007.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0007.pgc - ( + ) [tier=easy] * au_bt_0007.pgc - ( ) [tier=medium]
* *
* (status='R') * main . : au_bt_0007 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0007 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,71 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0007.pgc" #line 16 "app/batch/au_bt_0007.pgc"
static int run_au_bt_0007(const char *biz_date) static int run_au_bt_0007(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0007.pgc" #line 21 "app/batch/au_bt_0007.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_merch [ 16 ] ;
#line 25 "app/batch/au_bt_0007.pgc" #line 22 "app/batch/au_bt_0007.pgc"
char h_key [ 16 ] ; int h_cnt ;
#line 26 "app/batch/au_bt_0007.pgc" #line 23 "app/batch/au_bt_0007.pgc"
char h_merch_id [ 16 ] ; long h_sum , h_fee ;
#line 27 "app/batch/au_bt_0007.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0007.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0007.pgc" #line 24 "app/batch/au_bt_0007.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, grand = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0007 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_msum cursor for select merch_id , count ( * ) , sum ( amount ) , sum ( fee ) from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by merch_id order by sum ( amount ) desc */
#line 42 "app/batch/au_bt_0007.pgc" #line 35 "app/batch/au_bt_0007.pgc"
#line 42 "app/batch/au_bt_0007.pgc" #line 35 "app/batch/au_bt_0007.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_msum cursor for select merch_id , count ( * ) , sum ( amount ) , sum ( fee ) from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by merch_id order by sum ( amount ) desc",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0007 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0007.pgc" #line 36 "app/batch/au_bt_0007.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_msum"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0007");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0007] tx_begin 경고");
printf("===== 가맹점별 승인집계 [au_bt_0007] date=%s =====\n", biz_date);
printf(" %-15s %8s %15s %12s\n", "가맹점", "건수", "승인액", "수수료");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0007", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_msum", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0007.pgc" #line 42 "app/batch/au_bt_0007.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; merchants++;
if (sqlca.sqlcode != TX_SQL_OK) { grand += h_sum;
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0007"); printf(" %-15s %8d %15ld %12ld\n", h_merch, h_cnt, h_sum, h_fee);
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0007] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_msum", ECPGt_EOIT, ECPGt_EORT);}
#line 49 "app/batch/au_bt_0007.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0007", ECPGt_EOIT, ECPGt_EORT);} printf(" 가맹점수=%ld 총승인액=%ld\n", merchants, grand);
#line 82 "app/batch/au_bt_0007.pgc" tx_log(TX_LOG_INFO, "[au_bt_0007] 가맹점집계 date=%s merch=%ld", biz_date, merchants);
return TX_OK;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0007] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0007] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +164,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0007] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0007] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0007(biz_date); rc = run_au_bt_0007(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0007.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0007.pgc - 가맹점별 승인금액 집계 배치 (매출 리포트) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0007 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0007 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,38 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0007(const char *biz_date) static int run_au_bt_0007(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_merch[16];
char h_key[16]; int h_cnt;
char h_merch_id[16]; long h_sum, h_fee;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, grand = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0007 CURSOR FOR EXEC SQL DECLARE cur_msum CURSOR FOR
SELECT key, merch_id, amount SELECT merch_id, count(*), sum(amount), sum(fee)
FROM au_ledger FROM au_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date AND status IN ('M','S')
AND status = 'R' GROUP BY merch_id
ORDER BY key; ORDER BY sum(amount) DESC;
EXEC SQL OPEN cur_msum;
EXEC SQL OPEN cur_au_bt_0007; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_msum"); return TX_EDB; }
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0007");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0007] tx_begin 경고");
printf("===== 가맹점별 승인집계 [au_bt_0007] date=%s =====\n", biz_date);
printf(" %-15s %8s %15s %12s\n", "가맹점", "건수", "승인액", "수수료");
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0007 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_msum INTO :h_merch, :h_cnt, :h_sum, :h_fee;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; merchants++;
if (sqlca.sqlcode != TX_SQL_OK) { grand += h_sum;
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0007"); printf(" %-15s %8d %15ld %12ld\n", h_merch, h_cnt, h_sum, h_fee);
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0007] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_msum;
EXEC SQL CLOSE cur_au_bt_0007; printf(" 가맹점수=%ld 총승인액=%ld\n", merchants, grand);
tx_log(TX_LOG_INFO, "[au_bt_0007] 가맹점집계 date=%s merch=%ld", biz_date, merchants);
if (errcnt == 0) return TX_OK;
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0007] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0007] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +59,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0007] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0007] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0007(biz_date); rc = run_au_bt_0007(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0007] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0008.pgc" #line 1 "app/batch/au_bt_0008.pgc"
/* @tier hard @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0008.pgc - ( + ) [tier=hard] * au_bt_0008.pgc - ( R -> U) [tier=medium]
* *
* (status='R') * main . : au_bt_0008 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0008 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,44 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0008.pgc" #line 16 "app/batch/au_bt_0008.pgc"
static int run_au_bt_0008(const char *biz_date) static int run_au_bt_0008(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0008.pgc" #line 21 "app/batch/au_bt_0008.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/au_bt_0008.pgc" #line 22 "app/batch/au_bt_0008.pgc"
char h_key [ 16 ] ; int h_aff ;
#line 26 "app/batch/au_bt_0008.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0008.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0008.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0008.pgc" #line 23 "app/batch/au_bt_0008.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0008] tx_begin 경고");
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_ledger set status = 'U' , upd_ts = now ( ) where status = 'R' and biz_date < $1 ",
ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0008 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/au_bt_0008.pgc"
#line 42 "app/batch/au_bt_0008.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0008 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0008.pgc" #line 30 "app/batch/au_bt_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0008"); TX_DBIO_LOG_ERR("au_bt_0008 정리");
tx_abort();
return TX_EDB; return TX_EDB;
} }
h_aff = (int)sqlca.sqlerrd[2];
tx_commit();
if (tx_begin() != TX_OK) printf("===== 미승인 정리 [au_bt_0008] 기준일<%s 실효처리=%d 건 =====\n",
tx_log(TX_LOG_WARN, "[au_bt_0008] tx_begin 경고"); biz_date, h_aff);
tx_log(TX_LOG_INFO, "[au_bt_0008] 미승인 실효 %d건", h_aff);
for (;;) { return TX_OK;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0008", ECPGt_EOIT,
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_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0008.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0008");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0008] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0008", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/au_bt_0008.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0008] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0008] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +137,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0008] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0008] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0008(biz_date); rc = run_au_bt_0008(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier hard @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0008.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=hard] * au_bt_0008.pgc - 미승인 접수건 정리 배치 (장기 R -> 실효 U) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0008 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0008 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -22,83 +19,27 @@ static int run_au_bt_0008(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; int h_aff;
char h_merch_id[16];
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0008] tx_begin 경고");
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; EXEC SQL UPDATE au_ledger
SET status = 'U', upd_ts = now()
EXEC SQL DECLARE cur_au_bt_0008 CURSOR FOR WHERE status = 'R' AND biz_date < :h_biz_date;
SELECT key, merch_id, amount
FROM au_ledger
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key;
EXEC SQL OPEN cur_au_bt_0008;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0008"); TX_DBIO_LOG_ERR("au_bt_0008 정리");
tx_abort();
return TX_EDB; return TX_EDB;
} }
h_aff = (int)sqlca.sqlerrd[2];
tx_commit();
if (tx_begin() != TX_OK) printf("===== 미승인 정리 [au_bt_0008] 기준일<%s 실효처리=%d 건 =====\n",
tx_log(TX_LOG_WARN, "[au_bt_0008] tx_begin 경고"); biz_date, h_aff);
tx_log(TX_LOG_INFO, "[au_bt_0008] 미승인 실효 %d건", h_aff);
for (;;) { return TX_OK;
EXEC SQL FETCH cur_au_bt_0008 INTO :h_key, :h_merch_id, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0008");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0008] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
EXEC SQL CLOSE cur_au_bt_0008;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0008] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0008] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +49,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0008] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0008] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0008(biz_date); rc = run_au_bt_0008(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0008] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0009.pgc" #line 1 "app/batch/au_bt_0009.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0009.pgc - ( + ) [tier=easy] * au_bt_0009.pgc - ( UPDATE) [tier=medium]
* *
* (status='R') * main . : au_bt_0009 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0009 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,120 +90,77 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0009.pgc" #line 16 "app/batch/au_bt_0009.pgc"
static int run_au_bt_0009(const char *biz_date) static int run_au_bt_0009(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0009.pgc" #line 21 "app/batch/au_bt_0009.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_key [ 16 ] , h_merch [ 16 ] ;
#line 25 "app/batch/au_bt_0009.pgc" #line 22 "app/batch/au_bt_0009.pgc"
char h_key [ 16 ] ; long h_amount , h_fee ;
#line 26 "app/batch/au_bt_0009.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0009.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0009.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0009.pgc" #line 23 "app/batch/au_bt_0009.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0, feesum = 0;
int rc; int rate;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0009 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_fee cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) order by key */
#line 42 "app/batch/au_bt_0009.pgc" #line 33 "app/batch/au_bt_0009.pgc"
#line 42 "app/batch/au_bt_0009.pgc" #line 33 "app/batch/au_bt_0009.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_fee cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) order by key",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0009 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0009.pgc" #line 34 "app/batch/au_bt_0009.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_fee"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0009");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0009] tx_begin 경고");
if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0009] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0009", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_fee", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0009.pgc" #line 39 "app/batch/au_bt_0009.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0009");
errcnt++;
break;
}
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
total++; total++;
/* 금액구간별 차등요율 (basis point) */
rate = (h_amount >= 1000000L) ? 80 : (h_amount >= 100000L) ? 120 : 150;
h_fee = h_amount * rate / 10000;
feesum += h_fee;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_ledger set fee = $1 , upd_ts = now ( ) where key = $2 ",
ECPGt_long,&(h_fee),(long)1,(long)1,sizeof(long),
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 47 "app/batch/au_bt_0009.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) errcnt++;
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0009] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_fee", ECPGt_EOIT, ECPGt_EORT);}
#line 50 "app/batch/au_bt_0009.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0009", ECPGt_EOIT, ECPGt_EORT);} if (errcnt == 0) tx_commit(); else tx_abort();
#line 82 "app/batch/au_bt_0009.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0009] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0009] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
printf("===== 수수료 재정산 [au_bt_0009] 대상=%ld 수수료합=%ld 오류=%ld =====\n",
total, feesum, errcnt);
tx_log(TX_LOG_INFO, "[au_bt_0009] 수수료 재정산 date=%s feesum=%ld", biz_date, feesum);
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -217,31 +171,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0009] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0009] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0009(biz_date); rc = run_au_bt_0009(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0009.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0009.pgc - 승인 수수료 재정산 배치 (요율표 일괄 UPDATE) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0009 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0009 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,83 +18,41 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0009(const char *biz_date) static int run_au_bt_0009(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_key[16], h_merch[16];
char h_key[16]; long h_amount, h_fee;
char h_merch_id[16];
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, errcnt = 0, feesum = 0;
int rc; int rate;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0009 CURSOR FOR EXEC SQL DECLARE cur_fee CURSOR FOR
SELECT key, merch_id, amount SELECT key, merch_id, amount FROM au_ledger
FROM au_ledger WHERE biz_date = :h_biz_date AND status IN ('M','S')
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_fee;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_fee"); return TX_EDB; }
EXEC SQL OPEN cur_au_bt_0009; if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0009] tx_begin 경고");
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0009");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0009] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0009 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_fee INTO :h_key, :h_merch, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0009");
errcnt++;
break;
}
total++; total++;
/* 금액구간별 차등요율 (basis point) */
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ rate = (h_amount >= 1000000L) ? 80 : (h_amount >= 100000L) ? 120 : 150;
if (amount_is_valid(h_amount)) { h_fee = h_amount * rate / 10000;
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); feesum += h_fee;
done++; EXEC SQL UPDATE au_ledger SET fee = :h_fee, upd_ts = now() WHERE key = :h_key;
} else { if (sqlca.sqlcode != TX_SQL_OK) errcnt++;
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0009] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_fee;
if (errcnt == 0) tx_commit(); else tx_abort();
EXEC SQL CLOSE cur_au_bt_0009; printf("===== 수수료 재정산 [au_bt_0009] 대상=%ld 수수료합=%ld 오류=%ld =====\n",
total, feesum, errcnt);
if (errcnt == 0) tx_log(TX_LOG_INFO, "[au_bt_0009] 수수료 재정산 date=%s feesum=%ld", biz_date, feesum);
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0009] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0009] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -108,31 +63,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0009] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0009] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0009(biz_date); rc = run_au_bt_0009(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0009] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0010.pgc" #line 1 "app/batch/au_bt_0010.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0010.pgc - ( + ) [tier=easy] * au_bt_0010.pgc - ( ) [tier=medium]
* *
* (status='R') * main . : au_bt_0010 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0010 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,120 +90,67 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0010.pgc" #line 16 "app/batch/au_bt_0010.pgc"
static int run_au_bt_0010(const char *biz_date) static int run_au_bt_0010(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0010.pgc" #line 21 "app/batch/au_bt_0010.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_key [ 16 ] ;
#line 25 "app/batch/au_bt_0010.pgc" #line 22 "app/batch/au_bt_0010.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/au_bt_0010.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0010.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/au_bt_0010.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0010.pgc" #line 23 "app/batch/au_bt_0010.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, matured = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0010 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_inst cursor for select key , amount from au_ledger where biz_date = $1 and card_no = 'INSTALLMENT' and status = 'M' order by key */
#line 42 "app/batch/au_bt_0010.pgc" #line 32 "app/batch/au_bt_0010.pgc"
#line 42 "app/batch/au_bt_0010.pgc" #line 32 "app/batch/au_bt_0010.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_inst cursor for select key , amount from au_ledger where biz_date = $1 and card_no = 'INSTALLMENT' and status = 'M' order by key",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0010 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0010.pgc" #line 33 "app/batch/au_bt_0010.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_inst"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0010");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0010] tx_begin 경고");
if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0010] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0010", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_inst", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0010.pgc" #line 38 "app/batch/au_bt_0010.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0010");
errcnt++;
break;
}
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
total++; total++;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_ledger set status = 'S' , upd_ts = now ( ) where 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 42 "app/batch/au_bt_0010.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) errcnt++; else matured++;
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0010] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_inst", ECPGt_EOIT, ECPGt_EORT);}
#line 45 "app/batch/au_bt_0010.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0010", ECPGt_EOIT, ECPGt_EORT);} if (errcnt == 0) tx_commit(); else tx_abort();
#line 82 "app/batch/au_bt_0010.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0010] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0010] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
printf("===== 무이자할부 만기정산 [au_bt_0010] 대상=%ld 정산=%ld =====\n", total, matured);
tx_log(TX_LOG_INFO, "[au_bt_0010] 할부만기 date=%s 정산=%ld", biz_date, matured);
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -217,31 +161,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0010] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0010] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0010(biz_date); rc = run_au_bt_0010(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0010.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0010.pgc - 무이자할부 만기정산 배치 (할부건 정산전이) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0010 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0010 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,83 +18,35 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0010(const char *biz_date) static int run_au_bt_0010(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_key[16];
char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, matured = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0010 CURSOR FOR EXEC SQL DECLARE cur_inst CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount FROM au_ledger
FROM au_ledger WHERE biz_date = :h_biz_date AND card_no = 'INSTALLMENT' AND status = 'M'
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_inst;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_inst"); return TX_EDB; }
EXEC SQL OPEN cur_au_bt_0010; if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0010] tx_begin 경고");
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0010");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0010] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0010 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_inst INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) { errcnt++; break; }
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0010");
errcnt++;
break;
}
total++; total++;
EXEC SQL UPDATE au_ledger SET status = 'S', upd_ts = now() WHERE key = :h_key;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode != TX_SQL_OK) errcnt++; else matured++;
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0010] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_inst;
if (errcnt == 0) tx_commit(); else tx_abort();
EXEC SQL CLOSE cur_au_bt_0010; printf("===== 무이자할부 만기정산 [au_bt_0010] 대상=%ld 정산=%ld =====\n", total, matured);
tx_log(TX_LOG_INFO, "[au_bt_0010] 할부만기 date=%s 정산=%ld", biz_date, matured);
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0010] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0010] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
@ -108,31 +57,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0010] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0010] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0010(biz_date); rc = run_au_bt_0010(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0010] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -8,12 +8,9 @@
#line 1 "app/batch/au_bt_0011.pgc" #line 1 "app/batch/au_bt_0011.pgc"
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0011.pgc - ( + ) [tier=medium] * au_bt_0011.pgc - ( ) [tier=medium]
* *
* (status='R') * main . : au_bt_0011 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0011 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,69 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0011.pgc" #line 16 "app/batch/au_bt_0011.pgc"
static int run_au_bt_0011(const char *biz_date) static int run_au_bt_0011(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0011.pgc" #line 21 "app/batch/au_bt_0011.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_merch [ 16 ] ;
#line 25 "app/batch/au_bt_0011.pgc" #line 22 "app/batch/au_bt_0011.pgc"
char h_key [ 16 ] ; long h_sum ;
#line 26 "app/batch/au_bt_0011.pgc" #line 23 "app/batch/au_bt_0011.pgc"
char h_merch_id [ 16 ] ; long h_limit ;
#line 27 "app/batch/au_bt_0011.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0011.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0011.pgc" #line 24 "app/batch/au_bt_0011.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long over = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_limit = 100000000L;
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, &( h_limit ), __LINE__);\
/* declare cur_au_bt_0011 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ ECPGset_var( 1, ( h_biz_date ), __LINE__);\
#line 42 "app/batch/au_bt_0011.pgc" /* declare cur_over cursor for select merch_id , sum ( amount ) from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by merch_id having sum ( amount ) > $2 order by sum ( amount ) desc */
#line 36 "app/batch/au_bt_0011.pgc"
#line 42 "app/batch/au_bt_0011.pgc" #line 36 "app/batch/au_bt_0011.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_over cursor for select merch_id , sum ( amount ) from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by merch_id having sum ( amount ) > $2 order by sum ( amount ) desc",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0011 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_limit),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0011.pgc" #line 37 "app/batch/au_bt_0011.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_over"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0011");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0011] tx_begin 경고");
printf("===== 가맹점 한도초과 리포트 [au_bt_0011] (한도 %ld) =====\n", h_limit);
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0011", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_over", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0011.pgc" #line 42 "app/batch/au_bt_0011.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; over++;
if (sqlca.sqlcode != TX_SQL_OK) { printf(" [초과] merch=%s 승인액=%ld 초과=%ld\n", h_merch, h_sum, h_sum - h_limit);
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0011"); tx_log(TX_LOG_WARN, "[au_bt_0011] 한도초과 merch=%s sum=%ld", h_merch, h_sum);
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0011] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_over", ECPGt_EOIT, ECPGt_EORT);}
#line 49 "app/batch/au_bt_0011.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0011", ECPGt_EOIT, ECPGt_EORT);} printf(" 초과 가맹점수=%ld\n", over);
#line 82 "app/batch/au_bt_0011.pgc" return TX_OK;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0011] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0011] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +162,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0011] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0011] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0011(biz_date); rc = run_au_bt_0011(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier medium @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0011.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=medium] * au_bt_0011.pgc - 가맹점 한도초과 리포트 배치 (임계 초과 추출) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0011 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0011 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,37 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0011(const char *biz_date) static int run_au_bt_0011(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_merch[16];
char h_key[16]; long h_sum;
char h_merch_id[16]; long h_limit;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long over = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_limit = 100000000L;
EXEC SQL DECLARE cur_au_bt_0011 CURSOR FOR EXEC SQL DECLARE cur_over CURSOR FOR
SELECT key, merch_id, amount SELECT merch_id, sum(amount) FROM au_ledger
FROM au_ledger WHERE biz_date = :h_biz_date AND status IN ('M','S')
WHERE biz_date = :h_biz_date GROUP BY merch_id
AND status = 'R' HAVING sum(amount) > :h_limit
ORDER BY key; ORDER BY sum(amount) DESC;
EXEC SQL OPEN cur_over;
EXEC SQL OPEN cur_au_bt_0011; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_over"); return TX_EDB; }
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0011");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0011] tx_begin 경고");
printf("===== 가맹점 한도초과 리포트 [au_bt_0011] (한도 %ld) =====\n", h_limit);
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0011 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_over INTO :h_merch, :h_sum;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; over++;
if (sqlca.sqlcode != TX_SQL_OK) { printf(" [초과] merch=%s 승인액=%ld 초과=%ld\n", h_merch, h_sum, h_sum - h_limit);
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0011"); tx_log(TX_LOG_WARN, "[au_bt_0011] 한도초과 merch=%s sum=%ld", h_merch, h_sum);
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0011] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_over;
EXEC SQL CLOSE cur_au_bt_0011; printf(" 초과 가맹점수=%ld\n", over);
return TX_OK;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0011] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0011] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +58,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0011] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0011] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0011(biz_date); rc = run_au_bt_0011(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0011] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0012.pgc" #line 1 "app/batch/au_bt_0012.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0012.pgc - ( + ) [tier=easy] * au_bt_0012.pgc - (BIN ) [tier=medium]
* *
* (status='R') * main . : au_bt_0012 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0012 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,67 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0012.pgc" #line 16 "app/batch/au_bt_0012.pgc"
static int run_au_bt_0012(const char *biz_date) static int run_au_bt_0012(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0012.pgc" #line 21 "app/batch/au_bt_0012.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_bin [ 8 ] ;
#line 25 "app/batch/au_bt_0012.pgc" #line 22 "app/batch/au_bt_0012.pgc"
char h_key [ 16 ] ; int h_cnt ;
#line 26 "app/batch/au_bt_0012.pgc" #line 23 "app/batch/au_bt_0012.pgc"
char h_merch_id [ 16 ] ; long h_sum ;
#line 27 "app/batch/au_bt_0012.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0012.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0012.pgc" #line 24 "app/batch/au_bt_0012.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long bins = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0012 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_bin cursor for select substring ( card_no from 1 for 6 ) as bin , count ( * ) , sum ( amount ) from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by substring ( card_no from 1 for 6 ) order by count ( * ) desc */
#line 42 "app/batch/au_bt_0012.pgc" #line 35 "app/batch/au_bt_0012.pgc"
#line 42 "app/batch/au_bt_0012.pgc" #line 35 "app/batch/au_bt_0012.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_bin cursor for select substring ( card_no from 1 for 6 ) as bin , count ( * ) , sum ( amount ) from au_ledger where biz_date = $1 and status in ( 'M' , 'S' ) group by substring ( card_no from 1 for 6 ) order by count ( * ) desc",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0012 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0012.pgc" #line 36 "app/batch/au_bt_0012.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_bin"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0012");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0012] tx_begin 경고");
printf("===== 카드사별(BIN) 승인집계 [au_bt_0012] date=%s =====\n", biz_date);
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0012", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_bin", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_bin),(long)8,(long)1,(8)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0012.pgc" #line 41 "app/batch/au_bt_0012.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; bins++;
if (sqlca.sqlcode != TX_SQL_OK) { printf(" BIN %-6s : %6d 건 %15ld 원\n", h_bin, h_cnt, h_sum);
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0012");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0012] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_bin", ECPGt_EOIT, ECPGt_EORT);}
#line 47 "app/batch/au_bt_0012.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0012", ECPGt_EOIT, ECPGt_EORT);} printf(" BIN 구간수=%ld\n", bins);
#line 82 "app/batch/au_bt_0012.pgc" tx_log(TX_LOG_INFO, "[au_bt_0012] BIN집계 date=%s bins=%ld", biz_date, bins);
return TX_OK;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0012] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0012] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +160,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0012] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0012] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0012(biz_date); rc = run_au_bt_0012(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0012.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0012.pgc - 카드사별 승인집계 배치 (BIN 구간 그룹) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0012 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0012 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,36 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0012(const char *biz_date) static int run_au_bt_0012(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_bin[8];
char h_key[16]; int h_cnt;
char h_merch_id[16]; long h_sum;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long bins = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0012 CURSOR FOR EXEC SQL DECLARE cur_bin CURSOR FOR
SELECT key, merch_id, amount SELECT substring(card_no from 1 for 6) AS bin, count(*), sum(amount)
FROM au_ledger FROM au_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date AND status IN ('M','S')
AND status = 'R' GROUP BY substring(card_no from 1 for 6)
ORDER BY key; ORDER BY count(*) DESC;
EXEC SQL OPEN cur_bin;
EXEC SQL OPEN cur_au_bt_0012; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_bin"); return TX_EDB; }
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0012");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0012] tx_begin 경고");
printf("===== 카드사별(BIN) 승인집계 [au_bt_0012] date=%s =====\n", biz_date);
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0012 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_bin INTO :h_bin, :h_cnt, :h_sum;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; bins++;
if (sqlca.sqlcode != TX_SQL_OK) { printf(" BIN %-6s : %6d 건 %15ld 원\n", h_bin, h_cnt, h_sum);
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0012");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0012] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_bin;
EXEC SQL CLOSE cur_au_bt_0012; printf(" BIN 구간수=%ld\n", bins);
tx_log(TX_LOG_INFO, "[au_bt_0012] BIN집계 date=%s bins=%ld", biz_date, bins);
if (errcnt == 0) return TX_OK;
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0012] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0012] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +57,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0012] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0012] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0012(biz_date); rc = run_au_bt_0012(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0012] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0013.pgc" #line 1 "app/batch/au_bt_0013.pgc"
/* @tier medium @module au @transform authorization-batch */ /* @tier hard @module au @transform authorization-batch */
/* /*
* au_bt_0013.pgc - ( + ) [tier=medium] * au_bt_0013.pgc - ( tx_call) [tier=hard]
* *
* (status='R') * main . : au_bt_0013 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0013 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,85 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0013.pgc" #line 16 "app/batch/au_bt_0013.pgc"
static int run_au_bt_0013(const char *biz_date) static int run_au_bt_0013(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0013.pgc" #line 21 "app/batch/au_bt_0013.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_key [ 16 ] ;
#line 25 "app/batch/au_bt_0013.pgc" #line 22 "app/batch/au_bt_0013.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/au_bt_0013.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0013.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/au_bt_0013.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0013.pgc" #line 23 "app/batch/au_bt_0013.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; TXBUF *req, *resp;
long total = 0, ok = 0, fail = 0;
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0013 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_resend cursor for select key , amount from au_ledger where biz_date = $1 and status = 'U' order by key */
#line 42 "app/batch/au_bt_0013.pgc" #line 34 "app/batch/au_bt_0013.pgc"
#line 42 "app/batch/au_bt_0013.pgc" #line 34 "app/batch/au_bt_0013.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_resend cursor for select key , amount from au_ledger where biz_date = $1 and status = 'U' order by key",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0013 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0013.pgc" #line 35 "app/batch/au_bt_0013.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_resend"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0013");
return TX_EDB;
}
if (tx_begin() != TX_OK) req = tx_buf_alloc();
tx_log(TX_LOG_WARN, "[au_bt_0013] tx_begin 경고"); resp = tx_buf_alloc();
if (!req || !resp) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_resend", ECPGt_EOIT, ECPGt_EORT);}
#line 40 "app/batch/au_bt_0013.pgc"
return TX_ENOMEM; }
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0013", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_resend", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0013.pgc" #line 43 "app/batch/au_bt_0013.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0013");
errcnt++;
break;
}
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode != TX_SQL_OK) break;
total++; total++;
tx_buf_reset(req);
tx_buf_reset(resp);
tx_buf_sets(req, "KEY", h_key);
tx_buf_setlong(req, "AMOUNT", h_amount);
rc = tx_call("AU_ISSUER", req, resp);
if (rc == TX_OK) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update au_ledger set status = 'M' , upd_ts = now ( ) where 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 53 "app/batch/au_bt_0013.pgc"
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (sqlca.sqlcode == TX_SQL_OK) { tx_commit(); ok++; }
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else { } else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status)); fail++;
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0013] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
} }
} }
tx_buf_free(req);
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0013", ECPGt_EOIT, ECPGt_EORT);} tx_buf_free(resp);
#line 82 "app/batch/au_bt_0013.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_resend", ECPGt_EOIT, ECPGt_EORT);}
#line 61 "app/batch/au_bt_0013.pgc"
if (errcnt == 0) printf("===== 승인 재시도 [au_bt_0013] 대상=%ld 성공=%ld 실패=%ld =====\n", total, ok, fail);
tx_commit(); tx_log(TX_LOG_INFO, "[au_bt_0013] 재중계 date=%s ok=%ld fail=%ld", biz_date, ok, fail);
else return TX_OK;
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0013] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0013] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +178,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0013] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0013] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0013(biz_date); rc = run_au_bt_0013(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier medium @module au @transform authorization-batch */ /* @tier hard @module au @transform authorization-batch */
/* /*
* au_bt_0013.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=medium] * au_bt_0013.pgc - 승인 재시도 배치 (거절건 매입사 재중계 tx_call) [tier=hard]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0013 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0013 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,51 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0013(const char *biz_date) static int run_au_bt_0013(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_key[16];
char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; TXBUF *req, *resp;
long total = 0, ok = 0, fail = 0;
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0013 CURSOR FOR EXEC SQL DECLARE cur_resend CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount FROM au_ledger
FROM au_ledger WHERE biz_date = :h_biz_date AND status = 'U'
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_resend;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_resend"); return TX_EDB; }
EXEC SQL OPEN cur_au_bt_0013; req = tx_buf_alloc();
if (sqlca.sqlcode != TX_SQL_OK) { resp = tx_buf_alloc();
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0013"); if (!req || !resp) { EXEC SQL CLOSE cur_resend; return TX_ENOMEM; }
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0013] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0013 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_resend INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0013");
errcnt++;
break;
}
total++; total++;
tx_buf_reset(req);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ tx_buf_reset(resp);
if (amount_is_valid(h_amount)) { tx_buf_sets(req, "KEY", h_key);
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); tx_buf_setlong(req, "AMOUNT", h_amount);
done++; rc = tx_call("AU_ISSUER", req, resp);
if (rc == TX_OK) {
EXEC SQL UPDATE au_ledger SET status = 'M', upd_ts = now() WHERE key = :h_key;
if (sqlca.sqlcode == TX_SQL_OK) { tx_commit(); ok++; }
} else { } else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status)); fail++;
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0013] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
} }
} }
tx_buf_free(req);
tx_buf_free(resp);
EXEC SQL CLOSE cur_resend;
EXEC SQL CLOSE cur_au_bt_0013; printf("===== 승인 재시도 [au_bt_0013] 대상=%ld 성공=%ld 실패=%ld =====\n", total, ok, fail);
tx_log(TX_LOG_INFO, "[au_bt_0013] 재중계 date=%s ok=%ld fail=%ld", biz_date, ok, fail);
if (errcnt == 0) return TX_OK;
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0013] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0013] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +72,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0013] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0013] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0013(biz_date); rc = run_au_bt_0013(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0013] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0014.pgc" #line 1 "app/batch/au_bt_0014.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0014.pgc - ( + ) [tier=easy] * au_bt_0014.pgc - ( / ) [tier=medium]
* *
* (status='R') * main . : au_bt_0014 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0014 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,56 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0014.pgc" #line 16 "app/batch/au_bt_0014.pgc"
static int run_au_bt_0014(const char *biz_date) static int run_au_bt_0014(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0014.pgc" #line 21 "app/batch/au_bt_0014.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/au_bt_0014.pgc" #line 22 "app/batch/au_bt_0014.pgc"
char h_key [ 16 ] ; int h_recv , h_appr , h_settle ;
#line 26 "app/batch/au_bt_0014.pgc" #line 23 "app/batch/au_bt_0014.pgc"
char h_merch_id [ 16 ] ; long h_total ;
#line 27 "app/batch/au_bt_0014.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0014.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0014.pgc" #line 24 "app/batch/au_bt_0014.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) filter ( where status = 'R' ) , count ( * ) filter ( where status = 'M' ) , count ( * ) filter ( where status = 'S' ) , coalesce ( sum ( amount ) filter ( where status in ( 'M' , 'S' ) ) , 0 ) from au_ledger where biz_date = $1 ",
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0014 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/au_bt_0014.pgc"
#line 42 "app/batch/au_bt_0014.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0014 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
#line 44 "app/batch/au_bt_0014.pgc" ECPGt_int,&(h_recv),(long)1,(long)1,sizeof(int),
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0014");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0014] tx_begin 경고");
for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0014", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_int,&(h_appr),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_int,&(h_settle),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_total),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0014.pgc" #line 34 "app/batch/au_bt_0014.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("au_bt_0014 마감집계"); return TX_EDB; }
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (h_recv > 0)
break; tx_log(TX_LOG_WARN, "[au_bt_0014] 미처리 접수건 %d 존재 - 마감 확인필요", h_recv);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0014");
errcnt++;
break;
}
total++; printf("===== 승인 일마감 [au_bt_0014] date=%s =====\n", biz_date);
printf(" 미처리(R) : %d\n", h_recv);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ printf(" 승인(M) : %d\n", h_appr);
if (amount_is_valid(h_amount)) { printf(" 정산(S) : %d\n", h_settle);
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); printf(" 승인총액 : %ld\n", h_total);
done++; printf(" 마감상태 : %s\n", (h_recv == 0) ? "정상마감" : "보류");
} else { tx_log(TX_LOG_INFO, "[au_bt_0014] 일마감 date=%s total=%ld", biz_date, h_total);
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status)); return (h_recv == 0) ? TX_OK : TX_FAIL;
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0014] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0014", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/au_bt_0014.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0014] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0014] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +149,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0014] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0014] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0014(biz_date); rc = run_au_bt_0014(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0014.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0014.pgc - 승인 일마감 배치 (당일 마감/집계 확정) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0014 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0014 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -22,83 +19,32 @@ static int run_au_bt_0014(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; int h_recv, h_appr, h_settle;
char h_merch_id[16]; long h_total;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); EXEC SQL SELECT
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; count(*) FILTER (WHERE status = 'R'),
count(*) FILTER (WHERE status = 'M'),
count(*) FILTER (WHERE status = 'S'),
coalesce(sum(amount) FILTER (WHERE status IN ('M','S')), 0)
INTO :h_recv, :h_appr, :h_settle, :h_total
FROM au_ledger WHERE biz_date = :h_biz_date;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("au_bt_0014 마감집계"); return TX_EDB; }
EXEC SQL DECLARE cur_au_bt_0014 CURSOR FOR if (h_recv > 0)
SELECT key, merch_id, amount tx_log(TX_LOG_WARN, "[au_bt_0014] 미처리 접수건 %d 존재 - 마감 확인필요", h_recv);
FROM au_ledger
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key;
EXEC SQL OPEN cur_au_bt_0014; printf("===== 승인 일마감 [au_bt_0014] date=%s =====\n", biz_date);
if (sqlca.sqlcode != TX_SQL_OK) { printf(" 미처리(R) : %d\n", h_recv);
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0014"); printf(" 승인(M) : %d\n", h_appr);
return TX_EDB; printf(" 정산(S) : %d\n", h_settle);
} printf(" 승인총액 : %ld\n", h_total);
printf(" 마감상태 : %s\n", (h_recv == 0) ? "정상마감" : "보류");
if (tx_begin() != TX_OK) tx_log(TX_LOG_INFO, "[au_bt_0014] 일마감 date=%s total=%ld", biz_date, h_total);
tx_log(TX_LOG_WARN, "[au_bt_0014] tx_begin 경고"); return (h_recv == 0) ? TX_OK : TX_FAIL;
for (;;) {
EXEC SQL FETCH cur_au_bt_0014 INTO :h_key, :h_merch_id, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0014");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0014] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
EXEC SQL CLOSE cur_au_bt_0014;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0014] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0014] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +54,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0014] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0014] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0014(biz_date); rc = run_au_bt_0014(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0014] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0015.pgc" #line 1 "app/batch/au_bt_0015.pgc"
/* @tier medium @module au @transform authorization-batch */ /* @tier hard @module au @transform authorization-batch */
/* /*
* au_bt_0015.pgc - ( + ) [tier=medium] * au_bt_0015.pgc - ( vs ) [tier=hard]
* *
* (status='R') * main . : au_bt_0015 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0015 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,62 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0015.pgc" #line 16 "app/batch/au_bt_0015.pgc"
static int run_au_bt_0015(const char *biz_date) static int run_au_bt_0015(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0015.pgc" #line 21 "app/batch/au_bt_0015.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/au_bt_0015.pgc" #line 22 "app/batch/au_bt_0015.pgc"
char h_key [ 16 ] ; long h_appr_sum , h_settle_sum ;
#line 26 "app/batch/au_bt_0015.pgc" #line 23 "app/batch/au_bt_0015.pgc"
char h_merch_id [ 16 ] ; int h_appr_cnt , h_settle_cnt ;
#line 27 "app/batch/au_bt_0015.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0015.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0015.pgc" #line 24 "app/batch/au_bt_0015.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long diff;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select coalesce ( sum ( amount ) , 0 ) , count ( * ) from au_ledger where biz_date = $1 and status = 'M'",
/* declare cur_au_bt_0015 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/au_bt_0015.pgc"
#line 42 "app/batch/au_bt_0015.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0015 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
#line 44 "app/batch/au_bt_0015.pgc" ECPGt_long,&(h_appr_sum),(long)1,(long)1,sizeof(long),
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0015");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0015] tx_begin 경고");
for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0015", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_int,&(h_appr_cnt),(long)1,(long)1,sizeof(int),
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_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0015.pgc" #line 32 "app/batch/au_bt_0015.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("승인합"); return TX_EDB; }
if (sqlca.sqlcode == TX_SQL_NOTFOUND) { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select coalesce ( sum ( amount ) , 0 ) , count ( * ) from au_ledger where biz_date = $1 and status = 'S'",
break; ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
if (sqlca.sqlcode != TX_SQL_OK) { ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0015"); ECPGt_long,&(h_settle_sum),(long)1,(long)1,sizeof(long),
errcnt++; ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
break; ECPGt_int,&(h_settle_cnt),(long)1,(long)1,sizeof(int),
} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 37 "app/batch/au_bt_0015.pgc"
total++; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("정산합"); return TX_EDB; }
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ diff = h_appr_sum - h_settle_sum;
if (amount_is_valid(h_amount)) { printf("===== 승인-정산 대사 [au_bt_0015] date=%s =====\n", biz_date);
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status)); printf(" 승인(M) : %d 건 %ld 원\n", h_appr_cnt, h_appr_sum);
done++; printf(" 정산(S) : %d 건 %ld 원\n", h_settle_cnt, h_settle_sum);
} else { printf(" 차이 : %ld 원\n", diff);
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status)); printf(" 대사결과: %s\n", (h_appr_cnt == 0) ? "정산완료(승인잔여없음)" : "미정산 잔존");
unmatch++; tx_log(TX_LOG_INFO, "[au_bt_0015] 대사 date=%s diff=%ld", biz_date, diff);
} return TX_OK;
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0015] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0015", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/au_bt_0015.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0015] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0015] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +155,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0015] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0015] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0015(biz_date); rc = run_au_bt_0015(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier medium @module au @transform authorization-batch */ /* @tier hard @module au @transform authorization-batch */
/* /*
* au_bt_0015.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=medium] * au_bt_0015.pgc - 승인 대사 배치 (원장 vs 정산 합계 검증) [tier=hard]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0015 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0015 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -22,83 +19,32 @@ static int run_au_bt_0015(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; long h_appr_sum, h_settle_sum;
char h_merch_id[16]; int h_appr_cnt, h_settle_cnt;
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long diff;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0015 CURSOR FOR EXEC SQL SELECT coalesce(sum(amount), 0), count(*)
SELECT key, merch_id, amount INTO :h_appr_sum, :h_appr_cnt
FROM au_ledger FROM au_ledger WHERE biz_date = :h_biz_date AND status = 'M';
WHERE biz_date = :h_biz_date if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("승인합"); return TX_EDB; }
AND status = 'R'
ORDER BY key;
EXEC SQL OPEN cur_au_bt_0015; EXEC SQL SELECT coalesce(sum(amount), 0), count(*)
if (sqlca.sqlcode != TX_SQL_OK) { INTO :h_settle_sum, :h_settle_cnt
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0015"); FROM au_ledger WHERE biz_date = :h_biz_date AND status = 'S';
return TX_EDB; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("정산합"); return TX_EDB; }
}
if (tx_begin() != TX_OK) diff = h_appr_sum - h_settle_sum;
tx_log(TX_LOG_WARN, "[au_bt_0015] tx_begin 경고"); printf("===== 승인-정산 대사 [au_bt_0015] date=%s =====\n", biz_date);
printf(" 승인(M) : %d 건 %ld 원\n", h_appr_cnt, h_appr_sum);
for (;;) { printf(" 정산(S) : %d 건 %ld 원\n", h_settle_cnt, h_settle_sum);
EXEC SQL FETCH cur_au_bt_0015 INTO :h_key, :h_merch_id, :h_amount; printf(" 차이 : %ld 원\n", diff);
printf(" 대사결과: %s\n", (h_appr_cnt == 0) ? "정산완료(승인잔여없음)" : "미정산 잔존");
if (sqlca.sqlcode == TX_SQL_NOTFOUND) tx_log(TX_LOG_INFO, "[au_bt_0015] 대사 date=%s diff=%ld", biz_date, diff);
break; return TX_OK;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0015");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0015] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
EXEC SQL CLOSE cur_au_bt_0015;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0015] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0015] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +54,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0015] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0015] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0015(biz_date); rc = run_au_bt_0015(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0015] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0016.pgc" #line 1 "app/batch/au_bt_0016.pgc"
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0016.pgc - ( + ) [tier=easy] * au_bt_0016.pgc - (/ ) [tier=medium]
* *
* (status='R') * main . : au_bt_0016 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0016 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,66 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0016.pgc" #line 16 "app/batch/au_bt_0016.pgc"
static int run_au_bt_0016(const char *biz_date) static int run_au_bt_0016(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0016.pgc" #line 21 "app/batch/au_bt_0016.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] , h_merch [ 16 ] ;
#line 25 "app/batch/au_bt_0016.pgc" #line 22 "app/batch/au_bt_0016.pgc"
char h_key [ 16 ] ; int h_ok , h_all ;
#line 26 "app/batch/au_bt_0016.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0016.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0016.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0016.pgc" #line 23 "app/batch/au_bt_0016.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0;
int rc; int rate;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_au_bt_0016 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_rate cursor for select merch_id , count ( * ) filter ( where status in ( 'M' , 'S' ) ) , count ( * ) from au_ledger where biz_date = $1 group by merch_id having count ( * ) >= 1 order by merch_id */
#line 42 "app/batch/au_bt_0016.pgc" #line 37 "app/batch/au_bt_0016.pgc"
#line 42 "app/batch/au_bt_0016.pgc" #line 37 "app/batch/au_bt_0016.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_rate cursor for select merch_id , count ( * ) filter ( where status in ( 'M' , 'S' ) ) , count ( * ) from au_ledger where biz_date = $1 group by merch_id having count ( * ) >= 1 order by merch_id",
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0016 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0016.pgc" #line 38 "app/batch/au_bt_0016.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_rate"); return TX_EDB; }
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0016");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0016] tx_begin 경고");
printf("===== 가맹점별 승인율 [au_bt_0016] date=%s =====\n", biz_date);
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0016", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_rate", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_int,&(h_ok),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_int,&(h_all),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0016.pgc" #line 43 "app/batch/au_bt_0016.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; merchants++;
if (sqlca.sqlcode != TX_SQL_OK) { rate = (h_all > 0) ? h_ok * 100 / h_all : 0;
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0016"); printf(" %-15s : %3d%% (%d/%d)\n", h_merch, rate, h_ok, h_all);
errcnt++; if (rate < 50)
break; tx_log(TX_LOG_WARN, "[au_bt_0016] 저승인율 merch=%s rate=%d%%", h_merch, rate);
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0016] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_rate", ECPGt_EOIT, ECPGt_EORT);}
#line 52 "app/batch/au_bt_0016.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0016", ECPGt_EOIT, ECPGt_EORT);} printf(" 집계 가맹점수=%ld\n", merchants);
#line 82 "app/batch/au_bt_0016.pgc" return TX_OK;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0016] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0016] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +159,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0016] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0016] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0016(biz_date); rc = run_au_bt_0016(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier easy @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0016.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=easy] * au_bt_0016.pgc - 가맹점별 승인율 산출 배치 (성공/전체 비율) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0016 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0016 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,40 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0016(const char *biz_date) static int run_au_bt_0016(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9], h_merch[16];
char h_key[16]; int h_ok, h_all;
char h_merch_id[16];
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0;
int rc; int rate;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, 8); h_biz_date[8] = '\0';
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_au_bt_0016 CURSOR FOR EXEC SQL DECLARE cur_rate CURSOR FOR
SELECT key, merch_id, amount SELECT merch_id,
FROM au_ledger count(*) FILTER (WHERE status IN ('M','S')),
WHERE biz_date = :h_biz_date count(*)
AND status = 'R' FROM au_ledger WHERE biz_date = :h_biz_date
ORDER BY key; GROUP BY merch_id
HAVING count(*) >= 1
EXEC SQL OPEN cur_au_bt_0016; ORDER BY merch_id;
if (sqlca.sqlcode != TX_SQL_OK) { EXEC SQL OPEN cur_rate;
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0016"); if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("OPEN cur_rate"); return TX_EDB; }
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[au_bt_0016] tx_begin 경고");
printf("===== 가맹점별 승인율 [au_bt_0016] date=%s =====\n", biz_date);
for (;;) { for (;;) {
EXEC SQL FETCH cur_au_bt_0016 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_rate INTO :h_merch, :h_ok, :h_all;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) break;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK) break;
break; merchants++;
if (sqlca.sqlcode != TX_SQL_OK) { rate = (h_all > 0) ? h_ok * 100 / h_all : 0;
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0016"); printf(" %-15s : %3d%% (%d/%d)\n", h_merch, rate, h_ok, h_all);
errcnt++; if (rate < 50)
break; tx_log(TX_LOG_WARN, "[au_bt_0016] 저승인율 merch=%s rate=%d%%", h_merch, rate);
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0016] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_rate;
EXEC SQL CLOSE cur_au_bt_0016; printf(" 집계 가맹점수=%ld\n", merchants);
return TX_OK;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0016] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0016] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +61,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0016] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0016] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0016(biz_date); rc = run_au_bt_0016(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0016] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -6,14 +6,11 @@
/* End of automatic include section */ /* End of automatic include section */
#line 1 "app/batch/au_bt_0017.pgc" #line 1 "app/batch/au_bt_0017.pgc"
/* @tier hard @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0017.pgc - ( + ) [tier=hard] * au_bt_0017.pgc - ( ) [tier=medium]
* *
* (status='R') * main . : au_bt_0017 <YYYYMMDD> [db@host]
* ('M')/('U') . main .
*
* : au_bt_0017 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,121 +90,53 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/au_bt_0017.pgc" #line 16 "app/batch/au_bt_0017.pgc"
static int run_au_bt_0017(const char *biz_date) static int run_au_bt_0017(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/au_bt_0017.pgc" #line 21 "app/batch/au_bt_0017.pgc"
char h_biz_date [ 9 ] ; char h_cutoff [ 9 ] ;
#line 25 "app/batch/au_bt_0017.pgc" #line 22 "app/batch/au_bt_0017.pgc"
char h_key [ 16 ] ; int h_cnt , h_del ;
#line 26 "app/batch/au_bt_0017.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/au_bt_0017.pgc"
long h_amount ;
#line 28 "app/batch/au_bt_0017.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/au_bt_0017.pgc" #line 23 "app/batch/au_bt_0017.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; strncpy(h_cutoff, biz_date, 8); h_cutoff[8] = '\0';
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from au_ledger where status = 'S' and biz_date < $1 ",
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; ECPGt_char,(h_cutoff),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 28 "app/batch/au_bt_0017.pgc"
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("au_bt_0017 집계"); return TX_EDB; }
/* declare cur_au_bt_0017 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/au_bt_0017.pgc"
#line 42 "app/batch/au_bt_0017.pgc" if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0017] tx_begin 경고");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "delete from au_ledger where status = 'S' and biz_date < $1 ",
ECPGt_char,(h_cutoff),(long)9,(long)1,(9)*sizeof(char),
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_au_bt_0017 cursor for select key , merch_id , amount from au_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/au_bt_0017.pgc" #line 33 "app/batch/au_bt_0017.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0017"); TX_DBIO_LOG_ERR("au_bt_0017 삭제");
tx_abort();
return TX_EDB; return TX_EDB;
} }
h_del = (int)sqlca.sqlerrd[2];
tx_commit();
if (tx_begin() != TX_OK) printf("===== 승인원장 아카이브 [au_bt_0017] 기준일<%s =====\n", biz_date);
tx_log(TX_LOG_WARN, "[au_bt_0017] tx_begin 경고"); printf(" 대상=%d 삭제=%d\n", h_cnt, h_del);
tx_log(TX_LOG_INFO, "[au_bt_0017] 아카이브 삭제=%d건", h_del);
for (;;) { return TX_OK;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_au_bt_0017", ECPGt_EOIT,
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_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/au_bt_0017.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0017");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0017] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_au_bt_0017", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/au_bt_0017.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0017] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0017] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -217,31 +146,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0017] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0017] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0017(biz_date); rc = run_au_bt_0017(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -1,11 +1,8 @@
/* @tier hard @module au @transform authorization-batch */ /* @tier medium @module au @transform authorization-batch */
/* /*
* au_bt_0017.pgc - 승인한도 배치 (커서 순회 + 상태전이) [tier=hard] * au_bt_0017.pgc - 승인원장 아카이브 배치 (정산완료 노후건 삭제) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 배치 main 엔트리 포함. 실행: au_bt_0017 <YYYYMMDD> [db@host]
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함.
*
* 실행: au_bt_0017 <YYYYMMDD> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,84 +18,31 @@ EXEC SQL INCLUDE sqlca;
static int run_au_bt_0017(const char *biz_date) static int run_au_bt_0017(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_cutoff[9];
char h_key[16]; int h_cnt, h_del;
char h_merch_id[16];
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; strncpy(h_cutoff, biz_date, 8); h_cutoff[8] = '\0';
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); EXEC SQL SELECT count(*) INTO :h_cnt
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; FROM au_ledger WHERE status = 'S' AND biz_date < :h_cutoff;
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("au_bt_0017 집계"); return TX_EDB; }
EXEC SQL DECLARE cur_au_bt_0017 CURSOR FOR if (tx_begin() != TX_OK) tx_log(TX_LOG_WARN, "[au_bt_0017] tx_begin 경고");
SELECT key, merch_id, amount EXEC SQL DELETE FROM au_ledger
FROM au_ledger WHERE status = 'S' AND biz_date < :h_cutoff;
WHERE biz_date = :h_biz_date
AND status = 'R'
ORDER BY key;
EXEC SQL OPEN cur_au_bt_0017;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_au_bt_0017"); TX_DBIO_LOG_ERR("au_bt_0017 삭제");
tx_abort();
return TX_EDB; return TX_EDB;
} }
h_del = (int)sqlca.sqlerrd[2];
tx_commit();
if (tx_begin() != TX_OK) printf("===== 승인원장 아카이브 [au_bt_0017] 기준일<%s =====\n", biz_date);
tx_log(TX_LOG_WARN, "[au_bt_0017] tx_begin 경고"); printf(" 대상=%d 삭제=%d\n", h_cnt, h_del);
tx_log(TX_LOG_INFO, "[au_bt_0017] 아카이브 삭제=%d건", h_del);
for (;;) { return TX_OK;
EXEC SQL FETCH cur_au_bt_0017 INTO :h_key, :h_merch_id, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_au_bt_0017");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, AU_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, AU_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = au_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0017] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
}
EXEC SQL CLOSE cur_au_bt_0017;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO,
"[au_bt_0017] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 승인한도 배치 결과 [au_bt_0017] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -108,31 +52,24 @@ int main(int argc, char **argv)
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; biz_date = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(biz_date)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 시작 date=%s", biz_date);
rc = au_dbio_connect(target); rc = au_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[au_bt_0017] DB 접속 실패 rc=%d", rc); tx_log(TX_LOG_ERROR, "[au_bt_0017] DB 접속 실패 rc=%d", rc);
return 1; return 1;
} }
rc = run_au_bt_0017(biz_date); rc = run_au_bt_0017(biz_date);
au_dbio_disconnect(); au_dbio_disconnect();
tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc)); tx_log(TX_LOG_INFO, "[au_bt_0017] 배치 종료 rc=%d(%s)", rc, tx_strerror(rc));
return (rc == TX_OK) ? 0 : 1; return (rc == TX_OK) ? 0 : 1;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cl_bt_0002.pgc" #line 1 "app/batch/cl_bt_0002.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0002.pgc - ( + ) [tier=easy] * cl_bt_0002.pgc - ( + ) [tier=easy]
* *
* (status='R') * ( 'R') , ('M')/
* ('M')/('U') . main . * ('U') ('S') .
* (). main .
* *
* : cl_bt_0002 <YYYYMMDD> [db@host] * : cl_bt_0002 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0002.pgc" #line 20 "app/batch/cl_bt_0002.pgc"
static int run_cl_bt_0002(const char *biz_date) static int run_cl_bt_0002(const char *biz_date)
@ -102,44 +103,48 @@ static int run_cl_bt_0002(const char *biz_date)
#line 24 "app/batch/cl_bt_0002.pgc" #line 25 "app/batch/cl_bt_0002.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0002.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0002.pgc" #line 26 "app/batch/cl_bt_0002.pgc"
char h_merch_id [ 16 ] ; char h_key [ 16 ] ;
#line 27 "app/batch/cl_bt_0002.pgc" #line 27 "app/batch/cl_bt_0002.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/cl_bt_0002.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0002.pgc" #line 28 "app/batch/cl_bt_0002.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long recv = 0, settled = 0, errcnt = 0, sum_settle = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
/* 1) 미마감(접수 'R') 잔량 점검 */
recv = cl_rec_count(biz_date, CL_ST_RECV);
if (recv < 0) {
tx_log(TX_LOG_ERROR, "[cl_bt_0002] 미마감 건수 조회 실패");
return TX_EDB;
}
if (recv > 0)
tx_log(TX_LOG_WARN,
"[cl_bt_0002] 미마감(R) %ld건 잔존 - 일마감 보류 권고", recv);
/* 2) 처리완료('M')/불일치('U') → 정산완료('S') 전이 */
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0002 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0002 cursor for select key , amount from cl_ledger where biz_date = $1 and status in ( 'M' , 'U' ) order by key */
#line 42 "app/batch/cl_bt_0002.pgc" #line 53 "app/batch/cl_bt_0002.pgc"
#line 42 "app/batch/cl_bt_0002.pgc" #line 53 "app/batch/cl_bt_0002.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0002 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0002 cursor for select key , amount from cl_ledger where biz_date = $1 and status in ( 'M' , 'U' ) order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0002.pgc" #line 55 "app/batch/cl_bt_0002.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0002"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0002");
@ -153,11 +158,9 @@ static int run_cl_bt_0002(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0002", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0002", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0002.pgc" #line 65 "app/batch/cl_bt_0002.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,26 +171,18 @@ static int run_cl_bt_0002(const char *biz_date)
break; break;
} }
total++; rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0002] 정산전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
settled++;
sum_settle += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0002", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0002", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0002.pgc" #line 85 "app/batch/cl_bt_0002.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +190,21 @@ static int run_cl_bt_0002(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_settle, won, sizeof(won));
"[cl_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0002] ==========\n"); tx_log(TX_LOG_INFO,
"[cl_bt_0002] 요약 date=%s 미마감=%ld 정산=%ld 정산액=%ld 오류=%ld",
biz_date, recv, settled, sum_settle, errcnt);
printf("========== 일마감 배치 결과 [cl_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 미마감(R) : %ld\n", recv);
printf(" 완료(M) : %ld\n", done); printf(" 정산완료(S) : %ld\n", settled);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 정산액 합계 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); if (recv > 0)
printf(" ** 경고: 미마감 잔존으로 일마감 보류 권고 **\n");
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0002.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0002.pgc - 일마감 배치 (미마감 점검 + 정산완료 전이) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 미마감(접수 'R') 잔량을 먼저 점검하고, 처리완료('M')/
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 불일치('U') 건을 커서로 순회하며 정산완료('S')로 전이한다.
* 미마감 건이 남아 있으면 마감을 보류(경고)한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0002 <YYYYMMDD> [db@host] * 실행: cl_bt_0002 <YYYYMMDD> [db@host]
*/ */
@ -23,22 +24,32 @@ static int run_cl_bt_0002(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long recv = 0, settled = 0, errcnt = 0, sum_settle = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
/* 1) 미마감(접수 'R') 잔량 점검 */
recv = cl_rec_count(biz_date, CL_ST_RECV);
if (recv < 0) {
tx_log(TX_LOG_ERROR, "[cl_bt_0002] 미마감 건수 조회 실패");
return TX_EDB;
}
if (recv > 0)
tx_log(TX_LOG_WARN,
"[cl_bt_0002] 미마감(R) %ld건 잔존 - 일마감 보류 권고", recv);
/* 2) 처리완료('M')/불일치('U') → 정산완료('S') 전이 */
EXEC SQL DECLARE cur_cl_bt_0002 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0002 CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status IN ('M', 'U')
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0002; EXEC SQL OPEN cur_cl_bt_0002;
@ -51,7 +62,7 @@ static int run_cl_bt_0002(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0002] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0002] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0002 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0002 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,22 +72,14 @@ static int run_cl_bt_0002(const char *biz_date)
break; break;
} }
total++; rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0002] 정산전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
settled++;
sum_settle += h_amount;
} }
EXEC SQL CLOSE cur_cl_bt_0002; EXEC SQL CLOSE cur_cl_bt_0002;
@ -86,17 +89,21 @@ static int run_cl_bt_0002(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_settle, won, sizeof(won));
"[cl_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0002] ==========\n"); tx_log(TX_LOG_INFO,
"[cl_bt_0002] 요약 date=%s 미마감=%ld 정산=%ld 정산액=%ld 오류=%ld",
biz_date, recv, settled, sum_settle, errcnt);
printf("========== 일마감 배치 결과 [cl_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 미마감(R) : %ld\n", recv);
printf(" 완료(M) : %ld\n", done); printf(" 정산완료(S) : %ld\n", settled);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 정산액 합계 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); if (recv > 0)
printf(" ** 경고: 미마감 잔존으로 일마감 보류 권고 **\n");
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,12 +8,13 @@
#line 1 "app/batch/cl_bt_0003.pgc" #line 1 "app/batch/cl_bt_0003.pgc"
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0003.pgc - ( + ) [tier=medium] * cl_bt_0003.pgc - ( ) [tier=medium]
* *
* (status='R') * YYYYMM 'YYYYMM%' LIKE
* ('M')/('U') . main . * ('M')/('U') ('S') .
* . main .
* *
* : cl_bt_0003 <YYYYMMDD> [db@host] * : cl_bt_0003 <YYYYMM> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,51 +94,44 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0003.pgc" #line 20 "app/batch/cl_bt_0003.pgc"
static int run_cl_bt_0003(const char *biz_date) static int run_cl_bt_0003(const char *yyyymm)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0003.pgc"
char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0003.pgc" #line 25 "app/batch/cl_bt_0003.pgc"
char h_key [ 16 ] ; char h_pat [ 10 ] ;
#line 26 "app/batch/cl_bt_0003.pgc" #line 26 "app/batch/cl_bt_0003.pgc"
char h_merch_id [ 16 ] ; char h_key [ 16 ] ;
#line 27 "app/batch/cl_bt_0003.pgc" #line 27 "app/batch/cl_bt_0003.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/cl_bt_0003.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0003.pgc" #line 28 "app/batch/cl_bt_0003.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, settled = 0, errcnt = 0, sum_settle = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); /* 'YYYYMM%' LIKE 패턴 구성 */
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; snprintf(h_pat, sizeof(h_pat), "%.6s%%", yyyymm);
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_pat ), __LINE__);\
/* declare cur_cl_bt_0003 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0003 cursor for select key , amount from cl_ledger where biz_date like $1 and status in ( 'M' , 'U' ) order by biz_date , key */
#line 42 "app/batch/cl_bt_0003.pgc" #line 42 "app/batch/cl_bt_0003.pgc"
#line 42 "app/batch/cl_bt_0003.pgc" #line 42 "app/batch/cl_bt_0003.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0003 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0003 cursor for select key , amount from cl_ledger where biz_date like $1 and status in ( 'M' , 'U' ) order by biz_date , key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_pat),(long)10,(long)1,(10)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0003.pgc" #line 44 "app/batch/cl_bt_0003.pgc"
@ -153,8 +147,6 @@ static int run_cl_bt_0003(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0003", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0003", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0003.pgc" #line 54 "app/batch/cl_bt_0003.pgc"
@ -169,25 +161,18 @@ static int run_cl_bt_0003(const char *biz_date)
} }
total++; total++;
rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0003] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0003] 월마감 전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
settled++;
sum_settle += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0003", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0003", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0003.pgc" #line 75 "app/batch/cl_bt_0003.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,42 +180,56 @@ static int run_cl_bt_0003(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_settle, won, sizeof(won));
"[cl_bt_0003] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0003] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0003] 요약 월=%s 대상=%ld 마감=%ld 정산액=%ld 오류=%ld",
yyyymm, total, settled, sum_settle, errcnt);
printf("========== 월마감 배치 결과 [cl_bt_0003] ==========\n");
printf(" 대상 월 : %.6s\n", yyyymm);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 월 마감(S) : %ld\n", settled);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 월 정산액 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
static int yyyymm_is_valid(const char *s)
{
int i, mm;
if (!s || strlen(s) != 6)
return 0;
for (i = 0; i < 6; i++)
if (s[i] < '0' || s[i] > '9')
return 0;
mm = (s[4] - '0') * 10 + (s[5] - '0');
return (mm >= 1 && mm <= 12);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
const char *biz_date; const char *yyyymm;
const char *target; const char *target;
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMM> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; yyyymm = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!yyyymm_is_valid(yyyymm)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 마감월 '%s'\n", yyyymm);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cl_bt_0003] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cl_bt_0003] 배치 시작 월=%s", yyyymm);
rc = cl_dbio_connect(target); rc = cl_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
@ -238,7 +237,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
rc = run_cl_bt_0003(biz_date); rc = run_cl_bt_0003(yyyymm);
cl_dbio_disconnect(); cl_dbio_disconnect();

View file

@ -1,11 +1,12 @@
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0003.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=medium] * cl_bt_0003.pgc - 월마감 배치 (해당 월 정산완료 일괄 전이) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 인자 YYYYMM 으로부터 'YYYYMM%' LIKE 패턴을 구성하여 해당 월의
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 처리완료('M')/불일치('U') 건을 커서로 순회하며 정산완료('S')로 전이한다.
* 월 마감건수와 월 정산액 합계를 리포트한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0003 <YYYYMMDD> [db@host] * 실행: cl_bt_0003 <YYYYMM> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -18,28 +19,27 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
static int run_cl_bt_0003(const char *biz_date) static int run_cl_bt_0003(const char *yyyymm)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_pat[10];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, settled = 0, errcnt = 0, sum_settle = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); /* 'YYYYMM%' LIKE 패턴 구성 */
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; snprintf(h_pat, sizeof(h_pat), "%.6s%%", yyyymm);
EXEC SQL DECLARE cur_cl_bt_0003 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0003 CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date LIKE :h_pat
AND status = 'R' AND status IN ('M', 'U')
ORDER BY key; ORDER BY biz_date, key;
EXEC SQL OPEN cur_cl_bt_0003; EXEC SQL OPEN cur_cl_bt_0003;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -51,7 +51,7 @@ static int run_cl_bt_0003(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0003] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0003] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0003 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0003 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -62,21 +62,14 @@ static int run_cl_bt_0003(const char *biz_date)
} }
total++; total++;
rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0003] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0003] 월마감 전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
settled++;
sum_settle += h_amount;
} }
EXEC SQL CLOSE cur_cl_bt_0003; EXEC SQL CLOSE cur_cl_bt_0003;
@ -86,42 +79,56 @@ static int run_cl_bt_0003(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_settle, won, sizeof(won));
"[cl_bt_0003] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0003] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0003] 요약 월=%s 대상=%ld 마감=%ld 정산액=%ld 오류=%ld",
yyyymm, total, settled, sum_settle, errcnt);
printf("========== 월마감 배치 결과 [cl_bt_0003] ==========\n");
printf(" 대상 월 : %.6s\n", yyyymm);
printf(" 대상 건수 : %ld\n", total); printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done); printf(" 월 마감(S) : %ld\n", settled);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 월 정산액 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
static int yyyymm_is_valid(const char *s)
{
int i, mm;
if (!s || strlen(s) != 6)
return 0;
for (i = 0; i < 6; i++)
if (s[i] < '0' || s[i] > '9')
return 0;
mm = (s[4] - '0') * 10 + (s[5] - '0');
return (mm >= 1 && mm <= 12);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
const char *biz_date; const char *yyyymm;
const char *target; const char *target;
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr, "사용법: %s <YYYYMM> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; yyyymm = argv[1];
target = (argc >= 3) ? argv[2] : NULL; target = (argc >= 3) ? argv[2] : NULL;
if (!date_is_valid(biz_date)) { if (!yyyymm_is_valid(yyyymm)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 마감월 '%s'\n", yyyymm);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cl_bt_0003] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cl_bt_0003] 배치 시작 월=%s", yyyymm);
rc = cl_dbio_connect(target); rc = cl_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
@ -129,7 +136,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
rc = run_cl_bt_0003(biz_date); rc = run_cl_bt_0003(yyyymm);
cl_dbio_disconnect(); cl_dbio_disconnect();

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cl_bt_0004.pgc" #line 1 "app/batch/cl_bt_0004.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0004.pgc - ( + ) [tier=easy] * cl_bt_0004.pgc - ( ) [tier=easy]
* *
* (status='R') * // SELECT ,
* ('M')/('U') . main . * DBIO(cl_rec_count/cl_rec_sum) .
* (TX_FAIL) .
* *
* : cl_bt_0004 <YYYYMMDD> [db@host] * : cl_bt_0004 <YYYYMMDD> [db@host]
*/ */
@ -93,121 +94,98 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0004.pgc" #line 20 "app/batch/cl_bt_0004.pgc"
static int run_cl_bt_0004(const char *biz_date) static int run_cl_bt_0004(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0004.pgc" #line 25 "app/batch/cl_bt_0004.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0004.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0004.pgc" #line 26 "app/batch/cl_bt_0004.pgc"
char h_merch_id [ 16 ] ; int h_cnt ;
#line 27 "app/batch/cl_bt_0004.pgc" #line 27 "app/batch/cl_bt_0004.pgc"
long h_amount ; long h_sum_amt ;
#line 28 "app/batch/cl_bt_0004.pgc" #line 28 "app/batch/cl_bt_0004.pgc"
char h_new_status [ 2 ] ; long h_sum_fee ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0004.pgc" #line 29 "app/batch/cl_bt_0004.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long xcount, xsum;
int rc; int diff = 0;
char won_amt[32], won_fee[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ /* 1) 직접 집계 (건수/금액/수수료) */
/* declare cur_cl_bt_0004 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) , coalesce ( sum ( fee ) , 0 ) from cl_ledger where biz_date = $1 ",
#line 42 "app/batch/cl_bt_0004.pgc"
#line 42 "app/batch/cl_bt_0004.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0004 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
#line 44 "app/batch/cl_bt_0004.pgc" ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 42 "app/batch/cl_bt_0004.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0004"); if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT 집계 cl_bt_0004");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK) /* 2) 표준 DBIO 교차확인 (전체 상태 합산) */
tx_log(TX_LOG_WARN, "[cl_bt_0004] tx_begin 경고"); xcount = cl_rec_count(biz_date, CL_ST_RECV)
+ cl_rec_count(biz_date, CL_ST_DONE)
+ cl_rec_count(biz_date, CL_ST_FAIL)
+ cl_rec_count(biz_date, CL_ST_SETTLED);
for (;;) { if (cl_rec_sum(biz_date, &xsum) != TX_OK) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0004", ECPGt_EOIT, tx_log(TX_LOG_ERROR, "[cl_bt_0004] cl_rec_sum 실패");
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), return TX_EDB;
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_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0004.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0004");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0004] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0004", ECPGt_EOIT, ECPGt_EORT);} if ((long)h_cnt != xcount) {
#line 82 "app/batch/cl_bt_0004.pgc" tx_log(TX_LOG_ERROR, "[cl_bt_0004] 건수 불일치 direct=%d cross=%ld",
h_cnt, xcount);
diff++;
}
if (h_sum_amt != xsum) {
tx_log(TX_LOG_ERROR, "[cl_bt_0004] 금액 불일치 direct=%ld cross=%ld",
h_sum_amt, xsum);
diff++;
}
amount_format_won(h_sum_amt, won_amt, sizeof(won_amt));
if (errcnt == 0) amount_format_won(h_sum_fee, won_fee, sizeof(won_fee));
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0004] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0004] 요약 date=%s 건수=%d Σamount=%ld Σfee=%ld 불일치=%d",
biz_date, total, done, unmatch, errcnt); biz_date, h_cnt, h_sum_amt, h_sum_fee, diff);
printf("========== 마감 배치 결과 [cl_bt_0004] ==========\n"); printf("========== 마감 대사 배치 결과 [cl_bt_0004] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 직접 건수 : %d\n", h_cnt);
printf(" 완료(M) : %ld\n", done); printf(" 교차 건수 : %ld\n", xcount);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 금액 합계 : %s\n", won_amt);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 교차 금액 : %ld\n", xsum);
printf("=============================================\n"); printf(" 수수료 합계 : %s\n", won_fee);
printf(" 불일치 항목수 : %d\n", diff);
printf(" 대사 결과 : %s\n", (diff == 0) ? "정상" : "불일치(FAIL)");
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (diff == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -1,9 +1,10 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0004.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0004.pgc - 마감 대사 배치 (집계 교차확인) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 전체 건수/금액합계/수수료합계를 직접 SELECT 하고,
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 표준 DBIO(cl_rec_count/cl_rec_sum)로 재집계하여 교차확인한다.
* 건수 또는 금액이 불일치하면 대사 실패(TX_FAIL)로 리포트한다.
* *
* 실행: cl_bt_0004 <YYYYMMDD> [db@host] * 실행: cl_bt_0004 <YYYYMMDD> [db@host]
*/ */
@ -22,83 +23,70 @@ static int run_cl_bt_0004(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; int h_cnt;
char h_merch_id[16]; long h_sum_amt;
long h_amount; long h_sum_fee;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long xcount, xsum;
int rc; int diff = 0;
char won_amt[32], won_fee[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0004 CURSOR FOR /* 1) 직접 집계 (건수/금액/수수료) */
SELECT key, merch_id, amount EXEC SQL SELECT count(*), coalesce(sum(amount), 0), coalesce(sum(fee), 0)
INTO :h_cnt, :h_sum_amt, :h_sum_fee
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date;
AND status = 'R'
ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0004; if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("SELECT 집계 cl_bt_0004");
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0004");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK) /* 2) 표준 DBIO 교차확인 (전체 상태 합산) */
tx_log(TX_LOG_WARN, "[cl_bt_0004] tx_begin 경고"); xcount = cl_rec_count(biz_date, CL_ST_RECV)
+ cl_rec_count(biz_date, CL_ST_DONE)
+ cl_rec_count(biz_date, CL_ST_FAIL)
+ cl_rec_count(biz_date, CL_ST_SETTLED);
for (;;) { if (cl_rec_sum(biz_date, &xsum) != TX_OK) {
EXEC SQL FETCH cur_cl_bt_0004 INTO :h_key, :h_merch_id, :h_amount; tx_log(TX_LOG_ERROR, "[cl_bt_0004] cl_rec_sum 실패");
return TX_EDB;
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0004");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0004] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_cl_bt_0004; if ((long)h_cnt != xcount) {
tx_log(TX_LOG_ERROR, "[cl_bt_0004] 건수 불일치 direct=%d cross=%ld",
h_cnt, xcount);
diff++;
}
if (h_sum_amt != xsum) {
tx_log(TX_LOG_ERROR, "[cl_bt_0004] 금액 불일치 direct=%ld cross=%ld",
h_sum_amt, xsum);
diff++;
}
if (errcnt == 0) amount_format_won(h_sum_amt, won_amt, sizeof(won_amt));
tx_commit(); amount_format_won(h_sum_fee, won_fee, sizeof(won_fee));
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0004] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0004] 요약 date=%s 건수=%d Σamount=%ld Σfee=%ld 불일치=%d",
biz_date, total, done, unmatch, errcnt); biz_date, h_cnt, h_sum_amt, h_sum_fee, diff);
printf("========== 마감 배치 결과 [cl_bt_0004] ==========\n"); printf("========== 마감 대사 배치 결과 [cl_bt_0004] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 직접 건수 : %d\n", h_cnt);
printf(" 완료(M) : %ld\n", done); printf(" 교차 건수 : %ld\n", xcount);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 금액 합계 : %s\n", won_amt);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 교차 금액 : %ld\n", xsum);
printf("=============================================\n"); printf(" 수수료 합계 : %s\n", won_fee);
printf(" 불일치 항목수 : %d\n", diff);
printf(" 대사 결과 : %s\n", (diff == 0) ? "정상" : "불일치(FAIL)");
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (diff == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cl_bt_0005.pgc" #line 1 "app/batch/cl_bt_0005.pgc"
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0005.pgc - ( + ) [tier=medium] * cl_bt_0005.pgc - ( ) [tier=medium]
* *
* (status='R') * ('S') (merch_id) GROUP BY
* ('M')/('U') . main . * / .
* . main .
* *
* : cl_bt_0005 <YYYYMMDD> [db@host] * : cl_bt_0005 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0005.pgc" #line 20 "app/batch/cl_bt_0005.pgc"
static int run_cl_bt_0005(const char *biz_date) static int run_cl_bt_0005(const char *biz_date)
@ -101,63 +102,62 @@ static int run_cl_bt_0005(const char *biz_date)
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0005.pgc"
char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0005.pgc" #line 25 "app/batch/cl_bt_0005.pgc"
char h_key [ 16 ] ; char h_biz_date [ 9 ] ;
#line 26 "app/batch/cl_bt_0005.pgc" #line 26 "app/batch/cl_bt_0005.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0005.pgc" #line 27 "app/batch/cl_bt_0005.pgc"
long h_amount ; int h_cnt ;
#line 28 "app/batch/cl_bt_0005.pgc" #line 28 "app/batch/cl_bt_0005.pgc"
char h_new_status [ 2 ] ; long h_sum ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0005.pgc" #line 29 "app/batch/cl_bt_0005.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, grand_cnt = 0, grand_sum = 0, errcnt = 0;
int rc; char won[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0005 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0005 cursor for select merch_id , count ( * ) , coalesce ( sum ( amount ) , 0 ) from cl_ledger where biz_date = $1 and status = 'S' group by merch_id order by merch_id */
#line 42 "app/batch/cl_bt_0005.pgc" #line 43 "app/batch/cl_bt_0005.pgc"
#line 42 "app/batch/cl_bt_0005.pgc" #line 43 "app/batch/cl_bt_0005.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0005 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0005 cursor for select merch_id , count ( * ) , coalesce ( sum ( amount ) , 0 ) from cl_ledger where biz_date = $1 and status = 'S' group by merch_id order by merch_id",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0005.pgc" #line 45 "app/batch/cl_bt_0005.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0005"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0005");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK) printf("========== 마감후 집계 배치 [cl_bt_0005] ==========\n");
tx_log(TX_LOG_WARN, "[cl_bt_0005] tx_begin 경고"); printf(" 영업일 : %s\n", biz_date);
printf(" ---------------------------------------------\n");
printf(" %-14s %8s %18s\n", "가맹점", "건수", "정산액");
printf(" ---------------------------------------------\n");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0005", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0005", ECPGt_EOIT,
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_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0005.pgc" #line 58 "app/batch/cl_bt_0005.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,44 +168,30 @@ static int run_cl_bt_0005(const char *biz_date)
break; break;
} }
total++; amount_format_won(h_sum, won, sizeof(won));
printf(" %-14s %8d %18s\n", h_merch_id, h_cnt, won);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ merchants++;
if (amount_is_valid(h_amount)) { grand_cnt += h_cnt;
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); grand_sum += h_sum;
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0005] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0005", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0005", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0005.pgc" #line 76 "app/batch/cl_bt_0005.pgc"
if (errcnt == 0) amount_format_won(grand_sum, won, sizeof(won));
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0005] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0005] 요약 date=%s 가맹점=%ld 건수=%ld 정산액=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, merchants, grand_cnt, grand_sum, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0005] ==========\n"); printf(" ---------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 가맹점 수 : %ld\n", merchants);
printf(" 대상 건수 : %ld\n", total); printf(" 총 마감건수 : %ld\n", grand_cnt);
printf(" 완료(M) : %ld\n", done); printf(" 총 정산액 : %s\n", won);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf("=================================================\n");
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0005.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=medium] * cl_bt_0005.pgc - 마감후 집계 배치 (가맹점별 마감집계) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 정산완료('S') 건을 가맹점(merch_id)별로 GROUP BY 집계하여
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 커서로 순회하며 가맹점별 건수/금액합계를 리포트한다.
* 전체 가맹점 수와 총 정산액을 함께 출력한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0005 <YYYYMMDD> [db@host] * 실행: cl_bt_0005 <YYYYMMDD> [db@host]
*/ */
@ -22,24 +23,24 @@ static int run_cl_bt_0005(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
long h_amount; int h_cnt;
char h_new_status[2]; long h_sum;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long merchants = 0, grand_cnt = 0, grand_sum = 0, errcnt = 0;
int rc; char won[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0005 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0005 CURSOR FOR
SELECT key, merch_id, amount SELECT merch_id, count(*), coalesce(sum(amount), 0)
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'S'
ORDER BY key; GROUP BY merch_id
ORDER BY merch_id;
EXEC SQL OPEN cur_cl_bt_0005; EXEC SQL OPEN cur_cl_bt_0005;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -47,11 +48,14 @@ static int run_cl_bt_0005(const char *biz_date)
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK) printf("========== 마감후 집계 배치 [cl_bt_0005] ==========\n");
tx_log(TX_LOG_WARN, "[cl_bt_0005] tx_begin 경고"); printf(" 영업일 : %s\n", biz_date);
printf(" ---------------------------------------------\n");
printf(" %-14s %8s %18s\n", "가맹점", "건수", "정산액");
printf(" ---------------------------------------------\n");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0005 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0005 INTO :h_merch_id, :h_cnt, :h_sum;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,42 +65,28 @@ static int run_cl_bt_0005(const char *biz_date)
break; break;
} }
total++; amount_format_won(h_sum, won, sizeof(won));
printf(" %-14s %8d %18s\n", h_merch_id, h_cnt, won);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ merchants++;
if (amount_is_valid(h_amount)) { grand_cnt += h_cnt;
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); grand_sum += h_sum;
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0005] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_cl_bt_0005; EXEC SQL CLOSE cur_cl_bt_0005;
if (errcnt == 0) amount_format_won(grand_sum, won, sizeof(won));
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0005] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0005] 요약 date=%s 가맹점=%ld 건수=%ld 정산액=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, merchants, grand_cnt, grand_sum, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0005] ==========\n"); printf(" ---------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 가맹점 수 : %ld\n", merchants);
printf(" 대상 건수 : %ld\n", total); printf(" 총 마감건수 : %ld\n", grand_cnt);
printf(" 완료(M) : %ld\n", done); printf(" 총 정산액 : %s\n", won);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 오류 건수 : %ld\n", errcnt); printf("=================================================\n");
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cl_bt_0006.pgc" #line 1 "app/batch/cl_bt_0006.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0006.pgc - ( + ) [tier=easy] * cl_bt_0006.pgc - ( ) [tier=easy]
* *
* (status='R') * ('S') ('M')
* ('M')/('U') . main . * . .
* main .
* *
* : cl_bt_0006 <YYYYMMDD> [db@host] * : cl_bt_0006 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0006.pgc" #line 20 "app/batch/cl_bt_0006.pgc"
static int run_cl_bt_0006(const char *biz_date) static int run_cl_bt_0006(const char *biz_date)
@ -102,41 +103,34 @@ static int run_cl_bt_0006(const char *biz_date)
#line 24 "app/batch/cl_bt_0006.pgc" #line 25 "app/batch/cl_bt_0006.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0006.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0006.pgc" #line 26 "app/batch/cl_bt_0006.pgc"
char h_merch_id [ 16 ] ; char h_key [ 16 ] ;
#line 27 "app/batch/cl_bt_0006.pgc" #line 27 "app/batch/cl_bt_0006.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/cl_bt_0006.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0006.pgc" #line 28 "app/batch/cl_bt_0006.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, cancelled = 0, errcnt = 0, sum_amt = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0006 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0006 cursor for select key , amount from cl_ledger where biz_date = $1 and status = 'S' order by key */
#line 42 "app/batch/cl_bt_0006.pgc" #line 42 "app/batch/cl_bt_0006.pgc"
#line 42 "app/batch/cl_bt_0006.pgc" #line 42 "app/batch/cl_bt_0006.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0006 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0006 cursor for select key , amount from cl_ledger where biz_date = $1 and status = 'S' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0006.pgc" #line 44 "app/batch/cl_bt_0006.pgc"
@ -153,8 +147,6 @@ static int run_cl_bt_0006(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0006", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0006", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0006.pgc" #line 54 "app/batch/cl_bt_0006.pgc"
@ -169,25 +161,19 @@ static int run_cl_bt_0006(const char *biz_date)
} }
total++; total++;
/* 정산완료 → 처리완료 로 되돌려 재개방 */
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ rc = cl_rec_update_status(h_key, CL_ST_DONE);
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0006] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0006] 마감취소 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
cancelled++;
sum_amt += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0006", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0006", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0006.pgc" #line 76 "app/batch/cl_bt_0006.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +181,19 @@ static int run_cl_bt_0006(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amt, won, sizeof(won));
"[cl_bt_0006] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0006] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0006] 요약 date=%s 대상=%ld 취소=%ld 재개방액=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, total, cancelled, sum_amt, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 마감 취소 배치 결과 [cl_bt_0006] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 취소 대상(S) : %ld\n", total);
printf(" 취소/재개방 : %ld\n", cancelled);
printf(" 재개방 금액 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt);
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0006.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0006.pgc - 마감 취소 배치 (정산완료 재개방) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 정산완료('S') 건을 커서로 순회하며 처리완료('M')로
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 되돌려 재개방한다. 취소 건수와 재개방 금액 합계를 리포트한다.
* 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0006 <YYYYMMDD> [db@host] * 실행: cl_bt_0006 <YYYYMMDD> [db@host]
*/ */
@ -23,22 +24,21 @@ static int run_cl_bt_0006(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, cancelled = 0, errcnt = 0, sum_amt = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0006 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0006 CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'S'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0006; EXEC SQL OPEN cur_cl_bt_0006;
@ -51,7 +51,7 @@ static int run_cl_bt_0006(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0006] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0006] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0006 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0006 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -62,21 +62,15 @@ static int run_cl_bt_0006(const char *biz_date)
} }
total++; total++;
/* 정산완료 → 처리완료 로 되돌려 재개방 */
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ rc = cl_rec_update_status(h_key, CL_ST_DONE);
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0006] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0006] 마감취소 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
cancelled++;
sum_amt += h_amount;
} }
EXEC SQL CLOSE cur_cl_bt_0006; EXEC SQL CLOSE cur_cl_bt_0006;
@ -86,17 +80,19 @@ static int run_cl_bt_0006(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amt, won, sizeof(won));
"[cl_bt_0006] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0006] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0006] 요약 date=%s 대상=%ld 취소=%ld 재개방액=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, total, cancelled, sum_amt, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 마감 취소 배치 결과 [cl_bt_0006] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 취소 대상(S) : %ld\n", total);
printf(" 취소/재개방 : %ld\n", cancelled);
printf(" 재개방 금액 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt);
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cl_bt_0007.pgc" #line 1 "app/batch/cl_bt_0007.pgc"
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0007.pgc - ( + ) [tier=medium] * cl_bt_0007.pgc - ( ) [tier=medium]
* *
* (status='R') * ('M')/('U')
* ('M')/('U') . main . * ('S') . (M/U)
* . main .
* *
* : cl_bt_0007 <YYYYMMDD> [db@host] * : cl_bt_0007 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +94,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0007.pgc" #line 20 "app/batch/cl_bt_0007.pgc"
static int run_cl_bt_0007(const char *biz_date) static int run_cl_bt_0007(const char *biz_date)
@ -102,44 +103,38 @@ static int run_cl_bt_0007(const char *biz_date)
#line 24 "app/batch/cl_bt_0007.pgc" #line 25 "app/batch/cl_bt_0007.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0007.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0007.pgc" #line 26 "app/batch/cl_bt_0007.pgc"
char h_merch_id [ 16 ] ; char h_key [ 16 ] ;
#line 27 "app/batch/cl_bt_0007.pgc" #line 27 "app/batch/cl_bt_0007.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/cl_bt_0007.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0007.pgc" #line 28 "app/batch/cl_bt_0007.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, reclose = 0, errcnt = 0, sum_amt = 0;
long remain_m, remain_u;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0007 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0007 cursor for select key , amount from cl_ledger where biz_date = $1 and status in ( 'M' , 'U' ) order by key */
#line 42 "app/batch/cl_bt_0007.pgc" #line 43 "app/batch/cl_bt_0007.pgc"
#line 42 "app/batch/cl_bt_0007.pgc" #line 43 "app/batch/cl_bt_0007.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0007 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0007 cursor for select key , amount from cl_ledger where biz_date = $1 and status in ( 'M' , 'U' ) order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0007.pgc" #line 45 "app/batch/cl_bt_0007.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0007"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0007");
@ -153,11 +148,9 @@ static int run_cl_bt_0007(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0007", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0007", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0007.pgc" #line 55 "app/batch/cl_bt_0007.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -169,25 +162,18 @@ static int run_cl_bt_0007(const char *biz_date)
} }
total++; total++;
rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0007] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0007] 재마감 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
reclose++;
sum_amt += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0007", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0007", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0007.pgc" #line 76 "app/batch/cl_bt_0007.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,17 +181,25 @@ static int run_cl_bt_0007(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, /* 처리 후 잔여 확인 */
"[cl_bt_0007] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", remain_m = cl_rec_count(biz_date, CL_ST_DONE);
biz_date, total, done, unmatch, errcnt); remain_u = cl_rec_count(biz_date, CL_ST_FAIL);
printf("========== 마감 배치 결과 [cl_bt_0007] ==========\n"); amount_format_won(sum_amt, won, sizeof(won));
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); tx_log(TX_LOG_INFO,
printf(" 완료(M) : %ld\n", done); "[cl_bt_0007] 요약 date=%s 대상=%ld 재마감=%ld 잔여M=%ld 잔여U=%ld 오류=%ld",
printf(" 불일치(U) : %ld\n", unmatch); biz_date, total, reclose, remain_m, remain_u, errcnt);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("========== 재마감 배치 결과 [cl_bt_0007] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 재마감 대상 : %ld\n", total);
printf(" 재마감(S) : %ld\n", reclose);
printf(" 재마감 금액 : %s\n", won);
printf(" 잔여 처리(M) : %ld\n", remain_m);
printf(" 잔여 불일치(U): %ld\n", remain_u);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,10 @@
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0007.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=medium] * cl_bt_0007.pgc - 재마감 배치 (취소 후 잔여건 재마감) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 마감 취소 이후 남아 있는 처리완료('M')/불일치('U') 건을 커서로 순회하여
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 정산완료('S')로 재마감한다. 재마감 건수와 처리 후 잔여(M/U) 건수를
* 재확인하여 리포트한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0007 <YYYYMMDD> [db@host] * 실행: cl_bt_0007 <YYYYMMDD> [db@host]
*/ */
@ -23,22 +24,22 @@ static int run_cl_bt_0007(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, reclose = 0, errcnt = 0, sum_amt = 0;
long remain_m, remain_u;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0007 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0007 CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status IN ('M', 'U')
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0007; EXEC SQL OPEN cur_cl_bt_0007;
@ -51,7 +52,7 @@ static int run_cl_bt_0007(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0007] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0007] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0007 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0007 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -62,21 +63,14 @@ static int run_cl_bt_0007(const char *biz_date)
} }
total++; total++;
rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0007] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0007] 재마감 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
reclose++;
sum_amt += h_amount;
} }
EXEC SQL CLOSE cur_cl_bt_0007; EXEC SQL CLOSE cur_cl_bt_0007;
@ -86,17 +80,25 @@ static int run_cl_bt_0007(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, /* 처리 후 잔여 확인 */
"[cl_bt_0007] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", remain_m = cl_rec_count(biz_date, CL_ST_DONE);
biz_date, total, done, unmatch, errcnt); remain_u = cl_rec_count(biz_date, CL_ST_FAIL);
printf("========== 마감 배치 결과 [cl_bt_0007] ==========\n"); amount_format_won(sum_amt, won, sizeof(won));
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); tx_log(TX_LOG_INFO,
printf(" 완료(M) : %ld\n", done); "[cl_bt_0007] 요약 date=%s 대상=%ld 재마감=%ld 잔여M=%ld 잔여U=%ld 오류=%ld",
printf(" 불일치(U) : %ld\n", unmatch); biz_date, total, reclose, remain_m, remain_u, errcnt);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("========== 재마감 배치 결과 [cl_bt_0007] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 재마감 대상 : %ld\n", total);
printf(" 재마감(S) : %ld\n", reclose);
printf(" 재마감 금액 : %s\n", won);
printf(" 잔여 처리(M) : %ld\n", remain_m);
printf(" 잔여 불일치(U): %ld\n", remain_u);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,12 @@
#line 1 "app/batch/cl_bt_0008.pgc" #line 1 "app/batch/cl_bt_0008.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0008.pgc - ( + ) [tier=easy] * cl_bt_0008.pgc - (/ ) [tier=easy]
* *
* (status='R') * ('S') Σamount Σfee
* ('M')/('U') . main . * (= Σamount - Σfee) .
* (amount_is_valid ) ·.
* (TX_FAIL) . main .
* *
* : cl_bt_0008 <YYYYMMDD> [db@host] * : cl_bt_0008 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +95,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0008.pgc" #line 21 "app/batch/cl_bt_0008.pgc"
static int run_cl_bt_0008(const char *biz_date) static int run_cl_bt_0008(const char *biz_date)
@ -105,109 +107,123 @@ static int run_cl_bt_0008(const char *biz_date)
#line 24 "app/batch/cl_bt_0008.pgc" #line 26 "app/batch/cl_bt_0008.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0008.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0008.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0008.pgc" #line 27 "app/batch/cl_bt_0008.pgc"
long h_amount ; long h_sum_amt ;
#line 28 "app/batch/cl_bt_0008.pgc" #line 28 "app/batch/cl_bt_0008.pgc"
char h_new_status [ 2 ] ; long h_sum_fee ;
/* exec sql end declare section */
#line 29 "app/batch/cl_bt_0008.pgc" #line 29 "app/batch/cl_bt_0008.pgc"
char h_key [ 16 ] ;
#line 30 "app/batch/cl_bt_0008.pgc"
long h_amount ;
/* exec sql end declare section */
#line 31 "app/batch/cl_bt_0008.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long scanned = 0, invalid = 0;
int rc; long net;
int fail = 0;
char won_amt[32], won_fee[32], won_net[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
/* 1) 정산완료 건 Σamount / Σfee */
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select coalesce ( sum ( amount ) , 0 ) , coalesce ( sum ( fee ) , 0 ) from cl_ledger where biz_date = $1 and status = 'S'",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_sum_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 46 "app/batch/cl_bt_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT 잔액 cl_bt_0008");
return TX_EDB;
}
net = h_sum_amt - h_sum_fee;
if (net < 0) {
tx_log(TX_LOG_ERROR, "[cl_bt_0008] 순액 음수 net=%ld", net);
fail++;
}
/* 2) 금액 이상건 스캔 */
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0008 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0008 cursor for select key , amount from cl_ledger where biz_date = $1 and status = 'S' order by key */
#line 42 "app/batch/cl_bt_0008.pgc" #line 65 "app/batch/cl_bt_0008.pgc"
#line 42 "app/batch/cl_bt_0008.pgc" #line 65 "app/batch/cl_bt_0008.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0008 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0008 cursor for select key , amount from cl_ledger where biz_date = $1 and status = 'S' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0008.pgc" #line 67 "app/batch/cl_bt_0008.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0008"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0008");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0008] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0008", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0008", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0008.pgc" #line 74 "app/batch/cl_bt_0008.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0008"); TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0008");
errcnt++; fail++;
break; break;
} }
total++; scanned++;
if (!amount_is_valid(h_amount)) {
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ tx_log(TX_LOG_WARN, "[cl_bt_0008] 금액 이상건 key=%s amount=%ld",
if (amount_is_valid(h_amount)) { h_key, h_amount);
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); invalid++;
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0008] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
} }
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0008", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0008", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0008.pgc" #line 92 "app/batch/cl_bt_0008.pgc"
if (errcnt == 0) if (invalid > 0)
tx_commit(); fail++;
else
tx_abort(); amount_format_won(h_sum_amt, won_amt, sizeof(won_amt));
amount_format_won(h_sum_fee, won_fee, sizeof(won_fee));
amount_format_won(net, won_net, sizeof(won_net));
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0008] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0008] 요약 date=%s Σamt=%ld Σfee=%ld net=%ld 스캔=%ld 이상=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, h_sum_amt, h_sum_fee, net, scanned, invalid);
printf("========== 마감 배치 결과 [cl_bt_0008] ==========\n"); printf("========== 마감 잔액검증 배치 [cl_bt_0008] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" Σamount(S) : %s\n", won_amt);
printf(" 완료(M) : %ld\n", done); printf(" Σfee(S) : %s\n", won_fee);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 순액 : %s\n", won_net);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 스캔 건수 : %ld\n", scanned);
printf("=============================================\n"); printf(" 이상 건수 : %ld\n", invalid);
printf(" 검증 결과 : %s\n", (fail == 0) ? "정상" : "실패(FAIL)");
printf("==================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (fail == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -1,9 +1,11 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0008.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0008.pgc - 마감 잔액검증 배치 (순액/이상건 검증) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 정산완료('S') 건에 대해 Σamount 와 Σfee 를 집계하고
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 순액(= Σamount - Σfee)을 산출한다. 이어 커서로 순회하며 금액 이상건
* (amount_is_valid 실패)을 스캔·계수한다. 순액 음수 또는 이상건 존재 시
* 검증 실패(TX_FAIL)로 리포트한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0008 <YYYYMMDD> [db@host] * 실행: cl_bt_0008 <YYYYMMDD> [db@host]
*/ */
@ -22,23 +24,44 @@ static int run_cl_bt_0008(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
long h_sum_amt;
long h_sum_fee;
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long scanned = 0, invalid = 0;
int rc; long net;
int fail = 0;
char won_amt[32], won_fee[32], won_net[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0008 CURSOR FOR /* 1) 정산완료 건 Σamount / Σfee */
SELECT key, merch_id, amount EXEC SQL SELECT coalesce(sum(amount), 0), coalesce(sum(fee), 0)
INTO :h_sum_amt, :h_sum_fee
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'S';
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT 잔액 cl_bt_0008");
return TX_EDB;
}
net = h_sum_amt - h_sum_fee;
if (net < 0) {
tx_log(TX_LOG_ERROR, "[cl_bt_0008] 순액 음수 net=%ld", net);
fail++;
}
/* 2) 금액 이상건 스캔 */
EXEC SQL DECLARE cur_cl_bt_0008 CURSOR FOR
SELECT key, amount
FROM cl_ledger
WHERE biz_date = :h_biz_date
AND status = 'S'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0008; EXEC SQL OPEN cur_cl_bt_0008;
@ -47,58 +70,49 @@ static int run_cl_bt_0008(const char *biz_date)
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0008] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0008 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0008 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0008"); TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0008");
errcnt++; fail++;
break; break;
} }
total++; scanned++;
if (!amount_is_valid(h_amount)) {
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ tx_log(TX_LOG_WARN, "[cl_bt_0008] 금액 이상건 key=%s amount=%ld",
if (amount_is_valid(h_amount)) { h_key, h_amount);
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); invalid++;
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0008] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
} }
} }
EXEC SQL CLOSE cur_cl_bt_0008; EXEC SQL CLOSE cur_cl_bt_0008;
if (errcnt == 0) if (invalid > 0)
tx_commit(); fail++;
else
tx_abort(); amount_format_won(h_sum_amt, won_amt, sizeof(won_amt));
amount_format_won(h_sum_fee, won_fee, sizeof(won_fee));
amount_format_won(net, won_net, sizeof(won_net));
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0008] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0008] 요약 date=%s Σamt=%ld Σfee=%ld net=%ld 스캔=%ld 이상=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, h_sum_amt, h_sum_fee, net, scanned, invalid);
printf("========== 마감 배치 결과 [cl_bt_0008] ==========\n"); printf("========== 마감 잔액검증 배치 [cl_bt_0008] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" Σamount(S) : %s\n", won_amt);
printf(" 완료(M) : %ld\n", done); printf(" Σfee(S) : %s\n", won_fee);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 순액 : %s\n", won_net);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 스캔 건수 : %ld\n", scanned);
printf("=============================================\n"); printf(" 이상 건수 : %ld\n", invalid);
printf(" 검증 결과 : %s\n", (fail == 0) ? "정상" : "실패(FAIL)");
printf("==================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (fail == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -8,10 +8,16 @@
#line 1 "app/batch/cl_bt_0009.pgc" #line 1 "app/batch/cl_bt_0009.pgc"
/* @tier hard @module cl @transform closing-batch */ /* @tier hard @module cl @transform closing-batch */
/* /*
* cl_bt_0009.pgc - ( + ) [tier=hard] * cl_bt_0009.pgc - ( ) [tier=hard]
* *
* (status='R') * ('S') (count/Σamount/Σfee) ,
* ('M')/('U') . main . * cl_ledger INSERT .
* key = <biz_date> + "SS" (: 20260717 -> 20260717SS)
* merch_id = "*SNAP"
* status = 'S'
* amount = Σamount, fee = (count)
* .
* main .
* *
* : cl_bt_0009 <YYYYMMDD> [db@host] * : cl_bt_0009 <YYYYMMDD> [db@host]
*/ */
@ -93,119 +99,155 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0009.pgc" #line 25 "app/batch/cl_bt_0009.pgc"
static int run_cl_bt_0009(const char *biz_date) static int run_cl_bt_0009(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0009.pgc" #line 30 "app/batch/cl_bt_0009.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0009.pgc" #line 31 "app/batch/cl_bt_0009.pgc"
char h_key [ 16 ] ; int h_cnt ;
#line 26 "app/batch/cl_bt_0009.pgc" #line 32 "app/batch/cl_bt_0009.pgc"
long h_sum_amt ;
#line 33 "app/batch/cl_bt_0009.pgc"
long h_sum_fee ;
#line 34 "app/batch/cl_bt_0009.pgc"
char h_snap_key [ 16 ] ;
#line 35 "app/batch/cl_bt_0009.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0009.pgc" #line 36 "app/batch/cl_bt_0009.pgc"
char h_card_no [ 20 ] ;
#line 37 "app/batch/cl_bt_0009.pgc"
char h_status [ 2 ] ;
#line 38 "app/batch/cl_bt_0009.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/cl_bt_0009.pgc" #line 39 "app/batch/cl_bt_0009.pgc"
char h_new_status [ 2 ] ; long h_fee ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0009.pgc" #line 40 "app/batch/cl_bt_0009.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; int errcnt = 0;
int rc; long affected = 0;
char won_amt[32], won_fee[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ /* 1) 마감 집계 */
/* declare cur_cl_bt_0009 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) , coalesce ( sum ( fee ) , 0 ) from cl_ledger where biz_date = $1 and status = 'S'",
#line 42 "app/batch/cl_bt_0009.pgc"
#line 42 "app/batch/cl_bt_0009.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0009 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
#line 44 "app/batch/cl_bt_0009.pgc" ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0009");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0009] tx_begin 경고");
for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0009", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_long,&(h_sum_amt),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_sum_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0009.pgc" #line 54 "app/batch/cl_bt_0009.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
break; TX_DBIO_LOG_ERR("SELECT 집계 cl_bt_0009");
if (sqlca.sqlcode != TX_SQL_OK) { return TX_EDB;
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0009");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0009] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0009", ECPGt_EOIT, ECPGt_EORT);} /* 스냅샷 요약행 필드 구성 */
#line 82 "app/batch/cl_bt_0009.pgc" snprintf(h_snap_key, sizeof(h_snap_key), "%.8sSS", biz_date);
strncpy(h_merch_id, "*SNAP", sizeof(h_merch_id) - 1);
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
strncpy(h_card_no, "0000000000000000", sizeof(h_card_no) - 1);
h_card_no[sizeof(h_card_no) - 1] = '\0';
strncpy(h_status, CL_ST_SETTLED, sizeof(h_status) - 1);
h_status[sizeof(h_status) - 1] = '\0';
h_amount = h_sum_amt;
h_fee = (long)h_cnt;
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0009] tx_begin 경고");
/* 2) 기존 동일 스냅샷 선삭제 (재생성) */
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "delete from cl_ledger where key = $1 ",
ECPGt_char,(h_snap_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 76 "app/batch/cl_bt_0009.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("DELETE 스냅샷 cl_bt_0009");
errcnt++;
}
/* 3) 스냅샷 요약행 INSERT */
if (errcnt == 0) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into cl_ledger ( key , merch_id , card_no , amount , biz_date , status , fee ) values ( $1 , $2 , $3 , $4 , $5 , $6 , $7 )",
ECPGt_char,(h_snap_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_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
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_long,&(h_fee),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 88 "app/batch/cl_bt_0009.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT 스냅샷 cl_bt_0009");
errcnt++;
} else {
affected = sqlca.sqlerrd[2];
}
}
if (errcnt == 0) if (errcnt == 0)
tx_commit(); tx_commit();
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(h_sum_amt, won_amt, sizeof(won_amt));
"[cl_bt_0009] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", amount_format_won(h_sum_fee, won_fee, sizeof(won_fee));
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0009] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0009] 요약 date=%s snap=%s 건수=%d Σamt=%ld Σfee=%ld ins=%ld 오류=%d",
printf(" 대상 건수 : %ld\n", total); biz_date, h_snap_key, h_cnt, h_sum_amt, h_sum_fee, affected, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 마감 스냅샷 배치 [cl_bt_0009] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 스냅샷 키 : %s\n", h_snap_key);
printf(" 마감 건수 : %d\n", h_cnt);
printf(" Σamount : %s\n", won_amt);
printf(" Σfee : %s\n", won_fee);
printf(" 생성 행수 : %ld\n", affected);
printf(" 오류 건수 : %d\n", errcnt);
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,15 @@
/* @tier hard @module cl @transform closing-batch */ /* @tier hard @module cl @transform closing-batch */
/* /*
* cl_bt_0009.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=hard] * cl_bt_0009.pgc - 마감 스냅샷 배치 (요약행 생성) [tier=hard]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 정산완료('S') 건을 집계(count/Σamount/Σfee)한 뒤,
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 스냅샷 요약행을 cl_ledger 에 INSERT 한다.
* key = <biz_date> + "SS" (예: 20260717 -> 20260717SS)
* merch_id = "*SNAP"
* status = 'S'
* amount = Σamount, fee = 마감건수(count)
* 동일 스냅샷 키가 이미 있으면 재생성을 위해 선삭제한다.
* 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0009 <YYYYMMDD> [db@host] * 실행: cl_bt_0009 <YYYYMMDD> [db@host]
*/ */
@ -22,81 +28,94 @@ static int run_cl_bt_0009(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; int h_cnt;
long h_sum_amt;
long h_sum_fee;
char h_snap_key[16];
char h_merch_id[16]; char h_merch_id[16];
char h_card_no[20];
char h_status[2];
long h_amount; long h_amount;
char h_new_status[2]; long h_fee;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; int errcnt = 0;
int rc; long affected = 0;
char won_amt[32], won_fee[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0009 CURSOR FOR /* 1) 마감 집계 */
SELECT key, merch_id, amount EXEC SQL SELECT count(*), coalesce(sum(amount), 0), coalesce(sum(fee), 0)
INTO :h_cnt, :h_sum_amt, :h_sum_fee
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'S';
ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0009; if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("SELECT 집계 cl_bt_0009");
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0009");
return TX_EDB; return TX_EDB;
} }
/* 스냅샷 요약행 필드 구성 */
snprintf(h_snap_key, sizeof(h_snap_key), "%.8sSS", biz_date);
strncpy(h_merch_id, "*SNAP", sizeof(h_merch_id) - 1);
h_merch_id[sizeof(h_merch_id) - 1] = '\0';
strncpy(h_card_no, "0000000000000000", sizeof(h_card_no) - 1);
h_card_no[sizeof(h_card_no) - 1] = '\0';
strncpy(h_status, CL_ST_SETTLED, sizeof(h_status) - 1);
h_status[sizeof(h_status) - 1] = '\0';
h_amount = h_sum_amt;
h_fee = (long)h_cnt;
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0009] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0009] tx_begin 경고");
for (;;) { /* 2) 기존 동일 스냅샷 선삭제 (재생성) */
EXEC SQL FETCH cur_cl_bt_0009 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL DELETE FROM cl_ledger WHERE key = :h_snap_key;
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
if (sqlca.sqlcode == TX_SQL_NOTFOUND) TX_DBIO_LOG_ERR("DELETE 스냅샷 cl_bt_0009");
break; errcnt++;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0009");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0009] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_cl_bt_0009; /* 3) 스냅샷 요약행 INSERT */
if (errcnt == 0) {
EXEC SQL INSERT INTO cl_ledger
(key, merch_id, card_no, amount, biz_date, status, fee)
VALUES
(:h_snap_key, :h_merch_id, :h_card_no, :h_amount,
:h_biz_date, :h_status, :h_fee);
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("INSERT 스냅샷 cl_bt_0009");
errcnt++;
} else {
affected = sqlca.sqlerrd[2];
}
}
if (errcnt == 0) if (errcnt == 0)
tx_commit(); tx_commit();
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(h_sum_amt, won_amt, sizeof(won_amt));
"[cl_bt_0009] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", amount_format_won(h_sum_fee, won_fee, sizeof(won_fee));
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0009] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0009] 요약 date=%s snap=%s 건수=%d Σamt=%ld Σfee=%ld ins=%ld 오류=%d",
printf(" 대상 건수 : %ld\n", total); biz_date, h_snap_key, h_cnt, h_sum_amt, h_sum_fee, affected, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 마감 스냅샷 배치 [cl_bt_0009] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 스냅샷 키 : %s\n", h_snap_key);
printf(" 마감 건수 : %d\n", h_cnt);
printf(" Σamount : %s\n", won_amt);
printf(" Σfee : %s\n", won_fee);
printf(" 생성 행수 : %ld\n", affected);
printf(" 오류 건수 : %d\n", errcnt);
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,12 @@
#line 1 "app/batch/cl_bt_0010.pgc" #line 1 "app/batch/cl_bt_0010.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0010.pgc - ( + ) [tier=easy] * cl_bt_0010.pgc - ( ) [tier=easy]
* *
* (status='R') * ('S') key
* ('M')/('U') . main . * .
* upd_ts now() (UPDATE) .
* / . main .
* *
* : cl_bt_0010 <YYYYMMDD> [db@host] * : cl_bt_0010 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +95,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0010.pgc" #line 21 "app/batch/cl_bt_0010.pgc"
static int run_cl_bt_0010(const char *biz_date) static int run_cl_bt_0010(const char *biz_date)
@ -101,45 +103,32 @@ static int run_cl_bt_0010(const char *biz_date)
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0010.pgc" #line 26 "app/batch/cl_bt_0010.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0010.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0010.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0010.pgc" #line 27 "app/batch/cl_bt_0010.pgc"
long h_amount ; char h_key [ 16 ] ;
#line 28 "app/batch/cl_bt_0010.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0010.pgc" #line 28 "app/batch/cl_bt_0010.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long seq = 0, numbered = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0010 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0010 cursor for select key from cl_ledger where biz_date = $1 and status = 'S' order by key */
#line 42 "app/batch/cl_bt_0010.pgc" #line 40 "app/batch/cl_bt_0010.pgc"
#line 42 "app/batch/cl_bt_0010.pgc" #line 40 "app/batch/cl_bt_0010.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0010 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0010 cursor for select key from cl_ledger where biz_date = $1 and status = 'S' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0010.pgc" #line 42 "app/batch/cl_bt_0010.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0010"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0010");
@ -152,12 +141,8 @@ static int run_cl_bt_0010(const char *biz_date)
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0010", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0010", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), 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_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0010.pgc" #line 52 "app/batch/cl_bt_0010.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,26 +153,28 @@ static int run_cl_bt_0010(const char *biz_date)
break; break;
} }
total++; seq++; /* 로컬 순번 채번 */
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* upd_ts 갱신으로 채번 처리 반영 */
if (amount_is_valid(h_amount)) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update cl_ledger set upd_ts = now ( ) where key = $1 ",
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
done++; ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
} else { #line 67 "app/batch/cl_bt_0010.pgc"
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0010] 상태전이 실패 key=%s rc=%d", h_key, rc); TX_DBIO_LOG_ERR("UPDATE 채번 cl_bt_0010");
errcnt++; errcnt++;
continue;
} }
if (sqlca.sqlerrd[2] > 0)
numbered++;
tx_log(TX_LOG_DEBUG, "[cl_bt_0010] 채번 seq=%ld key=%s", seq, h_key);
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0010", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0010", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0010.pgc" #line 80 "app/batch/cl_bt_0010.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -196,16 +183,16 @@ static int run_cl_bt_0010(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0010] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0010] 요약 date=%s 채번=%ld 갱신=%ld 오류=%ld 최종순번=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, seq, numbered, errcnt, seq);
printf("========== 마감 배치 결과 [cl_bt_0010] ==========\n"); printf("========== 마감 순번 채번 배치 [cl_bt_0010] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 채번 건수 : %ld\n", seq);
printf(" 완료(M) : %ld\n", done); printf(" upd_ts 갱신 : %ld\n", numbered);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 최종 순번 : %ld\n", seq);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,11 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0010.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0010.pgc - 마감 순번 채번 배치 (정산건 순번 부여) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 정산완료('S') 건을 key 순으로 커서 순회하며 로컬 순번
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 카운터를 증가시켜 각 건에 마감 순번을 채번한다. 채번 시 각 건의
* upd_ts 를 now() 로 갱신(UPDATE)하여 채번 처리 시각을 반영한다.
* 순번 자체는 로컬 계산/로그로 남긴다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0010 <YYYYMMDD> [db@host] * 실행: cl_bt_0010 <YYYYMMDD> [db@host]
*/ */
@ -23,22 +25,18 @@ static int run_cl_bt_0010(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long seq = 0, numbered = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0010 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0010 CURSOR FOR
SELECT key, merch_id, amount SELECT key
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'S'
ORDER BY key; ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0010; EXEC SQL OPEN cur_cl_bt_0010;
@ -51,7 +49,7 @@ static int run_cl_bt_0010(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0010] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0010] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0010 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0010 INTO :h_key;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,22 +59,22 @@ static int run_cl_bt_0010(const char *biz_date)
break; break;
} }
total++; seq++; /* 로컬 순번 채번 */
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ /* upd_ts 갱신으로 채번 처리 반영 */
if (amount_is_valid(h_amount)) { EXEC SQL UPDATE cl_ledger
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); SET upd_ts = now()
done++; WHERE key = :h_key;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status); if (sqlca.sqlcode != TX_SQL_OK) {
if (rc != TX_OK) { TX_DBIO_LOG_ERR("UPDATE 채번 cl_bt_0010");
tx_log(TX_LOG_ERROR, "[cl_bt_0010] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
if (sqlca.sqlerrd[2] > 0)
numbered++;
tx_log(TX_LOG_DEBUG, "[cl_bt_0010] 채번 seq=%ld key=%s", seq, h_key);
} }
EXEC SQL CLOSE cur_cl_bt_0010; EXEC SQL CLOSE cur_cl_bt_0010;
@ -87,16 +85,16 @@ static int run_cl_bt_0010(const char *biz_date)
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0010] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0010] 요약 date=%s 채번=%ld 갱신=%ld 오류=%ld 최종순번=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, seq, numbered, errcnt, seq);
printf("========== 마감 배치 결과 [cl_bt_0010] ==========\n"); printf("========== 마감 순번 채번 배치 [cl_bt_0010] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" 채번 건수 : %ld\n", seq);
printf(" 완료(M) : %ld\n", done); printf(" upd_ts 갱신 : %ld\n", numbered);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 최종 순번 : %ld\n", seq);
printf(" 오류 건수 : %ld\n", errcnt); printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cl_bt_0011.pgc" #line 1 "app/batch/cl_bt_0011.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0011.pgc - ( + ) [tier=easy] * cl_bt_0011.pgc - ( ) [tier=easy]
* *
* (status='R') * (R/M/U/S) SELECT
* ('M')/('U') . main . * . (S/) .
* main .
* *
* : cl_bt_0011 <YYYYMMDD> [db@host] * : cl_bt_0011 <YYYYMMDD> [db@host]
*/ */
@ -93,121 +94,99 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0011.pgc" #line 20 "app/batch/cl_bt_0011.pgc"
static int run_cl_bt_0011(const char *biz_date) static int query_status_0011(const char *biz_date, const char *status,
long *out_cnt, long *out_sum)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0011.pgc" #line 26 "app/batch/cl_bt_0011.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0011.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0011.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0011.pgc" #line 27 "app/batch/cl_bt_0011.pgc"
long h_amount ; char h_status [ 2 ] ;
#line 28 "app/batch/cl_bt_0011.pgc" #line 28 "app/batch/cl_bt_0011.pgc"
char h_new_status [ 2 ] ; int h_cnt ;
/* exec sql end declare section */
#line 29 "app/batch/cl_bt_0011.pgc" #line 29 "app/batch/cl_bt_0011.pgc"
long h_sum ;
/* exec sql end declare section */
#line 30 "app/batch/cl_bt_0011.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_status, status, sizeof(h_status) - 1);
h_status[sizeof(h_status) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) from cl_ledger where biz_date = $1 and status = $2 ",
/* declare cur_cl_bt_0011 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/cl_bt_0011.pgc"
#line 42 "app/batch/cl_bt_0011.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0011 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
#line 44 "app/batch/cl_bt_0011.pgc" ECPGt_char,(h_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 41 "app/batch/cl_bt_0011.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0011"); if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT 상태집계 cl_bt_0011");
return TX_EDB; return TX_EDB;
} }
*out_cnt = (long)h_cnt;
*out_sum = h_sum;
return TX_OK;
}
if (tx_begin() != TX_OK) static int run_cl_bt_0011(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0011] tx_begin 경고"); {
static const char *codes[4] = { "R", "M", "U", "S" };
static const char *labels[4] = { "접수(R) ", "완료(M) ",
"불일치(U)", "정산(S) " };
long cnt[4], sum[4];
long tot_cnt = 0, tot_sum = 0;
int i, pct = 0;
char won[32];
for (;;) { for (i = 0; i < 4; i++) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0011", ECPGt_EOIT, if (query_status_0011(biz_date, codes[i], &cnt[i], &sum[i]) != TX_OK)
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), return TX_EDB;
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, tot_cnt += cnt[i];
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), tot_sum += sum[i];
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_EORT);}
#line 54 "app/batch/cl_bt_0011.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0011");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0011] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0011", ECPGt_EOIT, ECPGt_EORT);} if (tot_cnt > 0)
#line 82 "app/batch/cl_bt_0011.pgc" pct = (int)((cnt[3] * 100) / tot_cnt); /* 마감률 = S / 전체 */
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0011] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0011] 요약 date=%s R=%ld M=%ld U=%ld S=%ld 전체=%ld 마감률=%d%%",
biz_date, total, done, unmatch, errcnt); biz_date, cnt[0], cnt[1], cnt[2], cnt[3], tot_cnt, pct);
printf("========== 마감 배치 결과 [cl_bt_0011] ==========\n"); printf("========== 마감 리포트 배치 [cl_bt_0011] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" ---------------------------------------------\n");
printf(" 완료(M) : %ld\n", done); printf(" %-10s %8s %18s\n", "상태", "건수", "금액합계");
printf(" 불일치(U) : %ld\n", unmatch); printf(" ---------------------------------------------\n");
printf(" 오류 건수 : %ld\n", errcnt); for (i = 0; i < 4; i++) {
printf("=============================================\n"); amount_format_won(sum[i], won, sizeof(won));
printf(" %-10s %8ld %18s\n", labels[i], cnt[i], won);
}
amount_format_won(tot_sum, won, sizeof(won));
printf(" ---------------------------------------------\n");
printf(" %-10s %8ld %18s\n", "합계", tot_cnt, won);
printf(" 마감률(S/전체) : %d%%\n", pct);
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return TX_OK;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -1,9 +1,10 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0011.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0011.pgc - 마감 리포트 배치 (상태별 집계표) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 상태별(R/M/U/S) 건수와 금액합계를 개별 SELECT 로 조회하여
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 리포트표 형태로 출력한다. 전체 합계와 마감률(S/전체)을 함께 표시한다.
* 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0011 <YYYYMMDD> [db@host] * 실행: cl_bt_0011 <YYYYMMDD> [db@host]
*/ */
@ -18,87 +19,76 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
static int run_cl_bt_0011(const char *biz_date) static int query_status_0011(const char *biz_date, const char *status,
long *out_cnt, long *out_sum)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_status[2];
char h_merch_id[16]; int h_cnt;
long h_amount; long h_sum;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_status, status, sizeof(h_status) - 1);
h_status[sizeof(h_status) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0011 CURSOR FOR EXEC SQL SELECT count(*), coalesce(sum(amount), 0)
SELECT key, merch_id, amount INTO :h_cnt, :h_sum
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = :h_status;
ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0011; if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("SELECT 상태집계 cl_bt_0011");
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0011");
return TX_EDB; return TX_EDB;
} }
*out_cnt = (long)h_cnt;
*out_sum = h_sum;
return TX_OK;
}
if (tx_begin() != TX_OK) static int run_cl_bt_0011(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0011] tx_begin 경고"); {
static const char *codes[4] = { "R", "M", "U", "S" };
static const char *labels[4] = { "접수(R) ", "완료(M) ",
"불일치(U)", "정산(S) " };
long cnt[4], sum[4];
long tot_cnt = 0, tot_sum = 0;
int i, pct = 0;
char won[32];
for (;;) { for (i = 0; i < 4; i++) {
EXEC SQL FETCH cur_cl_bt_0011 INTO :h_key, :h_merch_id, :h_amount; if (query_status_0011(biz_date, codes[i], &cnt[i], &sum[i]) != TX_OK)
return TX_EDB;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) tot_cnt += cnt[i];
break; tot_sum += sum[i];
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0011");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0011] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_cl_bt_0011; if (tot_cnt > 0)
pct = (int)((cnt[3] * 100) / tot_cnt); /* 마감률 = S / 전체 */
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0011] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0011] 요약 date=%s R=%ld M=%ld U=%ld S=%ld 전체=%ld 마감률=%d%%",
biz_date, total, done, unmatch, errcnt); biz_date, cnt[0], cnt[1], cnt[2], cnt[3], tot_cnt, pct);
printf("========== 마감 배치 결과 [cl_bt_0011] ==========\n"); printf("========== 마감 리포트 배치 [cl_bt_0011] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" ---------------------------------------------\n");
printf(" 완료(M) : %ld\n", done); printf(" %-10s %8s %18s\n", "상태", "건수", "금액합계");
printf(" 불일치(U) : %ld\n", unmatch); printf(" ---------------------------------------------\n");
printf(" 오류 건수 : %ld\n", errcnt); for (i = 0; i < 4; i++) {
printf("=============================================\n"); amount_format_won(sum[i], won, sizeof(won));
printf(" %-10s %8ld %18s\n", labels[i], cnt[i], won);
}
amount_format_won(tot_sum, won, sizeof(won));
printf(" ---------------------------------------------\n");
printf(" %-10s %8ld %18s\n", "합계", tot_cnt, won);
printf(" 마감률(S/전체) : %d%%\n", pct);
printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return TX_OK;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -8,10 +8,12 @@
#line 1 "app/batch/cl_bt_0012.pgc" #line 1 "app/batch/cl_bt_0012.pgc"
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0012.pgc - ( + ) [tier=medium] * cl_bt_0012.pgc - ( ) [tier=medium]
* *
* (status='R') * ( 'R') ('U')
* ('M')/('U') . main . * . (R/U)
* . .
* main .
* *
* : cl_bt_0012 <YYYYMMDD> [db@host] * : cl_bt_0012 <YYYYMMDD> [db@host]
*/ */
@ -93,9 +95,12 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0012.pgc" #line 21 "app/batch/cl_bt_0012.pgc"
#define CL_ALERT_THRESHOLD 0 /* 미마감/불일치 임계치(초과 시 알림) */
#define CL_ALERT_TOPN 20 /* 알림 목록 상위 건수 */
static int run_cl_bt_0012(const char *biz_date) static int run_cl_bt_0012(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
@ -105,59 +110,92 @@ static int run_cl_bt_0012(const char *biz_date)
#line 24 "app/batch/cl_bt_0012.pgc" #line 29 "app/batch/cl_bt_0012.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0012.pgc" #line 30 "app/batch/cl_bt_0012.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0012.pgc" #line 31 "app/batch/cl_bt_0012.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0012.pgc" #line 32 "app/batch/cl_bt_0012.pgc"
long h_amount ; char h_status [ 2 ] ;
#line 28 "app/batch/cl_bt_0012.pgc" #line 33 "app/batch/cl_bt_0012.pgc"
char h_new_status [ 2 ] ; long h_amount ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0012.pgc" #line 34 "app/batch/cl_bt_0012.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long recv, unmatch, target_cnt;
int rc; long listed = 0, errcnt = 0;
char won[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
recv = cl_rec_count(biz_date, CL_ST_RECV);
unmatch = cl_rec_count(biz_date, CL_ST_FAIL);
if (recv < 0 || unmatch < 0) {
tx_log(TX_LOG_ERROR, "[cl_bt_0012] 알림대상 건수 조회 실패");
return TX_EDB;
}
target_cnt = recv + unmatch;
tx_log(TX_LOG_INFO,
"[cl_bt_0012] 알림대상 R=%ld U=%ld 합=%ld 임계=%d",
recv, unmatch, target_cnt, CL_ALERT_THRESHOLD);
printf("========== 마감 알림 배치 [cl_bt_0012] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 미마감(R) : %ld\n", recv);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 알림 임계치 : %d\n", CL_ALERT_THRESHOLD);
if (target_cnt <= CL_ALERT_THRESHOLD) {
printf(" ** 임계 이내 - 알림 없음 **\n");
printf("===============================================\n");
tx_log(TX_LOG_INFO, "[cl_bt_0012] 임계 이내 - 알림 없음");
return TX_OK;
}
printf(" ** 임계 초과 - 알림 대상 목록 (상위 %d) **\n", CL_ALERT_TOPN);
printf(" ---------------------------------------------\n");
printf(" %-14s %-4s %14s\n", "가맹점", "상태", "금액");
printf(" ---------------------------------------------\n");
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0012 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0012 cursor for select key , merch_id , status , amount from cl_ledger where biz_date = $1 and status in ( 'R' , 'U' ) order by status , key */
#line 42 "app/batch/cl_bt_0012.pgc" #line 78 "app/batch/cl_bt_0012.pgc"
#line 42 "app/batch/cl_bt_0012.pgc" #line 78 "app/batch/cl_bt_0012.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0012 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0012 cursor for select key , merch_id , status , amount from cl_ledger where biz_date = $1 and status in ( 'R' , 'U' ) order by status , key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0012.pgc" #line 80 "app/batch/cl_bt_0012.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0012"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0012");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0012] tx_begin 경고");
for (;;) { for (;;) {
if (listed >= CL_ALERT_TOPN)
break;
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0012", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0012", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0012.pgc" #line 90 "app/batch/cl_bt_0012.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,44 +206,24 @@ static int run_cl_bt_0012(const char *biz_date)
break; break;
} }
total++; amount_format_won(h_amount, won, sizeof(won));
printf(" %-14s %-4s %14s key=%s\n", h_merch_id, h_status, won, h_key);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ listed++;
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0012] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0012", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0012", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0012.pgc" #line 105 "app/batch/cl_bt_0012.pgc"
if (errcnt == 0) tx_log(TX_LOG_WARN,
tx_commit(); "[cl_bt_0012] 요약 date=%s 알림대상=%ld 출력=%ld 오류=%ld",
else biz_date, target_cnt, listed, errcnt);
tx_abort();
tx_log(TX_LOG_INFO, printf(" ---------------------------------------------\n");
"[cl_bt_0012] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", printf(" 알림 대상 수 : %ld\n", target_cnt);
biz_date, total, done, unmatch, errcnt); printf(" 출력 건수 : %ld\n", listed);
printf(" 오류 건수 : %ld\n", errcnt);
printf("========== 마감 배치 결과 [cl_bt_0012] ==========\n"); printf("===============================================\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,11 @@
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0012.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=medium] * cl_bt_0012.pgc - 마감 알림 배치 (임계 초과 알림) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 미마감(접수 'R') 및 불일치('U') 건수를 조회하여 알림
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 임계치와 비교한다. 임계 초과 시 알림 대상(R/U) 상위건을 커서로 순회
* 하며 목록으로 출력한다. 알림 발생 건수를 리포트한다.
* 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0012 <YYYYMMDD> [db@host] * 실행: cl_bt_0012 <YYYYMMDD> [db@host]
*/ */
@ -18,28 +20,62 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
#define CL_ALERT_THRESHOLD 0 /* 미마감/불일치 임계치(초과 시 알림) */
#define CL_ALERT_TOPN 20 /* 알림 목록 상위 건수 */
static int run_cl_bt_0012(const char *biz_date) static int run_cl_bt_0012(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
char h_status[2];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long recv, unmatch, target_cnt;
int rc; long listed = 0, errcnt = 0;
char won[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
recv = cl_rec_count(biz_date, CL_ST_RECV);
unmatch = cl_rec_count(biz_date, CL_ST_FAIL);
if (recv < 0 || unmatch < 0) {
tx_log(TX_LOG_ERROR, "[cl_bt_0012] 알림대상 건수 조회 실패");
return TX_EDB;
}
target_cnt = recv + unmatch;
tx_log(TX_LOG_INFO,
"[cl_bt_0012] 알림대상 R=%ld U=%ld 합=%ld 임계=%d",
recv, unmatch, target_cnt, CL_ALERT_THRESHOLD);
printf("========== 마감 알림 배치 [cl_bt_0012] ==========\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 미마감(R) : %ld\n", recv);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 알림 임계치 : %d\n", CL_ALERT_THRESHOLD);
if (target_cnt <= CL_ALERT_THRESHOLD) {
printf(" ** 임계 이내 - 알림 없음 **\n");
printf("===============================================\n");
tx_log(TX_LOG_INFO, "[cl_bt_0012] 임계 이내 - 알림 없음");
return TX_OK;
}
printf(" ** 임계 초과 - 알림 대상 목록 (상위 %d) **\n", CL_ALERT_TOPN);
printf(" ---------------------------------------------\n");
printf(" %-14s %-4s %14s\n", "가맹점", "상태", "금액");
printf(" ---------------------------------------------\n");
EXEC SQL DECLARE cur_cl_bt_0012 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0012 CURSOR FOR
SELECT key, merch_id, amount SELECT key, merch_id, status, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status IN ('R', 'U')
ORDER BY key; ORDER BY status, key;
EXEC SQL OPEN cur_cl_bt_0012; EXEC SQL OPEN cur_cl_bt_0012;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -47,11 +83,11 @@ static int run_cl_bt_0012(const char *biz_date)
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0012] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0012 INTO :h_key, :h_merch_id, :h_amount; if (listed >= CL_ALERT_TOPN)
break;
EXEC SQL FETCH cur_cl_bt_0012 INTO :h_key, :h_merch_id, :h_status, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,42 +97,22 @@ static int run_cl_bt_0012(const char *biz_date)
break; break;
} }
total++; amount_format_won(h_amount, won, sizeof(won));
printf(" %-14s %-4s %14s key=%s\n", h_merch_id, h_status, won, h_key);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ listed++;
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0012] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_cl_bt_0012; EXEC SQL CLOSE cur_cl_bt_0012;
if (errcnt == 0) tx_log(TX_LOG_WARN,
tx_commit(); "[cl_bt_0012] 요약 date=%s 알림대상=%ld 출력=%ld 오류=%ld",
else biz_date, target_cnt, listed, errcnt);
tx_abort();
tx_log(TX_LOG_INFO, printf(" ---------------------------------------------\n");
"[cl_bt_0012] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", printf(" 알림 대상 수 : %ld\n", target_cnt);
biz_date, total, done, unmatch, errcnt); printf(" 출력 건수 : %ld\n", listed);
printf(" 오류 건수 : %ld\n", errcnt);
printf("========== 마감 배치 결과 [cl_bt_0012] ==========\n"); printf("===============================================\n");
printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,12 @@
#line 1 "app/batch/cl_bt_0013.pgc" #line 1 "app/batch/cl_bt_0013.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0013.pgc - ( + ) [tier=easy] * cl_bt_0013.pgc - ( ) [tier=easy]
* *
* (status='R') * ( 'R' / 'U')
* ('M')/('U') . main . * .
* (TX_FAIL) .
* main .
* *
* : cl_bt_0013 <YYYYMMDD> [db@host] * : cl_bt_0013 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +95,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0013.pgc" #line 21 "app/batch/cl_bt_0013.pgc"
static int run_cl_bt_0013(const char *biz_date) static int run_cl_bt_0013(const char *biz_date)
@ -105,49 +107,52 @@ static int run_cl_bt_0013(const char *biz_date)
#line 24 "app/batch/cl_bt_0013.pgc" #line 26 "app/batch/cl_bt_0013.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0013.pgc" #line 27 "app/batch/cl_bt_0013.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0013.pgc" #line 28 "app/batch/cl_bt_0013.pgc"
char h_merch_id [ 16 ] ; char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0013.pgc"
long h_amount ;
#line 28 "app/batch/cl_bt_0013.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */
#line 29 "app/batch/cl_bt_0013.pgc" #line 29 "app/batch/cl_bt_0013.pgc"
char h_status [ 2 ] ;
#line 30 "app/batch/cl_bt_0013.pgc"
long h_amount ;
/* exec sql end declare section */
#line 31 "app/batch/cl_bt_0013.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long pending = 0, errcnt = 0, sum_amt = 0;
int rc; char won[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0013 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ /* declare cur_cl_bt_0013 cursor for select key , merch_id , status , amount from cl_ledger where biz_date = $1 and status in ( 'R' , 'U' ) order by status , key */
#line 42 "app/batch/cl_bt_0013.pgc" #line 44 "app/batch/cl_bt_0013.pgc"
#line 42 "app/batch/cl_bt_0013.pgc" #line 44 "app/batch/cl_bt_0013.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0013 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0013 cursor for select key , merch_id , status , amount from cl_ledger where biz_date = $1 and status in ( 'R' , 'U' ) order by status , key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0013.pgc" #line 46 "app/batch/cl_bt_0013.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0013"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0013");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK) printf("========== 미마감 점검 배치 [cl_bt_0013] ==========\n");
tx_log(TX_LOG_WARN, "[cl_bt_0013] tx_begin 경고"); printf(" 영업일 : %s\n", biz_date);
printf(" ---------------------------------------------\n");
printf(" %-14s %-14s %-4s %14s\n", "처리키", "가맹점", "상태", "금액");
printf(" ---------------------------------------------\n");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0013", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0013", ECPGt_EOIT,
@ -155,9 +160,11 @@ static int run_cl_bt_0013(const char *biz_date)
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0013.pgc" #line 59 "app/batch/cl_bt_0013.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,46 +175,33 @@ static int run_cl_bt_0013(const char *biz_date)
break; break;
} }
total++; amount_format_won(h_amount, won, sizeof(won));
printf(" %-14s %-14s %-4s %14s\n", h_key, h_merch_id, h_status, won);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ pending++;
if (amount_is_valid(h_amount)) { sum_amt += h_amount;
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0013] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0013", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0013", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0013.pgc" #line 75 "app/batch/cl_bt_0013.pgc"
if (errcnt == 0) amount_format_won(sum_amt, won, sizeof(won));
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0013] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0013] 요약 date=%s 미마감=%ld 미마감액=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, pending, sum_amt, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0013] ==========\n"); printf(" ---------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 미마감 건수 : %ld\n", pending);
printf(" 대상 건수 : %ld\n", total); printf(" 미마감 금액 : %s\n", won);
printf(" 완료(M) : %ld\n", done); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 점검 결과 : %s\n",
printf(" 오류 건수 : %ld\n", errcnt); (errcnt == 0 && pending == 0) ? "정상(마감가능)" : "미마감 존재(FAIL)");
printf("=============================================\n"); printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; if (errcnt > 0)
return TX_FAIL;
return (pending == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -1,9 +1,11 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0013.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0013.pgc - 미마감 점검 배치 (미결 목록 검출) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일에서 아직 마감되지 않은 미결건(접수 'R' / 불일치 'U')을
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 커서로 순회하며 목록과 합계를 출력한다. 미마감 건이 하나라도 존재하면
* 점검 실패(TX_FAIL)로 종료하여 후속 마감을 차단한다.
* 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0013 <YYYYMMDD> [db@host] * 실행: cl_bt_0013 <YYYYMMDD> [db@host]
*/ */
@ -24,22 +26,22 @@ static int run_cl_bt_0013(const char *biz_date)
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16]; char h_merch_id[16];
char h_status[2];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long pending = 0, errcnt = 0, sum_amt = 0;
int rc; char won[32];
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0013 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0013 CURSOR FOR
SELECT key, merch_id, amount SELECT key, merch_id, status, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status IN ('R', 'U')
ORDER BY key; ORDER BY status, key;
EXEC SQL OPEN cur_cl_bt_0013; EXEC SQL OPEN cur_cl_bt_0013;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -47,11 +49,14 @@ static int run_cl_bt_0013(const char *biz_date)
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK) printf("========== 미마감 점검 배치 [cl_bt_0013] ==========\n");
tx_log(TX_LOG_WARN, "[cl_bt_0013] tx_begin 경고"); printf(" 영업일 : %s\n", biz_date);
printf(" ---------------------------------------------\n");
printf(" %-14s %-14s %-4s %14s\n", "처리키", "가맹점", "상태", "금액");
printf(" ---------------------------------------------\n");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0013 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0013 INTO :h_key, :h_merch_id, :h_status, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,44 +66,31 @@ static int run_cl_bt_0013(const char *biz_date)
break; break;
} }
total++; amount_format_won(h_amount, won, sizeof(won));
printf(" %-14s %-14s %-4s %14s\n", h_key, h_merch_id, h_status, won);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ pending++;
if (amount_is_valid(h_amount)) { sum_amt += h_amount;
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0013] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
EXEC SQL CLOSE cur_cl_bt_0013; EXEC SQL CLOSE cur_cl_bt_0013;
if (errcnt == 0) amount_format_won(sum_amt, won, sizeof(won));
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0013] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0013] 요약 date=%s 미마감=%ld 미마감액=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, pending, sum_amt, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0013] ==========\n"); printf(" ---------------------------------------------\n");
printf(" 영업일 : %s\n", biz_date); printf(" 미마감 건수 : %ld\n", pending);
printf(" 대상 건수 : %ld\n", total); printf(" 미마감 금액 : %s\n", won);
printf(" 완료(M) : %ld\n", done); printf(" 오류 건수 : %ld\n", errcnt);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 점검 결과 : %s\n",
printf(" 오류 건수 : %ld\n", errcnt); (errcnt == 0 && pending == 0) ? "정상(마감가능)" : "미마감 존재(FAIL)");
printf("=============================================\n"); printf("=================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; if (errcnt > 0)
return TX_FAIL;
return (pending == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -8,12 +8,14 @@
#line 1 "app/batch/cl_bt_0014.pgc" #line 1 "app/batch/cl_bt_0014.pgc"
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0014.pgc - ( + ) [tier=medium] * cl_bt_0014.pgc - ( ) [tier=medium]
* *
* (status='R') * D1, D2 (biz_date BETWEEN :d1 AND :d2)
* ('M')/('U') . main . * ('M')/('U') ('S')
* . .
* 2(D1 D2) . main .
* *
* : cl_bt_0014 <YYYYMMDD> [db@host] * : cl_bt_0014 <YYYYMMDD_시작> <YYYYMMDD_종료> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -93,53 +95,55 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0014.pgc" #line 21 "app/batch/cl_bt_0014.pgc"
static int run_cl_bt_0014(const char *biz_date) static int run_cl_bt_0014(const char *d1, const char *d2)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0014.pgc"
char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0014.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0014.pgc" #line 26 "app/batch/cl_bt_0014.pgc"
char h_merch_id [ 16 ] ; char h_d1 [ 9 ] ;
#line 27 "app/batch/cl_bt_0014.pgc" #line 27 "app/batch/cl_bt_0014.pgc"
long h_amount ; char h_d2 [ 9 ] ;
#line 28 "app/batch/cl_bt_0014.pgc" #line 28 "app/batch/cl_bt_0014.pgc"
char h_new_status [ 2 ] ; char h_key [ 16 ] ;
/* exec sql end declare section */
#line 29 "app/batch/cl_bt_0014.pgc" #line 29 "app/batch/cl_bt_0014.pgc"
long h_amount ;
/* exec sql end declare section */
#line 30 "app/batch/cl_bt_0014.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, settled = 0, errcnt = 0, sum_amt = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_d1, d1, sizeof(h_d1) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_d1[sizeof(h_d1) - 1] = '\0';
strncpy(h_d2, d2, sizeof(h_d2) - 1);
h_d2[sizeof(h_d2) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ ECPGset_var( 0, ( h_d2 ), __LINE__);\
/* declare cur_cl_bt_0014 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ ECPGset_var( 1, ( h_d1 ), __LINE__);\
#line 42 "app/batch/cl_bt_0014.pgc" /* declare cur_cl_bt_0014 cursor for select key , amount from cl_ledger where biz_date between $1 and $2 and status in ( 'M' , 'U' ) order by biz_date , key */
#line 46 "app/batch/cl_bt_0014.pgc"
#line 42 "app/batch/cl_bt_0014.pgc" #line 46 "app/batch/cl_bt_0014.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0014 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0014 cursor for select key , amount from cl_ledger where biz_date between $1 and $2 and status in ( 'M' , 'U' ) order by biz_date , key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_d1),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_d2),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0014.pgc" #line 48 "app/batch/cl_bt_0014.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0014"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0014");
@ -153,11 +157,9 @@ static int run_cl_bt_0014(const char *biz_date)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0014", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0014", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0014.pgc" #line 58 "app/batch/cl_bt_0014.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -169,25 +171,18 @@ static int run_cl_bt_0014(const char *biz_date)
} }
total++; total++;
rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0014] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0014] 분기마감 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
settled++;
sum_amt += h_amount;
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0014", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0014", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0014.pgc" #line 79 "app/batch/cl_bt_0014.pgc"
if (errcnt == 0) if (errcnt == 0)
@ -195,42 +190,56 @@ static int run_cl_bt_0014(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amt, won, sizeof(won));
"[cl_bt_0014] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0014] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0014] 요약 기간=%s~%s 대상=%ld 마감=%ld 정산액=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); d1, d2, total, settled, sum_amt, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 분기마감 배치 결과 [cl_bt_0014] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 마감 기간 : %s ~ %s\n", d1, d2);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 분기마감(S) : %ld\n", settled);
printf(" 정산액 합계 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt);
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
const char *biz_date; const char *d1;
const char *d2;
const char *target; const char *target;
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 3) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr,
"사용법: %s <YYYYMMDD_시작> <YYYYMMDD_종료> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; d1 = argv[1];
target = (argc >= 3) ? argv[2] : NULL; d2 = argv[2];
target = (argc >= 4) ? argv[3] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(d1)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 시작영업일 '%s'\n", d1);
return 2;
}
if (!date_is_valid(d2)) {
fprintf(stderr, "오류: 유효하지 않은 종료영업일 '%s'\n", d2);
return 2;
}
if (strcmp(d1, d2) > 0) {
fprintf(stderr, "오류: 시작영업일이 종료영업일보다 큽니다 '%s' > '%s'\n",
d1, d2);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cl_bt_0014] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cl_bt_0014] 배치 시작 기간=%s~%s", d1, d2);
rc = cl_dbio_connect(target); rc = cl_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
@ -238,7 +247,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
rc = run_cl_bt_0014(biz_date); rc = run_cl_bt_0014(d1, d2);
cl_dbio_disconnect(); cl_dbio_disconnect();

View file

@ -1,11 +1,13 @@
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0014.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=medium] * cl_bt_0014.pgc - 분기마감 배치 (기간 일괄 정산) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 인자로 받은 두 영업일 D1, D2 사이(biz_date BETWEEN :d1 AND :d2)의
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 처리완료('M')/불일치('U') 건을 커서로 순회하여 정산완료('S')로 일괄
* 분기마감한다. 분기 마감건수와 정산액 합계를 리포트한다.
* 인자 2개(D1 D2)를 필수로 요구한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0014 <YYYYMMDD> [db@host] * 실행: cl_bt_0014 <YYYYMMDD_시작> <YYYYMMDD_종료> [db@host]
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -18,28 +20,30 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
static int run_cl_bt_0014(const char *biz_date) static int run_cl_bt_0014(const char *d1, const char *d2)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_d1[9];
char h_d2[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, settled = 0, errcnt = 0, sum_amt = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_d1, d1, sizeof(h_d1) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_d1[sizeof(h_d1) - 1] = '\0';
strncpy(h_d2, d2, sizeof(h_d2) - 1);
h_d2[sizeof(h_d2) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0014 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0014 CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date BETWEEN :h_d1 AND :h_d2
AND status = 'R' AND status IN ('M', 'U')
ORDER BY key; ORDER BY biz_date, key;
EXEC SQL OPEN cur_cl_bt_0014; EXEC SQL OPEN cur_cl_bt_0014;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -51,7 +55,7 @@ static int run_cl_bt_0014(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0014] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0014] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0014 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0014 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -62,21 +66,14 @@ static int run_cl_bt_0014(const char *biz_date)
} }
total++; total++;
rc = cl_rec_update_status(h_key, CL_ST_SETTLED);
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) { if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0014] 상태전이 실패 key=%s rc=%d", h_key, rc); tx_log(TX_LOG_ERROR, "[cl_bt_0014] 분기마감 실패 key=%s rc=%d", h_key, rc);
errcnt++; errcnt++;
continue;
} }
settled++;
sum_amt += h_amount;
} }
EXEC SQL CLOSE cur_cl_bt_0014; EXEC SQL CLOSE cur_cl_bt_0014;
@ -86,42 +83,56 @@ static int run_cl_bt_0014(const char *biz_date)
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(sum_amt, won, sizeof(won));
"[cl_bt_0014] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0014] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0014] 요약 기간=%s~%s 대상=%ld 마감=%ld 정산액=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); d1, d2, total, settled, sum_amt, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 분기마감 배치 결과 [cl_bt_0014] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 마감 기간 : %s ~ %s\n", d1, d2);
printf("=============================================\n"); printf(" 대상 건수 : %ld\n", total);
printf(" 분기마감(S) : %ld\n", settled);
printf(" 정산액 합계 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt);
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
const char *biz_date; const char *d1;
const char *d2;
const char *target; const char *target;
int rc; int rc;
tx_set_loglevel(TX_LOG_INFO); tx_set_loglevel(TX_LOG_INFO);
if (argc < 2) { if (argc < 3) {
fprintf(stderr, "사용법: %s <YYYYMMDD> [db@host]\n", argv[0]); fprintf(stderr,
"사용법: %s <YYYYMMDD_시작> <YYYYMMDD_종료> [db@host]\n", argv[0]);
return 2; return 2;
} }
biz_date = argv[1]; d1 = argv[1];
target = (argc >= 3) ? argv[2] : NULL; d2 = argv[2];
target = (argc >= 4) ? argv[3] : NULL;
if (!date_is_valid(biz_date)) { if (!date_is_valid(d1)) {
fprintf(stderr, "오류: 유효하지 않은 영업일 '%s'\n", biz_date); fprintf(stderr, "오류: 유효하지 않은 시작영업일 '%s'\n", d1);
return 2;
}
if (!date_is_valid(d2)) {
fprintf(stderr, "오류: 유효하지 않은 종료영업일 '%s'\n", d2);
return 2;
}
if (strcmp(d1, d2) > 0) {
fprintf(stderr, "오류: 시작영업일이 종료영업일보다 큽니다 '%s' > '%s'\n",
d1, d2);
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cl_bt_0014] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cl_bt_0014] 배치 시작 기간=%s~%s", d1, d2);
rc = cl_dbio_connect(target); rc = cl_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {
@ -129,7 +140,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
rc = run_cl_bt_0014(biz_date); rc = run_cl_bt_0014(d1, d2);
cl_dbio_disconnect(); cl_dbio_disconnect();

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cl_bt_0015.pgc" #line 1 "app/batch/cl_bt_0015.pgc"
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0015.pgc - ( + ) [tier=easy] * cl_bt_0015.pgc - ( ) [tier=easy]
* *
* (status='R') * (R/M/U/S) SELECT ,
* ('M')/('U') . main . * ( = /)
* . . main .
* *
* : cl_bt_0015 <YYYYMMDD> [db@host] * : cl_bt_0015 <YYYYMMDD> [db@host]
*/ */
@ -93,121 +94,100 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0015.pgc" #line 20 "app/batch/cl_bt_0015.pgc"
static int run_cl_bt_0015(const char *biz_date) static int query_stat_0015(const char *biz_date, const char *status,
long *out_cnt, long *out_sum)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cl_bt_0015.pgc" #line 26 "app/batch/cl_bt_0015.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0015.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0015.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0015.pgc" #line 27 "app/batch/cl_bt_0015.pgc"
long h_amount ; char h_status [ 2 ] ;
#line 28 "app/batch/cl_bt_0015.pgc" #line 28 "app/batch/cl_bt_0015.pgc"
char h_new_status [ 2 ] ; int h_cnt ;
/* exec sql end declare section */
#line 29 "app/batch/cl_bt_0015.pgc" #line 29 "app/batch/cl_bt_0015.pgc"
long h_sum ;
/* exec sql end declare section */
#line 30 "app/batch/cl_bt_0015.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_status, status, sizeof(h_status) - 1);
h_status[sizeof(h_status) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) , coalesce ( sum ( amount ) , 0 ) from cl_ledger where biz_date = $1 and status = $2 ",
/* declare cur_cl_bt_0015 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/cl_bt_0015.pgc"
#line 42 "app/batch/cl_bt_0015.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0015 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
#line 44 "app/batch/cl_bt_0015.pgc" ECPGt_char,(h_status),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&(h_cnt),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_sum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 41 "app/batch/cl_bt_0015.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0015"); if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT 통계 cl_bt_0015");
return TX_EDB; return TX_EDB;
} }
*out_cnt = (long)h_cnt;
*out_sum = h_sum;
return TX_OK;
}
if (tx_begin() != TX_OK) static int run_cl_bt_0015(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0015] tx_begin 경고"); {
static const char *codes[4] = { "R", "M", "U", "S" };
static const char *labels[4] = { "접수(R) ", "완료(M) ",
"불일치(U)", "정산(S) " };
long cnt[4], sum[4], avg;
long tot_cnt = 0, tot_sum = 0, tot_avg = 0;
int i;
char won_sum[32], won_avg[32];
for (;;) { for (i = 0; i < 4; i++) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0015", ECPGt_EOIT, if (query_stat_0015(biz_date, codes[i], &cnt[i], &sum[i]) != TX_OK)
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), return TX_EDB;
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, tot_cnt += cnt[i];
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), tot_sum += sum[i];
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_EORT);}
#line 54 "app/batch/cl_bt_0015.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break;
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0015");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0015] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
if (tot_cnt > 0)
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0015", ECPGt_EOIT, ECPGt_EORT);} tot_avg = tot_sum / tot_cnt; /* 전체 평균(정수 나눗셈) */
#line 82 "app/batch/cl_bt_0015.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0015] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0015] 요약 date=%s 전체건수=%ld 총액=%ld 전체평균=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, tot_cnt, tot_sum, tot_avg);
printf("========== 마감 배치 결과 [cl_bt_0015] ==========\n"); printf("========== 마감 통계 배치 [cl_bt_0015] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" -----------------------------------------------------\n");
printf(" 완료(M) : %ld\n", done); printf(" %-10s %8s %16s %14s\n", "상태", "건수", "금액합계", "평균");
printf(" 불일치(U) : %ld\n", unmatch); printf(" -----------------------------------------------------\n");
printf(" 오류 건수 : %ld\n", errcnt); for (i = 0; i < 4; i++) {
printf("=============================================\n"); avg = (cnt[i] > 0) ? (sum[i] / cnt[i]) : 0; /* 상태별 평균 */
amount_format_won(sum[i], won_sum, sizeof(won_sum));
amount_format_won(avg, won_avg, sizeof(won_avg));
printf(" %-10s %8ld %16s %14s\n", labels[i], cnt[i], won_sum, won_avg);
}
amount_format_won(tot_sum, won_sum, sizeof(won_sum));
amount_format_won(tot_avg, won_avg, sizeof(won_avg));
printf(" -----------------------------------------------------\n");
printf(" %-10s %8ld %16s %14s\n", "합계", tot_cnt, won_sum, won_avg);
printf("===============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return TX_OK;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -1,9 +1,10 @@
/* @tier easy @module cl @transform closing-batch */ /* @tier easy @module cl @transform closing-batch */
/* /*
* cl_bt_0015.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=easy] * cl_bt_0015.pgc - 마감 통계 배치 (상태별 통계표) [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 상태별(R/M/U/S) 건수와 금액합계를 개별 SELECT 로 조회하고,
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 각 상태의 평균 거래금액(정수 나눗셈 = 합계/건수)을 계산하여 통계표로
* 출력한다. 전체 평균도 함께 표시한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0015 <YYYYMMDD> [db@host] * 실행: cl_bt_0015 <YYYYMMDD> [db@host]
*/ */
@ -18,87 +19,77 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
static int run_cl_bt_0015(const char *biz_date) static int query_stat_0015(const char *biz_date, const char *status,
long *out_cnt, long *out_sum)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_status[2];
char h_merch_id[16]; int h_cnt;
long h_amount; long h_sum;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
strncpy(h_status, status, sizeof(h_status) - 1);
h_status[sizeof(h_status) - 1] = '\0';
EXEC SQL DECLARE cur_cl_bt_0015 CURSOR FOR EXEC SQL SELECT count(*), coalesce(sum(amount), 0)
SELECT key, merch_id, amount INTO :h_cnt, :h_sum
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = :h_status;
ORDER BY key;
EXEC SQL OPEN cur_cl_bt_0015; if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("SELECT 통계 cl_bt_0015");
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0015");
return TX_EDB; return TX_EDB;
} }
*out_cnt = (long)h_cnt;
*out_sum = h_sum;
return TX_OK;
}
if (tx_begin() != TX_OK) static int run_cl_bt_0015(const char *biz_date)
tx_log(TX_LOG_WARN, "[cl_bt_0015] tx_begin 경고"); {
static const char *codes[4] = { "R", "M", "U", "S" };
static const char *labels[4] = { "접수(R) ", "완료(M) ",
"불일치(U)", "정산(S) " };
long cnt[4], sum[4], avg;
long tot_cnt = 0, tot_sum = 0, tot_avg = 0;
int i;
char won_sum[32], won_avg[32];
for (;;) { for (i = 0; i < 4; i++) {
EXEC SQL FETCH cur_cl_bt_0015 INTO :h_key, :h_merch_id, :h_amount; if (query_stat_0015(biz_date, codes[i], &cnt[i], &sum[i]) != TX_OK)
return TX_EDB;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) tot_cnt += cnt[i];
break; tot_sum += sum[i];
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cl_bt_0015");
errcnt++;
break;
}
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status));
done++;
} else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status));
unmatch++;
}
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0015] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
}
} }
if (tot_cnt > 0)
EXEC SQL CLOSE cur_cl_bt_0015; tot_avg = tot_sum / tot_cnt; /* 전체 평균(정수 나눗셈) */
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cl_bt_0015] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cl_bt_0015] 요약 date=%s 전체건수=%ld 총액=%ld 전체평균=%ld",
biz_date, total, done, unmatch, errcnt); biz_date, tot_cnt, tot_sum, tot_avg);
printf("========== 마감 배치 결과 [cl_bt_0015] ==========\n"); printf("========== 마감 통계 배치 [cl_bt_0015] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 영업일 : %s\n", biz_date);
printf(" 대상 건수 : %ld\n", total); printf(" -----------------------------------------------------\n");
printf(" 완료(M) : %ld\n", done); printf(" %-10s %8s %16s %14s\n", "상태", "건수", "금액합계", "평균");
printf(" 불일치(U) : %ld\n", unmatch); printf(" -----------------------------------------------------\n");
printf(" 오류 건수 : %ld\n", errcnt); for (i = 0; i < 4; i++) {
printf("=============================================\n"); avg = (cnt[i] > 0) ? (sum[i] / cnt[i]) : 0; /* 상태별 평균 */
amount_format_won(sum[i], won_sum, sizeof(won_sum));
amount_format_won(avg, won_avg, sizeof(won_avg));
printf(" %-10s %8ld %16s %14s\n", labels[i], cnt[i], won_sum, won_avg);
}
amount_format_won(tot_sum, won_sum, sizeof(won_sum));
amount_format_won(tot_avg, won_avg, sizeof(won_avg));
printf(" -----------------------------------------------------\n");
printf(" %-10s %8ld %16s %14s\n", "합계", tot_cnt, won_sum, won_avg);
printf("===============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return TX_OK;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -8,10 +8,14 @@
#line 1 "app/batch/cl_bt_0016.pgc" #line 1 "app/batch/cl_bt_0016.pgc"
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0016.pgc - ( + ) [tier=medium] * cl_bt_0016.pgc - ( ) [tier=medium]
* *
* (status='R') * 2 .
* ('M')/('U') . main . * 1) ('R') ('M')/
* ('U') .
* 2) ('M') ('S')
* ( UPDATE) .
* / . main .
* *
* : cl_bt_0016 <YYYYMMDD> [db@host] * : cl_bt_0016 <YYYYMMDD> [db@host]
*/ */
@ -93,7 +97,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cl_bt_0016.pgc" #line 23 "app/batch/cl_bt_0016.pgc"
static int run_cl_bt_0016(const char *biz_date) static int run_cl_bt_0016(const char *biz_date)
@ -103,61 +107,64 @@ static int run_cl_bt_0016(const char *biz_date)
#line 24 "app/batch/cl_bt_0016.pgc" #line 28 "app/batch/cl_bt_0016.pgc"
char h_biz_date [ 9 ] ; char h_biz_date [ 9 ] ;
#line 25 "app/batch/cl_bt_0016.pgc" #line 29 "app/batch/cl_bt_0016.pgc"
char h_key [ 16 ] ; char h_key [ 16 ] ;
#line 26 "app/batch/cl_bt_0016.pgc" #line 30 "app/batch/cl_bt_0016.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/cl_bt_0016.pgc"
long h_amount ; long h_amount ;
#line 28 "app/batch/cl_bt_0016.pgc" #line 31 "app/batch/cl_bt_0016.pgc"
char h_new_status [ 2 ] ; long h_sum_settle ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cl_bt_0016.pgc" #line 32 "app/batch/cl_bt_0016.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; long recv0, applied_m = 0, applied_u = 0, closed = 0, errcnt = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ recv0 = cl_rec_count(biz_date, CL_ST_RECV);
/* declare cur_cl_bt_0016 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */ if (recv0 < 0) {
#line 42 "app/batch/cl_bt_0016.pgc" tx_log(TX_LOG_ERROR, "[cl_bt_0016] 접수 건수 조회 실패");
#line 42 "app/batch/cl_bt_0016.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0016 cursor for select key , merch_id , amount from cl_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cl_bt_0016.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0016");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK) if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0016] tx_begin 경고"); tx_log(TX_LOG_WARN, "[cl_bt_0016] tx_begin 경고");
/* 1단계: 접수('R') → 처리완료('M')/불일치('U') 반영 */
ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cl_bt_0016 cursor for select key , amount from cl_ledger where biz_date = $1 and status = 'R' order by key */
#line 56 "app/batch/cl_bt_0016.pgc"
#line 56 "app/batch/cl_bt_0016.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cl_bt_0016 cursor for select key , amount from cl_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 58 "app/batch/cl_bt_0016.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0016");
tx_abort();
return TX_EDB;
}
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0016", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cl_bt_0016", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 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_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cl_bt_0016.pgc" #line 66 "app/batch/cl_bt_0016.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
@ -168,44 +175,73 @@ static int run_cl_bt_0016(const char *biz_date)
break; break;
} }
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) { if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); rc = cl_rec_update_status(h_key, CL_ST_DONE);
done++; if (rc == TX_OK) applied_m++;
else { errcnt++; tx_log(TX_LOG_ERROR, "[cl_bt_0016] M반영 실패 key=%s", h_key); }
} else { } else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status)); rc = cl_rec_update_status(h_key, CL_ST_FAIL);
unmatch++; if (rc == TX_OK) applied_u++;
} else { errcnt++; tx_log(TX_LOG_ERROR, "[cl_bt_0016] U반영 실패 key=%s", h_key); }
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0016] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
} }
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0016", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cl_bt_0016", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cl_bt_0016.pgc" #line 87 "app/batch/cl_bt_0016.pgc"
/* 2단계: 전체 처리완료('M') → 정산완료('S') 일괄 마감 */
if (errcnt == 0) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update cl_ledger set status = 'S' , upd_ts = now ( ) where biz_date = $1 and status = 'M'",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 94 "app/batch/cl_bt_0016.pgc"
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE 일괄마감 cl_bt_0016");
errcnt++;
} else {
closed = sqlca.sqlerrd[2];
}
}
/* 정산액 집계 */
h_sum_settle = 0;
if (errcnt == 0) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select coalesce ( sum ( amount ) , 0 ) from cl_ledger where biz_date = $1 and status = 'S'",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(h_sum_settle),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 111 "app/batch/cl_bt_0016.pgc"
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT 정산집계 cl_bt_0016");
errcnt++;
}
}
if (errcnt == 0) if (errcnt == 0)
tx_commit(); tx_commit();
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(h_sum_settle, won, sizeof(won));
"[cl_bt_0016] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0016] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0016] 요약 date=%s 접수=%ld 반영M=%ld 반영U=%ld 마감S=%ld 정산액=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, recv0, applied_m, applied_u, closed, h_sum_settle, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 마감 배치반영 배치 [cl_bt_0016] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 접수(R) : %ld\n", recv0);
printf(" 반영 완료(M) : %ld\n", applied_m);
printf(" 반영 불일치(U): %ld\n", applied_u);
printf(" 일괄 마감(S) : %ld\n", closed);
printf(" 정산액 합계 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt);
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -1,9 +1,13 @@
/* @tier medium @module cl @transform closing-batch */ /* @tier medium @module cl @transform closing-batch */
/* /*
* cl_bt_0016.pgc - 마감 배치 (커서 순회 + 상태전이) [tier=medium] * cl_bt_0016.pgc - 마감 배치반영 배치 (종합 일일마감) [tier=medium]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 지정 영업일의 종합 일일마감을 2단계로 수행한다.
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 1) 접수('R') 건을 커서 순회하며 금액 유효성으로 처리완료('M')/
* 불일치('U') 로 반영한다.
* 2) 반영이 끝난 전체 처리완료('M') 건을 정산완료('S')로 일괄 마감
* (단일 UPDATE)하고 정산액을 집계한다.
* 반영 건수와 마감 건수/정산액을 리포트한다. 배치 main 엔트리 포함.
* *
* 실행: cl_bt_0016 <YYYYMMDD> [db@host] * 실행: cl_bt_0016 <YYYYMMDD> [db@host]
*/ */
@ -23,19 +27,29 @@ static int run_cl_bt_0016(const char *biz_date)
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_biz_date[9];
char h_key[16]; char h_key[16];
char h_merch_id[16];
long h_amount; long h_amount;
char h_new_status[2]; long h_sum_settle;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long recv0, applied_m = 0, applied_u = 0, closed = 0, errcnt = 0;
char won[32];
int rc; int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; h_biz_date[sizeof(h_biz_date) - 1] = '\0';
recv0 = cl_rec_count(biz_date, CL_ST_RECV);
if (recv0 < 0) {
tx_log(TX_LOG_ERROR, "[cl_bt_0016] 접수 건수 조회 실패");
return TX_EDB;
}
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0016] tx_begin 경고");
/* 1단계: 접수('R') → 처리완료('M')/불일치('U') 반영 */
EXEC SQL DECLARE cur_cl_bt_0016 CURSOR FOR EXEC SQL DECLARE cur_cl_bt_0016 CURSOR FOR
SELECT key, merch_id, amount SELECT key, amount
FROM cl_ledger FROM cl_ledger
WHERE biz_date = :h_biz_date WHERE biz_date = :h_biz_date
AND status = 'R' AND status = 'R'
@ -44,14 +58,12 @@ static int run_cl_bt_0016(const char *biz_date)
EXEC SQL OPEN cur_cl_bt_0016; EXEC SQL OPEN cur_cl_bt_0016;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0016"); TX_DBIO_LOG_ERR("OPEN cur_cl_bt_0016");
tx_abort();
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cl_bt_0016] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cl_bt_0016 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cl_bt_0016 INTO :h_key, :h_amount;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
@ -61,42 +73,68 @@ static int run_cl_bt_0016(const char *biz_date)
break; break;
} }
total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */
if (amount_is_valid(h_amount)) { if (amount_is_valid(h_amount)) {
strncpy(h_new_status, CL_ST_DONE, sizeof(h_new_status)); rc = cl_rec_update_status(h_key, CL_ST_DONE);
done++; if (rc == TX_OK) applied_m++;
else { errcnt++; tx_log(TX_LOG_ERROR, "[cl_bt_0016] M반영 실패 key=%s", h_key); }
} else { } else {
strncpy(h_new_status, CL_ST_FAIL, sizeof(h_new_status)); rc = cl_rec_update_status(h_key, CL_ST_FAIL);
unmatch++; if (rc == TX_OK) applied_u++;
} else { errcnt++; tx_log(TX_LOG_ERROR, "[cl_bt_0016] U반영 실패 key=%s", h_key); }
rc = cl_rec_update_status(h_key, h_new_status);
if (rc != TX_OK) {
tx_log(TX_LOG_ERROR, "[cl_bt_0016] 상태전이 실패 key=%s rc=%d", h_key, rc);
errcnt++;
} }
} }
EXEC SQL CLOSE cur_cl_bt_0016; EXEC SQL CLOSE cur_cl_bt_0016;
/* 2단계: 전체 처리완료('M') → 정산완료('S') 일괄 마감 */
if (errcnt == 0) {
EXEC SQL UPDATE cl_ledger
SET status = 'S', upd_ts = now()
WHERE biz_date = :h_biz_date
AND status = 'M';
if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("UPDATE 일괄마감 cl_bt_0016");
errcnt++;
} else {
closed = sqlca.sqlerrd[2];
}
}
/* 정산액 집계 */
h_sum_settle = 0;
if (errcnt == 0) {
EXEC SQL SELECT coalesce(sum(amount), 0)
INTO :h_sum_settle
FROM cl_ledger
WHERE biz_date = :h_biz_date
AND status = 'S';
if (sqlca.sqlcode != TX_SQL_OK && sqlca.sqlcode != TX_SQL_NOTFOUND) {
TX_DBIO_LOG_ERR("SELECT 정산집계 cl_bt_0016");
errcnt++;
}
}
if (errcnt == 0) if (errcnt == 0)
tx_commit(); tx_commit();
else else
tx_abort(); tx_abort();
tx_log(TX_LOG_INFO, amount_format_won(h_sum_settle, won, sizeof(won));
"[cl_bt_0016] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld",
biz_date, total, done, unmatch, errcnt);
printf("========== 마감 배치 결과 [cl_bt_0016] ==========\n"); tx_log(TX_LOG_INFO,
printf(" 영업일 : %s\n", biz_date); "[cl_bt_0016] 요약 date=%s 접수=%ld 반영M=%ld 반영U=%ld 마감S=%ld 정산액=%ld 오류=%ld",
printf(" 대상 건수 : %ld\n", total); biz_date, recv0, applied_m, applied_u, closed, h_sum_settle, errcnt);
printf(" 완료(M) : %ld\n", done);
printf(" 불일치(U) : %ld\n", unmatch); printf("========== 마감 배치반영 배치 [cl_bt_0016] ==========\n");
printf(" 오류 건수 : %ld\n", errcnt); printf(" 영업일 : %s\n", biz_date);
printf("=============================================\n"); printf(" 접수(R) : %ld\n", recv0);
printf(" 반영 완료(M) : %ld\n", applied_m);
printf(" 반영 불일치(U): %ld\n", applied_u);
printf(" 일괄 마감(S) : %ld\n", closed);
printf(" 정산액 합계 : %s\n", won);
printf(" 오류 건수 : %ld\n", errcnt);
printf("===================================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (errcnt == 0) ? TX_OK : TX_FAIL;
} }

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cm_bt_0001.pgc" #line 1 "app/batch/cm_bt_0001.pgc"
/* @tier easy @module cm @transform common-batch */ /* @tier easy @module cm @transform common-batch */
/* /*
* cm_bt_0001.pgc - ( + ) [tier=easy] * cm_bt_0001.pgc - [tier=easy]
* *
* (status='R') * (cm_code) //
* ('M')/('U') . main . * . , /
* . main .
* *
* : cm_bt_0001 <YYYYMMDD> [db@host] * : cm_bt_0001 <YYYYMMDD> [db@host]
*/ */
@ -93,121 +94,117 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cm_bt_0001.pgc" #line 20 "app/batch/cm_bt_0001.pgc"
/* 코드값 형식 규칙: 공백 아님 + 영숫자 2자리 이상 */
static int cm_code_format_ok(const char *code)
{
int i, n = 0;
if (!code || code[0] == '\0')
return 0;
for (i = 0; code[i]; i++) {
unsigned char c = (unsigned char)code[i];
if (c == ' ')
continue;
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z')))
return 0;
n++;
}
return (n >= 2);
}
static int run_cm_bt_0001(const char *biz_date) static int run_cm_bt_0001(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cm_bt_0001.pgc" #line 43 "app/batch/cm_bt_0001.pgc"
char h_biz_date [ 9 ] ; char h_grp [ 16 ] ;
#line 25 "app/batch/cm_bt_0001.pgc"
char h_key [ 16 ] ;
#line 26 "app/batch/cm_bt_0001.pgc"
char h_merch_id [ 16 ] ;
#line 27 "app/batch/cm_bt_0001.pgc"
long h_amount ;
#line 28 "app/batch/cm_bt_0001.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */
#line 29 "app/batch/cm_bt_0001.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1);
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\
/* declare cur_cm_bt_0001 cursor for select key , merch_id , amount from cm_ledger where biz_date = $1 and status = 'R' order by key */
#line 42 "app/batch/cm_bt_0001.pgc"
#line 42 "app/batch/cm_bt_0001.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cm_bt_0001 cursor for select key , merch_id , amount from cm_ledger where biz_date = $1 and status = 'R' order by key",
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cm_bt_0001.pgc" #line 44 "app/batch/cm_bt_0001.pgc"
char h_code [ 16 ] ;
#line 45 "app/batch/cm_bt_0001.pgc"
char h_use_yn [ 2 ] ;
#line 46 "app/batch/cm_bt_0001.pgc"
int h_sort ;
/* exec sql end declare section */
#line 47 "app/batch/cm_bt_0001.pgc"
long total = 0, valid = 0, invalid = 0, disabled = 0;
(void)biz_date;
/* declare cur_cm_bt_0001 cursor for select grp_cd , code_cd , use_yn , coalesce ( sort_no , 0 ) from cm_code order by grp_cd , sort_no */
#line 56 "app/batch/cm_bt_0001.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cm_bt_0001 cursor for select grp_cd , code_cd , use_yn , coalesce ( sort_no , 0 ) from cm_code order by grp_cd , sort_no", ECPGt_EOIT, ECPGt_EORT);}
#line 58 "app/batch/cm_bt_0001.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cm_bt_0001"); TX_DBIO_LOG_ERR("OPEN cur_cm_bt_0001");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cm_bt_0001] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cm_bt_0001", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cm_bt_0001", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_grp),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_code),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_char,(h_use_yn),(long)2,(long)1,(2)*sizeof(char),
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);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cm_bt_0001.pgc" #line 66 "app/batch/cm_bt_0001.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0001"); TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0001");
errcnt++;
break; break;
} }
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_use_yn[0] != 'Y') {
if (amount_is_valid(h_amount)) { disabled++;
strncpy(h_new_status, CM_ST_DONE, sizeof(h_new_status)); continue;
done++;
} else {
strncpy(h_new_status, CM_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
if (cm_code_format_ok(h_code)) {
rc = cm_rec_update_status(h_key, h_new_status); valid++;
if (rc != TX_OK) { } else {
tx_log(TX_LOG_ERROR, "[cm_bt_0001] 상태전이 실패 key=%s rc=%d", h_key, rc); invalid++;
errcnt++; tx_log(TX_LOG_WARN, "[cm_bt_0001] 코드형식 위반 grp=%s code=%s",
h_grp, h_code);
} }
} }
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cm_bt_0001", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cm_bt_0001", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cm_bt_0001.pgc" #line 90 "app/batch/cm_bt_0001.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cm_bt_0001] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cm_bt_0001] 요약 총=%ld 유효=%ld 위반=%ld 미사용=%ld",
biz_date, total, done, unmatch, errcnt); total, valid, invalid, disabled);
printf("========== 공통 배치 결과 [cm_bt_0001] ==========\n"); printf("========== 공통코드 정합성 점검 [cm_bt_0001] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 총 코드수 : %ld\n", total);
printf(" 대상 건수 : %ld\n", total); printf(" 유효 코드 : %ld\n", valid);
printf(" 완료(M) : %ld\n", done); printf(" 형식 위반 : %ld\n", invalid);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 미사용(N) : %ld\n", disabled);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (invalid == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -230,7 +227,7 @@ int main(int argc, char **argv)
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cm_bt_0001] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cm_bt_0001] 코드점검 배치 시작 date=%s", biz_date);
rc = cm_dbio_connect(target); rc = cm_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {

View file

@ -1,9 +1,10 @@
/* @tier easy @module cm @transform common-batch */ /* @tier easy @module cm @transform common-batch */
/* /*
* cm_bt_0001.pgc - 공통 배치 (커서 순회 + 상태전이) [tier=easy] * cm_bt_0001.pgc - 공통코드 캐시 정합성 점검 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 공통코드 마스터(cm_code)를 커서로 순회하며 코드값 형식/정렬순번/사용여부
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 를 검증한다. 형식 위반 건은 경고 로그로 리포트하고, 유효건/위반건을
* 집계한다. 배치 main 엔트리 포함.
* *
* 실행: cm_bt_0001 <YYYYMMDD> [db@host] * 실행: cm_bt_0001 <YYYYMMDD> [db@host]
*/ */
@ -18,28 +19,41 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
/* 코드값 형식 규칙: 공백 아님 + 영숫자 2자리 이상 */
static int cm_code_format_ok(const char *code)
{
int i, n = 0;
if (!code || code[0] == '\0')
return 0;
for (i = 0; code[i]; i++) {
unsigned char c = (unsigned char)code[i];
if (c == ' ')
continue;
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z')))
return 0;
n++;
}
return (n >= 2);
}
static int run_cm_bt_0001(const char *biz_date) static int run_cm_bt_0001(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_grp[16];
char h_key[16]; char h_code[16];
char h_merch_id[16]; char h_use_yn[2];
long h_amount; int h_sort;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; long total = 0, valid = 0, invalid = 0, disabled = 0;
int rc;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); (void)biz_date;
h_biz_date[sizeof(h_biz_date) - 1] = '\0';
EXEC SQL DECLARE cur_cm_bt_0001 CURSOR FOR EXEC SQL DECLARE cur_cm_bt_0001 CURSOR FOR
SELECT key, merch_id, amount SELECT grp_cd, code_cd, use_yn, COALESCE(sort_no, 0)
FROM cm_ledger FROM cm_code
WHERE biz_date = :h_biz_date ORDER BY grp_cd, sort_no;
AND status = 'R'
ORDER BY key;
EXEC SQL OPEN cur_cm_bt_0001; EXEC SQL OPEN cur_cm_bt_0001;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -47,58 +61,46 @@ static int run_cm_bt_0001(const char *biz_date)
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cm_bt_0001] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cm_bt_0001 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cm_bt_0001
INTO :h_grp, :h_code, :h_use_yn, :h_sort;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0001"); TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0001");
errcnt++;
break; break;
} }
total++; total++;
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ if (h_use_yn[0] != 'Y') {
if (amount_is_valid(h_amount)) { disabled++;
strncpy(h_new_status, CM_ST_DONE, sizeof(h_new_status)); continue;
done++;
} else {
strncpy(h_new_status, CM_ST_FAIL, sizeof(h_new_status));
unmatch++;
} }
if (cm_code_format_ok(h_code)) {
rc = cm_rec_update_status(h_key, h_new_status); valid++;
if (rc != TX_OK) { } else {
tx_log(TX_LOG_ERROR, "[cm_bt_0001] 상태전이 실패 key=%s rc=%d", h_key, rc); invalid++;
errcnt++; tx_log(TX_LOG_WARN, "[cm_bt_0001] 코드형식 위반 grp=%s code=%s",
h_grp, h_code);
} }
} }
EXEC SQL CLOSE cur_cm_bt_0001; EXEC SQL CLOSE cur_cm_bt_0001;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cm_bt_0001] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cm_bt_0001] 요약 총=%ld 유효=%ld 위반=%ld 미사용=%ld",
biz_date, total, done, unmatch, errcnt); total, valid, invalid, disabled);
printf("========== 공통 배치 결과 [cm_bt_0001] ==========\n"); printf("========== 공통코드 정합성 점검 [cm_bt_0001] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 총 코드수 : %ld\n", total);
printf(" 대상 건수 : %ld\n", total); printf(" 유효 코드 : %ld\n", valid);
printf(" 완료(M) : %ld\n", done); printf(" 형식 위반 : %ld\n", invalid);
printf(" 불일치(U) : %ld\n", unmatch); printf(" 미사용(N) : %ld\n", disabled);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (invalid == 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -121,7 +123,7 @@ int main(int argc, char **argv)
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cm_bt_0001] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cm_bt_0001] 코드점검 배치 시작 date=%s", biz_date);
rc = cm_dbio_connect(target); rc = cm_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {

View file

@ -8,10 +8,11 @@
#line 1 "app/batch/cm_bt_0002.pgc" #line 1 "app/batch/cm_bt_0002.pgc"
/* @tier easy @module cm @transform common-batch */ /* @tier easy @module cm @transform common-batch */
/* /*
* cm_bt_0002.pgc - ( + ) [tier=easy] * cm_bt_0002.pgc - [tier=easy]
* *
* (status='R') * (cm_code)
* ('M')/('U') . main . * . ,
* / . main .
* *
* : cm_bt_0002 <YYYYMMDD> [db@host] * : cm_bt_0002 <YYYYMMDD> [db@host]
*/ */
@ -93,121 +94,107 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif #endif
#line 19 "app/batch/cm_bt_0002.pgc" #line 20 "app/batch/cm_bt_0002.pgc"
/* 그룹 전환 여부 판정: 직전 그룹키와 다르면 새 그룹 */
static int cm_group_changed(const char *prev, const char *cur)
{
if (prev[0] == '\0')
return 1;
return (strcmp(prev, cur) != 0) ? 1 : 0;
}
static int run_cm_bt_0002(const char *biz_date) static int run_cm_bt_0002(const char *biz_date)
{ {
/* exec sql begin declare section */ /* exec sql begin declare section */
#line 24 "app/batch/cm_bt_0002.pgc" #line 33 "app/batch/cm_bt_0002.pgc"
char h_biz_date [ 9 ] ; char h_grp [ 16 ] ;
#line 25 "app/batch/cm_bt_0002.pgc" #line 34 "app/batch/cm_bt_0002.pgc"
char h_key [ 16 ] ; char h_code [ 16 ] ;
#line 26 "app/batch/cm_bt_0002.pgc" #line 35 "app/batch/cm_bt_0002.pgc"
char h_merch_id [ 16 ] ; char h_use_yn [ 2 ] ;
#line 27 "app/batch/cm_bt_0002.pgc"
long h_amount ;
#line 28 "app/batch/cm_bt_0002.pgc"
char h_new_status [ 2 ] ;
/* exec sql end declare section */ /* exec sql end declare section */
#line 29 "app/batch/cm_bt_0002.pgc" #line 36 "app/batch/cm_bt_0002.pgc"
long total = 0, done = 0, unmatch = 0, errcnt = 0; char prev_grp[16];
int rc; long groups = 0, codes = 0, active = 0, grp_codes = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); (void)biz_date;
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; prev_grp[0] = '\0';
ECPGset_var( 0, ( h_biz_date ), __LINE__);\ /* declare cur_cm_bt_0002 cursor for select grp_cd , code_cd , use_yn from cm_code order by grp_cd , sort_no */
/* declare cur_cm_bt_0002 cursor for select key , merch_id , amount from cm_ledger where biz_date = $1 and status = 'R' order by key */ #line 47 "app/batch/cm_bt_0002.pgc"
#line 42 "app/batch/cm_bt_0002.pgc"
#line 42 "app/batch/cm_bt_0002.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cm_bt_0002 cursor for select key , merch_id , amount from cm_ledger where biz_date = $1 and status = 'R' order by key", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_cm_bt_0002 cursor for select grp_cd , code_cd , use_yn from cm_code order by grp_cd , sort_no", ECPGt_EOIT, ECPGt_EORT);}
ECPGt_char,(h_biz_date),(long)9,(long)1,(9)*sizeof(char), #line 49 "app/batch/cm_bt_0002.pgc"
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
#line 44 "app/batch/cm_bt_0002.pgc"
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("OPEN cur_cm_bt_0002"); TX_DBIO_LOG_ERR("OPEN cur_cm_bt_0002");
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cm_bt_0002] tx_begin 경고");
for (;;) { for (;;) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cm_bt_0002", ECPGt_EOIT, { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_cm_bt_0002", ECPGt_EOIT,
ECPGt_char,(h_key),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_grp),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(h_merch_id),(long)16,(long)1,(16)*sizeof(char), ECPGt_char,(h_code),(long)16,(long)1,(16)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_long,&(h_amount),(long)1,(long)1,sizeof(long), ECPGt_char,(h_use_yn),(long)2,(long)1,(2)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 54 "app/batch/cm_bt_0002.pgc" #line 57 "app/batch/cm_bt_0002.pgc"
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0002"); TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0002");
errcnt++;
break; break;
} }
total++; if (cm_group_changed(prev_grp, h_grp)) {
if (groups > 0)
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ tx_log(TX_LOG_INFO, "[cm_bt_0002] 그룹 로드 grp=%s codes=%ld",
if (amount_is_valid(h_amount)) { prev_grp, grp_codes);
strncpy(h_new_status, CM_ST_DONE, sizeof(h_new_status)); groups++;
done++; grp_codes = 0;
} else { strncpy(prev_grp, h_grp, sizeof(prev_grp) - 1);
strncpy(h_new_status, CM_ST_FAIL, sizeof(h_new_status)); prev_grp[sizeof(prev_grp) - 1] = '\0';
unmatch++;
} }
rc = cm_rec_update_status(h_key, h_new_status); codes++;
if (rc != TX_OK) { grp_codes++;
tx_log(TX_LOG_ERROR, "[cm_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc); if (h_use_yn[0] == 'Y')
errcnt++; active++;
}
} }
if (groups > 0)
tx_log(TX_LOG_INFO, "[cm_bt_0002] 그룹 로드 grp=%s codes=%ld",
prev_grp, grp_codes);
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cm_bt_0002", ECPGt_EOIT, ECPGt_EORT);} { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_cm_bt_0002", ECPGt_EOIT, ECPGt_EORT);}
#line 82 "app/batch/cm_bt_0002.pgc" #line 86 "app/batch/cm_bt_0002.pgc"
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cm_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cm_bt_0002] 캐시 리로드 완료 groups=%ld codes=%ld active=%ld",
biz_date, total, done, unmatch, errcnt); groups, codes, active);
printf("========== 공통 배치 결과 [cm_bt_0002] ==========\n"); printf("========== 공통코드 캐시 리로드 [cm_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 로드 그룹수 : %ld\n", groups);
printf(" 대상 건수 : %ld\n", total); printf(" 전체 코드수 : %ld\n", codes);
printf(" 완료(M) : %ld\n", done); printf(" 사용중 코드 : %ld\n", active);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (codes > 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -230,7 +217,7 @@ int main(int argc, char **argv)
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cm_bt_0002] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cm_bt_0002] 캐시 리로드 배치 시작 date=%s", biz_date);
rc = cm_dbio_connect(target); rc = cm_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {

View file

@ -1,9 +1,10 @@
/* @tier easy @module cm @transform common-batch */ /* @tier easy @module cm @transform common-batch */
/* /*
* cm_bt_0002.pgc - 공통 배치 (커서 순회 + 상태전이) [tier=easy] * cm_bt_0002.pgc - 공통코드 캐시 리로드 배치 [tier=easy]
* *
* 지정 영업일의 접수(status='R') 건을 커서로 순회하며 업무규칙에 따라 * 공통코드 마스터(cm_code)를 그룹코드 순으로 커서 순회하며 그룹별 코드수
* 완료('M')/불일치('U') 로 상태를 전이한다. 배치 main 엔트리 포함. * 를 집계한다. 그룹이 바뀔 때마다 로드 로그를 남기고, 최종적으로 캐시에
* 적재된 그룹수/코드수를 리포트한다. 배치 main 엔트리 포함.
* *
* 실행: cm_bt_0002 <YYYYMMDD> [db@host] * 실행: cm_bt_0002 <YYYYMMDD> [db@host]
*/ */
@ -18,28 +19,32 @@
EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlca;
/* 그룹 전환 여부 판정: 직전 그룹키와 다르면 새 그룹 */
static int cm_group_changed(const char *prev, const char *cur)
{
if (prev[0] == '\0')
return 1;
return (strcmp(prev, cur) != 0) ? 1 : 0;
}
static int run_cm_bt_0002(const char *biz_date) static int run_cm_bt_0002(const char *biz_date)
{ {
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_biz_date[9]; char h_grp[16];
char h_key[16]; char h_code[16];
char h_merch_id[16]; char h_use_yn[2];
long h_amount;
char h_new_status[2];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long total = 0, done = 0, unmatch = 0, errcnt = 0; char prev_grp[16];
int rc; long groups = 0, codes = 0, active = 0, grp_codes = 0;
strncpy(h_biz_date, biz_date, sizeof(h_biz_date) - 1); (void)biz_date;
h_biz_date[sizeof(h_biz_date) - 1] = '\0'; prev_grp[0] = '\0';
EXEC SQL DECLARE cur_cm_bt_0002 CURSOR FOR EXEC SQL DECLARE cur_cm_bt_0002 CURSOR FOR
SELECT key, merch_id, amount SELECT grp_cd, code_cd, use_yn
FROM cm_ledger FROM cm_code
WHERE biz_date = :h_biz_date ORDER BY grp_cd, sort_no;
AND status = 'R'
ORDER BY key;
EXEC SQL OPEN cur_cm_bt_0002; EXEC SQL OPEN cur_cm_bt_0002;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
@ -47,58 +52,50 @@ static int run_cm_bt_0002(const char *biz_date)
return TX_EDB; return TX_EDB;
} }
if (tx_begin() != TX_OK)
tx_log(TX_LOG_WARN, "[cm_bt_0002] tx_begin 경고");
for (;;) { for (;;) {
EXEC SQL FETCH cur_cm_bt_0002 INTO :h_key, :h_merch_id, :h_amount; EXEC SQL FETCH cur_cm_bt_0002
INTO :h_grp, :h_code, :h_use_yn;
if (sqlca.sqlcode == TX_SQL_NOTFOUND) if (sqlca.sqlcode == TX_SQL_NOTFOUND)
break; break;
if (sqlca.sqlcode != TX_SQL_OK) { if (sqlca.sqlcode != TX_SQL_OK) {
TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0002"); TX_DBIO_LOG_ERR("FETCH cur_cm_bt_0002");
errcnt++;
break; break;
} }
total++; if (cm_group_changed(prev_grp, h_grp)) {
if (groups > 0)
/* 업무규칙: 금액 유효성으로 완료/불일치 판정 */ tx_log(TX_LOG_INFO, "[cm_bt_0002] 그룹 로드 grp=%s codes=%ld",
if (amount_is_valid(h_amount)) { prev_grp, grp_codes);
strncpy(h_new_status, CM_ST_DONE, sizeof(h_new_status)); groups++;
done++; grp_codes = 0;
} else { strncpy(prev_grp, h_grp, sizeof(prev_grp) - 1);
strncpy(h_new_status, CM_ST_FAIL, sizeof(h_new_status)); prev_grp[sizeof(prev_grp) - 1] = '\0';
unmatch++;
} }
rc = cm_rec_update_status(h_key, h_new_status); codes++;
if (rc != TX_OK) { grp_codes++;
tx_log(TX_LOG_ERROR, "[cm_bt_0002] 상태전이 실패 key=%s rc=%d", h_key, rc); if (h_use_yn[0] == 'Y')
errcnt++; active++;
}
} }
if (groups > 0)
tx_log(TX_LOG_INFO, "[cm_bt_0002] 그룹 로드 grp=%s codes=%ld",
prev_grp, grp_codes);
EXEC SQL CLOSE cur_cm_bt_0002; EXEC SQL CLOSE cur_cm_bt_0002;
if (errcnt == 0)
tx_commit();
else
tx_abort();
tx_log(TX_LOG_INFO, tx_log(TX_LOG_INFO,
"[cm_bt_0002] 요약 date=%s 대상=%ld 완료=%ld 불일치=%ld 오류=%ld", "[cm_bt_0002] 캐시 리로드 완료 groups=%ld codes=%ld active=%ld",
biz_date, total, done, unmatch, errcnt); groups, codes, active);
printf("========== 공통 배치 결과 [cm_bt_0002] ==========\n"); printf("========== 공통코드 캐시 리로드 [cm_bt_0002] ==========\n");
printf(" 영업일 : %s\n", biz_date); printf(" 로드 그룹수 : %ld\n", groups);
printf(" 대상 건수 : %ld\n", total); printf(" 전체 코드수 : %ld\n", codes);
printf(" 완료(M) : %ld\n", done); printf(" 사용중 코드 : %ld\n", active);
printf(" 불일치(U) : %ld\n", unmatch);
printf(" 오류 건수 : %ld\n", errcnt);
printf("=============================================\n"); printf("=============================================\n");
return (errcnt == 0) ? TX_OK : TX_FAIL; return (codes > 0) ? TX_OK : TX_FAIL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -121,7 +118,7 @@ int main(int argc, char **argv)
return 2; return 2;
} }
tx_log(TX_LOG_INFO, "[cm_bt_0002] 배치 시작 date=%s", biz_date); tx_log(TX_LOG_INFO, "[cm_bt_0002] 캐시 리로드 배치 시작 date=%s", biz_date);
rc = cm_dbio_connect(target); rc = cm_dbio_connect(target);
if (rc != TX_OK) { if (rc != TX_OK) {

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