/*==========================================================================*/
/*  ST_MDR.pc  -  MDR 수수료 원장기표 온라인 서비스 (As-Is 원본, Oracle Pro*C)*/
/*--------------------------------------------------------------------------*/
/*  대상 : BC 매입시스템 / Tuxedo ATMI 서비스 ST_MDR                          */
/*  DBMS : Oracle 19c   전처리 : Pro*C/C++ (proc)                            */
/*  기능 : 매입건 MDR 수수료를 계산·검증하여 원장(ledger)에 기표한다.         */
/*  ※ 이 파일은 **As-Is 역사 원본**이다. 현행 오픈스택 이식본은               */
/*     app/src/st/svc/ST_MDR.pgc (ECPG/PostgreSQL). 컴파일 제외.             */
/*--------------------------------------------------------------------------*/
/*  변경이력                                                                  */
/*   2000.03.21  PARK J.S  최초작성 (MDR 원장기표)                            */
/*   2007.11.05  HAN Y.J   가맹점 요율(mdr_bps) 마스터 연동, DECODE 분기       */
/*   2013.06.30  LEE S.W   부가세 분리기표, 복식부기 차대변 연계               */
/*   2019.09.01  CHOI H.W  Oracle 11g -> 19c, 시퀀스 채번 표준화              */
/*==========================================================================*/
#include <stdio.h>
#include <string.h>
#include <atmi.h>
#include <fml32.h>
#include <userlog.h>

EXEC SQL INCLUDE sqlca;
EXEC SQL INCLUDE oraca;
EXEC ORACLE OPTION (ORACA=YES);

#include "stfld.h"

EXEC SQL BEGIN DECLARE SECTION;
    VARCHAR   h_merch[64];
    VARCHAR   h_bizdate[9];       /* YYYYMMDD */
    VARCHAR   h_pstat[2];
    long      h_pid;
    long      h_sid;
    long      h_amount;
    long      h_fee;
    long      h_vat;
    long      h_net;
    long      h_mdr_bps;
    long      h_led;
    long      h_dup;
EXEC SQL END DECLARE SECTION;

