/*
 * MM_PARTNER_UPD.pgc - mm 모듈 서비스 MM_PARTNER_UPD (one service = one file).
 * 기능: 제휴사 마스터 명칭/표시순서 변경 (PARTNER 코드그룹, 기존 건만 갱신).
 * 입력: T_KEY1=제휴사 코드, T_STR1=신규 명칭, T_ARG1=신규 순서.
 * RC: 0=변경, 1=제휴사 없음, 3=명칭 누락.
 * caller의 XA 브랜치에서 실행(EXEC SQL CONNECT 없음); mm_svr가 tpadvertise 한다.
 */
#include "MM_PARTNER_UPD.h"

void MM_PARTNER_UPD(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    char code[16], name[64];
    EXEC SQL BEGIN DECLARE SECTION;
    char h_code[16], h_name[64];
    long h_sort, h_exist;
    EXEC SQL END DECLARE SECTION;

    gets_(b, T_KEY1, code, sizeof(code));
    gets_(b, T_STR1, name, sizeof(name));
    h_sort = getl(b, T_ARG1);
    if (name[0] == 0) { setl(b, T_RC, 3); OK(b); }
    strncpy(h_code, code, sizeof(h_code)-1); h_code[sizeof(h_code)-1] = 0;
    strncpy(h_name, name, sizeof(h_name)-1); h_name[sizeof(h_name)-1] = 0;

    EXEC SQL SELECT count(*) INTO :h_exist FROM mm_code
        WHERE code_group = 'PARTNER' AND code = :h_code;
    if (sqlca.sqlcode < 0) FAIL(b);
    if (h_exist == 0) { setl(b, T_RC, 1); OK(b); }

    EXEC SQL UPDATE mm_code SET code_name = :h_name, sort_order = :h_sort
        WHERE code_group = 'PARTNER' AND code = :h_code;
    if (sqlca.sqlcode < 0) FAIL(b);
    setl(b, T_RC, 0);

    /* ====================================================================
     * [심화 후처리] MM_PARTNER_UPD - 공통코드/제휴 마스터 정합/감사 확장부 (mm 코드)
     * 코드그룹 활성 규모와 중복/상태 정합성을 재점검하고 감사 로그를 남긴다.
     * ==================================================================== */
    {
        EXEC SQL BEGIN DECLARE SECTION;
        char  zx_svc[24], zx_key[64], zx_grp[32], zx_msg[192];
        long  zx_logid, zx_n1, zx_n2, zx_n3, zx_bps, zx_act, zx_grps;
        EXEC SQL END DECLARE SECTION;
        char  zx_in[64], zx_gin[32];
        long  zx_depth = 0, zx_score = 0, zx_fee = 0, zx_vat = 0, zx_wht = 0;

        /* (1) 입력 재확인부: 코드/그룹 키 확보 */
        strcpy(zx_svc, "MM_PARTNER_UPD");
        gets_(b, T_KEY1, zx_in, sizeof(zx_in));
        if (zx_in[0] == 0) gets_(b, T_STR1, zx_in, sizeof(zx_in));
        if (zx_in[0] == 0) strcpy(zx_in, "-");
        strncpy(zx_key, zx_in, sizeof(zx_key)-1); zx_key[sizeof(zx_key)-1] = 0;
        gets_(b, T_STR1, zx_gin, sizeof(zx_gin));
        if (zx_gin[0] == 0) strcpy(zx_gin, "GEN");
        strncpy(zx_grp, zx_gin, sizeof(zx_grp)-1); zx_grp[sizeof(zx_grp)-1] = 0;
        zx_bps = 0;

        /* (2) 코드그룹 조회부: 그룹 내 활성 코드 수 + 전체 코드 수 */
        zx_act = 0; zx_n1 = 0;
        EXEC SQL SELECT count(*) INTO :zx_act
            FROM mm_code WHERE code_group = :zx_grp AND status = 'ACTIVE';
        if (sqlca.sqlcode < 0) FAIL(b);
        EXEC SQL SELECT count(*) INTO :zx_n1
            FROM mm_code WHERE code_group = :zx_grp;
        if (sqlca.sqlcode < 0) FAIL(b);
        zx_n2 = zx_act;

        /* (3) 업무규칙 분기부: 그룹 규모/활성 비율별 상태 판정 */
        if (zx_n1 == 0) {
            zx_depth = 0; zx_score = 0;          /* 빈 코드그룹 */
        } else if (zx_act == zx_n1) {
            zx_depth = 3; zx_score = 80;         /* 전량 활성 */
        } else if (zx_act * 2 >= zx_n1) {
            zx_depth = 2; zx_score = 55;         /* 과반 활성 */
        } else {
            zx_depth = 1; zx_score = 30;         /* 비활성 우세 */
        }

        /* (6) 전사 코드 재집계부: 코드그룹 종류 수 */
        zx_grps = 0;
        EXEC SQL SELECT count(DISTINCT code_group) INTO :zx_grps FROM mm_code;
        if (sqlca.sqlcode < 0) FAIL(b);
        zx_n3 = zx_grps;

        /* (2b) 영업일/공휴일 정책 조회 (정산 스케줄 판정 보조) */
        {
            char zc_today[16], zc_next[16];
            int  zc_hol;
            EXEC SQL BEGIN DECLARE SECTION;
            char zc_hd[16];
            long zc_holcnt;
            EXEC SQL END DECLARE SECTION;
            EXEC SQL SELECT to_char(current_date, 'YYYY-MM-DD') INTO :zc_hd;
            if (sqlca.sqlcode < 0) FAIL(b);
            strncpy(zc_today, zc_hd, sizeof(zc_today)-1); zc_today[sizeof(zc_today)-1] = 0;
            acq_next_bizday(zc_today, zc_next);
            zc_hol = mmdb_is_holiday(zc_today);
            EXEC SQL SELECT count(*) INTO :zc_holcnt FROM mm_holiday;
            if (sqlca.sqlcode < 0) FAIL(b);
            if (zc_hol > 0)          userlog("MM_PARTNER_UPD 금일 공휴일 -> 익영업일 %s", zc_next);
            else if (zc_holcnt == 0) userlog("MM_PARTNER_UPD 공휴일 마스터 미적재 (기본 스케줄)");
            else                     userlog("MM_PARTNER_UPD 영업일 처리 익영업일=%s 공휴일수=%ld", zc_next, zc_holcnt);
        }

        /* (4) 본처리 계산부: 기준금액 수수료/부가세/원천 산출 (공통유틸) */
        zx_fee = acq_fee(1000000, zx_bps > 0 ? zx_bps : 25);
        zx_vat = acq_vat(zx_fee);
        zx_wht = acq_wht_amt(zx_fee, 330);
        if (zx_score < 0) zx_score = 0;
        if (zx_score > 100) zx_score = 100;

        /* (7) 감사 로그 적재부: cm_log 처리요약 1건 (실패 시 XA 롤백) */
        EXEC SQL SELECT nextval('cm_log_seq') INTO :zx_logid;
        if (sqlca.sqlcode < 0) FAIL(b);
        snprintf(zx_msg, sizeof(zx_msg),
            "MM_PARTNER_UPD key=%s d=%ld n1=%ld n2=%ld score=%ld fee=%ld",
            zx_key, zx_depth, zx_n1, zx_n2, zx_score, zx_fee);
        EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
            VALUES (:zx_logid, :zx_svc, 'I', :zx_msg, current_date);
        if (sqlca.sqlcode < 0) FAIL(b);

        /* (9) 완료 로깅부: 진입 키/분기/집계 결과 감사 추적 */
        userlog("MM_PARTNER_UPD 확장후처리 key=%s 분기심도=%ld 점수=%ld", zx_key, zx_depth, zx_score);
        userlog("MM_PARTNER_UPD 집계 n1=%ld n2=%ld n3=%ld", zx_n1, zx_n2, zx_n3);
        userlog("MM_PARTNER_UPD 수수료 fee=%ld vat=%ld wht=%ld bps=%ld", zx_fee, zx_vat, zx_wht, zx_bps);
        (void)zx_vat; (void)zx_wht; (void)zx_n3;
    }

    OK(b);
}
