/*
 * CL_APPRHIST.pgc - cl 모듈 서비스 CL_APPRHIST (one service = one file).
 * 마감 승인 이력: 기간 프리픽스(YYYY-MM 등)의 마감을 승인(A/L)/완료(C)/취소(X)
 * 로 CASE 집계하여 승인 진행률 현황을 한 번의 SELECT 로 반환한다.
 * 호출자의 XA 브랜치에서 수행(EXEC SQL CONNECT 없음); cl_svr 가 광고한다.
 */
#include "CL_APPRHIST.h"

void CL_APPRHIST(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    char svc[24];
    char logmsg[192];
    char o_msg[128];
    long o_rc = 0, o_count = 0, o_amount = 0;
    long groups = 0; long topamt = 0; char topdim[64];
    int z_sev = 0, z_comp = 0;
    char z_msg[64];
    char z_buf[192];
    EXEC SQL BEGIN DECLARE SECTION;
    char h_bizdate[16];
    char h_period[24];
    char h_svc[24];
    char h_logmsg[192];
    long h_grpcnt, h_grpamt, h_cid;
    char h_dim[64], h_key[32];
    long h_zn, h_zcnt, h_zamt;
    long h_zopen, h_zsev;
    long h_kcid;
    char h_zbuf[192];
    EXEC SQL END DECLARE SECTION;
    h_bizdate[0] = 0; h_period[0] = 0; h_zbuf[0] = 0;
    z_msg[0] = 0; z_buf[0] = 0; h_zopen = 0; h_zsev = 0;


    /* --- 섹션9: 진입 로깅 --- */
    strcpy(svc, "CL_APPRHIST");
    userlog("CL_APPRHIST 진입: 마감처리 시작 (승인이력)", svc);

    gets_(b, T_KEY1, h_key, sizeof(h_key));
    if (h_key[0] == 0) gets_(b, T_STR1, h_key, sizeof(h_key));

    /* --- 섹션1: 입력 검증부 --- */
    if (h_key[0] == 0) {
        setl(b, T_RC, 6502);
        Bchg(b, T_MSG, 0, "리포트 키(close_type/기간) 필수", 0L); FAIL(b);
    }

    /* --- 섹션2: 그룹 수 사전 확인부 --- */
    EXEC SQL SELECT count(DISTINCT status) INTO :h_grpcnt
        FROM cl_close_log WHERE period_key LIKE :h_key || '%';
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 6504); FAIL(b); }
    if (h_grpcnt == 0) {
        o_rc = 1; o_count = 0;
        strcpy(o_msg, "리포트 대상 그룹 없음");
        setl(b, T_COUNT, 0); Bchg(b, T_MSG, 0, o_msg, 0L); OK(b);
    }

    /* --- 섹션4: 그룹별 집계 커서(상위추출) --- */
    strcpy(topdim, "");
    EXEC SQL DECLARE crpt CURSOR FOR
        SELECT status, count(*), coalesce(sum(total_amount),0) FROM cl_close_log
        WHERE period_key LIKE :h_key || '%' GROUP BY status ORDER BY 2 DESC;
    EXEC SQL OPEN crpt;
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 6505); FAIL(b); }
    for (;;) {
        EXEC SQL FETCH crpt INTO :h_dim, :h_grpcnt, :h_grpamt;
        if (sqlca.sqlcode == 100) break;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE crpt; setl(b, T_RC, 6506); FAIL(b); }
        if (groups < 20) {
            Bchg(b, T_STR2, (BFLDOCC)groups, h_dim, 0L);
            setl(b, T_ARG3, h_grpamt);
        }
        if (h_grpamt > topamt) {
            topamt = h_grpamt;
            strncpy(topdim, h_dim, sizeof(topdim)-1); topdim[sizeof(topdim)-1]=0;
        }
        groups++;
    }
    EXEC SQL CLOSE crpt;

    /* --- 섹션3: 상위그룹 판정 분기부 --- */
    if (groups == 0) {
        o_rc = 1; strcpy(o_msg, "승인이력 집계 결과 없음");
    } else if (topamt == 0) {
        o_rc = 2; strcpy(o_msg, "승인이력 집계 금액 0");
    } else {
        o_rc = 0;
        snprintf(o_msg, sizeof(o_msg), "승인이력 최다=%s(%ld)", topdim, topamt);
    }
    Bchg(b, T_STR1, 0, topdim, 0L);
    o_count = groups; o_amount = topamt;

    /* --- 섹션6b: 마감 집계/요약 재산출부 --- */
    EXEC SQL SELECT count(*), coalesce(sum(txn_count),0),
                    coalesce(sum(total_amount),0)
        INTO :h_zn, :h_zcnt, :h_zamt
        FROM cl_close_log
        WHERE status <> 'X'
          AND (:h_period = '' OR period_key = :h_period);
    if (sqlca.sqlcode < 0) {
        userlog("CL_APPRHIST 마감요약 재집계 실패[%d] - 요약 생략", sqlca.sqlcode);
        h_zn = 0; h_zcnt = 0; h_zamt = 0;
    }
    setl(b, T_ARG6, h_zcnt);
    setl(b, T_ARG7, h_zn);

    /* --- 섹션3c: 마감 규모별 추가 업무규칙 분기부 --- */
    if (h_zn == 0) {
        z_sev = 0;
        strcpy(z_msg, "마감이력 없음");
    } else if (h_zamt >= 2000000000L) {
        z_sev = 3;
        strcpy(z_msg, "초과대형 마감구간");
    } else if (h_zamt >= 200000000L) {
        z_sev = 2;
        strcpy(z_msg, "중대형 마감구간");
    } else {
        z_sev = 1;
        strcpy(z_msg, "일반 마감구간");
    }
    h_zsev = (long)z_sev;

    /* --- 섹션7: 예외/보상 판정부 (부분처리 방지) --- */
    if (o_rc != 0) {
        z_comp = 1;
        EXEC SQL SELECT count(*) INTO :h_zopen FROM cl_close_log
            WHERE status = 'O'
              AND (:h_bizdate = '' OR period_key = :h_bizdate);
        if (sqlca.sqlcode < 0) h_zopen = 0;
        if (h_zopen > 0)
            userlog("CL_APPRHIST 경고: 미완결 개시(O) %ld건 잔존 - 보상대상", h_zopen);
        userlog("CL_APPRHIST 예외분기 rc=%ld sev=%d - 상태전이 실패 이력 적재",
                o_rc, z_sev);
    } else {
        z_comp = 0;
        h_zopen = 0;
    }

    /* --- 섹션5b: 처리 요약 이력 적재부 --- */
    snprintf(z_buf, sizeof(z_buf), "%s sev=%d comp=%d open=%ld %s",
             svc, z_sev, z_comp, h_zopen, z_msg);
    strncpy(h_zbuf, z_buf, sizeof(h_zbuf)-1);
    h_zbuf[sizeof(h_zbuf)-1] = 0;
    strncpy(h_svc, svc, sizeof(h_svc)-1); h_svc[sizeof(h_svc)-1] = 0;
    EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
        VALUES (nextval('cm_log_seq'), :h_svc,
                CASE WHEN :h_zsev > 2 THEN 'W' ELSE 'I' END, :h_zbuf,
                COALESCE(NULLIF(:h_bizdate,'')::date, CURRENT_DATE));
    if (sqlca.sqlcode < 0)
        userlog("CL_APPRHIST 요약이력 적재 실패[%d] - 업무는 계속", sqlca.sqlcode);
    setl(b, T_ARG8, h_zsev);

    /* --- 섹션5: 이력/감사 적재 (cm_log, best-effort) --- */
    snprintf(logmsg, sizeof(logmsg), "CL_APPRHIST 승인이력 cnt=%ld amt=%ld rc=%ld",
             o_count, o_amount, o_rc);
    strncpy(h_logmsg, logmsg, sizeof(h_logmsg)-1);
    h_logmsg[sizeof(h_logmsg)-1] = 0;
    strncpy(h_svc, svc, sizeof(h_svc)-1); h_svc[sizeof(h_svc)-1] = 0;
    EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
        VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_logmsg,
                COALESCE(NULLIF(:h_bizdate,'')::date, CURRENT_DATE));
    if (sqlca.sqlcode < 0)
        userlog("CL_APPRHIST 감사로그 적재 실패[%d] - 업무는 계속", sqlca.sqlcode);

    /* --- 섹션8: 응답부 --- */
    setl(b, T_RC, o_rc);
    setl(b, T_COUNT, o_count);
    setl(b, T_GROSS, o_amount);
    Bchg(b, T_MSG, 0, o_msg, 0L);
    userlog("CL_APPRHIST 완료: rc=%ld count=%ld amount=%ld", o_rc, o_count, o_amount);
    OK(b);
}

/* vim: set ts=4 sw=4 et smartindent: */
