/* @tier easy @module cl @transform closing-online */ /* * cl_ol_0022.pgc - 마감 온라인 서비스 (CL_OL_0022) [tier=easy] * * 스냅샷 조회 * ---------------------------------------------------------------------- * 요청 영업일(BIZDATE)의 마감 스냅샷 요약행을 key=BIZDATE+"SS" 로 표준 * DBIO(cl_rec_select) 를 통해 조회한다. 스냅샷 요약행은 마감 시점의 * 합계(amount)/건수(fee) 를 담고 있으며, 없으면 스냅샷 미생성으로 보아 * ENOENT(FOUND=N) 를 응답한다. * * 스냅샷이 존재하면 현재 원장의 실집계(합계/건수)를 재산출하여 스냅샷 * 시점 대비 변동분(DRIFT)을 함께 제공한다. 변동이 0 이면 스냅샷과 * 현행이 일치(FRESH=Y). 감사추적을 위해 선택 입력 REQID 를 반영한다. */ #include #include #include "txcore.h" #include "txcore_dbio.h" #include "acq_util.h" #include "cl_core.h" EXEC SQL INCLUDE sqlca; TX_SERVICE(CL_OL_0022, ctx) { EXEC SQL BEGIN DECLARE SECTION; char h_biz_date[9]; long h_live_sum; int h_live_cnt; EXEC SQL END DECLARE SECTION; cl_rec_t rec; char bizdate[16]; char reqid[32]; char snap_key[16]; char snap_won[32]; char drift_won[32]; long drift; tx_log(TX_LOG_INFO, "[CL_OL_0022] 스냅샷 조회 서비스 진입"); /* 1) 입력 수신 및 검증 */ if (tx_buf_get(ctx->in, "BIZDATE", bizdate, sizeof(bizdate)) != TX_OK) { tx_log(TX_LOG_ERROR, "[CL_OL_0022] BIZDATE 누락"); tx_buf_reset(ctx->out); tx_buf_sets(ctx->out, "RESPCODE", RESP_INVALID); tx_return(ctx, TX_EINVAL, ctx->out); return; } if (tx_buf_get(ctx->in, "REQID", reqid, sizeof(reqid)) != TX_OK) strncpy(reqid, "-", sizeof(reqid) - 1); if (!date_is_valid(bizdate)) { tx_log(TX_LOG_WARN, "[CL_OL_0022] 영업일 형식 오류 date=%s", bizdate); tx_buf_reset(ctx->out); tx_buf_sets(ctx->out, "RESPCODE", RESP_INVALID); tx_return(ctx, TX_EINVAL, ctx->out); return; } /* 2) 스냅샷 요약행 키 구성 = 영업일 + "SS" */ snprintf(snap_key, sizeof(snap_key), "%.8sSS", bizdate); /* 3) 스냅샷 요약행 조회 */ memset(&rec, 0, sizeof(rec)); if (cl_rec_select(snap_key, &rec) == TX_ENOENT) { tx_log(TX_LOG_WARN, "[CL_OL_0022] 스냅샷 없음 key=%s", snap_key); tx_buf_reset(ctx->out); tx_buf_sets(ctx->out, "RESPCODE", RESP_INVALID); tx_buf_sets(ctx->out, "BIZDATE", bizdate); tx_buf_sets(ctx->out, "SNAPKEY", snap_key); tx_buf_sets(ctx->out, "FOUND", "N"); tx_buf_sets(ctx->out, "MESSAGE", "마감 스냅샷 미생성"); tx_return(ctx, TX_ENOENT, ctx->out); return; } /* 4) 현행 실집계 재산출 (요약행 제외) */ memset(h_biz_date, 0, sizeof(h_biz_date)); strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1); EXEC SQL SELECT coalesce(sum(amount), 0), count(*) INTO :h_live_sum, :h_live_cnt FROM cl_ledger WHERE biz_date = :h_biz_date AND merch_id <> '*AGG'; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("cl_ol_0022 현행집계"); tx_buf_reset(ctx->out); tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR); tx_return(ctx, TX_EDB, ctx->out); return; } /* 5) 스냅샷 대비 변동분 산출 (amount=합계, fee=건수) */ drift = h_live_sum - rec.amount; amount_format_won(rec.amount, snap_won, sizeof(snap_won)); amount_format_won(drift, drift_won, sizeof(drift_won)); tx_buf_reset(ctx->out); tx_buf_sets(ctx->out, "RESPCODE", RESP_OK); tx_buf_sets(ctx->out, "BIZDATE", bizdate); tx_buf_sets(ctx->out, "REQID", reqid); tx_buf_sets(ctx->out, "SNAPKEY", snap_key); tx_buf_sets(ctx->out, "FOUND", "Y"); tx_buf_setlong(ctx->out, "SNAPSUM", rec.amount); tx_buf_sets(ctx->out, "SNAPSUMWON", snap_won); tx_buf_setlong(ctx->out, "SNAPCNT", rec.fee); tx_buf_setlong(ctx->out, "LIVESUM", h_live_sum); tx_buf_setlong(ctx->out, "LIVECNT", (long)h_live_cnt); tx_buf_setlong(ctx->out, "DRIFT", drift); tx_buf_sets(ctx->out, "DRIFTWON", drift_won); tx_buf_sets(ctx->out, "FRESH", (drift == 0) ? "Y" : "N"); tx_buf_sets(ctx->out, "STATUS", rec.status); tx_log(TX_LOG_INFO, "[CL_OL_0022] 스냅샷 조회완료 key=%s 스냅=%ld 현행=%ld 변동=%ld", snap_key, rec.amount, h_live_sum, drift); tx_return(ctx, TX_OK, ctx->out); }