/*
 * SETTLE.pgc - st 모듈 서비스 SETTLE (one service = one file).
 * Moved verbatim from the former inline st_svr.pgc; runs on the caller's XA
 * branch (no EXEC SQL CONNECT). Advertised by st_svr at tpsvrinit.
 */
#include "SETTLE.h"

/* ========================================================================= */
void SETTLE(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    char merch[64], bizdate[16];
    EXEC SQL BEGIN DECLARE SECTION;
    long h_pid, h_sid, h_net;
    char h_merch[64], h_bizdate[16];
    EXEC SQL END DECLARE SECTION;

    h_pid = getl(b, T_PURCHASE_ID);
    h_net = getl(b, T_NET);
    gets_(b, T_MERCHANT, merch, sizeof(merch));
    gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
    strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    EXEC SQL SELECT nextval('settlement_seq') INTO :h_sid;
    if (sqlca.sqlcode < 0) FAIL(b);
    EXEC SQL INSERT INTO settlement (settlement_id, purchase_id, merchant_id, net, biz_date, status)
        VALUES (:h_sid, :h_pid, :h_merch, :h_net, :h_bizdate, 'SETTLED');
    if (sqlca.sqlcode < 0) { userlog("SETTLE INSERT settlement FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); FAIL(b); }
    EXEC SQL INSERT INTO ledger (ledger_id, purchase_id, entry_type, amount, biz_date)
        VALUES (nextval('ledger_seq'), :h_pid, 'SETTLE', :h_net, :h_bizdate);
    if (sqlca.sqlcode < 0) FAIL(b);

    setl(b, T_SETTLE_ID, h_sid);
    Bchg(b, T_STATUS, 0, "S", 0L);
    userlog("SETTLE pid=%ld settlement_id=%ld net=%ld", h_pid, h_sid, h_net);

    /* ===== 8b) 업무 체인 호출부: SETTLE -> ST_MDR (정산확정-수수료산출) =====
     * XA 규율: tpcall 로 부르는 ST_MDR 는 별도 XA 브랜치라 SETTLE 가 방금
     * INSERT/UPDATE 한 미커밋 행을 볼 수 없다. 그러므로 체인에 필요한 값은 모두
     * UBF 전문(T_*)에 실어 넘기고, 하위는 전문값을 우선 사용한다(owner-writes).
     * 하위 호출 실패는 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요). */
    {
        long cx_rlen = 0;
        long cx_pid  = getl(b, T_PURCHASE_ID);
        long cx_sid  = getl(b, T_SETTLE_ID);
        long cx_amt  = getl(b, T_AMOUNT);
        long cx_fee  = getl(b, T_FEE);
        long cx_net  = getl(b, T_NET);
        long cx_cnt  = getl(b, T_COUNT);
        long cx_grs  = getl(b, T_GROSS);
        long cx_samt, cx_sfee, cx_snet;
        char cx_bd[16], cx_mid[64], cx_sts[16];

        gets_(b, T_BIZDATE,  cx_bd,  sizeof(cx_bd));
        gets_(b, T_MERCHANT, cx_mid, sizeof(cx_mid));
        gets_(b, T_STATUS,   cx_sts, sizeof(cx_sts));
        if (strlen(cx_bd) != 10) strcpy(cx_bd, "2026-07-20");
        if (cx_pid < 0) cx_pid = 0;
        if (cx_sid < 0) cx_sid = 0;
        cx_samt = (cx_amt < 0) ? -cx_amt : cx_amt;
        cx_sfee = (cx_fee < 0) ? -cx_fee : cx_fee;
        cx_snet = (cx_net < 0) ?        0 : cx_net;

        /* 하위가 필요로 하는 값을 전문에 적재 */
        Bchg(b, T_BIZDATE, 0, cx_bd, 0L);
        if (cx_mid[0] != 0) Bchg(b, T_MERCHANT, 0, cx_mid, 0L);
        setl(b, T_PURCHASE_ID, cx_pid);
        setl(b, T_SETTLE_ID,   cx_sid);
        setl(b, T_AMOUNT,      cx_samt);
        setl(b, T_FEE,         cx_sfee);
        setl(b, T_NET,         cx_snet);
        Bchg(b, T_SVCNAME, 0, "SETTLE", 0L);
        Bchg(b, T_REASON,  0, "정산확정-수수료산출", 0L);

        {
            long cx_dl = getl(b, T_DELTA);
            if (cx_dl > 100000000L || cx_dl < -100000000L) setl(b, T_DELTA, 0);
        }
        userlog("[SETTLE] 정산확정-수수료산출: 체인 호출 -> ST_MDR pid=%ld sid=%ld amt=%ld biz=%s",
                cx_pid, cx_sid, cx_samt, cx_bd);
        if (tpcall("ST_MDR", (char *)b, 0L, (char **)&b, &cx_rlen, 0L) < 0) {
            userlog("[SETTLE] tpcall(ST_MDR) 실패: %s", tpstrerror(tperrno));
            setl(b, T_RC, 8710);
            Bchg(b, T_MSG, 0, "수수료 산출 체인(ST_MDR) 호출 실패", 0L);
            FAIL(b);
        }
        /* 하위 응답 수신 — b 가 재할당될 수 있으므로 이후 Bget/Bchg 는 갱신된 b 사용.
         * SETTLE 자신의 응답 계약(출력 필드)은 하위 응답에 덮이지 않도록 복원한다. */
        setl(b, T_PURCHASE_ID, cx_pid);
        setl(b, T_AMOUNT,      cx_amt);
        setl(b, T_FEE,         cx_fee);
        setl(b, T_NET,         cx_net);
        setl(b, T_COUNT,       cx_cnt);
        setl(b, T_GROSS,       cx_grs);
        if (cx_sid > 0)     setl(b, T_SETTLE_ID, cx_sid);
        if (cx_sts[0] != 0) Bchg(b, T_STATUS, 0, cx_sts, 0L);
        Bchg(b, T_SVCNAME, 0, "SETTLE", 0L);
        setl(b, T_RC, 0);
        userlog("[SETTLE] 정산확정-수수료산출: 체인 완료 <- ST_MDR pid=%ld", cx_pid);
    }

    OK(b);
}

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