규모확장 Wave B: 전 11모듈 svc 75→133·batch 35→46 (BAIS 온라인 1:1)
- svc 825→1,463 (모듈당 133), batch 385→506 (모듈당 46) — 전부 새 고유 실업무 로직 + 카피북 헤더, 디스패처 133 advertise, 한글 기능설명(매니페스트 추출) - BAIS As-Is 대비: 온라인 1,463 vs 1,466(99.8%), 배치 506 vs 503(초과) - 화면 매니페스트 1,463 재생성 - 검증: build DONE modules=11 batches=506, 12서버 runok, xadmin psc 1,466 AVAIL, 매입체인 XA 커밋, 신규서비스 실데이터 스모크, 전 코퍼스 .pgc 클론 0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ea90bef264
commit
c62d91b7a7
1526 changed files with 59213 additions and 12 deletions
|
|
@ -96,6 +96,65 @@
|
|||
#include "ACQ_APPRGAP.h"
|
||||
#include "ACQ_FXCONVERT.h"
|
||||
|
||||
#include "ACQ_CHANDETAIL.h"
|
||||
#include "ACQ_BRANDSUM.h"
|
||||
#include "ACQ_BRANDQRY.h"
|
||||
#include "ACQ_CTRYQRY.h"
|
||||
#include "ACQ_CCYQRY.h"
|
||||
#include "ACQ_CCYRANK.h"
|
||||
#include "ACQ_CHANRANK.h"
|
||||
#include "ACQ_BRANDRANK.h"
|
||||
#include "ACQ_CTRYRANK.h"
|
||||
#include "ACQ_ERRCLASS.h"
|
||||
#include "ACQ_ERRQRY.h"
|
||||
#include "ACQ_ERRRETRY.h"
|
||||
#include "ACQ_ERRSTAT.h"
|
||||
#include "ACQ_REBUYAPPR.h"
|
||||
#include "ACQ_REBUYREJ.h"
|
||||
#include "ACQ_REBUYHIST.h"
|
||||
#include "ACQ_CB_RND2.h"
|
||||
#include "ACQ_CB_ARB.h"
|
||||
#include "ACQ_CB_FINAL.h"
|
||||
#include "ACQ_CB_REVERSE.h"
|
||||
#include "ACQ_CORRRSN.h"
|
||||
#include "ACQ_CORRSTAT.h"
|
||||
#include "ACQ_CORRAPPR.h"
|
||||
#include "ACQ_INSTQRY.h"
|
||||
#include "ACQ_INSTPREPAY.h"
|
||||
#include "ACQ_INSTPLAN.h"
|
||||
#include "ACQ_INSTCXL.h"
|
||||
#include "ACQ_ESCROW.h"
|
||||
#include "ACQ_ESCROWREL.h"
|
||||
#include "ACQ_GUARANTEE.h"
|
||||
#include "ACQ_GUARQRY.h"
|
||||
#include "ACQ_TAXMODIFY.h"
|
||||
#include "ACQ_TAXREVERSE.h"
|
||||
#include "ACQ_TAXQRY.h"
|
||||
#include "ACQ_ALERTAMT.h"
|
||||
#include "ACQ_ALERTVEL.h"
|
||||
#include "ACQ_ALERTDUP.h"
|
||||
#include "ACQ_ALERTQRY.h"
|
||||
#include "ACQ_EDIRSNDCH.h"
|
||||
#include "ACQ_EDIQRY.h"
|
||||
#include "ACQ_EDISTAT.h"
|
||||
#include "ACQ_HOURSTAT.h"
|
||||
#include "ACQ_DOWSTAT.h"
|
||||
#include "ACQ_QTRSTAT.h"
|
||||
#include "ACQ_GRADESTAT.h"
|
||||
#include "ACQ_HALFSTAT.h"
|
||||
#include "ACQ_BULKCHK.h"
|
||||
#include "ACQ_BULKRPT.h"
|
||||
#include "ACQ_EVENTBUY.h"
|
||||
#include "ACQ_PROMOQRY.h"
|
||||
#include "ACQ_PROMOSTAT.h"
|
||||
#include "ACQ_LIMITEXC.h"
|
||||
#include "ACQ_LIMITOVR.h"
|
||||
#include "ACQ_SETTLEPRE.h"
|
||||
#include "ACQ_SETTLEEXP.h"
|
||||
#include "ACQ_EXCHANGE.h"
|
||||
#include "ACQ_RETURNQRY.h"
|
||||
#include "ACQ_RETURNSTAT.h"
|
||||
|
||||
/* ----- advertise table: {service name, function} (fn is extern from its file) */
|
||||
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
|
||||
{"ACQUIRE", ACQUIRE}, {"ACQ_DDC", ACQ_DDC},
|
||||
|
|
@ -136,6 +195,64 @@ static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
|
|||
{"ACQ_VELOCITY", ACQ_VELOCITY}, {"ACQ_TOPMERCH", ACQ_TOPMERCH},
|
||||
{"ACQ_NETCALC", ACQ_NETCALC}, {"ACQ_APPRGAP", ACQ_APPRGAP},
|
||||
{"ACQ_FXCONVERT", ACQ_FXCONVERT},
|
||||
{"ACQ_CHANDETAIL", ACQ_CHANDETAIL},
|
||||
{"ACQ_BRANDSUM", ACQ_BRANDSUM},
|
||||
{"ACQ_BRANDQRY", ACQ_BRANDQRY},
|
||||
{"ACQ_CTRYQRY", ACQ_CTRYQRY},
|
||||
{"ACQ_CCYQRY", ACQ_CCYQRY},
|
||||
{"ACQ_CCYRANK", ACQ_CCYRANK},
|
||||
{"ACQ_CHANRANK", ACQ_CHANRANK},
|
||||
{"ACQ_BRANDRANK", ACQ_BRANDRANK},
|
||||
{"ACQ_CTRYRANK", ACQ_CTRYRANK},
|
||||
{"ACQ_ERRCLASS", ACQ_ERRCLASS},
|
||||
{"ACQ_ERRQRY", ACQ_ERRQRY},
|
||||
{"ACQ_ERRRETRY", ACQ_ERRRETRY},
|
||||
{"ACQ_ERRSTAT", ACQ_ERRSTAT},
|
||||
{"ACQ_REBUYAPPR", ACQ_REBUYAPPR},
|
||||
{"ACQ_REBUYREJ", ACQ_REBUYREJ},
|
||||
{"ACQ_REBUYHIST", ACQ_REBUYHIST},
|
||||
{"ACQ_CB_RND2", ACQ_CB_RND2},
|
||||
{"ACQ_CB_ARB", ACQ_CB_ARB},
|
||||
{"ACQ_CB_FINAL", ACQ_CB_FINAL},
|
||||
{"ACQ_CB_REVERSE", ACQ_CB_REVERSE},
|
||||
{"ACQ_CORRRSN", ACQ_CORRRSN},
|
||||
{"ACQ_CORRSTAT", ACQ_CORRSTAT},
|
||||
{"ACQ_CORRAPPR", ACQ_CORRAPPR},
|
||||
{"ACQ_INSTQRY", ACQ_INSTQRY},
|
||||
{"ACQ_INSTPREPAY", ACQ_INSTPREPAY},
|
||||
{"ACQ_INSTPLAN", ACQ_INSTPLAN},
|
||||
{"ACQ_INSTCXL", ACQ_INSTCXL},
|
||||
{"ACQ_ESCROW", ACQ_ESCROW},
|
||||
{"ACQ_ESCROWREL", ACQ_ESCROWREL},
|
||||
{"ACQ_GUARANTEE", ACQ_GUARANTEE},
|
||||
{"ACQ_GUARQRY", ACQ_GUARQRY},
|
||||
{"ACQ_TAXMODIFY", ACQ_TAXMODIFY},
|
||||
{"ACQ_TAXREVERSE", ACQ_TAXREVERSE},
|
||||
{"ACQ_TAXQRY", ACQ_TAXQRY},
|
||||
{"ACQ_ALERTAMT", ACQ_ALERTAMT},
|
||||
{"ACQ_ALERTVEL", ACQ_ALERTVEL},
|
||||
{"ACQ_ALERTDUP", ACQ_ALERTDUP},
|
||||
{"ACQ_ALERTQRY", ACQ_ALERTQRY},
|
||||
{"ACQ_EDIRSNDCH", ACQ_EDIRSNDCH},
|
||||
{"ACQ_EDIQRY", ACQ_EDIQRY},
|
||||
{"ACQ_EDISTAT", ACQ_EDISTAT},
|
||||
{"ACQ_HOURSTAT", ACQ_HOURSTAT},
|
||||
{"ACQ_DOWSTAT", ACQ_DOWSTAT},
|
||||
{"ACQ_QTRSTAT", ACQ_QTRSTAT},
|
||||
{"ACQ_GRADESTAT", ACQ_GRADESTAT},
|
||||
{"ACQ_HALFSTAT", ACQ_HALFSTAT},
|
||||
{"ACQ_BULKCHK", ACQ_BULKCHK},
|
||||
{"ACQ_BULKRPT", ACQ_BULKRPT},
|
||||
{"ACQ_EVENTBUY", ACQ_EVENTBUY},
|
||||
{"ACQ_PROMOQRY", ACQ_PROMOQRY},
|
||||
{"ACQ_PROMOSTAT", ACQ_PROMOSTAT},
|
||||
{"ACQ_LIMITEXC", ACQ_LIMITEXC},
|
||||
{"ACQ_LIMITOVR", ACQ_LIMITOVR},
|
||||
{"ACQ_SETTLEPRE", ACQ_SETTLEPRE},
|
||||
{"ACQ_SETTLEEXP", ACQ_SETTLEEXP},
|
||||
{"ACQ_EXCHANGE", ACQ_EXCHANGE},
|
||||
{"ACQ_RETURNQRY", ACQ_RETURNQRY},
|
||||
{"ACQ_RETURNSTAT", ACQ_RETURNSTAT},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
|||
19
app/src/ac/batch/ac_brand_batch.h
Normal file
19
app/src/ac/batch/ac_brand_batch.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ac_brand_batch.h - ac 배치 ac_brand_batch 카피북 (batch copybook / record header).
|
||||
* ac 발급사(브랜드)별 매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_BRAND_BATCH_H
|
||||
#define AC_BRAND_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long brands;
|
||||
long gross;
|
||||
} ac_brand_batch_rec_t;
|
||||
|
||||
#endif /* AC_BRAND_BATCH_H */
|
||||
35
app/src/ac/batch/ac_brand_batch.pgc
Normal file
35
app/src/ac/batch/ac_brand_batch.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ac_brand_batch.pgc - ac 발급사(브랜드)별 매입 집계 (단건 집계 배치, XA).
|
||||
* 영업일 매입을 발급사 기준으로 브랜드 종수와 총 매출을 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_brand_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_brand_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_brands, h_gross;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(distinct issuer), coalesce(sum(amount),0)
|
||||
INTO :h_brands, :h_gross FROM purchase WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_brand_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_brand_batch COMMIT: bizdate=%s brands=%ld gross=%ld\n", bizdate, h_brands, h_gross);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_ccyband_batch.h
Normal file
20
app/src/ac/batch/ac_ccyband_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_ccyband_batch.h - ac 배치 ac_ccyband_batch 카피북 (batch copybook / record header).
|
||||
* ac 통화별 해외매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_CCYBAND_BATCH_H
|
||||
#define AC_CCYBAND_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long ccys;
|
||||
long fx_amount;
|
||||
long krw_amount;
|
||||
} ac_ccyband_batch_rec_t;
|
||||
|
||||
#endif /* AC_CCYBAND_BATCH_H */
|
||||
35
app/src/ac/batch/ac_ccyband_batch.pgc
Normal file
35
app/src/ac/batch/ac_ccyband_batch.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ac_ccyband_batch.pgc - ac 통화별 해외매입 집계 (단건 집계 배치, XA).
|
||||
* 해외매입 원장에서 통화 종수와 원통화/원화 합계를 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_ccyband_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_ccyband_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_ccys, h_fx, h_krw;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(distinct ccy), coalesce(sum(fx_amount),0), coalesce(sum(krw_amount),0)
|
||||
INTO :h_ccys, :h_fx, :h_krw FROM ac_fx WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_ccyband_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_ccyband_batch COMMIT: bizdate=%s ccys=%ld fx=%ld krw=%ld\n", bizdate, h_ccys, h_fx, h_krw);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_country_batch.h
Normal file
20
app/src/ac/batch/ac_country_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_country_batch.h - ac 배치 ac_country_batch 카피북 (batch copybook / record header).
|
||||
* ac 국가(통화권역)별 해외매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_COUNTRY_BATCH_H
|
||||
#define AC_COUNTRY_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long us;
|
||||
long jp;
|
||||
long etc;
|
||||
} ac_country_batch_rec_t;
|
||||
|
||||
#endif /* AC_COUNTRY_BATCH_H */
|
||||
37
app/src/ac/batch/ac_country_batch.pgc
Normal file
37
app/src/ac/batch/ac_country_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ac_country_batch.pgc - ac 국가(통화권역)별 해외매입 집계 (단건 집계 배치, XA).
|
||||
* 해외매입 원화금액을 미주/일본/기타 권역 대표통화 기준으로 분해 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_country_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_country_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_us, h_jp, h_etc;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(krw_amount) FILTER (WHERE ccy IN ('USD','CAD')),0),
|
||||
coalesce(sum(krw_amount) FILTER (WHERE ccy = 'JPY'),0),
|
||||
coalesce(sum(krw_amount) FILTER (WHERE ccy NOT IN ('USD','CAD','JPY')),0)
|
||||
INTO :h_us, :h_jp, :h_etc FROM ac_fx WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_country_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_country_batch COMMIT: bizdate=%s us=%ld jp=%ld etc=%ld\n", bizdate, h_us, h_jp, h_etc);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_dow_batch.h
Normal file
20
app/src/ac/batch/ac_dow_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_dow_batch.h - ac 배치 ac_dow_batch 카피북 (batch copybook / record header).
|
||||
* ac 요일별 매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_DOW_BATCH_H
|
||||
#define AC_DOW_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long weekday;
|
||||
long weekend;
|
||||
long gross;
|
||||
} ac_dow_batch_rec_t;
|
||||
|
||||
#endif /* AC_DOW_BATCH_H */
|
||||
36
app/src/ac/batch/ac_dow_batch.pgc
Normal file
36
app/src/ac/batch/ac_dow_batch.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ac_dow_batch.pgc - ac 요일별 매입 집계 (단건 집계 배치, XA).
|
||||
* 영업일의 요일(dow)을 판정해 평일/주말 매입 건수와 매출을 분해 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_dow_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_dow_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_wd, h_we, h_gross;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE extract(dow from biz_date) BETWEEN 1 AND 5),
|
||||
count(*) FILTER (WHERE extract(dow from biz_date) IN (0, 6)), coalesce(sum(amount),0)
|
||||
INTO :h_wd, :h_we, :h_gross FROM purchase WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_dow_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_dow_batch COMMIT: bizdate=%s weekday=%ld weekend=%ld gross=%ld\n", bizdate, h_wd, h_we, h_gross);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_errtype_batch.h
Normal file
20
app/src/ac/batch/ac_errtype_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_errtype_batch.h - ac 배치 ac_errtype_batch 카피북 (batch copybook / record header).
|
||||
* ac 오류유형별 미매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_ERRTYPE_BATCH_H
|
||||
#define AC_ERRTYPE_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long dup;
|
||||
long limit;
|
||||
long fx;
|
||||
} ac_errtype_batch_rec_t;
|
||||
|
||||
#endif /* AC_ERRTYPE_BATCH_H */
|
||||
37
app/src/ac/batch/ac_errtype_batch.pgc
Normal file
37
app/src/ac/batch/ac_errtype_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ac_errtype_batch.pgc - ac 오류유형별 미매입 집계 (단건 집계 배치, XA).
|
||||
* 미매입 원장의 사유 접두어별로 중복/한도/환율 오류 건수를 분해 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_errtype_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_errtype_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_dup, h_lim, h_fx;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE reason LIKE 'DUP%'),
|
||||
count(*) FILTER (WHERE reason LIKE 'LIMIT%'),
|
||||
count(*) FILTER (WHERE reason LIKE 'FX%')
|
||||
INTO :h_dup, :h_lim, :h_fx FROM ac_unmatch WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_errtype_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_errtype_batch COMMIT: bizdate=%s dup=%ld limit=%ld fx=%ld\n", bizdate, h_dup, h_lim, h_fx);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_escrow_batch.h
Normal file
20
app/src/ac/batch/ac_escrow_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_escrow_batch.h - ac 배치 ac_escrow_batch 카피북 (batch copybook / record header).
|
||||
* ac 에스크로 잔액 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_ESCROW_BATCH_H
|
||||
#define AC_ESCROW_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long escrow;
|
||||
long release;
|
||||
long balance;
|
||||
} ac_escrow_batch_rec_t;
|
||||
|
||||
#endif /* AC_ESCROW_BATCH_H */
|
||||
37
app/src/ac/batch/ac_escrow_batch.pgc
Normal file
37
app/src/ac/batch/ac_escrow_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ac_escrow_batch.pgc - ac 에스크로 잔액 집계 (단건 집계 배치, XA).
|
||||
* 원장에서 예치(ESCROW)와 해제(ESCROW_REL) 합계를 구해 순 예치 잔액을 낸다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_escrow_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_escrow_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_esc, h_rel, h_bal;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount) FILTER (WHERE entry_type = 'ESCROW'),0),
|
||||
coalesce(sum(amount) FILTER (WHERE entry_type = 'ESCROW_REL'),0)
|
||||
INTO :h_esc, :h_rel FROM ledger WHERE biz_date = :h_bizdate;
|
||||
h_bal = h_esc - h_rel;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_escrow_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_escrow_batch COMMIT: bizdate=%s escrow=%ld release=%ld balance=%ld\n", bizdate, h_esc, h_rel, h_bal);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_exchange_batch.h
Normal file
20
app/src/ac/batch/ac_exchange_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_exchange_batch.h - ac 배치 ac_exchange_batch 카피북 (batch copybook / record header).
|
||||
* ac 반품/교환 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_EXCHANGE_BATCH_H
|
||||
#define AC_EXCHANGE_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long returns;
|
||||
long exchanges;
|
||||
long amount;
|
||||
} ac_exchange_batch_rec_t;
|
||||
|
||||
#endif /* AC_EXCHANGE_BATCH_H */
|
||||
37
app/src/ac/batch/ac_exchange_batch.pgc
Normal file
37
app/src/ac/batch/ac_exchange_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ac_exchange_batch.pgc - ac 반품/교환 집계 (단건 집계 배치, XA).
|
||||
* 취소 원장에서 반품(RETURN)/교환(EXCHANGE) 건수와 금액을 분해 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_exchange_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_exchange_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_ret, h_exc, h_amt;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE cancel_type = 'RETURN'),
|
||||
count(*) FILTER (WHERE cancel_type = 'EXCHANGE'),
|
||||
coalesce(sum(amount) FILTER (WHERE cancel_type IN ('RETURN','EXCHANGE')),0)
|
||||
INTO :h_ret, :h_exc, :h_amt FROM ac_cancel WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_exchange_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_exchange_batch COMMIT: bizdate=%s return=%ld exchange=%ld amount=%ld\n", bizdate, h_ret, h_exc, h_amt);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_grade_batch.h
Normal file
20
app/src/ac/batch/ac_grade_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_grade_batch.h - ac 배치 ac_grade_batch 카피북 (batch copybook / record header).
|
||||
* ac 가맹점등급별 매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_GRADE_BATCH_H
|
||||
#define AC_GRADE_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long premium;
|
||||
long std;
|
||||
long basic;
|
||||
} ac_grade_batch_rec_t;
|
||||
|
||||
#endif /* AC_GRADE_BATCH_H */
|
||||
38
app/src/ac/batch/ac_grade_batch.pgc
Normal file
38
app/src/ac/batch/ac_grade_batch.pgc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* ac_grade_batch.pgc - ac 가맹점등급별 매입 집계 (단건 집계 배치, XA).
|
||||
* 가맹점 MDR(bps)을 프리미엄(<=20)/일반/기본 등급으로 나눠 매출을 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_grade_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_grade_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_prem, h_std, h_basic;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(p.amount) FILTER (WHERE m.mdr_bps <= 20),0),
|
||||
coalesce(sum(p.amount) FILTER (WHERE m.mdr_bps BETWEEN 21 AND 28),0),
|
||||
coalesce(sum(p.amount) FILTER (WHERE m.mdr_bps > 28),0)
|
||||
INTO :h_prem, :h_std, :h_basic FROM purchase p
|
||||
JOIN merchant m ON m.merchant_id = p.merchant_id WHERE p.biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_grade_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_grade_batch COMMIT: bizdate=%s premium=%ld std=%ld basic=%ld\n", bizdate, h_prem, h_std, h_basic);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
19
app/src/ac/batch/ac_hourly_batch.h
Normal file
19
app/src/ac/batch/ac_hourly_batch.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* ac_hourly_batch.h - ac 배치 ac_hourly_batch 카피북 (batch copybook / record header).
|
||||
* ac 시간대별 매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_HOURLY_BATCH_H
|
||||
#define AC_HOURLY_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long day;
|
||||
long night;
|
||||
} ac_hourly_batch_rec_t;
|
||||
|
||||
#endif /* AC_HOURLY_BATCH_H */
|
||||
36
app/src/ac/batch/ac_hourly_batch.pgc
Normal file
36
app/src/ac/batch/ac_hourly_batch.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ac_hourly_batch.pgc - ac 시간대별 매입 집계 (단건 집계 배치, XA).
|
||||
* 접수시각을 주간(6~17시)/야간으로 나눠 시간대별 매입 건수를 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_hourly_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_hourly_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_day, h_night;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE extract(hour from created_at) BETWEEN 6 AND 17),
|
||||
count(*) FILTER (WHERE extract(hour from created_at) NOT BETWEEN 6 AND 17)
|
||||
INTO :h_day, :h_night FROM purchase WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_hourly_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_hourly_batch COMMIT: bizdate=%s day=%ld night=%ld\n", bizdate, h_day, h_night);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
21
app/src/ac/batch/ac_quarter_batch.h
Normal file
21
app/src/ac/batch/ac_quarter_batch.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* ac_quarter_batch.h - ac 배치 ac_quarter_batch 카피북 (batch copybook / record header).
|
||||
* ac 분기별 매입 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_QUARTER_BATCH_H
|
||||
#define AC_QUARTER_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long q1;
|
||||
long q2;
|
||||
long q3;
|
||||
long q4;
|
||||
} ac_quarter_batch_rec_t;
|
||||
|
||||
#endif /* AC_QUARTER_BATCH_H */
|
||||
40
app/src/ac/batch/ac_quarter_batch.pgc
Normal file
40
app/src/ac/batch/ac_quarter_batch.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* ac_quarter_batch.pgc - ac 분기별 매입 집계 (단건 집계 배치, XA).
|
||||
* 영업일이 속한 연도의 분기별 매출 합계를 한 번의 집계로 산출한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_quarter_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_quarter_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_q1, h_q2, h_q3, h_q4;
|
||||
int h_yr;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
h_yr = atoi(bizdate);
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount) FILTER (WHERE extract(quarter from biz_date) = 1),0),
|
||||
coalesce(sum(amount) FILTER (WHERE extract(quarter from biz_date) = 2),0),
|
||||
coalesce(sum(amount) FILTER (WHERE extract(quarter from biz_date) = 3),0),
|
||||
coalesce(sum(amount) FILTER (WHERE extract(quarter from biz_date) = 4),0)
|
||||
INTO :h_q1, :h_q2, :h_q3, :h_q4 FROM purchase WHERE extract(year from biz_date) = :h_yr;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_quarter_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_quarter_batch COMMIT: year=%d q1=%ld q2=%ld q3=%ld q4=%ld\n", h_yr, h_q1, h_q2, h_q3, h_q4);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
20
app/src/ac/batch/ac_rebuy_batch.h
Normal file
20
app/src/ac/batch/ac_rebuy_batch.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* ac_rebuy_batch.h - ac 배치 ac_rebuy_batch 카피북 (batch copybook / record header).
|
||||
* ac 재매입/취소 유형 집계 (단건 집계 배치, XA).
|
||||
*/
|
||||
#ifndef AC_REBUY_BATCH_H
|
||||
#define AC_REBUY_BATCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "ac_dbio.h"
|
||||
|
||||
typedef struct {
|
||||
long cb;
|
||||
long cb2;
|
||||
long refund;
|
||||
} ac_rebuy_batch_rec_t;
|
||||
|
||||
#endif /* AC_REBUY_BATCH_H */
|
||||
37
app/src/ac/batch/ac_rebuy_batch.pgc
Normal file
37
app/src/ac/batch/ac_rebuy_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ac_rebuy_batch.pgc - ac 재매입/취소 유형 집계 (단건 집계 배치, XA).
|
||||
* 취소 원장에서 지불거절(CB/CB2)과 환불(REFUND) 건수를 분해 집계한다.
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, aggregate(s) run on the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: ac_rebuy_batch [YYYY-MM-DD]
|
||||
*/
|
||||
EXEC SQL INCLUDE ac_rebuy_batch;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cb, h_cb2, h_rf;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE cancel_type = 'CB'),
|
||||
count(*) FILTER (WHERE cancel_type = 'CB2'),
|
||||
count(*) FILTER (WHERE cancel_type = 'REFUND')
|
||||
INTO :h_cb, :h_cb2, :h_rf FROM ac_cancel WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_rebuy_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> ac_rebuy_batch COMMIT: bizdate=%s cb=%ld cb2=%ld refund=%ld\n", bizdate, h_cb, h_cb2, h_rf);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ALERTAMT.h
Normal file
18
app/src/ac/svc/ACQ_ALERTAMT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ALERTAMT.h - ac 서비스 ACQ_ALERTAMT 카피북 (copybook / record header).
|
||||
* 매입 금액초과 알림: 가맹점의 영업일 매입 중 임계금액(T_AMOUNT)을 초과한
|
||||
*/
|
||||
#ifndef ACQ_ALERTAMT_H
|
||||
#define ACQ_ALERTAMT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long threshold;
|
||||
long over_count;
|
||||
long max_amount;
|
||||
} acq_alertamt_rec_t;
|
||||
|
||||
void ACQ_ALERTAMT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ALERTAMT_H */
|
||||
30
app/src/ac/svc/ACQ_ALERTAMT.pgc
Normal file
30
app/src/ac/svc/ACQ_ALERTAMT.pgc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* ACQ_ALERTAMT.pgc - ac 모듈 서비스 ACQ_ALERTAMT (one service = one file).
|
||||
* 매입 금액초과 알림: 가맹점의 영업일 매입 중 임계금액(T_AMOUNT)을 초과한
|
||||
* 고액 건수와 최고 매입액을 조회해 경보 여부를 판정한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ALERTAMT.h"
|
||||
|
||||
void ACQ_ALERTAMT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_lim, h_over = 0, h_max = 0;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_lim = getl(b, T_AMOUNT); if (h_lim <= 0) h_lim = 1000000;
|
||||
gets_(b, T_MERCHANT, h_merch, sizeof(h_merch));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE amount > :h_lim), coalesce(max(amount),0)
|
||||
INTO :h_over, :h_max FROM purchase
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_COUNT, h_over);
|
||||
setl(b, T_AMT1, h_max);
|
||||
setl(b, T_RC, h_over > 0 ? 1 : 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ALERTDUP.h
Normal file
18
app/src/ac/svc/ACQ_ALERTDUP.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ALERTDUP.h - ac 서비스 ACQ_ALERTDUP 카피북 (copybook / record header).
|
||||
* 매입 중복 알림: 가맹점의 영업일 매입 중 동일 금액이 2건 이상 반복된
|
||||
*/
|
||||
#ifndef ACQ_ALERTDUP_H
|
||||
#define ACQ_ALERTDUP_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant[64];
|
||||
long dup_groups;
|
||||
long rc;
|
||||
} acq_alertdup_rec_t;
|
||||
|
||||
void ACQ_ALERTDUP(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ALERTDUP_H */
|
||||
28
app/src/ac/svc/ACQ_ALERTDUP.pgc
Normal file
28
app/src/ac/svc/ACQ_ALERTDUP.pgc
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* ACQ_ALERTDUP.pgc - ac 모듈 서비스 ACQ_ALERTDUP (one service = one file).
|
||||
* 매입 중복 알림: 가맹점의 영업일 매입 중 동일 금액이 2건 이상 반복된
|
||||
* 금액 그룹 수를 세어 중복 의심 여부를 알린다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ALERTDUP.h"
|
||||
|
||||
void ACQ_ALERTDUP(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_grp = 0;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_MERCHANT, h_merch, sizeof(h_merch));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*) INTO :h_grp FROM (
|
||||
SELECT amount FROM purchase WHERE merchant_id = :h_merch
|
||||
AND biz_date = :h_bizdate GROUP BY amount HAVING count(*) > 1) d;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_COUNT, h_grp);
|
||||
setl(b, T_RC, h_grp > 0 ? 1 : 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ALERTQRY.h
Normal file
18
app/src/ac/svc/ACQ_ALERTQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ALERTQRY.h - ac 서비스 ACQ_ALERTQRY 카피북 (copybook / record header).
|
||||
* 매입 알림 유형별 조회: 미매입 원장을 알림 유형(속도/한도/중복) 접두어로
|
||||
*/
|
||||
#ifndef ACQ_ALERTQRY_H
|
||||
#define ACQ_ALERTQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long velocity;
|
||||
long limit;
|
||||
long dup;
|
||||
} acq_alertqry_rec_t;
|
||||
|
||||
void ACQ_ALERTQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ALERTQRY_H */
|
||||
30
app/src/ac/svc/ACQ_ALERTQRY.pgc
Normal file
30
app/src/ac/svc/ACQ_ALERTQRY.pgc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* ACQ_ALERTQRY.pgc - ac 모듈 서비스 ACQ_ALERTQRY (one service = one file).
|
||||
* 매입 알림 유형별 조회: 미매입 원장을 알림 유형(속도/한도/중복) 접두어로
|
||||
* 한 번에 분해 집계해 유형별 미해소 알림 건수를 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ALERTQRY.h"
|
||||
|
||||
void ACQ_ALERTQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_vel = 0, h_lim = 0, h_dup = 0;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE reason LIKE 'VEL%'),
|
||||
count(*) FILTER (WHERE reason LIKE 'LIMIT%'),
|
||||
count(*) FILTER (WHERE reason LIKE 'DUP%')
|
||||
INTO :h_vel, :h_lim, :h_dup FROM ac_unmatch WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_ARG1, h_vel);
|
||||
setl(b, T_ARG2, h_lim);
|
||||
setl(b, T_ARG3, h_dup);
|
||||
setl(b, T_COUNT, h_vel + h_lim + h_dup);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ALERTVEL.h
Normal file
18
app/src/ac/svc/ACQ_ALERTVEL.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ALERTVEL.h - ac 서비스 ACQ_ALERTVEL 카피북 (copybook / record header).
|
||||
* 매입 속도 알림: 채널의 최근 5분간 유입 건수를 재어 분당 허용치를 넘으면
|
||||
*/
|
||||
#ifndef ACQ_ALERTVEL_H
|
||||
#define ACQ_ALERTVEL_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char channel[16];
|
||||
long win5m;
|
||||
long win30m;
|
||||
} acq_alertvel_rec_t;
|
||||
|
||||
void ACQ_ALERTVEL(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ALERTVEL_H */
|
||||
30
app/src/ac/svc/ACQ_ALERTVEL.pgc
Normal file
30
app/src/ac/svc/ACQ_ALERTVEL.pgc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* ACQ_ALERTVEL.pgc - ac 모듈 서비스 ACQ_ALERTVEL (one service = one file).
|
||||
* 매입 속도 알림: 채널의 최근 5분간 유입 건수를 재어 분당 허용치를 넘으면
|
||||
* 경보한다. 참고로 직전 30분 건수도 함께 조회한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ALERTVEL.h"
|
||||
|
||||
void ACQ_ALERTVEL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long allow;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_5m = 0, h_30m = 0;
|
||||
char h_chan[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
allow = getl(b, T_ARG1); if (allow <= 0) allow = 50;
|
||||
gets_(b, T_CHANNEL, h_chan, sizeof(h_chan));
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE created_at >= now() - interval '5 minutes'),
|
||||
count(*) FILTER (WHERE created_at >= now() - interval '30 minutes')
|
||||
INTO :h_5m, :h_30m FROM purchase WHERE channel = :h_chan;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_ARG2, h_5m);
|
||||
setl(b, T_ARG3, h_30m);
|
||||
setl(b, T_RC, h_5m > allow ? 1 : 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_BRANDQRY.h
Normal file
18
app/src/ac/svc/ACQ_BRANDQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_BRANDQRY.h - ac 서비스 ACQ_BRANDQRY 카피북 (copybook / record header).
|
||||
* 매입 브랜드별 조회: 지정 발급사(T_ISSUER)의 영업일 매입 건수와 총액,
|
||||
*/
|
||||
#ifndef ACQ_BRANDQRY_H
|
||||
#define ACQ_BRANDQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char issuer[32];
|
||||
long count;
|
||||
long gross;
|
||||
} acq_brandqry_rec_t;
|
||||
|
||||
void ACQ_BRANDQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_BRANDQRY_H */
|
||||
30
app/src/ac/svc/ACQ_BRANDQRY.pgc
Normal file
30
app/src/ac/svc/ACQ_BRANDQRY.pgc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* ACQ_BRANDQRY.pgc - ac 모듈 서비스 ACQ_BRANDQRY (one service = one file).
|
||||
* 매입 브랜드별 조회: 지정 발급사(T_ISSUER)의 영업일 매입 건수와 총액,
|
||||
* 평균 수수료를 단건으로 조회해 응답 버퍼에 채운다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_BRANDQRY.h"
|
||||
|
||||
void ACQ_BRANDQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_n = 0, h_sum = 0, h_fee = 0;
|
||||
char h_iss[32], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_ISSUER, h_iss, sizeof(h_iss));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*), coalesce(sum(amount),0), coalesce(sum(fee),0)
|
||||
INTO :h_n, :h_sum, :h_fee FROM purchase
|
||||
WHERE issuer = :h_iss AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_COUNT, h_n);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
setl(b, T_FEE, h_fee);
|
||||
setl(b, T_RC, h_n > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_BRANDRANK.h
Normal file
18
app/src/ac/svc/ACQ_BRANDRANK.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_BRANDRANK.h - ac 서비스 ACQ_BRANDRANK 카피북 (copybook / record header).
|
||||
* 매입 브랜드별 순위: 발급사 매출 상위 순으로 커서 조회하며 누적 점유율을
|
||||
*/
|
||||
#ifndef ACQ_BRANDRANK_H
|
||||
#define ACQ_BRANDRANK_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char issuer[32];
|
||||
long grand;
|
||||
long half_at;
|
||||
} acq_brandrank_rec_t;
|
||||
|
||||
void ACQ_BRANDRANK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_BRANDRANK_H */
|
||||
42
app/src/ac/svc/ACQ_BRANDRANK.pgc
Normal file
42
app/src/ac/svc/ACQ_BRANDRANK.pgc
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* ACQ_BRANDRANK.pgc - ac 모듈 서비스 ACQ_BRANDRANK (one service = one file).
|
||||
* 매입 브랜드별 순위: 발급사 매출 상위 순으로 커서 조회하며 누적 점유율을
|
||||
* 계산해 상위 브랜드가 전체의 절반을 넘는 지점(집중도)을 함께 낸다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_BRANDRANK.h"
|
||||
|
||||
void ACQ_BRANDRANK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long rank = 0, run = 0, half_at = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_sum, h_grand = 0;
|
||||
char h_iss[32], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_grand FROM purchase WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
EXEC SQL DECLARE brr_cur CURSOR FOR
|
||||
SELECT issuer, sum(amount) FROM purchase WHERE biz_date = :h_bizdate
|
||||
GROUP BY issuer ORDER BY sum(amount) DESC;
|
||||
EXEC SQL OPEN brr_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH brr_cur INTO :h_iss, :h_sum;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE brr_cur; FAIL(b); }
|
||||
rank++; run += h_sum;
|
||||
if (half_at == 0 && h_grand > 0 && run * 2 >= h_grand) half_at = rank;
|
||||
if (rank <= 6) Badd(b, T_ISSUER, h_iss, 0L);
|
||||
}
|
||||
EXEC SQL CLOSE brr_cur;
|
||||
|
||||
setl(b, T_GROSS, h_grand);
|
||||
setl(b, T_ARG1, rank);
|
||||
setl(b, T_ARG2, half_at);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_BRANDSUM.h
Normal file
18
app/src/ac/svc/ACQ_BRANDSUM.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_BRANDSUM.h - ac 서비스 ACQ_BRANDSUM 카피북 (copybook / record header).
|
||||
* 매입 브랜드별 집계: 발급사(카드 브랜드) 기준으로 매출 합계를 그룹 집계해
|
||||
*/
|
||||
#ifndef ACQ_BRANDSUM_H
|
||||
#define ACQ_BRANDSUM_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char issuer[32];
|
||||
long amount;
|
||||
long kinds;
|
||||
} acq_brandsum_rec_t;
|
||||
|
||||
void ACQ_BRANDSUM(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_BRANDSUM_H */
|
||||
37
app/src/ac/svc/ACQ_BRANDSUM.pgc
Normal file
37
app/src/ac/svc/ACQ_BRANDSUM.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ACQ_BRANDSUM.pgc - ac 모듈 서비스 ACQ_BRANDSUM (one service = one file).
|
||||
* 매입 브랜드별 집계: 발급사(카드 브랜드) 기준으로 매출 합계를 그룹 집계해
|
||||
* 브랜드명·매출액 쌍을 occurrence 로 내리고 최다 브랜드 건수를 함께 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_BRANDSUM.h"
|
||||
|
||||
void ACQ_BRANDSUM(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long grand = 0, kinds = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_sum, h_n;
|
||||
char h_iss[32], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE brs_cur CURSOR FOR
|
||||
SELECT issuer, sum(amount), count(*) FROM purchase
|
||||
WHERE biz_date = :h_bizdate GROUP BY issuer ORDER BY sum(amount) DESC;
|
||||
EXEC SQL OPEN brs_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH brs_cur INTO :h_iss, :h_sum, :h_n;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE brs_cur; FAIL(b); }
|
||||
if (kinds < 8) { Badd(b, T_ISSUER, h_iss, 0L); Badd(b, T_AMT1, (char *)&h_sum, 0L); }
|
||||
grand += h_sum; kinds++;
|
||||
}
|
||||
EXEC SQL CLOSE brs_cur;
|
||||
|
||||
setl(b, T_GROSS, grand);
|
||||
setl(b, T_ARG1, kinds);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_BULKCHK.h
Normal file
18
app/src/ac/svc/ACQ_BULKCHK.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_BULKCHK.h - ac 서비스 ACQ_BULKCHK 카피북 (copybook / record header).
|
||||
* 대량매입 배치검증: 영업일 접수(A) 매입을 커서로 순회하며 금액 양수 및
|
||||
*/
|
||||
#ifndef ACQ_BULKCHK_H
|
||||
#define ACQ_BULKCHK_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long ok_count;
|
||||
long bad_count;
|
||||
long rc;
|
||||
} acq_bulkchk_rec_t;
|
||||
|
||||
void ACQ_BULKCHK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_BULKCHK_H */
|
||||
38
app/src/ac/svc/ACQ_BULKCHK.pgc
Normal file
38
app/src/ac/svc/ACQ_BULKCHK.pgc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* ACQ_BULKCHK.pgc - ac 모듈 서비스 ACQ_BULKCHK (one service = one file).
|
||||
* 대량매입 배치검증: 영업일 접수(A) 매입을 커서로 순회하며 금액 양수 및
|
||||
* 수수료 정합(net=amount-fee)을 점검해 정상/오류 건수를 분리 집계한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_BULKCHK.h"
|
||||
|
||||
void ACQ_BULKCHK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long ok = 0, bad = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_amt, h_fee, h_net;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE blk_cur CURSOR FOR
|
||||
SELECT purchase_id, amount, fee, net FROM purchase
|
||||
WHERE biz_date = :h_bizdate AND status = 'A';
|
||||
EXEC SQL OPEN blk_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH blk_cur INTO :h_pid, :h_amt, :h_fee, :h_net;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE blk_cur; FAIL(b); }
|
||||
if (h_amt > 0 && h_net == h_amt - h_fee) ok++;
|
||||
else { bad++; if (bad <= 8) Badd(b, T_PURCHASE_ID, (char *)&h_pid, 0L); }
|
||||
}
|
||||
EXEC SQL CLOSE blk_cur;
|
||||
|
||||
setl(b, T_ARG1, ok);
|
||||
setl(b, T_ARG2, bad);
|
||||
setl(b, T_RC, bad > 0 ? 1 : 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_BULKRPT.h
Normal file
18
app/src/ac/svc/ACQ_BULKRPT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_BULKRPT.h - ac 서비스 ACQ_BULKRPT 카피북 (copybook / record header).
|
||||
* 대량매입 리포트: 영업일 매입을 상태(접수/대사/정산/취소)별로 한 번에 분해
|
||||
*/
|
||||
#ifndef ACQ_BULKRPT_H
|
||||
#define ACQ_BULKRPT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long a;
|
||||
long m;
|
||||
long settled;
|
||||
} acq_bulkrpt_rec_t;
|
||||
|
||||
void ACQ_BULKRPT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_BULKRPT_H */
|
||||
32
app/src/ac/svc/ACQ_BULKRPT.pgc
Normal file
32
app/src/ac/svc/ACQ_BULKRPT.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ACQ_BULKRPT.pgc - ac 모듈 서비스 ACQ_BULKRPT (one service = one file).
|
||||
* 대량매입 리포트: 영업일 매입을 상태(접수/대사/정산/취소)별로 한 번에 분해
|
||||
* 집계해 상태별 건수와 총 매출·순정산 금액을 요약 리포트로 낸다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_BULKRPT.h"
|
||||
|
||||
void ACQ_BULKRPT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_a = 0, h_m = 0, h_s = 0, h_c = 0, h_g = 0, h_net = 0;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE status = 'A'), count(*) FILTER (WHERE status = 'M'),
|
||||
count(*) FILTER (WHERE status = 'S'), count(*) FILTER (WHERE status = 'C'),
|
||||
coalesce(sum(amount),0), coalesce(sum(net) FILTER (WHERE status = 'S'),0)
|
||||
INTO :h_a, :h_m, :h_s, :h_c, :h_g, :h_net FROM purchase WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_ARG1, h_a);
|
||||
setl(b, T_ARG2, h_m);
|
||||
setl(b, T_ARG3, h_s);
|
||||
setl(b, T_ARG4, h_c);
|
||||
setl(b, T_GROSS, h_g);
|
||||
setl(b, T_NET, h_net);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CB_ARB.h
Normal file
18
app/src/ac/svc/ACQ_CB_ARB.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CB_ARB.h - ac 서비스 ACQ_CB_ARB 카피북 (copybook / record header).
|
||||
* 지불거절 중재: 라운드2까지 미해결 건을 카드사 중재로 넘긴다. 해당 CB
|
||||
*/
|
||||
#ifndef ACQ_CB_ARB_H
|
||||
#define ACQ_CB_ARB_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long cancel_id;
|
||||
long purchase_id;
|
||||
long rc;
|
||||
} acq_cb_arb_rec_t;
|
||||
|
||||
void ACQ_CB_ARB(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CB_ARB_H */
|
||||
36
app/src/ac/svc/ACQ_CB_ARB.pgc
Normal file
36
app/src/ac/svc/ACQ_CB_ARB.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ACQ_CB_ARB.pgc - ac 모듈 서비스 ACQ_CB_ARB (one service = one file).
|
||||
* 지불거절 중재: 라운드2까지 미해결 건을 카드사 중재로 넘긴다. 해당 CB
|
||||
* 행 사유를 ARB 로 갱신하고 원매입을 보류(H)로 유지한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CB_ARB.h"
|
||||
|
||||
void ACQ_CB_ARB(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char note[80];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_cid, h_pid = 0;
|
||||
char h_reason[100];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_cid = getl(b, T_CANCEL_ID);
|
||||
gets_(b, T_REASON, note, sizeof(note));
|
||||
snprintf(h_reason, sizeof(h_reason), "ARB:%s", note[0] ? note : "PENDING");
|
||||
|
||||
EXEC SQL SELECT purchase_id INTO :h_pid FROM ac_cancel
|
||||
WHERE cancel_id = :h_cid AND cancel_type IN ('CB', 'CB2');
|
||||
if (sqlca.sqlcode == 100) { setl(b, T_RC, 4); FAIL(b); }
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
EXEC SQL UPDATE ac_cancel SET reason = :h_reason WHERE cancel_id = :h_cid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL UPDATE purchase SET status = 'H', updated_at = now()
|
||||
WHERE purchase_id = :h_pid AND status <> 'C';
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_CB_ARB FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_PURCHASE_ID, h_pid);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CB_FINAL.h
Normal file
18
app/src/ac/svc/ACQ_CB_FINAL.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CB_FINAL.h - ac 서비스 ACQ_CB_FINAL 카피북 (copybook / record header).
|
||||
* 지불거절 최종확정: 중재 결과로 매입사 패소가 확정되면 원매입을 취소(C)로
|
||||
*/
|
||||
#ifndef ACQ_CB_FINAL_H
|
||||
#define ACQ_CB_FINAL_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long affected;
|
||||
long rc;
|
||||
} acq_cb_final_rec_t;
|
||||
|
||||
void ACQ_CB_FINAL(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CB_FINAL_H */
|
||||
26
app/src/ac/svc/ACQ_CB_FINAL.pgc
Normal file
26
app/src/ac/svc/ACQ_CB_FINAL.pgc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* ACQ_CB_FINAL.pgc - ac 모듈 서비스 ACQ_CB_FINAL (one service = one file).
|
||||
* 지불거절 최종확정: 중재 결과로 매입사 패소가 확정되면 원매입을 취소(C)로
|
||||
* 확정 전이하고, 확정 여부(반영 건수)를 결과코드로 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CB_FINAL.h"
|
||||
|
||||
void ACQ_CB_FINAL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL UPDATE purchase SET status = 'C', updated_at = now()
|
||||
WHERE purchase_id = :h_pid AND status = 'H';
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_CB_FINAL FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
if (h_aff > 0) Bchg(b, T_STATUS, 0, "C", 0L);
|
||||
setl(b, T_COUNT, h_aff);
|
||||
setl(b, T_RC, h_aff > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CB_REVERSE.h
Normal file
18
app/src/ac/svc/ACQ_CB_REVERSE.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CB_REVERSE.h - ac 서비스 ACQ_CB_REVERSE 카피북 (copybook / record header).
|
||||
* 지불거절 역전: 방어 승소로 CB 를 무효화한다. 최근 CB/CB2 행을 조회해
|
||||
*/
|
||||
#ifndef ACQ_CB_REVERSE_H
|
||||
#define ACQ_CB_REVERSE_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long cancel_id;
|
||||
long restored;
|
||||
} acq_cb_reverse_rec_t;
|
||||
|
||||
void ACQ_CB_REVERSE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CB_REVERSE_H */
|
||||
33
app/src/ac/svc/ACQ_CB_REVERSE.pgc
Normal file
33
app/src/ac/svc/ACQ_CB_REVERSE.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* ACQ_CB_REVERSE.pgc - ac 모듈 서비스 ACQ_CB_REVERSE (one service = one file).
|
||||
* 지불거절 역전: 방어 승소로 CB 를 무효화한다. 최근 CB/CB2 행을 조회해
|
||||
* 취소 사유를 REVERSED 로 바꾸고 보류 원매입을 대사완료(M)로 복원한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CB_REVERSE.h"
|
||||
|
||||
void ACQ_CB_REVERSE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long restored;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_cid = 0, h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL SELECT max(cancel_id) INTO :h_cid FROM ac_cancel
|
||||
WHERE purchase_id = :h_pid AND cancel_type IN ('CB', 'CB2');
|
||||
if (sqlca.sqlcode < 0 || h_cid == 0) { setl(b, T_RC, 4); FAIL(b); }
|
||||
|
||||
EXEC SQL UPDATE ac_cancel SET reason = 'REVERSED' WHERE cancel_id = :h_cid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL UPDATE purchase SET status = 'M', updated_at = now()
|
||||
WHERE purchase_id = :h_pid AND status = 'H';
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_CB_REVERSE FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
restored = h_aff;
|
||||
setl(b, T_CANCEL_ID, h_cid);
|
||||
setl(b, T_RC, restored > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CB_RND2.h
Normal file
18
app/src/ac/svc/ACQ_CB_RND2.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CB_RND2.h - ac 서비스 ACQ_CB_RND2 카피북 (copybook / record header).
|
||||
* 지불거절 2차(라운드2): 1차 방어 이후 재청구를 접수한다. 원매입에 이미
|
||||
*/
|
||||
#ifndef ACQ_CB_RND2_H
|
||||
#define ACQ_CB_RND2_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long cancel_id;
|
||||
long prev_cb;
|
||||
} acq_cb_rnd2_rec_t;
|
||||
|
||||
void ACQ_CB_RND2(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CB_RND2_H */
|
||||
38
app/src/ac/svc/ACQ_CB_RND2.pgc
Normal file
38
app/src/ac/svc/ACQ_CB_RND2.pgc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* ACQ_CB_RND2.pgc - ac 모듈 서비스 ACQ_CB_RND2 (one service = one file).
|
||||
* 지불거절 2차(라운드2): 1차 방어 이후 재청구를 접수한다. 원매입에 이미
|
||||
* 1차 CB 이력이 있어야 하며, ac_cancel 에 CB2 유형 행을 추가한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CB_RND2.h"
|
||||
|
||||
void ACQ_CB_RND2(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char why[80];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_pid, h_amt, h_prev = 0;
|
||||
char h_reason[100], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
h_amt = getl(b, T_AMOUNT);
|
||||
gets_(b, T_REASON, why, sizeof(why));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*) INTO :h_prev FROM ac_cancel
|
||||
WHERE purchase_id = :h_pid AND cancel_type = 'CB';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_prev == 0) { setl(b, T_RC, 4); FAIL(b); }
|
||||
snprintf(h_reason, sizeof(h_reason), "CB2:%s", why[0] ? why : "REPRESENT");
|
||||
|
||||
EXEC SQL SELECT nextval('ac_cancel_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ac_cancel (cancel_id, purchase_id, cancel_type, amount, reason, biz_date)
|
||||
VALUES (:h_id, :h_pid, 'CB2', :h_amt, :h_reason, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_CB_RND2 FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_CANCEL_ID, h_id);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CCYQRY.h
Normal file
18
app/src/ac/svc/ACQ_CCYQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CCYQRY.h - ac 서비스 ACQ_CCYQRY 카피북 (copybook / record header).
|
||||
* 매입 통화별 조회: 지정 통화(T_CCY)의 원통화 합계와 원화 환산 합계를
|
||||
*/
|
||||
#ifndef ACQ_CCYQRY_H
|
||||
#define ACQ_CCYQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char ccy[8];
|
||||
long fx_amount;
|
||||
long krw_amount;
|
||||
} acq_ccyqry_rec_t;
|
||||
|
||||
void ACQ_CCYQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CCYQRY_H */
|
||||
29
app/src/ac/svc/ACQ_CCYQRY.pgc
Normal file
29
app/src/ac/svc/ACQ_CCYQRY.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* ACQ_CCYQRY.pgc - ac 모듈 서비스 ACQ_CCYQRY (one service = one file).
|
||||
* 매입 통화별 조회: 지정 통화(T_CCY)의 원통화 합계와 원화 환산 합계를
|
||||
* 해외매입 원장에서 조회해 환산차(원화-원통화)를 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CCYQRY.h"
|
||||
|
||||
void ACQ_CCYQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long diff;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_fx = 0, h_krw = 0;
|
||||
char h_ccy[8];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_CCY, h_ccy, sizeof(h_ccy));
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(fx_amount),0), coalesce(sum(krw_amount),0)
|
||||
INTO :h_fx, :h_krw FROM ac_fx WHERE ccy = :h_ccy;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
diff = h_krw - h_fx;
|
||||
setl(b, T_FX_AMT, h_fx);
|
||||
setl(b, T_GROSS, h_krw);
|
||||
setl(b, T_DELTA, diff);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CCYRANK.h
Normal file
18
app/src/ac/svc/ACQ_CCYRANK.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CCYRANK.h - ac 서비스 ACQ_CCYRANK 카피북 (copybook / record header).
|
||||
* 매입 통화별 순위: 해외매입 통화 그룹을 원화 합계 내림차순으로 커서 조회해
|
||||
*/
|
||||
#ifndef ACQ_CCYRANK_H
|
||||
#define ACQ_CCYRANK_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char top_ccy[8];
|
||||
long ranks;
|
||||
long krw;
|
||||
} acq_ccyrank_rec_t;
|
||||
|
||||
void ACQ_CCYRANK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CCYRANK_H */
|
||||
40
app/src/ac/svc/ACQ_CCYRANK.pgc
Normal file
40
app/src/ac/svc/ACQ_CCYRANK.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* ACQ_CCYRANK.pgc - ac 모듈 서비스 ACQ_CCYRANK (one service = one file).
|
||||
* 매입 통화별 순위: 해외매입 통화 그룹을 원화 합계 내림차순으로 커서 조회해
|
||||
* 상위 통화코드·원화액 쌍을 occurrence 로 내리고 1위 통화를 표시한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CCYRANK.h"
|
||||
|
||||
void ACQ_CCYRANK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long rank = 0;
|
||||
char top[8];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_krw;
|
||||
char h_ccy[8], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
top[0] = 0;
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE ccr_cur CURSOR FOR
|
||||
SELECT ccy, sum(krw_amount) FROM ac_fx WHERE biz_date = :h_bizdate
|
||||
GROUP BY ccy ORDER BY sum(krw_amount) DESC;
|
||||
EXEC SQL OPEN ccr_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH ccr_cur INTO :h_ccy, :h_krw;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE ccr_cur; FAIL(b); }
|
||||
if (rank == 0) { strncpy(top, h_ccy, sizeof(top)-1); top[sizeof(top)-1] = 0; }
|
||||
if (rank < 5) { Badd(b, T_CCY, h_ccy, 0L); Badd(b, T_AMT1, (char *)&h_krw, 0L); }
|
||||
rank++;
|
||||
}
|
||||
EXEC SQL CLOSE ccr_cur;
|
||||
|
||||
if (top[0]) Bchg(b, T_STR1, 0, top, 0L);
|
||||
setl(b, T_ARG1, rank);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CHANDETAIL.h
Normal file
18
app/src/ac/svc/ACQ_CHANDETAIL.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CHANDETAIL.h - ac 서비스 ACQ_CHANDETAIL 카피북 (copybook / record header).
|
||||
* 매입 채널별 상세 조회: 영업일 채널 그룹의 건수/총액/평균을 커서로 훑어
|
||||
*/
|
||||
#ifndef ACQ_CHANDETAIL_H
|
||||
#define ACQ_CHANDETAIL_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char channel[16];
|
||||
long avg_amount;
|
||||
long kinds;
|
||||
} acq_chandetail_rec_t;
|
||||
|
||||
void ACQ_CHANDETAIL(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CHANDETAIL_H */
|
||||
39
app/src/ac/svc/ACQ_CHANDETAIL.pgc
Normal file
39
app/src/ac/svc/ACQ_CHANDETAIL.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* ACQ_CHANDETAIL.pgc - ac 모듈 서비스 ACQ_CHANDETAIL (one service = one file).
|
||||
* 매입 채널별 상세 조회: 영업일 채널 그룹의 건수/총액/평균을 커서로 훑어
|
||||
* 채널명·평균단가 쌍을 occurrence 로 내리고 전체 평균을 함께 반환한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CHANDETAIL.h"
|
||||
|
||||
void ACQ_CHANDETAIL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long tot = 0, cnt = 0, kinds = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_n, h_sum, h_avg;
|
||||
char h_chan[16], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE chd_cur CURSOR FOR
|
||||
SELECT channel, count(*), sum(amount), avg(amount)::bigint FROM purchase
|
||||
WHERE biz_date = :h_bizdate AND status <> 'C' GROUP BY channel ORDER BY channel;
|
||||
EXEC SQL OPEN chd_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH chd_cur INTO :h_chan, :h_n, :h_sum, :h_avg;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE chd_cur; FAIL(b); }
|
||||
if (kinds < 8) { Badd(b, T_STR1, h_chan, 0L); Badd(b, T_AMT1, (char *)&h_avg, 0L); }
|
||||
tot += h_sum; cnt += h_n; kinds++;
|
||||
}
|
||||
EXEC SQL CLOSE chd_cur;
|
||||
|
||||
setl(b, T_GROSS, tot);
|
||||
setl(b, T_COUNT, cnt);
|
||||
setl(b, T_ARG1, kinds);
|
||||
setl(b, T_AMT2, cnt > 0 ? tot / cnt : 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CHANRANK.h
Normal file
18
app/src/ac/svc/ACQ_CHANRANK.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CHANRANK.h - ac 서비스 ACQ_CHANRANK 카피북 (copybook / record header).
|
||||
* 매입 채널별 순위: 영업일 채널을 건수 내림차순으로 정렬해 커서 조회하고
|
||||
*/
|
||||
#ifndef ACQ_CHANRANK_H
|
||||
#define ACQ_CHANRANK_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char busiest[16];
|
||||
long count;
|
||||
long ranks;
|
||||
} acq_chanrank_rec_t;
|
||||
|
||||
void ACQ_CHANRANK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CHANRANK_H */
|
||||
41
app/src/ac/svc/ACQ_CHANRANK.pgc
Normal file
41
app/src/ac/svc/ACQ_CHANRANK.pgc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* ACQ_CHANRANK.pgc - ac 모듈 서비스 ACQ_CHANRANK (one service = one file).
|
||||
* 매입 채널별 순위: 영업일 채널을 건수 내림차순으로 정렬해 커서 조회하고
|
||||
* 채널명·건수 쌍을 occurrence 로 내려 최다 유입 채널을 판별한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CHANRANK.h"
|
||||
|
||||
void ACQ_CHANRANK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long rank = 0, busiest = 0;
|
||||
char topchan[16];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_n;
|
||||
char h_chan[16], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
topchan[0] = 0;
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE chr_cur CURSOR FOR
|
||||
SELECT channel, count(*) FROM purchase WHERE biz_date = :h_bizdate
|
||||
GROUP BY channel ORDER BY count(*) DESC, channel;
|
||||
EXEC SQL OPEN chr_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH chr_cur INTO :h_chan, :h_n;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE chr_cur; FAIL(b); }
|
||||
if (rank == 0) { strncpy(topchan, h_chan, sizeof(topchan)-1); topchan[sizeof(topchan)-1] = 0; busiest = h_n; }
|
||||
if (rank < 6) { Badd(b, T_CHANNEL, h_chan, 0L); Badd(b, T_ARG3, (char *)&h_n, 0L); }
|
||||
rank++;
|
||||
}
|
||||
EXEC SQL CLOSE chr_cur;
|
||||
|
||||
if (topchan[0]) Bchg(b, T_STR2, 0, topchan, 0L);
|
||||
setl(b, T_COUNT, busiest);
|
||||
setl(b, T_ARG1, rank);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CORRAPPR.h
Normal file
18
app/src/ac/svc/ACQ_CORRAPPR.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CORRAPPR.h - ac 서비스 ACQ_CORRAPPR 카피북 (copybook / record header).
|
||||
* 매입 정정 승인: 접수된 조정(ac_fee_adj) 행의 사유 앞에 OK 승인 표식을
|
||||
*/
|
||||
#ifndef ACQ_CORRAPPR_H
|
||||
#define ACQ_CORRAPPR_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long adj_id;
|
||||
long affected;
|
||||
long rc;
|
||||
} acq_corrappr_rec_t;
|
||||
|
||||
void ACQ_CORRAPPR(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CORRAPPR_H */
|
||||
30
app/src/ac/svc/ACQ_CORRAPPR.pgc
Normal file
30
app/src/ac/svc/ACQ_CORRAPPR.pgc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* ACQ_CORRAPPR.pgc - ac 모듈 서비스 ACQ_CORRAPPR (one service = one file).
|
||||
* 매입 정정 승인: 접수된 조정(ac_fee_adj) 행의 사유 앞에 OK 승인 표식을
|
||||
* 덧대어 확정한다. 이미 승인된 건은 중복 승인하지 않는다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CORRAPPR.h"
|
||||
|
||||
void ACQ_CORRAPPR(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_aff;
|
||||
char h_reason[128];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_id = getl(b, T_ADJ);
|
||||
|
||||
EXEC SQL SELECT reason INTO :h_reason FROM ac_fee_adj WHERE adj_id = :h_id;
|
||||
if (sqlca.sqlcode == 100) { setl(b, T_RC, 5); FAIL(b); }
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (strncmp(h_reason, "OK:", 3) == 0) { setl(b, T_RC, 2); FAIL(b); }
|
||||
|
||||
EXEC SQL UPDATE ac_fee_adj SET reason = 'OK:' || reason WHERE adj_id = :h_id;
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_CORRAPPR FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
setl(b, T_ADJ, h_id);
|
||||
setl(b, T_RC, h_aff > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CORRRSN.h
Normal file
18
app/src/ac/svc/ACQ_CORRRSN.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CORRRSN.h - ac 서비스 ACQ_CORRRSN 카피북 (copybook / record header).
|
||||
* 매입 정정 사유별 처리: 수수료 조정 원장(ac_fee_adj)에 사유 코드가 붙은
|
||||
*/
|
||||
#ifndef ACQ_CORRRSN_H
|
||||
#define ACQ_CORRRSN_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long adj_id;
|
||||
long delta;
|
||||
} acq_corrrsn_rec_t;
|
||||
|
||||
void ACQ_CORRRSN(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CORRRSN_H */
|
||||
34
app/src/ac/svc/ACQ_CORRRSN.pgc
Normal file
34
app/src/ac/svc/ACQ_CORRRSN.pgc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* ACQ_CORRRSN.pgc - ac 모듈 서비스 ACQ_CORRRSN (one service = one file).
|
||||
* 매입 정정 사유별 처리: 수수료 조정 원장(ac_fee_adj)에 사유 코드가 붙은
|
||||
* 증감 행을 남긴다. 증감액(T_DELTA)과 사유(T_REASON)를 그대로 기록한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CORRRSN.h"
|
||||
|
||||
void ACQ_CORRRSN(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char why[80];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_pid, h_delta;
|
||||
char h_reason[100], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
h_delta = getl(b, T_DELTA);
|
||||
gets_(b, T_REASON, why, sizeof(why));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
if (h_delta == 0) { setl(b, T_RC, 3); FAIL(b); }
|
||||
snprintf(h_reason, sizeof(h_reason), "CORR:%s", why[0] ? why : "MISC");
|
||||
|
||||
EXEC SQL SELECT nextval('ac_feeadj_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ac_fee_adj (adj_id, purchase_id, delta, reason, biz_date)
|
||||
VALUES (:h_id, :h_pid, :h_delta, :h_reason, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_CORRRSN FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_ADJ, h_id);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CORRSTAT.h
Normal file
18
app/src/ac/svc/ACQ_CORRSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CORRSTAT.h - ac 서비스 ACQ_CORRSTAT 카피북 (copybook / record header).
|
||||
* 매입 정정 사유별 통계: 조정 원장을 사유 접두어별로 그룹 집계해 사유코드·
|
||||
*/
|
||||
#ifndef ACQ_CORRSTAT_H
|
||||
#define ACQ_CORRSTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char reason[64];
|
||||
long net;
|
||||
long kinds;
|
||||
} acq_corrstat_rec_t;
|
||||
|
||||
void ACQ_CORRSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CORRSTAT_H */
|
||||
37
app/src/ac/svc/ACQ_CORRSTAT.pgc
Normal file
37
app/src/ac/svc/ACQ_CORRSTAT.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ACQ_CORRSTAT.pgc - ac 모듈 서비스 ACQ_CORRSTAT (one service = one file).
|
||||
* 매입 정정 사유별 통계: 조정 원장을 사유 접두어별로 그룹 집계해 사유코드·
|
||||
* 증감합계 쌍을 occurrence 로 내리고 순증감 총액을 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CORRSTAT.h"
|
||||
|
||||
void ACQ_CORRSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long net = 0, kinds = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_sum;
|
||||
char h_reason[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE crs_cur CURSOR FOR
|
||||
SELECT split_part(reason, ':', 1), sum(delta) FROM ac_fee_adj
|
||||
WHERE biz_date = :h_bizdate GROUP BY split_part(reason, ':', 1) ORDER BY 1;
|
||||
EXEC SQL OPEN crs_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH crs_cur INTO :h_reason, :h_sum;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE crs_cur; FAIL(b); }
|
||||
if (kinds < 8) { Badd(b, T_REASON, h_reason, 0L); Badd(b, T_DELTA, (char *)&h_sum, 0L); }
|
||||
net += h_sum; kinds++;
|
||||
}
|
||||
EXEC SQL CLOSE crs_cur;
|
||||
|
||||
setl(b, T_GROSS, net);
|
||||
setl(b, T_ARG1, kinds);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CTRYQRY.h
Normal file
18
app/src/ac/svc/ACQ_CTRYQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CTRYQRY.h - ac 서비스 ACQ_CTRYQRY 카피북 (copybook / record header).
|
||||
* 매입 국가별 조회: 통화권역 대표 통화(T_CCY)로 해외매입(ac_fx)을 필터해
|
||||
*/
|
||||
#ifndef ACQ_CTRYQRY_H
|
||||
#define ACQ_CTRYQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char ccy[8];
|
||||
long krw;
|
||||
long rate_bps;
|
||||
} acq_ctryqry_rec_t;
|
||||
|
||||
void ACQ_CTRYQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CTRYQRY_H */
|
||||
29
app/src/ac/svc/ACQ_CTRYQRY.pgc
Normal file
29
app/src/ac/svc/ACQ_CTRYQRY.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* ACQ_CTRYQRY.pgc - ac 모듈 서비스 ACQ_CTRYQRY (one service = one file).
|
||||
* 매입 국가별 조회: 통화권역 대표 통화(T_CCY)로 해외매입(ac_fx)을 필터해
|
||||
* 권역 원화 합계와 건수를 조회하고 평균 환율(bps)을 함께 낸다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CTRYQRY.h"
|
||||
|
||||
void ACQ_CTRYQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_n = 0, h_krw = 0, h_rate = 0;
|
||||
char h_ccy[8], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_CCY, h_ccy, sizeof(h_ccy));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*), coalesce(sum(krw_amount),0), coalesce(avg(rate_bps),0)::bigint
|
||||
INTO :h_n, :h_krw, :h_rate FROM ac_fx
|
||||
WHERE ccy = :h_ccy AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_COUNT, h_n);
|
||||
setl(b, T_GROSS, h_krw);
|
||||
setl(b, T_ARG1, h_rate);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_CTRYRANK.h
Normal file
18
app/src/ac/svc/ACQ_CTRYRANK.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_CTRYRANK.h - ac 서비스 ACQ_CTRYRANK 카피북 (copybook / record header).
|
||||
* 매입 국가별 순위: 통화코드를 권역(미주/일본/유럽/기타)으로 분류하는 C
|
||||
*/
|
||||
#ifndef ACQ_CTRYRANK_H
|
||||
#define ACQ_CTRYRANK_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long buckets[4];
|
||||
long best;
|
||||
long rc;
|
||||
} acq_ctryrank_rec_t;
|
||||
|
||||
void ACQ_CTRYRANK(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_CTRYRANK_H */
|
||||
49
app/src/ac/svc/ACQ_CTRYRANK.pgc
Normal file
49
app/src/ac/svc/ACQ_CTRYRANK.pgc
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* ACQ_CTRYRANK.pgc - ac 모듈 서비스 ACQ_CTRYRANK (one service = one file).
|
||||
* 매입 국가별 순위: 통화코드를 권역(미주/일본/유럽/기타)으로 분류하는 C
|
||||
* 분류기로 원화 합계를 권역 버킷에 모아 최대 권역 인덱스를 판정한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_CTRYRANK.h"
|
||||
|
||||
/* 통화 → 권역 인덱스 (0=미주 1=일본 2=유럽 3=기타) */
|
||||
static int ac_region(const char *c)
|
||||
{
|
||||
if (strcmp(c, "USD") == 0 || strcmp(c, "CAD") == 0) return 0;
|
||||
if (strcmp(c, "JPY") == 0) return 1;
|
||||
if (strcmp(c, "EUR") == 0 || strcmp(c, "GBP") == 0) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
void ACQ_CTRYRANK(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long bucket[4] = {0, 0, 0, 0};
|
||||
int i, best = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_krw;
|
||||
char h_ccy[8], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE ctr_rk CURSOR FOR
|
||||
SELECT ccy, sum(krw_amount) FROM ac_fx WHERE biz_date = :h_bizdate GROUP BY ccy;
|
||||
EXEC SQL OPEN ctr_rk;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH ctr_rk INTO :h_ccy, :h_krw;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE ctr_rk; FAIL(b); }
|
||||
bucket[ac_region(h_ccy)] += h_krw;
|
||||
}
|
||||
EXEC SQL CLOSE ctr_rk;
|
||||
|
||||
for (i = 1; i < 4; i++) if (bucket[i] > bucket[best]) best = i;
|
||||
setl(b, T_ARG1, bucket[0]);
|
||||
setl(b, T_ARG2, bucket[1]);
|
||||
setl(b, T_ARG3, bucket[2]);
|
||||
setl(b, T_ARG4, bucket[3]);
|
||||
setl(b, T_RC, best);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_DOWSTAT.h
Normal file
18
app/src/ac/svc/ACQ_DOWSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_DOWSTAT.h - ac 서비스 ACQ_DOWSTAT 카피북 (copybook / record header).
|
||||
* 매입 요일별 통계: 지정 기간(T_STR1~T_STR2)의 매입을 요일(0~6)별로 그룹
|
||||
*/
|
||||
#ifndef ACQ_DOWSTAT_H
|
||||
#define ACQ_DOWSTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long total;
|
||||
long weekend;
|
||||
long rc;
|
||||
} acq_dowstat_rec_t;
|
||||
|
||||
void ACQ_DOWSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_DOWSTAT_H */
|
||||
41
app/src/ac/svc/ACQ_DOWSTAT.pgc
Normal file
41
app/src/ac/svc/ACQ_DOWSTAT.pgc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* ACQ_DOWSTAT.pgc - ac 모듈 서비스 ACQ_DOWSTAT (one service = one file).
|
||||
* 매입 요일별 통계: 지정 기간(T_STR1~T_STR2)의 매입을 요일(0~6)별로 그룹
|
||||
* 집계해 요일번호·건수 쌍을 occurrence 로 내리고 주말 비중을 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_DOWSTAT.h"
|
||||
|
||||
void ACQ_DOWSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long total = 0, weekend = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_dow, h_n;
|
||||
char h_from[16], h_to[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_STR1, h_from, sizeof(h_from));
|
||||
gets_(b, T_STR2, h_to, sizeof(h_to));
|
||||
|
||||
EXEC SQL DECLARE dow_cur CURSOR FOR
|
||||
SELECT extract(dow from biz_date)::int, count(*) FROM purchase
|
||||
WHERE biz_date BETWEEN :h_from AND :h_to GROUP BY 1 ORDER BY 1;
|
||||
EXEC SQL OPEN dow_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH dow_cur INTO :h_dow, :h_n;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE dow_cur; FAIL(b); }
|
||||
Badd(b, T_ARG5, (char *)&h_dow, 0L);
|
||||
Badd(b, T_ARG6, (char *)&h_n, 0L);
|
||||
total += h_n;
|
||||
if (h_dow == 0 || h_dow == 6) weekend += h_n;
|
||||
}
|
||||
EXEC SQL CLOSE dow_cur;
|
||||
|
||||
setl(b, T_COUNT, total);
|
||||
setl(b, T_ARG1, weekend);
|
||||
setl(b, T_RC, total > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_EDIQRY.h
Normal file
18
app/src/ac/svc/ACQ_EDIQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_EDIQRY.h - ac 서비스 ACQ_EDIQRY 카피북 (copybook / record header).
|
||||
* EDI 조회: 지정 가맹점(T_MERCHANT)의 영업일 EDI 접수 문서 건수와 금액
|
||||
*/
|
||||
#ifndef ACQ_EDIQRY_H
|
||||
#define ACQ_EDIQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant[64];
|
||||
long count;
|
||||
long sum;
|
||||
} acq_ediqry_rec_t;
|
||||
|
||||
void ACQ_EDIQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_EDIQRY_H */
|
||||
28
app/src/ac/svc/ACQ_EDIQRY.pgc
Normal file
28
app/src/ac/svc/ACQ_EDIQRY.pgc
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* ACQ_EDIQRY.pgc - ac 모듈 서비스 ACQ_EDIQRY (one service = one file).
|
||||
* EDI 조회: 지정 가맹점(T_MERCHANT)의 영업일 EDI 접수 문서 건수와 금액
|
||||
* 합계를 조회해 응답한다. 접수분이 없으면 결과코드 1.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_EDIQRY.h"
|
||||
|
||||
void ACQ_EDIQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_n = 0, h_sum = 0;
|
||||
char h_merch[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_MERCHANT, h_merch, sizeof(h_merch));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*), coalesce(sum(amount),0) INTO :h_n, :h_sum
|
||||
FROM ac_edi WHERE merchant_id = :h_merch AND biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_COUNT, h_n);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
setl(b, T_RC, h_n > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_EDIRSNDCH.h
Normal file
18
app/src/ac/svc/ACQ_EDIRSNDCH.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_EDIRSNDCH.h - ac 서비스 ACQ_EDIRSNDCH 카피북 (copybook / record header).
|
||||
* EDI 재전송 채널별: 영업일 미수신 EDI 문서를 가맹점별로 커서 조회해
|
||||
*/
|
||||
#ifndef ACQ_EDIRSNDCH_H
|
||||
#define ACQ_EDIRSNDCH_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char doc_no[32];
|
||||
long count;
|
||||
long total;
|
||||
} acq_edirsndch_rec_t;
|
||||
|
||||
void ACQ_EDIRSNDCH(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_EDIRSNDCH_H */
|
||||
37
app/src/ac/svc/ACQ_EDIRSNDCH.pgc
Normal file
37
app/src/ac/svc/ACQ_EDIRSNDCH.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ACQ_EDIRSNDCH.pgc - ac 모듈 서비스 ACQ_EDIRSNDCH (one service = one file).
|
||||
* EDI 재전송 채널별: 영업일 미수신 EDI 문서를 가맹점별로 커서 조회해
|
||||
* 문서번호·금액 쌍을 occurrence 로 내리고 재전송 대상 건수를 집계한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_EDIRSNDCH.h"
|
||||
|
||||
void ACQ_EDIRSNDCH(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long n = 0, tot = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_amt;
|
||||
char h_doc[32], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE edr_cur CURSOR FOR
|
||||
SELECT doc_no, amount FROM ac_edi WHERE biz_date = :h_bizdate ORDER BY doc_no;
|
||||
EXEC SQL OPEN edr_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH edr_cur INTO :h_doc, :h_amt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE edr_cur; FAIL(b); }
|
||||
if (n < 8) { Badd(b, T_DOCNO, h_doc, 0L); Badd(b, T_AMT1, (char *)&h_amt, 0L); }
|
||||
n++; tot += h_amt;
|
||||
}
|
||||
EXEC SQL CLOSE edr_cur;
|
||||
|
||||
setl(b, T_COUNT, n);
|
||||
setl(b, T_GROSS, tot);
|
||||
setl(b, T_RC, n > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_EDISTAT.h
Normal file
18
app/src/ac/svc/ACQ_EDISTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_EDISTAT.h - ac 서비스 ACQ_EDISTAT 카피북 (copybook / record header).
|
||||
* EDI 통계: 영업일 EDI 문서를 금액대(소액/중액/고액)로 나눠 대역별 건수를
|
||||
*/
|
||||
#ifndef ACQ_EDISTAT_H
|
||||
#define ACQ_EDISTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long lo;
|
||||
long mid;
|
||||
long hi;
|
||||
} acq_edistat_rec_t;
|
||||
|
||||
void ACQ_EDISTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_EDISTAT_H */
|
||||
30
app/src/ac/svc/ACQ_EDISTAT.pgc
Normal file
30
app/src/ac/svc/ACQ_EDISTAT.pgc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* ACQ_EDISTAT.pgc - ac 모듈 서비스 ACQ_EDISTAT (one service = one file).
|
||||
* EDI 통계: 영업일 EDI 문서를 금액대(소액/중액/고액)로 나눠 대역별 건수를
|
||||
* 한 번의 집계에서 산출하고 전체 문서 금액 합계를 함께 낸다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_EDISTAT.h"
|
||||
|
||||
void ACQ_EDISTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_lo = 0, h_mid = 0, h_hi = 0, h_sum = 0;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE amount < 100000),
|
||||
count(*) FILTER (WHERE amount >= 100000 AND amount < 1000000),
|
||||
count(*) FILTER (WHERE amount >= 1000000), coalesce(sum(amount),0)
|
||||
INTO :h_lo, :h_mid, :h_hi, :h_sum FROM ac_edi WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_ARG1, h_lo);
|
||||
setl(b, T_ARG2, h_mid);
|
||||
setl(b, T_ARG3, h_hi);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ERRCLASS.h
Normal file
18
app/src/ac/svc/ACQ_ERRCLASS.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ERRCLASS.h - ac 서비스 ACQ_ERRCLASS 카피북 (copybook / record header).
|
||||
* 매입 오류유형별 분류: 미매입 원장(ac_unmatch)의 사유 접두어를 읽어
|
||||
*/
|
||||
#ifndef ACQ_ERRCLASS_H
|
||||
#define ACQ_ERRCLASS_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long classes[4];
|
||||
long count;
|
||||
long rc;
|
||||
} acq_errclass_rec_t;
|
||||
|
||||
void ACQ_ERRCLASS(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ERRCLASS_H */
|
||||
46
app/src/ac/svc/ACQ_ERRCLASS.pgc
Normal file
46
app/src/ac/svc/ACQ_ERRCLASS.pgc
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* ACQ_ERRCLASS.pgc - ac 모듈 서비스 ACQ_ERRCLASS (one service = one file).
|
||||
* 매입 오류유형별 분류: 미매입 원장(ac_unmatch)의 사유 접두어를 읽어
|
||||
* 중복/한도/환율/기타 4개 오류군으로 분류하고 군별 건수를 집계한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ERRCLASS.h"
|
||||
|
||||
/* 사유 접두어 → 오류군 (0=중복 1=한도 2=환율 3=기타) */
|
||||
static int ac_errkind(const char *r)
|
||||
{
|
||||
if (strncmp(r, "DUP", 3) == 0) return 0;
|
||||
if (strncmp(r, "LIMIT", 5) == 0) return 1;
|
||||
if (strncmp(r, "FX", 2) == 0) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
void ACQ_ERRCLASS(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long cls[4] = {0, 0, 0, 0};
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_reason[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE erc_cur CURSOR FOR
|
||||
SELECT reason FROM ac_unmatch WHERE biz_date = :h_bizdate;
|
||||
EXEC SQL OPEN erc_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH erc_cur INTO :h_reason;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE erc_cur; FAIL(b); }
|
||||
cls[ac_errkind(h_reason)]++;
|
||||
}
|
||||
EXEC SQL CLOSE erc_cur;
|
||||
|
||||
setl(b, T_ARG1, cls[0]);
|
||||
setl(b, T_ARG2, cls[1]);
|
||||
setl(b, T_ARG3, cls[2]);
|
||||
setl(b, T_ARG4, cls[3]);
|
||||
setl(b, T_COUNT, cls[0] + cls[1] + cls[2] + cls[3]);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ERRQRY.h
Normal file
18
app/src/ac/svc/ACQ_ERRQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ERRQRY.h - ac 서비스 ACQ_ERRQRY 카피북 (copybook / record header).
|
||||
* 매입 오류유형별 조회: 사유 접두어(T_REASON)로 시작하는 미매입 건을
|
||||
*/
|
||||
#ifndef ACQ_ERRQRY_H
|
||||
#define ACQ_ERRQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char pattern[64];
|
||||
long count;
|
||||
long rc;
|
||||
} acq_errqry_rec_t;
|
||||
|
||||
void ACQ_ERRQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ERRQRY_H */
|
||||
28
app/src/ac/svc/ACQ_ERRQRY.pgc
Normal file
28
app/src/ac/svc/ACQ_ERRQRY.pgc
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* ACQ_ERRQRY.pgc - ac 모듈 서비스 ACQ_ERRQRY (one service = one file).
|
||||
* 매입 오류유형별 조회: 사유 접두어(T_REASON)로 시작하는 미매입 건을
|
||||
* 패턴 조회해 해당 오류유형의 건수를 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ERRQRY.h"
|
||||
|
||||
void ACQ_ERRQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char pat[64];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_n = 0;
|
||||
char h_like[70];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_REASON, pat, sizeof(pat));
|
||||
if (pat[0] == 0) strcpy(pat, "DUP");
|
||||
snprintf(h_like, sizeof(h_like), "%s%%", pat);
|
||||
|
||||
EXEC SQL SELECT count(*) INTO :h_n FROM ac_unmatch WHERE reason LIKE :h_like;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_COUNT, h_n);
|
||||
setl(b, T_RC, h_n > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ERRRETRY.h
Normal file
18
app/src/ac/svc/ACQ_ERRRETRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ERRRETRY.h - ac 서비스 ACQ_ERRRETRY 카피북 (copybook / record header).
|
||||
* 매입 오류 재처리: 보류(H) 상태로 묶여 있던 오류 매입을 접수(A)로 되돌려
|
||||
*/
|
||||
#ifndef ACQ_ERRRETRY_H
|
||||
#define ACQ_ERRRETRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long affected;
|
||||
long rc;
|
||||
} acq_errretry_rec_t;
|
||||
|
||||
void ACQ_ERRRETRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ERRRETRY_H */
|
||||
25
app/src/ac/svc/ACQ_ERRRETRY.pgc
Normal file
25
app/src/ac/svc/ACQ_ERRRETRY.pgc
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* ACQ_ERRRETRY.pgc - ac 모듈 서비스 ACQ_ERRRETRY (one service = one file).
|
||||
* 매입 오류 재처리: 보류(H) 상태로 묶여 있던 오류 매입을 접수(A)로 되돌려
|
||||
* 재처리 큐에 태우고 반영 건수를 결과코드로 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ERRRETRY.h"
|
||||
|
||||
void ACQ_ERRRETRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL UPDATE purchase SET status = 'A', updated_at = now()
|
||||
WHERE purchase_id = :h_pid AND status = 'H';
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_ERRRETRY FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
if (h_aff > 0) Bchg(b, T_STATUS, 0, "A", 0L);
|
||||
setl(b, T_RC, h_aff > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ERRSTAT.h
Normal file
18
app/src/ac/svc/ACQ_ERRSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ERRSTAT.h - ac 서비스 ACQ_ERRSTAT 카피북 (copybook / record header).
|
||||
* 매입 오류유형별 통계: 미매입 원장을 사유 접두어 기준으로 한 번의 집계에서
|
||||
*/
|
||||
#ifndef ACQ_ERRSTAT_H
|
||||
#define ACQ_ERRSTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long dup;
|
||||
long limit;
|
||||
long fx;
|
||||
} acq_errstat_rec_t;
|
||||
|
||||
void ACQ_ERRSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ERRSTAT_H */
|
||||
30
app/src/ac/svc/ACQ_ERRSTAT.pgc
Normal file
30
app/src/ac/svc/ACQ_ERRSTAT.pgc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* ACQ_ERRSTAT.pgc - ac 모듈 서비스 ACQ_ERRSTAT (one service = one file).
|
||||
* 매입 오류유형별 통계: 미매입 원장을 사유 접두어 기준으로 한 번의 집계에서
|
||||
* 중복/한도/환율 오류 건수를 FILTER 로 분해해 동시에 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ERRSTAT.h"
|
||||
|
||||
void ACQ_ERRSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_dup = 0, h_lim = 0, h_fx = 0, h_all = 0;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT count(*) FILTER (WHERE reason LIKE 'DUP%'),
|
||||
count(*) FILTER (WHERE reason LIKE 'LIMIT%'),
|
||||
count(*) FILTER (WHERE reason LIKE 'FX%'), count(*)
|
||||
INTO :h_dup, :h_lim, :h_fx, :h_all FROM ac_unmatch WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_ARG1, h_dup);
|
||||
setl(b, T_ARG2, h_lim);
|
||||
setl(b, T_ARG3, h_fx);
|
||||
setl(b, T_COUNT, h_all);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ESCROW.h
Normal file
18
app/src/ac/svc/ACQ_ESCROW.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ESCROW.h - ac 서비스 ACQ_ESCROW 카피북 (copybook / record header).
|
||||
* 매입 에스크로 예치: 분쟁 소지 매입 금액을 정산 전 유보하기 위해 원장에
|
||||
*/
|
||||
#ifndef ACQ_ESCROW_H
|
||||
#define ACQ_ESCROW_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long ledger_id;
|
||||
long amount;
|
||||
} acq_escrow_rec_t;
|
||||
|
||||
void ACQ_ESCROW(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ESCROW_H */
|
||||
31
app/src/ac/svc/ACQ_ESCROW.pgc
Normal file
31
app/src/ac/svc/ACQ_ESCROW.pgc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* ACQ_ESCROW.pgc - ac 모듈 서비스 ACQ_ESCROW (one service = one file).
|
||||
* 매입 에스크로 예치: 분쟁 소지 매입 금액을 정산 전 유보하기 위해 원장에
|
||||
* ESCROW 항목으로 예치액을 적립한다. 금액이 0 이하면 거절.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ESCROW.h"
|
||||
|
||||
void ACQ_ESCROW(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_amt, h_lid;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
h_amt = getl(b, T_AMOUNT);
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
if (h_amt <= 0) { setl(b, T_RC, 3); FAIL(b); }
|
||||
|
||||
EXEC SQL SELECT nextval('ledger_seq') INTO :h_lid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (:h_lid, :h_pid, 'ESCROW', :h_amt, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_ESCROW FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_SETTLE_ID, h_lid);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_ESCROWREL.h
Normal file
18
app/src/ac/svc/ACQ_ESCROWREL.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_ESCROWREL.h - ac 서비스 ACQ_ESCROWREL 카피북 (copybook / record header).
|
||||
* 매입 에스크로 해제: 예치(ESCROW)와 해제(ESCROW_REL) 원장 잔액을 계산해
|
||||
*/
|
||||
#ifndef ACQ_ESCROWREL_H
|
||||
#define ACQ_ESCROWREL_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long balance;
|
||||
long rc;
|
||||
} acq_escrowrel_rec_t;
|
||||
|
||||
void ACQ_ESCROWREL(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_ESCROWREL_H */
|
||||
36
app/src/ac/svc/ACQ_ESCROWREL.pgc
Normal file
36
app/src/ac/svc/ACQ_ESCROWREL.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ACQ_ESCROWREL.pgc - ac 모듈 서비스 ACQ_ESCROWREL (one service = one file).
|
||||
* 매입 에스크로 해제: 예치(ESCROW)와 해제(ESCROW_REL) 원장 잔액을 계산해
|
||||
* 잔여 예치금을 해제 항목으로 전액 반제하고 잔액을 0 으로 만든다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_ESCROWREL.h"
|
||||
|
||||
void ACQ_ESCROWREL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_esc = 0, h_rel = 0, h_lid, h_bal;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount) FILTER (WHERE entry_type = 'ESCROW'),0),
|
||||
coalesce(sum(amount) FILTER (WHERE entry_type = 'ESCROW_REL'),0)
|
||||
INTO :h_esc, :h_rel FROM ledger WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
h_bal = h_esc - h_rel;
|
||||
if (h_bal <= 0) { setl(b, T_GROSS, 0); setl(b, T_RC, 1); OK(b); }
|
||||
|
||||
EXEC SQL SELECT nextval('ledger_seq') INTO :h_lid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (:h_lid, :h_pid, 'ESCROW_REL', :h_bal, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_ESCROWREL FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_GROSS, h_bal);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_EVENTBUY.h
Normal file
18
app/src/ac/svc/ACQ_EVENTBUY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_EVENTBUY.h - ac 서비스 ACQ_EVENTBUY 카피북 (copybook / record header).
|
||||
* 이벤트 매입: 프로모션 행사 매입을 EVENT 채널로 접수한다. 활성 가맹점만
|
||||
*/
|
||||
#ifndef ACQ_EVENTBUY_H
|
||||
#define ACQ_EVENTBUY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long fee;
|
||||
long net;
|
||||
} acq_eventbuy_rec_t;
|
||||
|
||||
void ACQ_EVENTBUY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_EVENTBUY_H */
|
||||
41
app/src/ac/svc/ACQ_EVENTBUY.pgc
Normal file
41
app/src/ac/svc/ACQ_EVENTBUY.pgc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* ACQ_EVENTBUY.pgc - ac 모듈 서비스 ACQ_EVENTBUY (one service = one file).
|
||||
* 이벤트 매입: 프로모션 행사 매입을 EVENT 채널로 접수한다. 활성 가맹점만
|
||||
* 허용하며 이벤트 할인율(T_ARG1, bps)만큼 수수료를 감면해 net 을 올린다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_EVENTBUY.h"
|
||||
|
||||
void ACQ_EVENTBUY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long fee, disc;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_amt, h_bps = 0, h_disc, h_fee, h_net;
|
||||
char h_merch[64], h_mst[16], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_amt = getl(b, T_AMOUNT);
|
||||
disc = getl(b, T_ARG1); if (disc < 0) disc = 0;
|
||||
gets_(b, T_MERCHANT, h_merch, sizeof(h_merch));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
if (h_amt <= 0) { setl(b, T_RC, 3); FAIL(b); }
|
||||
|
||||
EXEC SQL SELECT status, mdr_bps INTO :h_mst, :h_bps FROM merchant WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode == 100) { setl(b, T_RC, 5); FAIL(b); }
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (strcmp(h_mst, "ACTIVE") != 0) { setl(b, T_RC, 6); FAIL(b); }
|
||||
h_disc = (h_bps > disc) ? h_bps - disc : 0;
|
||||
fee = h_amt * h_disc / 10000; h_fee = fee; h_net = h_amt - fee;
|
||||
|
||||
EXEC SQL SELECT nextval('purchase_seq') INTO :h_pid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO purchase (purchase_id, merchant_id, amount, fee, net, status, biz_date, channel, category)
|
||||
VALUES (:h_pid, :h_merch, :h_amt, :h_fee, :h_net, 'A', :h_bizdate, 'EVENT', 'PROMO');
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_EVENTBUY FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_PURCHASE_ID, h_pid);
|
||||
setl(b, T_FEE, h_fee);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_EXCHANGE.h
Normal file
18
app/src/ac/svc/ACQ_EXCHANGE.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_EXCHANGE.h - ac 서비스 ACQ_EXCHANGE 카피북 (copybook / record header).
|
||||
* 매입 교환 처리: 반품 후 동일가 재구매를 한 번에 처리한다. 원매입에 대해
|
||||
*/
|
||||
#ifndef ACQ_EXCHANGE_H
|
||||
#define ACQ_EXCHANGE_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long cancel_id;
|
||||
long amount;
|
||||
} acq_exchange_rec_t;
|
||||
|
||||
void ACQ_EXCHANGE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_EXCHANGE_H */
|
||||
38
app/src/ac/svc/ACQ_EXCHANGE.pgc
Normal file
38
app/src/ac/svc/ACQ_EXCHANGE.pgc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* ACQ_EXCHANGE.pgc - ac 모듈 서비스 ACQ_EXCHANGE (one service = one file).
|
||||
* 매입 교환 처리: 반품 후 동일가 재구매를 한 번에 처리한다. 원매입에 대해
|
||||
* EXCHANGE 취소 행을 남기고 원매입 상태를 대사완료(M)로 유지한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_EXCHANGE.h"
|
||||
|
||||
void ACQ_EXCHANGE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
char why[80];
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_pid, h_amt, h_orig = 0;
|
||||
char h_reason[100], h_st[4], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
h_amt = getl(b, T_AMOUNT);
|
||||
gets_(b, T_REASON, why, sizeof(why));
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT status, amount INTO :h_st, :h_orig FROM purchase WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode == 100) { setl(b, T_RC, 5); FAIL(b); }
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_amt <= 0 || h_amt > h_orig) { setl(b, T_RC, 3); FAIL(b); }
|
||||
snprintf(h_reason, sizeof(h_reason), "EXCHANGE:%s", why[0] ? why : "SWAP");
|
||||
|
||||
EXEC SQL SELECT nextval('ac_cancel_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ac_cancel (cancel_id, purchase_id, cancel_type, amount, reason, biz_date)
|
||||
VALUES (:h_id, :h_pid, 'EXCHANGE', :h_amt, :h_reason, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_EXCHANGE FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_CANCEL_ID, h_id);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_GRADESTAT.h
Normal file
18
app/src/ac/svc/ACQ_GRADESTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_GRADESTAT.h - ac 서비스 ACQ_GRADESTAT 카피북 (copybook / record header).
|
||||
* 매입 가맹점등급별 통계: 가맹점 MDR(bps)을 프리미엄/일반/기본 등급으로 나눠
|
||||
*/
|
||||
#ifndef ACQ_GRADESTAT_H
|
||||
#define ACQ_GRADESTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long grades[3];
|
||||
long gross;
|
||||
long rc;
|
||||
} acq_gradestat_rec_t;
|
||||
|
||||
void ACQ_GRADESTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_GRADESTAT_H */
|
||||
47
app/src/ac/svc/ACQ_GRADESTAT.pgc
Normal file
47
app/src/ac/svc/ACQ_GRADESTAT.pgc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* ACQ_GRADESTAT.pgc - ac 모듈 서비스 ACQ_GRADESTAT (one service = one file).
|
||||
* 매입 가맹점등급별 통계: 가맹점 MDR(bps)을 프리미엄/일반/기본 등급으로 나눠
|
||||
* 등급별 매출 합계를 버킷 집계한다. 등급 경계는 C 분류기로 판정한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_GRADESTAT.h"
|
||||
|
||||
/* MDR(bps) → 등급 (0=프리미엄 1=일반 2=기본) */
|
||||
static int ac_grade(long bps)
|
||||
{
|
||||
if (bps <= 20) return 0;
|
||||
if (bps <= 28) return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
void ACQ_GRADESTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long g[3] = {0, 0, 0};
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_bps, h_sum;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE grd_cur CURSOR FOR
|
||||
SELECT m.mdr_bps, coalesce(sum(p.amount),0) FROM merchant m
|
||||
JOIN purchase p ON p.merchant_id = m.merchant_id AND p.biz_date = :h_bizdate
|
||||
GROUP BY m.merchant_id, m.mdr_bps;
|
||||
EXEC SQL OPEN grd_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH grd_cur INTO :h_bps, :h_sum;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE grd_cur; FAIL(b); }
|
||||
g[ac_grade(h_bps)] += h_sum;
|
||||
}
|
||||
EXEC SQL CLOSE grd_cur;
|
||||
|
||||
setl(b, T_ARG1, g[0]);
|
||||
setl(b, T_ARG2, g[1]);
|
||||
setl(b, T_ARG3, g[2]);
|
||||
setl(b, T_GROSS, g[0] + g[1] + g[2]);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_GUARANTEE.h
Normal file
18
app/src/ac/svc/ACQ_GUARANTEE.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_GUARANTEE.h - ac 서비스 ACQ_GUARANTEE 카피북 (copybook / record header).
|
||||
* 매입 보증 등록: 대형 매입에 대한 이행보증금을 원장에 GUARANTEE 항목으로
|
||||
*/
|
||||
#ifndef ACQ_GUARANTEE_H
|
||||
#define ACQ_GUARANTEE_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long guarantee;
|
||||
long ledger_id;
|
||||
} acq_guarantee_rec_t;
|
||||
|
||||
void ACQ_GUARANTEE(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_GUARANTEE_H */
|
||||
34
app/src/ac/svc/ACQ_GUARANTEE.pgc
Normal file
34
app/src/ac/svc/ACQ_GUARANTEE.pgc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* ACQ_GUARANTEE.pgc - ac 모듈 서비스 ACQ_GUARANTEE (one service = one file).
|
||||
* 매입 보증 등록: 대형 매입에 대한 이행보증금을 원장에 GUARANTEE 항목으로
|
||||
* 적립한다. 보증률(T_ARG1, bps)로 보증금을 산출하며 기본 10%.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_GUARANTEE.h"
|
||||
|
||||
void ACQ_GUARANTEE(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_amt, h_bps, h_lid, h_guar;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
h_amt = getl(b, T_AMOUNT);
|
||||
h_bps = getl(b, T_ARG1); if (h_bps <= 0) h_bps = 1000;
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
h_guar = h_amt * h_bps / 10000;
|
||||
if (h_guar <= 0) { setl(b, T_RC, 3); FAIL(b); }
|
||||
|
||||
EXEC SQL SELECT nextval('ledger_seq') INTO :h_lid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
|
||||
VALUES (:h_lid, :h_pid, 'GUARANTEE', :h_guar, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_GUARANTEE FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_AMT1, h_guar);
|
||||
setl(b, T_SETTLE_ID, h_lid);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_GUARQRY.h
Normal file
18
app/src/ac/svc/ACQ_GUARQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_GUARQRY.h - ac 서비스 ACQ_GUARQRY 카피북 (copybook / record header).
|
||||
* 매입 보증 조회: 한 매입에 적립된 보증금(GUARANTEE) 총액과 건수를 원장에서
|
||||
*/
|
||||
#ifndef ACQ_GUARQRY_H
|
||||
#define ACQ_GUARQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long guarantee;
|
||||
long count;
|
||||
} acq_guarqry_rec_t;
|
||||
|
||||
void ACQ_GUARQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_GUARQRY_H */
|
||||
26
app/src/ac/svc/ACQ_GUARQRY.pgc
Normal file
26
app/src/ac/svc/ACQ_GUARQRY.pgc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* ACQ_GUARQRY.pgc - ac 모듈 서비스 ACQ_GUARQRY (one service = one file).
|
||||
* 매입 보증 조회: 한 매입에 적립된 보증금(GUARANTEE) 총액과 건수를 원장에서
|
||||
* 조회해 응답한다. 보증 이력이 없으면 결과코드 1.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_GUARQRY.h"
|
||||
|
||||
void ACQ_GUARQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_sum = 0, h_n = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount),0), count(*) INTO :h_sum, :h_n
|
||||
FROM ledger WHERE purchase_id = :h_pid AND entry_type = 'GUARANTEE';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_AMT1, h_sum);
|
||||
setl(b, T_COUNT, h_n);
|
||||
setl(b, T_RC, h_n > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_HALFSTAT.h
Normal file
18
app/src/ac/svc/ACQ_HALFSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_HALFSTAT.h - ac 서비스 ACQ_HALFSTAT 카피북 (copybook / record header).
|
||||
* 매입 반기별 통계: 지정 연도(T_ARG1) 매입을 상반기(1~6월)/하반기(7~12월)로
|
||||
*/
|
||||
#ifndef ACQ_HALFSTAT_H
|
||||
#define ACQ_HALFSTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long h1;
|
||||
long h2;
|
||||
long share;
|
||||
} acq_halfstat_rec_t;
|
||||
|
||||
void ACQ_HALFSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_HALFSTAT_H */
|
||||
32
app/src/ac/svc/ACQ_HALFSTAT.pgc
Normal file
32
app/src/ac/svc/ACQ_HALFSTAT.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ACQ_HALFSTAT.pgc - ac 모듈 서비스 ACQ_HALFSTAT (one service = one file).
|
||||
* 매입 반기별 통계: 지정 연도(T_ARG1) 매입을 상반기(1~6월)/하반기(7~12월)로
|
||||
* 나눠 반기별 매출과 건수를 산출하고 상반기 비중을 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_HALFSTAT.h"
|
||||
|
||||
void ACQ_HALFSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long share = 0, total;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_h1 = 0, h_h2 = 0, h_n = 0;
|
||||
int h_yr;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_yr = (int)getl(b, T_ARG1); if (h_yr < 2000) h_yr = 2026;
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(amount) FILTER (WHERE extract(month from biz_date) <= 6),0),
|
||||
coalesce(sum(amount) FILTER (WHERE extract(month from biz_date) > 6),0), count(*)
|
||||
INTO :h_h1, :h_h2, :h_n FROM purchase WHERE extract(year from biz_date) = :h_yr;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
total = h_h1 + h_h2;
|
||||
if (total > 0) share = h_h1 * 100 / total;
|
||||
|
||||
setl(b, T_ARG2, h_h1);
|
||||
setl(b, T_ARG3, h_h2);
|
||||
setl(b, T_COUNT, h_n);
|
||||
setl(b, T_RC, share);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_HOURSTAT.h
Normal file
18
app/src/ac/svc/ACQ_HOURSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_HOURSTAT.h - ac 서비스 ACQ_HOURSTAT 카피북 (copybook / record header).
|
||||
* 매입 시간대별 통계: 접수시각을 새벽/오전/오후/야간 네 구간으로 나눠 구간별
|
||||
*/
|
||||
#ifndef ACQ_HOURSTAT_H
|
||||
#define ACQ_HOURSTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long bands[4];
|
||||
long peak;
|
||||
long rc;
|
||||
} acq_hourstat_rec_t;
|
||||
|
||||
void ACQ_HOURSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_HOURSTAT_H */
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue