규모확장 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
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 */
|
||||
35
app/src/ac/svc/ACQ_HOURSTAT.pgc
Normal file
35
app/src/ac/svc/ACQ_HOURSTAT.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ACQ_HOURSTAT.pgc - ac 모듈 서비스 ACQ_HOURSTAT (one service = one file).
|
||||
* 매입 시간대별 통계: 접수시각을 새벽/오전/오후/야간 네 구간으로 나눠 구간별
|
||||
* 매입 건수를 한 번의 집계로 분해하고 피크 구간 인덱스를 판정한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_HOURSTAT.h"
|
||||
|
||||
void ACQ_HOURSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long v[4]; int i, peak = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_d = 0, h_m = 0, h_a = 0, h_n = 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 extract(hour from created_at) < 6),
|
||||
count(*) FILTER (WHERE extract(hour from created_at) BETWEEN 6 AND 11),
|
||||
count(*) FILTER (WHERE extract(hour from created_at) BETWEEN 12 AND 17),
|
||||
count(*) FILTER (WHERE extract(hour from created_at) >= 18)
|
||||
INTO :h_d, :h_m, :h_a, :h_n FROM purchase WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
v[0] = h_d; v[1] = h_m; v[2] = h_a; v[3] = h_n;
|
||||
for (i = 1; i < 4; i++) if (v[i] > v[peak]) peak = i;
|
||||
setl(b, T_ARG1, h_d);
|
||||
setl(b, T_ARG2, h_m);
|
||||
setl(b, T_ARG3, h_a);
|
||||
setl(b, T_ARG4, h_n);
|
||||
setl(b, T_RC, peak);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_INSTCXL.h
Normal file
18
app/src/ac/svc/ACQ_INSTCXL.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_INSTCXL.h - ac 서비스 ACQ_INSTCXL 카피북 (copybook / record header).
|
||||
* 할부 취소: 한 매입의 할부 스케줄 전 회차를 원장에서 삭제해 할부를 해지한다.
|
||||
*/
|
||||
#ifndef ACQ_INSTCXL_H
|
||||
#define ACQ_INSTCXL_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long deleted;
|
||||
long rc;
|
||||
} acq_instcxl_rec_t;
|
||||
|
||||
void ACQ_INSTCXL(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_INSTCXL_H */
|
||||
24
app/src/ac/svc/ACQ_INSTCXL.pgc
Normal file
24
app/src/ac/svc/ACQ_INSTCXL.pgc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* ACQ_INSTCXL.pgc - ac 모듈 서비스 ACQ_INSTCXL (one service = one file).
|
||||
* 할부 취소: 한 매입의 할부 스케줄 전 회차를 원장에서 삭제해 할부를 해지한다.
|
||||
* 삭제된 회차수를 건수로 응답하며, 없으면 결과코드 1.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_INSTCXL.h"
|
||||
|
||||
void ACQ_INSTCXL(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_del;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL DELETE FROM ac_install WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_INSTCXL FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
h_del = sqlca.sqlerrd[2];
|
||||
setl(b, T_COUNT, h_del);
|
||||
setl(b, T_RC, h_del > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_INSTPLAN.h
Normal file
18
app/src/ac/svc/ACQ_INSTPLAN.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_INSTPLAN.h - ac 서비스 ACQ_INSTPLAN 카피북 (copybook / record header).
|
||||
* 할부 계획 조회: 한 매입의 약정 개월수와 회차 합계, 회차당 금액을 단건
|
||||
*/
|
||||
#ifndef ACQ_INSTPLAN_H
|
||||
#define ACQ_INSTPLAN_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long months;
|
||||
long total;
|
||||
} acq_instplan_rec_t;
|
||||
|
||||
void ACQ_INSTPLAN(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_INSTPLAN_H */
|
||||
28
app/src/ac/svc/ACQ_INSTPLAN.pgc
Normal file
28
app/src/ac/svc/ACQ_INSTPLAN.pgc
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* ACQ_INSTPLAN.pgc - ac 모듈 서비스 ACQ_INSTPLAN (one service = one file).
|
||||
* 할부 계획 조회: 한 매입의 약정 개월수와 회차 합계, 회차당 금액을 단건
|
||||
* 조회해 계획 개요를 응답한다. 할부가 없으면 결과코드 1.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_INSTPLAN.h"
|
||||
|
||||
void ACQ_INSTPLAN(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_months = 0, h_sum = 0, h_first = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL SELECT coalesce(max(months),0), coalesce(sum(month_amount),0),
|
||||
coalesce(min(month_amount),0)
|
||||
INTO :h_months, :h_sum, :h_first FROM ac_install WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
|
||||
setl(b, T_INSTALL_N, h_months);
|
||||
setl(b, T_GROSS, h_sum);
|
||||
setl(b, T_AMT1, h_first);
|
||||
setl(b, T_RC, h_months > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_INSTPREPAY.h
Normal file
18
app/src/ac/svc/ACQ_INSTPREPAY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_INSTPREPAY.h - ac 서비스 ACQ_INSTPREPAY 카피북 (copybook / record header).
|
||||
* 할부 조기상환: 지정 회차(T_ARG1) 이후 남은 할부금 합계를 계산해 원장에
|
||||
*/
|
||||
#ifndef ACQ_INSTPREPAY_H
|
||||
#define ACQ_INSTPREPAY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long remaining;
|
||||
long count;
|
||||
} acq_instprepay_rec_t;
|
||||
|
||||
void ACQ_INSTPREPAY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_INSTPREPAY_H */
|
||||
36
app/src/ac/svc/ACQ_INSTPREPAY.pgc
Normal file
36
app/src/ac/svc/ACQ_INSTPREPAY.pgc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ACQ_INSTPREPAY.pgc - ac 모듈 서비스 ACQ_INSTPREPAY (one service = one file).
|
||||
* 할부 조기상환: 지정 회차(T_ARG1) 이후 남은 할부금 합계를 계산해 원장에
|
||||
* PREPAY 항목으로 선지급을 기록하고 잔여 회차수를 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_INSTPREPAY.h"
|
||||
|
||||
void ACQ_INSTPREPAY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_from, h_left = 0, h_cnt = 0, h_lid;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
h_from = getl(b, T_ARG1);
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL SELECT coalesce(sum(month_amount),0), count(*) INTO :h_left, :h_cnt
|
||||
FROM ac_install WHERE purchase_id = :h_pid AND seq_no > :h_from;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
if (h_cnt == 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, 'PREPAY', :h_left, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_INSTPREPAY FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_GROSS, h_left);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_INSTQRY.h
Normal file
18
app/src/ac/svc/ACQ_INSTQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_INSTQRY.h - ac 서비스 ACQ_INSTQRY 카피북 (copybook / record header).
|
||||
* 할부 회차조회: 한 매입의 할부 스케줄(ac_install)을 회차 순으로 커서 조회해
|
||||
*/
|
||||
#ifndef ACQ_INSTQRY_H
|
||||
#define ACQ_INSTQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long months;
|
||||
long total;
|
||||
} acq_instqry_rec_t;
|
||||
|
||||
void ACQ_INSTQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_INSTQRY_H */
|
||||
38
app/src/ac/svc/ACQ_INSTQRY.pgc
Normal file
38
app/src/ac/svc/ACQ_INSTQRY.pgc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* ACQ_INSTQRY.pgc - ac 모듈 서비스 ACQ_INSTQRY (one service = one file).
|
||||
* 할부 회차조회: 한 매입의 할부 스케줄(ac_install)을 회차 순으로 커서 조회해
|
||||
* 회차·회차금액 쌍을 occurrence 로 내리고 총 회차수와 합계를 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_INSTQRY.h"
|
||||
|
||||
void ACQ_INSTQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long n = 0, tot = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_seq, h_mamt;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL DECLARE isq_cur CURSOR FOR
|
||||
SELECT seq_no, month_amount FROM ac_install WHERE purchase_id = :h_pid
|
||||
ORDER BY seq_no;
|
||||
EXEC SQL OPEN isq_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH isq_cur INTO :h_seq, :h_mamt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE isq_cur; FAIL(b); }
|
||||
Badd(b, T_ARG5, (char *)&h_seq, 0L);
|
||||
Badd(b, T_AMT1, (char *)&h_mamt, 0L);
|
||||
n++; tot += h_mamt;
|
||||
}
|
||||
EXEC SQL CLOSE isq_cur;
|
||||
|
||||
setl(b, T_INSTALL_N, n);
|
||||
setl(b, T_GROSS, tot);
|
||||
setl(b, T_RC, n > 0 ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_LIMITEXC.h
Normal file
18
app/src/ac/svc/ACQ_LIMITEXC.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_LIMITEXC.h - ac 서비스 ACQ_LIMITEXC 카피북 (copybook / record header).
|
||||
* 매입 한도 예외처리: 가맹점 일한도와 당일 누적 매입을 비교해 한도 초과 시
|
||||
*/
|
||||
#ifndef ACQ_LIMITEXC_H
|
||||
#define ACQ_LIMITEXC_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char merchant[64];
|
||||
long room;
|
||||
long rc;
|
||||
} acq_limitexc_rec_t;
|
||||
|
||||
void ACQ_LIMITEXC(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_LIMITEXC_H */
|
||||
40
app/src/ac/svc/ACQ_LIMITEXC.pgc
Normal file
40
app/src/ac/svc/ACQ_LIMITEXC.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* ACQ_LIMITEXC.pgc - ac 모듈 서비스 ACQ_LIMITEXC (one service = one file).
|
||||
* 매입 한도 예외처리: 가맹점 일한도와 당일 누적 매입을 비교해 한도 초과 시
|
||||
* 미매입 원장에 LIMIT_EXC 예외를 기록하고, 여유 한도를 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_LIMITEXC.h"
|
||||
|
||||
void ACQ_LIMITEXC(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long room;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id, h_lim = 0, h_used = 0;
|
||||
char h_merch[64], h_bizdate[16], h_reason[64];
|
||||
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 daily_limit INTO :h_lim FROM merchant WHERE merchant_id = :h_merch;
|
||||
if (sqlca.sqlcode == 100) { setl(b, T_RC, 5); FAIL(b); }
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_used FROM purchase
|
||||
WHERE merchant_id = :h_merch AND biz_date = :h_bizdate AND status <> 'C';
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
room = h_lim - h_used;
|
||||
if (room >= 0) { setl(b, T_DELTA, room); setl(b, T_RC, 0); OK(b); }
|
||||
|
||||
snprintf(h_reason, sizeof(h_reason), "LIMIT_EXC:%ld", -room);
|
||||
EXEC SQL SELECT nextval('ac_unmatch_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO ac_unmatch (unmatch_id, purchase_id, reason, biz_date)
|
||||
VALUES (:h_id, 0, :h_reason, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_LIMITEXC FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_DELTA, room);
|
||||
setl(b, T_RC, 1);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_LIMITOVR.h
Normal file
18
app/src/ac/svc/ACQ_LIMITOVR.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_LIMITOVR.h - ac 서비스 ACQ_LIMITOVR 카피북 (copybook / record header).
|
||||
* 매입 한도 초과 승인: 한도 초과로 보류(H)된 매입을 관리자가 예외 승인해
|
||||
*/
|
||||
#ifndef ACQ_LIMITOVR_H
|
||||
#define ACQ_LIMITOVR_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long affected;
|
||||
long rc;
|
||||
} acq_limitovr_rec_t;
|
||||
|
||||
void ACQ_LIMITOVR(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_LIMITOVR_H */
|
||||
26
app/src/ac/svc/ACQ_LIMITOVR.pgc
Normal file
26
app/src/ac/svc/ACQ_LIMITOVR.pgc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* ACQ_LIMITOVR.pgc - ac 모듈 서비스 ACQ_LIMITOVR (one service = one file).
|
||||
* 매입 한도 초과 승인: 한도 초과로 보류(H)된 매입을 관리자가 예외 승인해
|
||||
* 접수(A)로 되살린다. 승인 표식(net 유지)만 남기고 반영 건수를 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_LIMITOVR.h"
|
||||
|
||||
void ACQ_LIMITOVR(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' AND channel <> 'RSV';
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_LIMITOVR 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_COUNT, h_aff);
|
||||
setl(b, T_RC, h_aff > 0 ? 0 : 2);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_PROMOQRY.h
Normal file
18
app/src/ac/svc/ACQ_PROMOQRY.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_PROMOQRY.h - ac 서비스 ACQ_PROMOQRY 카피북 (copybook / record header).
|
||||
* 프로모션 조회: 영업일 프로모션(category=PROMO) 매입의 건수와 매출, 감면
|
||||
*/
|
||||
#ifndef ACQ_PROMOQRY_H
|
||||
#define ACQ_PROMOQRY_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long count;
|
||||
long gross;
|
||||
long fee;
|
||||
} acq_promoqry_rec_t;
|
||||
|
||||
void ACQ_PROMOQRY(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_PROMOQRY_H */
|
||||
29
app/src/ac/svc/ACQ_PROMOQRY.pgc
Normal file
29
app/src/ac/svc/ACQ_PROMOQRY.pgc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* ACQ_PROMOQRY.pgc - ac 모듈 서비스 ACQ_PROMOQRY (one service = one file).
|
||||
* 프로모션 조회: 영업일 프로모션(category=PROMO) 매입의 건수와 매출, 감면
|
||||
* 수수료 합계를 조회해 행사 성과를 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_PROMOQRY.h"
|
||||
|
||||
void ACQ_PROMOQRY(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_n = 0, h_sum = 0, h_fee = 0;
|
||||
char h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
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 category = 'PROMO' 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_PROMOSTAT.h
Normal file
18
app/src/ac/svc/ACQ_PROMOSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_PROMOSTAT.h - ac 서비스 ACQ_PROMOSTAT 카피북 (copybook / record header).
|
||||
* 프로모션 통계: 영업일 업종/분류별 매출을 그룹 집계해 분류코드·매출 쌍을
|
||||
*/
|
||||
#ifndef ACQ_PROMOSTAT_H
|
||||
#define ACQ_PROMOSTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
char category[32];
|
||||
long grand;
|
||||
long promo;
|
||||
} acq_promostat_rec_t;
|
||||
|
||||
void ACQ_PROMOSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_PROMOSTAT_H */
|
||||
40
app/src/ac/svc/ACQ_PROMOSTAT.pgc
Normal file
40
app/src/ac/svc/ACQ_PROMOSTAT.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* ACQ_PROMOSTAT.pgc - ac 모듈 서비스 ACQ_PROMOSTAT (one service = one file).
|
||||
* 프로모션 통계: 영업일 업종/분류별 매출을 그룹 집계해 분류코드·매출 쌍을
|
||||
* occurrence 로 내리고 프로모션 분류가 차지하는 비중을 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_PROMOSTAT.h"
|
||||
|
||||
void ACQ_PROMOSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long grand = 0, promo = 0, kinds = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_sum;
|
||||
char h_cat[32], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
gets_(b, T_BIZDATE, h_bizdate, sizeof(h_bizdate));
|
||||
|
||||
EXEC SQL DECLARE pms_cur CURSOR FOR
|
||||
SELECT category, sum(amount) FROM purchase WHERE biz_date = :h_bizdate
|
||||
GROUP BY category ORDER BY sum(amount) DESC;
|
||||
EXEC SQL OPEN pms_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pms_cur INTO :h_cat, :h_sum;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pms_cur; FAIL(b); }
|
||||
if (kinds < 8) { Badd(b, T_CATEGORY, h_cat, 0L); Badd(b, T_AMT1, (char *)&h_sum, 0L); }
|
||||
grand += h_sum;
|
||||
if (strcmp(h_cat, "PROMO") == 0) promo = h_sum;
|
||||
kinds++;
|
||||
}
|
||||
EXEC SQL CLOSE pms_cur;
|
||||
|
||||
setl(b, T_GROSS, grand);
|
||||
setl(b, T_AMT2, promo);
|
||||
setl(b, T_RC, grand > 0 ? promo * 100 / grand : 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_QTRSTAT.h
Normal file
18
app/src/ac/svc/ACQ_QTRSTAT.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_QTRSTAT.h - ac 서비스 ACQ_QTRSTAT 카피북 (copybook / record header).
|
||||
* 매입 분기별 통계: 지정 연도(T_ARG1)의 매입 매출을 1~4분기로 나눠 분기별
|
||||
*/
|
||||
#ifndef ACQ_QTRSTAT_H
|
||||
#define ACQ_QTRSTAT_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long year;
|
||||
long q[4];
|
||||
long gross;
|
||||
} acq_qtrstat_rec_t;
|
||||
|
||||
void ACQ_QTRSTAT(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_QTRSTAT_H */
|
||||
35
app/src/ac/svc/ACQ_QTRSTAT.pgc
Normal file
35
app/src/ac/svc/ACQ_QTRSTAT.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* ACQ_QTRSTAT.pgc - ac 모듈 서비스 ACQ_QTRSTAT (one service = one file).
|
||||
* 매입 분기별 통계: 지정 연도(T_ARG1)의 매입 매출을 1~4분기로 나눠 분기별
|
||||
* 합계를 한 번의 집계로 산출하고 연간 총매출을 함께 응답한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_QTRSTAT.h"
|
||||
|
||||
void ACQ_QTRSTAT(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long yr;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_q1 = 0, h_q2 = 0, h_q3 = 0, h_q4 = 0;
|
||||
int h_yr;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
yr = getl(b, T_ARG1); if (yr < 2000) yr = 2026;
|
||||
h_yr = (int)yr;
|
||||
|
||||
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) FAIL(b);
|
||||
|
||||
setl(b, T_ARG2, h_q1);
|
||||
setl(b, T_ARG3, h_q2);
|
||||
setl(b, T_ARG4, h_q3);
|
||||
setl(b, T_ARG5, h_q4);
|
||||
setl(b, T_GROSS, h_q1 + h_q2 + h_q3 + h_q4);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_REBUYAPPR.h
Normal file
18
app/src/ac/svc/ACQ_REBUYAPPR.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_REBUYAPPR.h - ac 서비스 ACQ_REBUYAPPR 카피북 (copybook / record header).
|
||||
* 재매입 승인: 취소(C)된 원매입에 한해 승인 원장(approval)에 재승인 행을
|
||||
*/
|
||||
#ifndef ACQ_REBUYAPPR_H
|
||||
#define ACQ_REBUYAPPR_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long approval_id;
|
||||
long rc;
|
||||
} acq_rebuyappr_rec_t;
|
||||
|
||||
void ACQ_REBUYAPPR(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_REBUYAPPR_H */
|
||||
34
app/src/ac/svc/ACQ_REBUYAPPR.pgc
Normal file
34
app/src/ac/svc/ACQ_REBUYAPPR.pgc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* ACQ_REBUYAPPR.pgc - ac 모듈 서비스 ACQ_REBUYAPPR (one service = one file).
|
||||
* 재매입 승인: 취소(C)된 원매입에 한해 승인 원장(approval)에 재승인 행을
|
||||
* 남기고 원매입을 접수(A)로 되살려 재매입을 개시한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_REBUYAPPR.h"
|
||||
|
||||
void ACQ_REBUYAPPR(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_aid;
|
||||
char st[4];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL SELECT status INTO :st 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 (st[0] != 'C') { setl(b, T_RC, 2); FAIL(b); }
|
||||
|
||||
EXEC SQL SELECT nextval('approval_seq') INTO :h_aid;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL INSERT INTO approval (approval_id, purchase_id, approved) VALUES (:h_aid, :h_pid, true);
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
EXEC SQL UPDATE purchase SET status = 'A', updated_at = now() WHERE purchase_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) { userlog("ACQ_REBUYAPPR FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
|
||||
|
||||
setl(b, T_ID1, h_aid);
|
||||
setl(b, T_RC, 0);
|
||||
OK(b);
|
||||
}
|
||||
18
app/src/ac/svc/ACQ_REBUYHIST.h
Normal file
18
app/src/ac/svc/ACQ_REBUYHIST.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* ACQ_REBUYHIST.h - ac 서비스 ACQ_REBUYHIST 카피북 (copybook / record header).
|
||||
* 재매입 이력: 한 매입의 승인 원장을 승인시각 순으로 커서 조회해 승인 ID를
|
||||
*/
|
||||
#ifndef ACQ_REBUYHIST_H
|
||||
#define ACQ_REBUYHIST_H
|
||||
|
||||
#include "ac_svc.h"
|
||||
|
||||
typedef struct {
|
||||
long purchase_id;
|
||||
long count;
|
||||
long rc;
|
||||
} acq_rebuyhist_rec_t;
|
||||
|
||||
void ACQ_REBUYHIST(TPSVCINFO *p);
|
||||
|
||||
#endif /* ACQ_REBUYHIST_H */
|
||||
37
app/src/ac/svc/ACQ_REBUYHIST.pgc
Normal file
37
app/src/ac/svc/ACQ_REBUYHIST.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ACQ_REBUYHIST.pgc - ac 모듈 서비스 ACQ_REBUYHIST (one service = one file).
|
||||
* 재매입 이력: 한 매입의 승인 원장을 승인시각 순으로 커서 조회해 승인 ID를
|
||||
* occurrence 로 내리고 총 승인 횟수와 최근 승인 여부를 계산한다.
|
||||
* Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
|
||||
*/
|
||||
#include "ACQ_REBUYHIST.h"
|
||||
|
||||
void ACQ_REBUYHIST(TPSVCINFO *p)
|
||||
{
|
||||
UBFH *b = (UBFH *)p->data;
|
||||
long n = 0; int last = 0;
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_pid, h_aid;
|
||||
int h_ok;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
h_pid = getl(b, T_PURCHASE_ID);
|
||||
|
||||
EXEC SQL DECLARE rbh_cur CURSOR FOR
|
||||
SELECT approval_id, approved FROM approval WHERE purchase_id = :h_pid
|
||||
ORDER BY approved_at;
|
||||
EXEC SQL OPEN rbh_cur;
|
||||
if (sqlca.sqlcode < 0) FAIL(b);
|
||||
for (;;) {
|
||||
EXEC SQL FETCH rbh_cur INTO :h_aid, :h_ok;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE rbh_cur; FAIL(b); }
|
||||
Badd(b, T_ID1, (char *)&h_aid, 0L);
|
||||
last = h_ok; n++;
|
||||
}
|
||||
EXEC SQL CLOSE rbh_cur;
|
||||
|
||||
setl(b, T_COUNT, n);
|
||||
setl(b, T_RC, last ? 0 : 1);
|
||||
OK(b);
|
||||
}
|
||||
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