/* @tier medium @module cm @transform common-online */ /* * cm_ol_0020.pgc - 금액 한글 표기 서비스 (CM_OL_0020) [tier=medium] * * 요청의 금액(AMOUNT)을 만/억/조 단위 절(節)로 분해하여 한글 금액표기 * (예: 123000000 -> "일억이천삼백만")로 변환하여 응답한다. 증서/전표 * 출력용 변환 서비스. 변환 결과는 증서 발급 감사이력(cm_amt_hangeul_log) * 에 적재하여 발급 근거로 남긴다. (ATMI void SVC(TPSVCINFO*) 대응) */ #include #include #include "txcore.h" #include "txcore_dbio.h" #include "acq_util.h" #include "cm_core.h" EXEC SQL INCLUDE sqlca; /* 0~9999 한 절(節)을 천/백/십 단위 한글로 변환하여 out 에 누적 */ static void hangeul_group(int val, char *out, int outlen) { static const char *DIG[10] = { "", "일", "이", "삼", "사", "오", "육", "칠", "팔", "구" }; static const char *POS[4] = { "", "십", "백", "천" }; int unit[4]; int i; unit[3] = (val / 1000) % 10; unit[2] = (val / 100) % 10; unit[1] = (val / 10) % 10; unit[0] = val % 10; for (i = 3; i >= 0; i--) { if (unit[i] == 0) continue; /* 십/백/천 자리의 '일'은 관용상 생략 (예: 15 -> 십오) */ if (!(unit[i] == 1 && i > 0)) strncat(out, DIG[unit[i]], outlen - strlen(out) - 1); strncat(out, POS[i], outlen - strlen(out) - 1); } } TX_SERVICE(CM_OL_0020, ctx) { static const char *GUNIT[4] = { "", "만", "억", "조" }; EXEC SQL BEGIN DECLARE SECTION; long h_amount; char h_hangeul[128]; EXEC SQL END DECLARE SECTION; char hangeul[128]; char won_fmt[48]; long amount = 0; long n; long logged = 0; int neg = 0; int groups[4]; int i; tx_log(TX_LOG_INFO, "[CM_OL_0020] 금액 한글 표기 서비스 진입"); if (tx_buf_getlong(ctx->in, "AMOUNT", &amount) != TX_OK) { tx_log(TX_LOG_ERROR, "[CM_OL_0020] AMOUNT 누락"); tx_return(ctx, TX_EINVAL, ctx->out); return; } hangeul[0] = '\0'; n = amount; if (n < 0) { neg = 1; n = -n; } if (n == 0) { strncpy(hangeul, "영", sizeof(hangeul) - 1); } else { /* 4자리 절 단위 분해: 일/만/억/조 (조 단위까지 지원) */ for (i = 0; i < 4; i++) { groups[i] = (int)(n % 10000); n /= 10000; } for (i = 3; i >= 0; i--) { if (groups[i] == 0) continue; hangeul_group(groups[i], hangeul, sizeof(hangeul)); strncat(hangeul, GUNIT[i], sizeof(hangeul) - strlen(hangeul) - 1); } } strncat(hangeul, "원", sizeof(hangeul) - strlen(hangeul) - 1); if (neg) { char tmp[128]; snprintf(tmp, sizeof(tmp), "마이너스%s", hangeul); strncpy(hangeul, tmp, sizeof(hangeul) - 1); hangeul[sizeof(hangeul) - 1] = '\0'; } /* 교차표시용: 콤마 구분 숫자표기 */ amount_format_won(amount, won_fmt, sizeof(won_fmt)); /* 변환 결과 증서 감사이력 적재 */ h_amount = amount; strncpy(h_hangeul, hangeul, sizeof(h_hangeul) - 1); h_hangeul[sizeof(h_hangeul) - 1] = '\0'; if (tx_begin() != TX_OK) { tx_log(TX_LOG_WARN, "[CM_OL_0020] tx_begin 경고"); } else { EXEC SQL INSERT INTO cm_amt_hangeul_log (amount, hangeul_txt, conv_ts) VALUES (:h_amount, :h_hangeul, now()); if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("CM_OL_0020 INSERT cm_amt_hangeul_log"); tx_abort(); } else { logged = (long)sqlca.sqlerrd[2]; tx_commit(); } } tx_buf_reset(ctx->out); tx_buf_setlong(ctx->out, "AMOUNT", amount); tx_buf_sets(ctx->out, "HANGEUL", hangeul); tx_buf_sets(ctx->out, "WON", won_fmt); tx_buf_setlong(ctx->out, "LOGGED", logged); tx_log(TX_LOG_INFO, "[CM_OL_0020] 변환완료 amount=%ld -> %s", amount, hangeul); tx_return(ctx, TX_OK, ctx->out); }