/*
 * ACQ_RETRIEVAL.pgc - ac (매입) 모듈 서비스 ACQ_RETRIEVAL (one service = one file).
 * 매출전표 조회요청(retrieval request) 생성/이행: 정식 채그백 직전 단계로, 발급사가
 *   거래 증빙(매출전표/서명/수령증)을 요청하면 조회요청을 열고(OPEN, SLA=today+20),
 *   가맹점이 증빙을 제출하면 이행(FULFILLED + fulfilled_at)한다.
 * 처리단계: 입력검증 -> 매입 컨텍스트 조회 -> action 분기(FULFILL/신규) -> 본처리 ->
 *   감사이력 -> 재검증 -> 응답 -> 로깅.
 * 호출자 XA 브랜치에서 수행(EXEC SQL CONNECT 없음). ac_svr 가 tpsvrinit 에서 광고.
 * XA 격리: 조회요청/매입은 본 브랜치에서 조회 가능한 커밋행 기준으로 판정한다.
 */
#include "ACQ_RETRIEVAL.h"

/* ACQ_RETRIEVAL - 매출전표 조회요청 생성/이행. */
void ACQ_RETRIEVAL(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    /* ---- 지역 스크래치 (DECLARE SECTION 밖에서 초기화) ---- */
    char  reason[128], msgbuf[220];
    int   fulfil = 0;

    EXEC SQL BEGIN DECLARE SECTION;
    long  h_pid, h_retr, h_chk;
    char  h_merch[64], h_reason[128], h_status[16], h_bizdate[16];
    char  h_cstatus[16], h_svc[24], h_msg[220];
    EXEC SQL END DECLARE SECTION;

    strcpy(h_svc, "ACQ_RETRIEVAL");
    h_pid = h_retr = h_chk = 0;
    strcpy(h_merch, "UNKNOWN"); strcpy(h_status, "OPEN");
    strcpy(h_bizdate, "2026-07-19"); h_cstatus[0] = 0;

    /* ===== 1) 입력 검증부 ===== */
    h_pid = getl(b, T_PURCHASE_ID);
    if (h_pid <= 0) {
        setl(b, T_RC, 8801); Bchg(b, T_MSG, 0, "매입 ID(purchase_id) 필수", 0L);
        userlog("[ACQ_RETRIEVAL] 매입 ID 검증 실패 pid=%ld", h_pid); FAIL(b);
    }
    gets_(b, T_STR1, reason, sizeof(reason));
    if (strcmp(reason, "FULFILL") == 0) fulfil = 1;
    if (reason[0] == 0) strcpy(reason, "매출전표사본");
    strncpy(h_reason, reason, sizeof(h_reason)-1); h_reason[sizeof(h_reason)-1] = 0;
    userlog("[운영] 조회요청 진입 pid=%ld action=%s", h_pid, fulfil ? "FULFILL" : reason);

    /* ===== 2) 매입 컨텍스트 조회부 (가맹점/영업일) ===== */
    EXEC SQL SELECT merchant_id, biz_date INTO :h_merch, :h_bizdate FROM purchase WHERE purchase_id = :h_pid;
    if (sqlca.sqlcode == 100) {
        strcpy(h_merch, "UNKNOWN");
        if (h_bizdate[0] == 0) strcpy(h_bizdate, "2026-07-19");
        userlog("[ACQ_RETRIEVAL] 매입 미조회 pid=%ld — 기본값으로 진행", h_pid);
    } else if (sqlca.sqlcode < 0) {
        setl(b, T_RC, 8810); Bchg(b, T_MSG, 0, "매입 조회 오류", 0L); FAIL(b);
    }

    /* ===== 3) action 분기부 (이행 / 신규 생성) ===== */
    if (fulfil) {
        /* 이행: 열린 조회요청 1건을 FULFILLED 로 전이 */
        EXEC SQL SELECT retr_id INTO :h_retr FROM ac_retrieval
            WHERE purchase_id = :h_pid AND status = 'OPEN' ORDER BY retr_id LIMIT 1;
        if (sqlca.sqlcode == 100) {
            Bchg(b, T_STATUS, 0, "NOOPEN", 0L);
            setl(b, T_ID1, 0); Bchg(b, T_SVCNAME, 0, "ACQ_RETRIEVAL", 0L); setl(b, T_RC, 0);
            userlog("[ACQ_RETRIEVAL] 이행 대상(OPEN) 없음 pid=%ld", h_pid);
            OK(b);
        } else if (sqlca.sqlcode < 0) {
            setl(b, T_RC, 8811); Bchg(b, T_MSG, 0, "조회요청 조회 오류", 0L); FAIL(b);
        }
        strcpy(h_status, "FULFILLED");
        EXEC SQL UPDATE ac_retrieval SET status = 'FULFILLED', fulfilled_at = now()
            WHERE retr_id = :h_retr;
        if (sqlca.sqlcode < 0) {
            setl(b, T_RC, 8820); Bchg(b, T_MSG, 0, "조회요청 이행 실패", 0L);
            userlog("[ACQ_RETRIEVAL] FULFILL UPDATE 실패 [%d] retr=%ld", sqlca.sqlcode, h_retr); FAIL(b);
        }
    } else {
        /* 신규: OPEN 조회요청 생성(SLA = today + 20) */
        strcpy(h_status, "OPEN");
        EXEC SQL SELECT nextval('ac_retrieval_seq') INTO :h_retr;
        if (sqlca.sqlcode < 0) { setl(b, T_RC, 8821); Bchg(b, T_MSG, 0, "조회요청 시퀀스 실패", 0L); FAIL(b); }
        EXEC SQL INSERT INTO ac_retrieval
            (retr_id, purchase_id, merchant_id, reason, status, sla_due)
            VALUES (:h_retr, :h_pid, :h_merch, :h_reason, 'OPEN', CURRENT_DATE + 20);
        if (sqlca.sqlcode < 0) {
            setl(b, T_RC, 8822); Bchg(b, T_MSG, 0, "조회요청 적재 실패", 0L);
            userlog("[ACQ_RETRIEVAL] ac_retrieval INSERT 실패 [%d]", sqlca.sqlcode); FAIL(b);
        }
    }

    /* ===== 4) 감사이력 적재부 (cm_log) ===== */
    snprintf(msgbuf, sizeof(msgbuf), "ACQ_RETRIEVAL pid=%ld retr=%ld merch=%s status=%s reason=%s",
             h_pid, h_retr, h_merch, h_status, h_reason);
    strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-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_msg, :h_bizdate);
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 8830); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); }

    /* ===== 5) 재검증부 (적재/전이 상태 재조회) ===== */
    EXEC SQL SELECT retr_id INTO :h_chk FROM ac_retrieval WHERE retr_id = :h_retr AND status = :h_status;
    if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
        setl(b, T_RC, 8840); Bchg(b, T_MSG, 0, "조회요청 재검증 실패", 0L);
        userlog("[ACQ_RETRIEVAL] 재검증 실패 code=%d retr=%ld status=%s", sqlca.sqlcode, h_retr, h_status); FAIL(b);
    }

    /* ===== 6) 응답부 (계약: T_ID1=retr_id, T_STATUS) ===== */
    setl(b, T_ID1, h_retr);
    Bchg(b, T_STATUS, 0, h_status, 0L);
    setl(b, T_PURCHASE_ID, h_pid);
    Bchg(b, T_MERCHANT, 0, h_merch, 0L);
    Bchg(b, T_REASON, 0, h_reason, 0L);
    Bchg(b, T_SVCNAME, 0, "ACQ_RETRIEVAL", 0L);
    setl(b, T_RC, 0);

    /* ===== 7) 완료 로깅 ===== */
    userlog("[운영] 조회요청 완료 pid=%ld retr=%ld status=%s merch=%s", h_pid, h_retr, h_status, h_merch);
    OK(b);
}

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