/*--------------------------------------------------------------------------*/
/*  ST_MDR  -  Tuxedo 서비스 엔트리                                           */
/*--------------------------------------------------------------------------*/
void ST_MDR(TPSVCINFO *rqst)
{
    FBFR32 *fb = (FBFR32 *)rqst->data;
    char    merch[64], bizdate[9];

    userlog("ST_MDR 진입: MDR 수수료 원장기표");
    EXEC SQL WHENEVER SQLERROR GOTO sql_error;

    /* ---- 1) 요청 FML 파싱 -------------------------------------------- */
    h_pid  = Fvall(fb, ST_PURCHASE_ID, 0);
    h_sid  = Fvall(fb, ST_SETTLE_ID, 0);
    h_fee  = Fvall(fb, ST_FEE, 0);
    Fget(fb, ST_BIZDATE, 0, bizdate, (FLDLEN32 *)NULL);
    strcpy((char *)h_bizdate.arr, bizdate); h_bizdate.len = strlen(bizdate);
    if (h_bizdate.len == 0) {
        EXEC SQL SELECT TO_CHAR(SYSDATE,'YYYYMMDD') INTO :h_bizdate FROM DUAL;
    }
    if (h_pid <= 0) {
        userlog("ST_MDR: 매입 ID 필수 pid=%ld", h_pid);
        Fchg(fb, ST_RC, 0, (char *)"E802", 0L);
        tpreturn(TPFAIL, 0, (char *)fb, 0L, 0L);
        return;
    }

    /* ---- 2) 매입원장 조회 (금액/가맹점/상태 확보, NVL 널가드) --------- */
    EXEC SQL
        SELECT NVL(p.amount, 0),
               NVL(p.merchant_id, ' '),
               NVL(p.status, 'A')
          INTO :h_amount, :h_merch, :h_pstat
          FROM purchase p
         WHERE p.purchase_id = :h_pid;
    if (sqlca.sqlcode == 1403) {
        /* 체인 내 신규매입(미커밋)은 전문값을 사용 */
        h_amount = Fvall(fb, ST_AMOUNT, 0);
        Fget(fb, ST_MERCHANT, 0, merch, (FLDLEN32 *)NULL);
        strcpy((char *)h_merch.arr, merch); h_merch.len = strlen(merch);
        userlog("ST_MDR: 미커밋 매입 pid=%ld — 전문값 사용", h_pid);
    }

    /* ---- 3) 요율조회 및 수수료 산출 (요청 fee 우선, 없으면 재계산) --- */
    EXEC SQL
        SELECT NVL(m.mdr_bps, 25),
               DECODE(NVL(m.status,'N'), 'A', 0, 1)
          INTO :h_mdr_bps, :h_dup
          FROM merchant m
         WHERE m.merchant_id = :h_merch;
    if (h_fee <= 0) h_fee = ROUND(h_amount * h_mdr_bps / 10000);
    h_vat = ROUND(h_fee / 10);          /* 수수료 부가세 10% 분리기표 */
    h_net = h_amount - h_fee - h_vat;

    /* ---- 4) 중복기표 방지: 동일 매입 MDR 기존 원장 존재여부 --------- */
    EXEC SQL
        SELECT COUNT(*) INTO :h_dup
          FROM ledger
         WHERE purchase_id = :h_pid
           AND entry_type  = 'MDR';
    if (h_dup > 0) {
        userlog("ST_MDR: MDR 기표 이미 존재 pid=%ld — 스킵", h_pid);
        Fchg(fb, ST_STATUS, 0, (char *)"D", 0L);
        EXEC SQL COMMIT WORK;
        tpreturn(TPSUCCESS, 0, (char *)fb, 0L, 0L);
        return;
    }

    /* ---- 5) 원장 기표: 시퀀스 채번 (.NEXTVAL) 후 MDR/VAT 2건 적재 --- */
    EXEC SQL SELECT ledger_seq.NEXTVAL INTO :h_led FROM DUAL;
    EXEC SQL
        INSERT INTO ledger
               (ledger_id, purchase_id, entry_type, amount, biz_date, posted_at)
        VALUES (:h_led, :h_pid, 'MDR', :h_fee,
                TO_DATE(:h_bizdate,'YYYYMMDD'), SYSDATE);
    EXEC SQL
        INSERT INTO ledger
               (ledger_id, purchase_id, entry_type, amount, biz_date, posted_at)
        VALUES (ledger_seq.NEXTVAL, :h_pid, 'VAT', :h_vat,
                TO_DATE(:h_bizdate,'YYYYMMDD'), SYSDATE);

    /* ---- 6) 복식부기 전표 반영 (PL/SQL 원장 패키지) ----------------- */
    EXEC SQL EXECUTE
        BEGIN
            pkg_ledger.post_voucher(:h_pid, 'MDR', :h_fee, :h_vat, :h_bizdate);
        END;
    END-EXEC;

    /* ---- 7) 정산연계: 수수료-원장반영 (LG_SETTLEPOST PL/SQL) -------- */
    EXEC SQL EXECUTE
        BEGIN
            pkg_settle.settle_post(:h_pid, :h_sid, :h_fee, :h_net);
        END;
    END-EXEC;

    EXEC SQL COMMIT WORK;

    Fchg(fb, ST_LEDGER_ID, 0, (char *)&h_led, 0L);
    Fchg(fb, ST_FEE,       0, (char *)&h_fee, 0L);
    Fchg(fb, ST_NET,       0, (char *)&h_net, 0L);
    Fchg(fb, ST_STATUS,    0, (char *)"S", 0L);
    userlog("ST_MDR 완료: pid=%ld ledger=%ld fee=%ld vat=%ld net=%ld",
            h_pid, h_led, h_fee, h_vat, h_net);
    tpreturn(TPSUCCESS, 0, (char *)fb, 0L, 0L);
    return;

sql_error:
    userlog("ST_MDR SQL 오류: %.70s (sqlcode=%ld)",
            sqlca.sqlerrm.sqlerrmc, sqlca.sqlcode);
    EXEC SQL WHENEVER SQLERROR CONTINUE;
    EXEC SQL ROLLBACK WORK;
    Fchg(fb, ST_RC, 0, (char *)"E900", 0L);
    tpreturn(TPFAIL, 0, (char *)fb, 0L, 0L);
    return;
}
