merge master into develop - CscListRForm.jsp FAQ 아코디언 버그 수정

This commit is contained in:
jilee4unity
2026-05-28 23:34:06 +09:00
7250 changed files with 570509 additions and 25 deletions

View File

@@ -0,0 +1,933 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wb.domainserver.domain.gcone.bnft.purstmp.mapper.BOPurstmpStampMapper">
<!-- gc_order 테이블에서 매장 구매 정보 조회 (스탬프 적립/차감 처리용) -->
<select id="selectStoreOrdersForStamp"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- gc_order 테이블에서 매장 구매 정보 조회 (디바이스 등록일 기준 조회기간 적용)
SELECT
O.ORDR_INNB AS ORDR_INNB, -- 주문 고유번호
O.STR_INNB AS STR_INNB, -- 매장 고유번호
O.RL_SETLE_AMT AS RL_SETLE_AMT, -- 실 결제금액
CASE
WHEN ST.TENTCPN_NM IS NOT NULL THEN ST.TENTCPN_NM
WHEN ST.STR_NM IS NOT NULL THEN ST.STR_NM
ELSE CONCAT('매장_', O.STR_INNB)
END AS STR_NM, -- 매장명
DATE_FORMAT(O.SETLE_COMPT_DT, '%Y-%m-%d %H:%i:%s') AS SETLE_COMPT_DT, -- 결제완료일시
O.SLE_ENVRN_CD AS SLE_ENVRN_CD, -- 판매환경코드
O.SKN_ENVRN_CD AS SKN_ENVRN_CD, -- 스킨환경코드
O.ORDR_STTUS_CD AS ORDR_STTUS_CD, -- 주문상태코드 추가
CASE
WHEN O.ORDR_STTUS_CD IN ('25', '30', '35', '40', '45', '50', '55', '60', '65', '70', '75', '80') THEN 'ACCUMULATE'
WHEN O.ORDR_STTUS_CD IN ('85', '95', '99') THEN 'DEDUCT'
ELSE 'IGNORE'
END AS STAMP_ACTION -- 스탬프 처리 액션 (적립/차감/무시)
FROM
GC_ORDER O
LEFT JOIN
GC_STORE ST ON O.STR_INNB = ST.STR_INNB
LEFT JOIN
GC_BENEFIT_STMP BS ON O.ORDR_INNB = BS.ORDR_INNB
AND O.MBR_INNB = BS.MBR_INNB
AND O.SOPMAL_CD = BS.SOPMAL_CD
-- 회원 디바이스 정보 JOIN 추가 (조회 기간 산정용)
LEFT JOIN
GC_MEMBER_DEVICE_INFO MDI ON O.MBR_INNB = MDI.MBR_INNB
AND O.MBR_DV_CD = MDI.MBR_DV_CD
AND O.SOPMAL_CD = MDI.SOPMAL_CD
WHERE
O.MBR_INNB = #{mbrInnb}
AND O.MBR_DV_CD = #{mbrDvCd}
AND O.SOPMAL_CD = #{sopmalCd}
AND O.USE_AT = 'Y'
AND (
-- 스탬프 적립 대상 (정상 결제완료 상태)
O.ORDR_STTUS_CD IN ('25', '30', '35', '40', '45', '50', '55', '60', '65', '70', '75', '80')
OR
-- 스탬프 차감 대상 (결제취소/주문무효/결제실패)
O.ORDR_STTUS_CD IN ('85')
)
AND (
-- gc_order 참고사항: 매장 구매금액 조건
O.SLE_ENVRN_CD IN ('S1', 'S2', 'S3')
OR O.SKN_ENVRN_CD = 'POS'
)
-- 차감 대상은 이미 처리된 주문도 포함
AND (
(O.ORDR_STTUS_CD IN ('25', '30', '35', '40', '45', '50', '55', '60', '65', '70', '75', '80') AND BS.ORDR_INNB IS NULL) -- 적립: 미처리만
OR
(O.ORDR_STTUS_CD IN ('85') AND BS.ORDR_INNB IS NOT NULL AND BS.REFUND_AT = 'N') -- 차감: 이미 적립된 것만
)
<if test="strInnb != null and strInnb != '' and strInnb != 'null'">
AND O.STR_INNB = #{strInnb}
</if>
AND O.SETLE_COMPT_DT IS NOT NULL
-- 디바이스 등록일부터 현재까지 조회 (디바이스 정보 없으면 전체 조회)
<if test="true">
AND (MDI.REGIST_DT IS NULL OR O.SETLE_COMPT_DT &gt;= DATE(MDI.REGIST_DT))
</if>
AND O.SETLE_COMPT_DT &lt;= NOW() -- 현재까지
ORDER BY
O.SETLE_COMPT_DT DESC
</select>
<!-- 매장별 적립카드 조회 (유효기간 내, 교환권 포함) - 정렬 수정 -->
<select id="selectStampCards" parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO" resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 매장별 진행 중인 스탬프 적립카드와 교환권 정보 조회 (쿠폰 정보 포함, 매장명 개선)
SELECT
SE.BNF_EXTIKET_INNB AS BNF_EXTIKET_INNB, -- 교환권 고유번호
SE.SOPMAL_CD AS SOPMAL_CD, -- 쇼핑몰코드
SE.STR_INNB AS STR_INNB, -- 매장 고유번호
CASE
WHEN ST.STR_NM IS NOT NULL THEN ST.STR_NM
WHEN ST.TENTCPN_NM IS NOT NULL THEN ST.TENTCPN_NM
ELSE CONCAT('매장_', SE.STR_INNB)
END AS STR_NM, -- 매장명 (gc_store 테이블 연동)
SE.MBR_INNB AS MBR_INNB, -- 회원 고유번호
SE.MBR_DV_CD AS MBR_DV_CD, -- 회원 구분코드
SE.EXTIKET_STMP_CNT AS EXTIKET_STMP_CNT, -- 교환권 스탬프 수
DATE_FORMAT(SE.STMP_VALID_DT, '%Y-%m-%d') AS STMP_VALID_DT, -- 스탬프 유효일시
SE.EXCHNG_AT AS EXCHNG_AT, -- 교환여부
SE.COUPON_INNB AS COUPON_INNB, -- 쿠폰고유번호
DATE_FORMAT(SE.REGIST_DT, '%Y-%m-%d') AS REGIST_DT, -- 등록일시
CASE
WHEN SE.EXCHNG_AT = 'Y' THEN 'COMPLETED'
WHEN NOW() &gt; SE.STMP_VALID_DT THEN 'EXPIRED'
ELSE 'ACTIVE'
END AS STATUS,
CASE
WHEN SE.COUPON_INNB IS NOT NULL THEN 'Y'
ELSE 'N'
END AS HAS_COUPON
FROM
GC_BENEFIT_STMP_EXTIKET SE
LEFT JOIN
GC_STORE ST ON SE.STR_INNB = ST.STR_INNB
WHERE
SE.MBR_INNB = #{mbrInnb}
AND SE.MBR_DV_CD = #{mbrDvCd}
AND SE.SOPMAL_CD = #{sopmalCd}
<if test="strInnb != null and strInnb != '' and strInnb > 0">
AND SE.STR_INNB = #{strInnb}
</if>
AND (
-- 유효기간 내의 카드이거나 교환권 발급 완료된 카드
(NOW() &lt;= SE.STMP_VALID_DT OR SE.EXCHNG_AT = 'Y')
)
ORDER BY
-- 교환되지 않은 카드를 먼저 표시
CASE WHEN SE.EXCHNG_AT = 'N' THEN 0 ELSE 1 END ASC,
SE.REGIST_DT ASC
</select>
<!-- 보유한 적립카드 개수 조회 (교환권 발급 완료 건도 포함) -->
<select id="selectTotalCardCount" parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO" resultType="int">
-- 보유한 적립카드 개수 조회 (교환권 발급 완료 건도 포함)
SELECT
COUNT(*) AS CARD_COUNT
FROM
GC_BENEFIT_STMP_EXTIKET SE
WHERE
SE.MBR_INNB = #{mbrInnb}
AND SE.MBR_DV_CD = #{mbrDvCd}
AND SE.SOPMAL_CD = #{sopmalCd}
AND NOW() &lt;= SE.STMP_VALID_DT
</select>
<!-- 스탬프 적립 내역 조회 -->
<select id="selectRecentPurchasesWithStamps"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 최근 스탬프 적립 내역 조회 (매장명 연동)
SELECT
BS.BNF_STMP_INNB AS BNF_STMP_INNB,
BS.ORDR_INNB AS ORDR_INNB,
BS.REFUND_AT AS REFUND_AT,
BS.PURCHS_AMT AS PURCHS_AMT,
BS.RL_SETLE_AMT AS RL_SETLE_AMT,
BS.STMP_CNT AS STMP_CNT,
BS.AMT_FOR_CHG AS AMT_FOR_CHG,
DATE_FORMAT(BS.SETLE_COMPT_DT, '%Y-%m-%d %H:%i:%s') AS SETLE_COMPT_DT,
DATE_FORMAT(BS.REGIST_DT, '%Y-%m-%d %H:%i:%s') AS REGIST_DT,
CASE
WHEN ST.STR_NM IS NOT NULL THEN ST.STR_NM
WHEN ST.TENTCPN_NM IS NOT NULL THEN ST.TENTCPN_NM
ELSE CONCAT('매장_', BS.STR_INNB)
END AS BRANCH_NAME -- 매장명 (gc_store 테이블 연동)
FROM
GC_BENEFIT_STMP BS
LEFT JOIN
GC_STORE ST ON BS.STR_INNB = ST.STR_INNB
WHERE
BS.MBR_INNB = #{mbrInnb}
AND BS.MBR_DV_CD = #{mbrDvCd}
AND BS.SOPMAL_CD = #{sopmalCd}
AND (BS.REFUND_AT IS NULL OR BS.REFUND_AT != 'Y') -- 환불된 건 제외
<if test="strInnb != null and strInnb != ''">
AND BS.STR_INNB = #{strInnb}
</if>
AND BS.REGIST_DT &gt;= DATE_SUB(NOW(), INTERVAL 12 MONTH)
ORDER BY
BS.REGIST_DT DESC
LIMIT 20
</select>
<!-- 스탬프 적립 내역 추가 로딩 (스크롤 시 20개 추가) - 컬럼 추가 -->
<select id="selectMorePurchasesWithStamps"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 스크롤 시 추가 로딩할 스탬프 적립 내역 조회
SELECT
BS.BNF_STMP_INNB AS BNF_STMP_INNB,
BS.ORDR_INNB AS ORDR_INNB,
BS.REFUND_AT AS REFUND_AT,
BS.PURCHS_AMT AS PURCHS_AMT,
BS.RL_SETLE_AMT AS RL_SETLE_AMT,
BS.STMP_CNT AS STMP_CNT,
BS.AMT_FOR_CHG AS AMT_FOR_CHG,
DATE_FORMAT(BS.SETLE_COMPT_DT, '%Y-%m-%d %H:%i:%s') AS SETLE_COMPT_DT,
DATE_FORMAT(BS.REGIST_DT, '%Y-%m-%d %H:%i:%s') AS REGIST_DT,
CASE
WHEN ST.STR_NM IS NOT NULL THEN ST.STR_NM
WHEN ST.TENTCPN_NM IS NOT NULL THEN ST.TENTCPN_NM
ELSE CONCAT('매장_', BS.STR_INNB)
END AS BRANCH_NAME
FROM
GC_BENEFIT_STMP BS
LEFT JOIN
GC_STORE ST ON BS.STR_INNB = ST.STR_INNB
WHERE
BS.MBR_INNB = #{mbrInnb}
AND BS.MBR_DV_CD = #{mbrDvCd}
AND BS.SOPMAL_CD = #{sopmalCd}
AND (BS.REFUND_AT IS NULL OR BS.REFUND_AT != 'Y') -- 환불된 건 제외
<if test="strInnb != null and strInnb != ''">
AND BS.STR_INNB = #{strInnb}
</if>
AND BS.REGIST_DT &gt;= DATE_SUB(NOW(), INTERVAL 12 MONTH)
<if test="lastStmpInnb != null and lastStmpInnb &gt; 0">
AND BS.REGIST_DT &lt; (
SELECT REGIST_DT
FROM GC_BENEFIT_STMP
WHERE BNF_STMP_INNB = #{lastStmpInnb}
)
</if>
ORDER BY
BS.REGIST_DT DESC
LIMIT 20
</select>
<!-- 새로운 스탬프 적립 기록 추가 -->
<insert id="insertNewPurchase" parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO">
-- 새로운 구매 기록 추가 및 스탬프 적립
INSERT INTO GC_BENEFIT_STMP (
SOPMAL_CD, -- 쇼핑몰코드
STR_INNB, -- 매장고유번호
ORDR_INNB, -- 주문 고유번호
REFUND_AT, -- 환불여부
MBR_INNB, -- 회원고유번호
MBR_DV_CD, -- 회원구분코드
PURCHS_INNB, -- 구매식별 고유번호
PURCHS_AMT, -- 구매금액
RL_SETLE_AMT, -- 실 결제금액
SETLE_COMPT_DT, -- 결제완료일시
STMP_CNT, -- 적립 스탬프 수
AMT_FOR_CHG, -- 충전필요금액
REGIST_DT -- 등록일시
) VALUES (
#{sopmalCd},
#{strInnb},
#{ordrInnb},
IFNULL(#{refundAt}, 'N'),
#{mbrInnb},
#{mbrDvCd},
#{purchsInnb},
#{purchsAmt},
#{rlSetleAmt},
#{setleCmptDt},
#{stmpCnt},
#{amtForChg},
NOW()
)
</insert>
<!-- 새로운 적립카드(교환권) 생성 -->
<insert id="insertExchangeTicket"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
useGeneratedKeys="true"
keyProperty="bnfExtiketInnb">
-- 새로운 교환권(스탬프 적립카드) 생성
INSERT INTO GC_BENEFIT_STMP_EXTIKET (
SOPMAL_CD,
STR_INNB,
MBR_INNB,
MBR_DV_CD,
EXTIKET_STMP_CNT,
STMP_VALID_DT,
EXCHNG_AT,
REGIST_DT
) VALUES (
#{sopmalCd},
#{strInnb},
#{mbrInnb},
#{mbrDvCd},
#{extiketStmpCnt},
<choose>
<when test="stmpValidDt != null">
#{stmpValidDt}
</when>
<otherwise>
DATE_ADD(NOW(), INTERVAL 12 MONTH) -- 기본: 현재시점으로부터 12개월
</otherwise>
</choose>,
IFNULL(#{exchngAt}, 'N'),
NOW()
)
</insert>
<!-- Step 1: 교환권 완료 대상 PK 조회 -->
<select id="selectExchangeTicketForComplete"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="Long">
-- 교환권 완료 처리 대상 PK 조회
SELECT
BNF_EXTIKET_INNB
FROM
GC_BENEFIT_STMP_EXTIKET
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
AND EXCHNG_AT = 'N'
AND EXTIKET_STMP_CNT = #{requiredStampCnt}
AND NOW() &lt;= STMP_VALID_DT
ORDER BY
REGIST_DT ASC
LIMIT 1
</select>
<!-- Step 2: PK 기준 교환권 완료 처리 (쿠폰 포함) -->
<update id="completeExchangeTicketWithCoupon"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO">
-- PK 기준 교환권 완료 처리 (쿠폰 정보 포함)
UPDATE
GC_BENEFIT_STMP_EXTIKET
SET
EXCHNG_AT = 'Y',
EXCHNG_DT = NOW(),
COUPON_INNB = #{couponInnb},
UPDT_DT = NOW()
WHERE
BNF_EXTIKET_INNB = #{bnfExtiketInnb}
AND MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
</update>
<!-- ✅ 새로 추가: 쿠폰 번호만 업데이트하는 쿼리 -->
<update id="updateExchangeTicketCouponOnly"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO">
-- 교환권에 쿠폰 번호만 업데이트
UPDATE
GC_BENEFIT_STMP_EXTIKET
SET
COUPON_INNB = #{couponInnb},
UPDT_DT = NOW()
WHERE
BNF_EXTIKET_INNB = #{bnfExtiketInnb}
AND EXCHNG_AT = 'Y' -- 이미 완료된 상태에서만 업데이트
-- 추가 조건 제거하여 업데이트 확률 높임
</update>
<!-- 교환권 사용 완료 후 적립카드 삭제 처리 -->
<update id="deleteCompletedExchangeTicket" parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO">
-- 교환권 사용 완료 후 적립카드 삭제 처리
DELETE FROM
GC_BENEFIT_STMP_EXTIKET
WHERE
BNF_EXTIKET_INNB = #{bnfExtiketInnb}
AND MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND EXCHNG_AT = 'Y'
</update>
<!-- 총 미교환 스탬프 수 조회 -->
<select id="selectTotalUnexchangedStamps"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="int">
-- ✅ 수정: 실제 사용 가능한 스탬프 수 조회 (완료된 교환권의 스탬프만 제외)
SELECT
GREATEST(0,
(
-- 총 적립된 스탬프 수
SELECT IFNULL(SUM(STMP_CNT), 0)
FROM GC_BENEFIT_STMP
WHERE MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
AND REFUND_AT = 'N'
) - (
-- 완료된 교환권의 스탬프만 차감 (진행 중인 것은 제외)
SELECT IFNULL(SUM(EXTIKET_STMP_CNT), 0)
FROM GC_BENEFIT_STMP_EXTIKET
WHERE MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
AND EXCHNG_AT = 'Y' -- 완료된 교환권만 차감
)
) AS AVAILABLE_STAMPS
</select>
<!-- 잔액 조회 수정 (동적 스탬프 기준 금액 적용) -->
<select id="selectRemainingAmount"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="java.lang.Double">
-- 간단한 잔액 조회 (0으로 고정 - 매번 새로운 구매로 처리)
SELECT 0.0 AS REMAINING_AMOUNT
</select>
<!-- 교환권 갯수 조회 -->
<select id="selectTotalRowCountFromBenefitExtiket"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="int">
-- 특정 회원의 유효한 교환권 개수 조회
SELECT
COUNT(*) AS TOTAL_COUNT
FROM
GC_BENEFIT_STMP_EXTIKET
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
<if test="strInnb != null and strInnb != ''">
AND STR_INNB = #{strInnb}
</if>
AND NOW() &lt;= STMP_VALID_DT
</select>
<!-- 스탬프 화면 정보 조회 (gc_benefit_content 테이블 연동) -->
<select id="selectPurstmpScreenInfo"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 스탬프 적립 이벤트의 화면 정보 조회
SELECT
B.BNF_INNB AS BNF_INNB, -- 혜택 설정 고유번호
BC.CN_SJ AS CN_SJ, -- 컨텐츠 제목
BC.IMG_FIL_COURS AS IMG_FIL_COURS, -- 이미지 파일 경로
BC.WORDS_CN AS WORDS_CN -- 안내 내용
FROM
GC_BENEFIT B
INNER JOIN
GC_BENEFIT_CONTENT BC ON B.BNF_INNB = BC.BNF_INNB
WHERE
B.BNF_DV_CD = '140' -- 스탬프 적립 이벤트 코드 (140)
AND B.SOPMAL_CD = #{sopmalCd}
ORDER BY
B.BNF_INNB DESC
LIMIT 1
</select>
<!-- 관리자 설정 이달의 선물 정보 조회 -->
<select id="selectMonthlyGiftInfo"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
SELECT
B.BNF_INNB AS BNF_INNB, -- 혜택 설정 고유번호
BC.COUPON_INNB AS COUPON_INNB -- 쿠폰 고유번호
FROM
GC_BENEFIT B
INNER JOIN
GC_BENEFIT_REWARD BC ON B.BNF_INNB = BC.BNF_INNB
WHERE
B.BNF_DV_CD = '140' -- 스탬프 적립 이벤트 코드 (140)
AND B.SOPMAL_CD = #{sopmalCd}
ORDER BY
B.BNF_INNB DESC
</select>
<!-- selectCurrentExchangeTicket 수정 -->
<select id="selectCurrentExchangeTicket"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
SELECT
BNF_EXTIKET_INNB AS bnfExtiketInnb,
EXTIKET_STMP_CNT AS extiketStmpCnt
FROM
GC_BENEFIT_STMP_EXTIKET
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
AND EXCHNG_AT = 'N'
AND EXTIKET_STMP_CNT &lt; 10
AND NOW() &lt;= STMP_VALID_DT
ORDER BY
REGIST_DT ASC
LIMIT 1
</select>
<!-- 교환권 스탬프 수 업데이트 -->
<update id="updateExchangeTicketStampCount">
-- 교환권의 스탬프 수를 업데이트
UPDATE
GC_BENEFIT_STMP_EXTIKET
SET
EXTIKET_STMP_CNT = EXTIKET_STMP_CNT + #{newStampCount},
UPDT_DT = NOW()
WHERE
BNF_EXTIKET_INNB = #{extiketInnb}
</update>
<!-- 쿠폰(교환권) 목록 조회 - 정렬 수정 -->
<select id="selectCouponList"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 회원의 쿠폰(교환권) 목록 조회 (쿠폰 정보 포함, 매장명 개선)
SELECT
SE.BNF_EXTIKET_INNB AS bnfExtiketInnb,
SE.SOPMAL_CD AS sopmalCd,
SE.STR_INNB AS strInnb,
CASE
WHEN ST.STR_NM IS NOT NULL THEN ST.STR_NM
WHEN ST.TENTCPN_NM IS NOT NULL THEN ST.TENTCPN_NM
ELSE CONCAT('매장_', SE.STR_INNB)
END AS branchName, -- 매장명 (gc_store 테이블 연동)
SE.MBR_INNB AS mbrInnb,
SE.MBR_DV_CD AS mbrDvCd,
SE.EXTIKET_STMP_CNT AS extiketStmpCnt,
DATE_FORMAT(SE.STMP_VALID_DT, '%Y-%m-%d %H:%i:%s') AS stmpValidDt,
SE.EXCHNG_AT AS exchngAt,
DATE_FORMAT(SE.EXCHNG_DT, '%Y-%m-%d %H:%i:%s') AS exchngDt,
DATE_FORMAT(SE.REGIST_DT, '%Y-%m-%d %H:%i:%s') AS registDt,
DATE_FORMAT(SE.UPDT_DT, '%Y-%m-%d %H:%i:%s') AS updtDt,
SE.COUPON_INNB AS couponInnb,
CASE
WHEN SE.EXCHNG_AT = 'N' AND NOW() &lt;= SE.STMP_VALID_DT AND SE.EXTIKET_STMP_CNT >= 10 THEN 'Y'
ELSE 'N'
END AS exchangeable,
CASE
WHEN SE.COUPON_INNB IS NOT NULL THEN 'Y'
ELSE 'N'
END AS hasCoupon
FROM
GC_BENEFIT_STMP_EXTIKET SE
LEFT JOIN
GC_STORE ST ON SE.STR_INNB = ST.STR_INNB
WHERE
SE.MBR_INNB = #{mbrInnb}
AND SE.MBR_DV_CD = #{mbrDvCd}
AND SE.SOPMAL_CD = #{sopmalCd}
<if test="strInnb != null and strInnb != ''">
AND SE.STR_INNB = #{strInnb}
</if>
ORDER BY
-- 교환되지 않은 쿠폰을 먼저 표시
CASE WHEN SE.EXCHNG_AT = 'N' THEN 0 ELSE 1 END ASC,
-- 교환되지 않은 쿠폰들은 최신순으로, 교환된 쿠폰들도 최신순으로
SE.REGIST_DT DESC
</select>
<!-- 특정 교환권 정보 조회 -->
<select id="selectSpecificVoucherInfo"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 특정 교환권의 상세 정보 조회
SELECT
SE.BNF_EXTIKET_INNB AS bnfExtiketInnb,
SE.SOPMAL_CD AS sopmalCd,
SE.STR_INNB AS strInnb,
CASE
WHEN ST.STR_NM IS NOT NULL THEN ST.STR_NM
WHEN ST.TENTCPN_NM IS NOT NULL THEN ST.TENTCPN_NM
ELSE CONCAT('매장_', SE.STR_INNB)
END AS branchName,
SE.MBR_INNB AS mbrInnb,
SE.MBR_DV_CD AS mbrDvCd,
SE.EXTIKET_STMP_CNT AS extiketStmpCnt,
DATE_FORMAT(SE.STMP_VALID_DT, '%Y-%m-%d %H:%i:%s') AS stmpValidDt,
SE.EXCHNG_AT AS exchngAt,
DATE_FORMAT(SE.EXCHNG_DT, '%Y-%m-%d %H:%i:%s') AS exchngDt,
DATE_FORMAT(SE.REGIST_DT, '%Y-%m-%d %H:%i:%s') AS registDt,
DATE_FORMAT(SE.UPDT_DT, '%Y-%m-%d %H:%i:%s') AS updtDt
FROM
GC_BENEFIT_STMP_EXTIKET SE
LEFT JOIN
GC_STORE ST ON SE.STR_INNB = ST.STR_INNB
WHERE
SE.BNF_EXTIKET_INNB = #{bnfExtiketInnb}
AND SE.MBR_INNB = #{mbrInnb}
AND SE.MBR_DV_CD = #{mbrDvCd}
AND SE.SOPMAL_CD = #{sopmalCd}
</select>
<!-- 기존 구매 데이터 개수 조회 (더 정확한 조건) -->
<select id="countExistingPurchaseData"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="int">
-- 특정 회원의 기존 구매 데이터 개수 확인
SELECT
COUNT(*) AS PURCHASE_COUNT
FROM
GC_BENEFIT_STMP
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND REGIST_DT &gt;= DATE_SUB(NOW(), INTERVAL 6 MONTH) -- 최근 6개월 데이터만 확인
</select>
<!-- 기존 교환권 데이터 개수 조회 (더 정확한 조건) -->
<select id="countExistingTicketData"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="int">
-- 특정 회원의 기존 교환권 데이터 개수 확인
SELECT
COUNT(*) AS TICKET_COUNT
FROM
GC_BENEFIT_STMP_EXTIKET
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND REGIST_DT &gt;= DATE_SUB(NOW(), INTERVAL 6 MONTH) -- 최근 6개월 데이터만 확인
</select>
<!-- 스탬프 교환 보상 정보 조회 (gc_benefit_reward에서) -->
<select id="selectStampExchangeReward"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 스탬프 교환 보상 정보 조회 (쿠폰/마일리지)
SELECT
br.BNF_RWD_CATE_DV_CD AS BNF_RWD_CATE_DV_CD, -- 보상 항목 구분 코드
br.BNF_RWD_GODS_DV_CD AS BNF_RWD_GODS_DV_CD, -- 보상 상품 구분 코드
br.MLG_RWD_AMT AS MLG_RWD_AMT, -- 마일리지 보상 금액
br.COUPON_INNB AS COUPON_INNB, -- 쿠폰 고유 번호
COALESCE(cs.COUPON_SNDNG_NM, br.ITM_NM) AS ITM_NM -- 쿠폰 이름
FROM
GC_BENEFIT_REWARD br
LEFT JOIN
GC_COUPON_SNDNG cs ON br.COUPON_INNB = cs.COUPON_SNDNG_INNB
AND cs.SOPMAL_CD = #{sopmalCd}
WHERE
br.BNF_INNB = #{bnfInnb}
AND br.BNF_RWD_CATE_DV_CD LIKE '14%' -- 모바일스탬프(140) 관련 보상
ORDER BY
br.BNF_RWD_CATE_DV_CD
LIMIT 1
</select>
<!-- 스탬프 혜택 참여 정보 저장 -->
<insert id="insertStampParticipation"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
useGeneratedKeys="true"
keyProperty="bnfPrtInnb"
keyColumn="BNF_PRT_INNB">
-- 스탬프 적립 시 혜택 참여 정보 저장
INSERT INTO GC_BENEFIT_PARTCPTN (
BNF_INNB, -- 혜택 고유 번호
BNF_PRT_DT, -- 혜택 참여 일시
MBR_INNB, -- 회원 고유 번호
MBR_DV_CD, -- 회원 구분 코드
STR_INNB, -- 매장 고유번호 (스탬프용)
REGUSR, -- 등록자
REGIST_DT -- 등록 일시
) VALUES (
#{bnfInnb},
NOW(),
#{mbrInnb},
#{mbrDvCd},
#{strInnb},
#{regusr},
NOW()
)
</insert>
<!-- 스탬프 혜택 설정 정보 조회 -->
<select id="selectStampBenefitInfo"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
<![CDATA[
-- 스탬프 혜택 설정 정보 조회
SELECT
BNF_INNB, -- 혜택 고유 번호
USE_AT, -- 사용여부
BNF_BGN_DT, -- 진행기간 시작일시
BNF_END_DT, -- 진행기간 종료일시
SCR_REPRSNT_IMG, -- 화면 대표 이미지 경로
SCR_RWD_IMG, -- 보상 이미지 경로
BNF_WORDS_CN -- 혜택 안내 문구
FROM
GC_BENEFIT
WHERE
BNF_DV_CD = '140' -- 모바일스탬프 혜택 구분 코드
AND SOPMAL_CD = #{sopmalCd}
ORDER BY
BNF_INNB DESC
LIMIT 1
]]>
</select>
<!-- 혜택 보상 영수증 저장 수정 -->
<insert id="insertMileageReceipt" parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
useGeneratedKeys="true" keyProperty="bnfRcvInnb" keyColumn="BNF_RCV_INNB">
INSERT INTO GC_BENEFIT_RECEIPT (
BNF_PRT_INNB, -- 혜택 참여 고유 번호
BNF_RWD_CATE_DV_CD, -- 보상 항목 구분 코드
BNF_RWD_GODS_DV_CD, -- 보상 상품 구분 코드
MLG_RWD_AMT, -- 마일리지 보상 금액
COUPON_INNB, -- 쿠폰 고유 번호
REGUSR, -- 등록자
REGIST_DT -- 등록 일시
) VALUES (
#{bnfPrtInnb},
#{bnfRwdCateDvCd},
#{bnfRwdGodsDvCd},
#{mlgRwdAmt},
#{couponInnb},
#{regusr},
NOW()
)
</insert>
<!-- Step 2: PK 기준 교환권 완료 처리 -->
<update id="completeExchangeTicketByPk"
parameterType="Long">
-- PK 기준 교환권 완료 처리
UPDATE
GC_BENEFIT_STMP_EXTIKET
SET
EXCHNG_AT = 'Y',
EXCHNG_DT = NOW(),
UPDT_DT = NOW()
WHERE
BNF_EXTIKET_INNB = #{bnfExtiketInnb}
</update>
<!-- 스탬프 적립 기준 금액 조회 (gc_benefit_chg_config에서) -->
<select id="selectStampAccumulationAmount"
parameterType="String"
resultType="java.lang.Double">
-- 스탬프 적립 기준 금액 조회 (gc_benefit_chg_config 테이블에서)
SELECT
AMT_FOR_CHG AS AMT_FOR_CHG
FROM
GC_BENEFIT_CHG_CONFIG
WHERE
SOPMAL_CD = #{sopmalCd}
AND BNF_DV_CD = '140' -- 모바일스탬프 구분 코드
LIMIT 1
</select>
<!-- 아직 스탬프 적립되지 않은 구매건만 조회 -->
<select id="selectUnprocessedStoreOrders"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 아직 스탬프 적립되지 않은 매장 구매건만 조회
SELECT
O.ORDR_INNB AS ordrInnb, -- 주문 고유번호
O.STR_INNB AS strInnb, -- 매장 고유번호
O.RL_SETLE_AMT AS rlSetleAmt, -- 실 결제금액
CASE
WHEN ST.STR_NM IS NOT NULL THEN ST.STR_NM
WHEN ST.TENTCPN_NM IS NOT NULL THEN ST.TENTCPN_NM
ELSE CONCAT('매장_', O.STR_INNB)
END AS strNm, -- 매장명
DATE_FORMAT(O.SETLE_COMPT_DT, '%Y-%m-%d %H:%i:%s') AS setleComptDt, -- 결제완료일시
O.SLE_ENVRN_CD AS sleEnvrnCd, -- 판매환경코드
O.SKN_ENVRN_CD AS sknEnvrnCd -- 스킨환경코드
FROM
GC_ORDER O
LEFT JOIN
GC_STORE ST ON O.STR_INNB = ST.STR_INNB
LEFT JOIN
GC_BENEFIT_STMP BS ON O.ORDR_INNB = BS.PURCHS_INNB
AND O.MBR_INNB = BS.MBR_INNB
AND O.MBR_DV_CD = BS.MBR_DV_CD
AND O.SOPMAL_CD = BS.SOPMAL_CD
WHERE
O.MBR_INNB = #{mbrInnb}
AND O.MBR_DV_CD = #{mbrDvCd}
AND O.SOPMAL_CD = #{sopmalCd}
AND O.USE_AT = 'Y'
AND O.ORDR_STTUS_CD IN ('25', '30', '35', '40', '45', '50', '55', '60', '65', '70', '75', '80') -- 결제완료 이후 상태만
AND (
-- gc_order 참고사항: 매장 구매금액 조건
O.SLE_ENVRN_CD IN ('S1', 'S2', 'S3')
OR O.SKN_ENVRN_CD = 'POS'
)
<if test="strInnb != null and strInnb != '' and strInnb != 'null'">
AND O.STR_INNB = #{strInnb}
</if>
AND O.SETLE_COMPT_DT IS NOT NULL
AND O.SETLE_COMPT_DT &gt;= DATE_SUB(NOW(), INTERVAL 12 MONTH) -- 최근 12개월 데이터만
AND BS.BNF_STMP_INNB IS NULL -- 아직 스탬프 적립 기록이 없는 주문만
ORDER BY
O.SETLE_COMPT_DT DESC
</select>
<!-- 첫 스탬프 적립일 조회 -->
<select id="selectFirstStampAccumulationDate"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="java.sql.Date">
-- 해당 매장의 첫 스탬프 적립일 조회
SELECT
MIN(DATE(REGIST_DT)) AS FIRST_STAMP_DATE
FROM
GC_BENEFIT_STMP
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
</select>
<!-- 특정 주문으로 적립된 스탬프 기록 조회 -->
<select id="selectStampsByPurchaseOrder"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
SELECT
BNF_STMP_INNB,
STMP_CNT,
REFUND_AT, -- EXCHNG_AT 대신 REFUND_AT 사용
ORDR_INNB
FROM
GC_BENEFIT_STMP
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND ORDR_INNB = #{ordrInnb}
AND STR_INNB = #{strInnb}
AND REFUND_AT = 'N' -- 환불되지 않은 기록만 조회
</select>
<!-- 스탬프 기록 삭제 → 환불 처리로 변경 -->
<update id="updateStampRefundStatus" parameterType="Long">
-- 스탬프 환불 처리 (삭제 대신 상태 변경)
UPDATE GC_BENEFIT_STMP
SET
REFUND_AT = 'Y',
REGIST_DT = NOW()
WHERE
BNF_STMP_INNB = #{bnfStmpInnb}
AND REFUND_AT = 'N'
</update>
<!-- 환불 처리 시 스탬프 차감용 UPDATE 쿼리 추가 -->
<update id="updateRefundStatus" parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO">
-- 환불 처리 시 스탬프 차감
UPDATE GC_BENEFIT_STMP
SET
REFUND_AT = 'Y',
UPDT_DT = NOW()
WHERE
ORDR_INNB = #{ordrInnb}
AND MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND REFUND_AT = 'N'
</update>
<!-- 특정 주문의 스탬프 정보 조회 -->
<select id="selectStampByOrder"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
-- 주문번호로 스탬프 정보 조회
SELECT
BS.BNF_STMP_INNB AS BNF_STMP_INNB,
BS.ORDR_INNB AS ORDR_INNB,
BS.REFUND_AT AS REFUND_AT,
BS.PURCHS_AMT AS PURCHS_AMT,
BS.RL_SETLE_AMT AS RL_SETLE_AMT,
BS.STMP_CNT AS STMP_CNT,
BS.AMT_FOR_CHG AS AMT_FOR_CHG,
DATE_FORMAT(BS.SETLE_COMPT_DT, '%Y-%m-%d %H:%i:%s') AS SETLE_COMPT_DT,
DATE_FORMAT(BS.REGIST_DT, '%Y-%m-%d %H:%i:%s') AS REGIST_DT
FROM
GC_BENEFIT_STMP BS
WHERE
BS.ORDR_INNB = #{ordrInnb}
AND BS.MBR_INNB = #{mbrInnb}
AND BS.MBR_DV_CD = #{mbrDvCd}
AND BS.SOPMAL_CD = #{sopmalCd}
</select>
<!-- 주문 처리 여부 확인 쿼리 추가 -->
<select id="countProcessedOrder"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="int">
SELECT COUNT(*)
FROM GC_BENEFIT_STMP
WHERE SOPMAL_CD = #{sopmalCd}
AND MBR_INNB = #{mbrInnb}
AND ORDR_INNB = #{purchsInnb}
</select>
<!-- 환불로 인해 영향받은 교환권 삭제 -->
<delete id="deleteAffectedExchangeTickets"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO">
<![CDATA[
-- 환불된 스탬프로 인해 유효하지 않은 교환권 삭제
DELETE FROM GC_BENEFIT_STMP_EXTIKET
WHERE MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
AND EXCHNG_AT = 'N' -- 미교환 교환권만
AND EXTIKET_STMP_CNT > (
-- 현재 유효한 스탬프 수보다 교환권 스탬프가 많으면 삭제
SELECT IFNULL(SUM(STMP_CNT), 0)
FROM GC_BENEFIT_STMP
WHERE MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
AND REFUND_AT = 'N'
)
]]>
</delete>
<!-- 교환안된 교환권 조회 (오래된 순) -->
<select id="selectUnexchangedTicketsForDeduction"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO"
resultType="com.wb.domainserver.util.dataaccess.DataMap">
SELECT
BNF_EXTIKET_INNB,
EXTIKET_STMP_CNT
FROM
GC_BENEFIT_STMP_EXTIKET
WHERE
MBR_INNB = #{mbrInnb}
AND MBR_DV_CD = #{mbrDvCd}
AND SOPMAL_CD = #{sopmalCd}
AND STR_INNB = #{strInnb}
AND EXCHNG_AT = 'N' -- 교환안된 것만
ORDER BY
REGIST_DT ASC -- 오래된 것부터 처리
</select>
<!-- 교환권 스탬프 수 감소 -->
<update id="reduceExchangeTicketStamps"
parameterType="com.wb.domainserver.domain.gcone.bnft.purstmp.vo.BOPurstmpStampVO">
UPDATE GC_BENEFIT_STMP_EXTIKET
SET
EXTIKET_STMP_CNT = EXTIKET_STMP_CNT - #{deductStampCnt},
UPDT_DT = NOW()
WHERE
BNF_EXTIKET_INNB = #{bnfExtiketInnb}
AND EXTIKET_STMP_CNT >= #{deductStampCnt}
</update>
<!-- 특정 교환권 삭제 -->
<delete id="deleteSpecificExchangeTicket" parameterType="Long">
DELETE FROM GC_BENEFIT_STMP_EXTIKET
WHERE BNF_EXTIKET_INNB = #{bnfExtiketInnb}
</delete>
</mapper>