package com.style24.core.biz.service;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.rest.server.GagaResponseStatus;
import com.style24.core.biz.dao.TscNaverPayDao;
import com.style24.core.biz.dao.TscOrderChangeDao;
import com.style24.core.biz.dao.TscOrderDao;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.core.support.util.CryptoUtils;
import com.style24.persistence.domain.DeliveryFee;
import com.style24.persistence.domain.GiftCard;
import com.style24.persistence.domain.Order;
import com.style24.persistence.domain.OrderChange;
import com.style24.persistence.domain.Payment;
import com.style24.persistence.domain.WmsDelivery;

import lombok.extern.slf4j.Slf4j;

/**
 * 취소, 반품, 교환 Service
 *
 * @author jsh77b
 * @since 2021. 01. 18
 */
@Service
@Slf4j
public class TscOrderChangeService {
	@Autowired
	private Environment env;

	@Autowired
	private TscMessageByLocale message;

	@Autowired
	private TscOrderChangeDao orderChangeDao;

	@Autowired
	private TscOrderDao orderDao;
	
	@Autowired
	private TscOrderService orderService;

	@Autowired
	private TscOrderRefundService orderRefundService;

	@Autowired
	private TscKcpService kcpService;

	@Autowired
	private TscKakaoPayService kakaoPayService;

	@Autowired
	private TscNaverPayService naverPayService;

	@Autowired
	private TscNaverPayDao naverPayDao;
	
	@Autowired
	private TscWmsService wmsService;
	
	@Autowired
	private TscDeliveryService deliveryService;

	/**
	 * 주문변경 대상목록 조회 (취소, 반품, 교환)
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2020. 12. 16
	 */
	public List<Order> getCancelRequestTargetList(Order order) {
		return orderChangeDao.getCancelRequestTargetList(order);
	}
	
	/**
	 * 주문변경 대상목록 조회 (취소, 반품, 교환) 2
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 05. 24
	 */
	public List<Order> getCancelRequestTargetList2(Order order) {
		return orderChangeDao.getCancelRequestTargetList2(order);
	}

	/**
	 * 주문변경신청목록 조회 (취소, 반품, 교환)
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 27
	 */
	public List<Order> getOrderChangeDetailList(Order order) {
		return orderChangeDao.getOrderChangeDetailList(order);
	}

	/**
	 * 취소신청철회 (admin)
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 19
	 */
	@Transactional("shopTxnManager")
	public GagaMap cnclReqCancel(GagaMap mav, int userNo) {

		Order order = new Order();
		order.setOrdNo(mav.getInt("ordNo"));
		order.setOrdChgSq(mav.getInt("ordChgSq"));
		order.setChgStat(TscConstants.OrderChangeStat.CANCEL_CANCEL.value());
		order.setRegNo(userNo);
		order.setUpdNo(userNo);
		order.setDelYn("Y");

		// 1. 주문변경정보 (TB_ORDER_CHANGE_DTL(수정))
		orderChangeDao.updateOrderChangeDtlCancel(order);

		// 2. 주문변경이력정보 (TB_ORDER_CHANGE_DETAIL_HST(수정))
		OrderChange orderChange = new OrderChange();
		orderChange.setOrdChgSq(mav.getInt("ordChgSq"));
		orderChange.setChgStat(TscConstants.OrderChangeStat.CANCEL_CANCEL.value());
		orderChange.setRegNo(userNo);
		orderChange.setUpdNo(userNo);
		orderChangeDao.createOrderChangeDetailHstForAllCancel(orderChange);

		return mav;
	}

	/**
	 * 마이페이지 부분취소 처리
	 *
	 * @param GagaMap
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 05. 24
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap partialCancel(GagaMap map, Integer userNo) {
		
		// 1. 취소요청목록 및 정보 설정
		List<Order> cancelOrderRefundList 	= (List<Order>) map.get("cancelOrderRefundList");	// 취소환불금액 목록 (주문상세단품 단위)
		List<Order> cancelDelvRefundList 	= (List<Order>) map.get("cancelDelvRefundList");	// 취소환불배송금액 목록 (DELV_FEE_CD 단위)

		int ordNo 				= map.getInt("ordNo");											// 주문번호
		Integer custNo			= map.getInt("custNo");											// 고객번호
		int ordChgSq			= map.getInt("ordChgSq");										// 주문변경일련번호
		String chgReason 		= map.getString("chgReason");									// 변경사유
		String chgReasonNm 		= map.getString("chgReasonNm");									// 변경사유명
		String chgMemo 			= map.getString("chgMemo");										// 변경메모
		String allLastCanYn		= map.getString("allLastCanYn");								// 마지막 취소 여부
		String ipAddress		= map.getString("ipAddress");									// IP주소
		String pgTid			= map.getString("pgTid");										// PG거래ID
		String payMeans			= map.getString("payMeans");									// 결제수단
		String pgGb				= map.getString("pgGb");										// PG구분
		String accountNo		= map.getString("accountNo");									// 환불계좌번호
		String accountNm		= map.getString("accountNm");									// 환불계좌주명
		String bankCd			= map.getString("bankCd");										// 환불계좌은행코드
		String reqGbn			= map.getString("reqGbn");										// 신청구분
		String chgGb			= TscConstants.OrderChangeGb.CANCEL.value(); 					// 취소요청 (공톹코드:G680)
		String ordDtlStat		= TscConstants.OrderDetailStat.PAYMENT_AFTER_CANCEL.value();	// 주문상세상태
		String chgStat			= TscConstants.OrderChangeStat.PAYMENT_AFTER_CANCEL.value();	// 주문변경상태
		int payAmt				= map.getInt("spanPayAmt");										// 부분취소 전 결제금액
		String modType			= "";
		String batchYn			= map.getString("batchYn");										// 배치여부
		String pgStat			= map.getString("pgStat");										// PG점프
		int depositAmt			= map.getInt("depositAmt");										// PG점프 입금액
		int regNo				= userNo;														// 등록자번호
		int updNo				= userNo;														// 수정자번호

		// 2. 무통장입금 결제 주문 전체취소 상태값 처리
		// 2021.09.09 페이코 조건 누락 추가
		if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
			if (TscConstants.PayMeans.BANK_DEPOSIT.value().equals(payMeans)) {
				modType = "STPD";																			// KCP 무통장입금 부분취소
			} else {
				modType = "STPC";																			// KCP 부분취소
			}
		}
		
		// 3. 교환출고 재고부족 취소 처리
		// 2021.06.21 교환출고 재고부족 취소실행
		Order exchangeDelvFailCnclVo = new Order();
		exchangeDelvFailCnclVo.setUpdNo(userNo);
		exchangeDelvFailCnclVo.setOrdChgSq(ordChgSq);
		orderChangeDao.updateExchangeDelvFailCnclYn(exchangeDelvFailCnclVo);

		// 4. 환불정보 설정
		OrderChange refundInfo = this.calculateRefundAmt(map);
		int refundAmt = refundInfo.getRefundAmt();

		// 5. 주문변경정보, 주문정보, 환불정보 (배송정책코드 별)
		List<Payment> pgList = new ArrayList<>();
		List<GiftCard> cashReceiptsList = new ArrayList<>();
		
		for (Order obj : cancelDelvRefundList) {
			// 취소금액 있을 시 처리
			if (obj.getCnclRtnAmt() > 0) {
				// 5-1. 주문변경정보 생성
				OrderChange orderChange = new OrderChange();
				orderChange.setOrdNo(ordNo);
				orderChange.setChgGb(chgGb);
				orderChange.setChgReason(chgReason);
				orderChange.setChgMemo(chgMemo);
				orderChange.setAddPayCost(0);
				orderChange.setAddPayAmt(0);
				orderChange.setRegNo(userNo);
				orderChange.setUpdNo(userNo);

				// 신청구분 처리
				if ("cnclReqComplete".equals(reqGbn)) {
					// 취소접수승인 시 ordChgSq 설정
					orderChange.setOrdChgSq(ordChgSq);
				} else {
					// 취소 완료 시 생성
					orderChangeDao.createOrderChange(orderChange);
					ordChgSq = orderChange.getOrdChgSq();
				}
				
				// 주문변경일련번호 설정
				map.setInt("ordChgSq", ordChgSq);

				// 5-2. 주문상세정보 수정
				int sumGfcdUseAmt = 0;
				for (Order vo : cancelOrderRefundList) {
					vo.setRegNo(userNo);
					vo.setUpdNo(userNo);
					vo.setOrdDtlStat(ordDtlStat);
					
					// 배송정책코드 별 주문상세 처리
					if (obj.getDelvFeeCd().equals(vo.getDelvFeeCd()) && vo.getOrdCanChgQty() > 0) {
						// 주문상세 별 전체취소여부 설정
						int leftQty = vo.getOrdQty() - vo.getCnclRtnQty() - vo.getOrdCanChgQty();

						// 5-2-1. 주문상세정보 수정
						orderChangeDao.updateOrderDetail(vo);

						// 5-2-2. 주문상세 이력 등록
						orderChangeDao.createOrderDetailHstCnclRtn(vo);

						// 5-2-3. 주문상세단품정보 수정 및 주문상세단품이력 등록
						// 주문상세단품정보조회
						Collection<Order> orderDetailItemList = orderChangeDao.getOrderDetailItemForCnclRtn(vo);
						int ordDtlOrdAmt 			= orderDetailItemList.iterator().next().getOrdAmt();
						int ordDtlCnclRtnAmt	 	= orderDetailItemList.iterator().next().getCnclRtnAmt();
						int ordDtlCpn1DcAmt 		= orderDetailItemList.iterator().next().getCpn1DcAmt();
						int ordDtlTmtb1DcAmt 		= orderDetailItemList.iterator().next().getTmtb1DcAmt();
						int ordDtlTmtb2DcAmt 		= orderDetailItemList.iterator().next().getTmtb2DcAmt();
						int ordDtlGoodsCpnDcAmt 	= orderDetailItemList.iterator().next().getGoodsCpnDcAmt();
						int ordDtlCartCpnDcAmt 		= orderDetailItemList.iterator().next().getCartCpnDcAmt();
						int ordDtlPntDcAmt 			= orderDetailItemList.iterator().next().getPntDcAmt();
						int ordDtlPrePntDcAmt 		= orderDetailItemList.iterator().next().getPrePntDcAmt();
						int ordDtlSavePntAmt 		= orderDetailItemList.iterator().next().getSavePntAmt();
						int ordDtlRealOrdAmt 		= orderDetailItemList.iterator().next().getRealOrdAmt();
						int ordDtlGfcdUseAmt 		= orderDetailItemList.iterator().next().getGfcdUseAmt();

						// 주문상세단품단위 금액 등록
						int length					= orderDetailItemList.size();
						int index					= 1;
						int leftOrdAmt 				= ordDtlOrdAmt;
						int leftCnclRtnAmt			= ordDtlCnclRtnAmt;
						int leftCpn1DcAmt 			= ordDtlCpn1DcAmt;
						int leftTmtb1DcAmt 			= ordDtlTmtb1DcAmt;
						int leftTmtb2DcAmt 			= ordDtlTmtb2DcAmt;
						int leftGoodsCpnDcAmt 		= ordDtlGoodsCpnDcAmt;
						int leftCartCpnDcAmt 		= ordDtlCartCpnDcAmt;
						int leftPntDcAmt 			= ordDtlPntDcAmt;
						int leftPrePntDcAmt 		= ordDtlPrePntDcAmt;
						int leftSavePntAmt 			= ordDtlSavePntAmt;
						int leftRealOrdAmt 			= ordDtlRealOrdAmt;
						int leftGfcdUseAmt 			= ordDtlGfcdUseAmt;

						for (Order orderDetailItem : orderDetailItemList) {
							double dtlOrdAmt		= orderDetailItem.getDtlOrdAmt();
							double dtlItemOrdAmt	= orderDetailItem.getDtlItemOrdAmt();
							double tempDivD			= (dtlItemOrdAmt / dtlOrdAmt) * 100;
							
							int tempDiv				= Integer.parseInt(String.valueOf(Math.round(tempDivD)));

							if (index == length) {
								orderDetailItem.setCnclRtnAmt(leftCnclRtnAmt);
								orderDetailItem.setCpn1DcAmt(leftCpn1DcAmt);
								orderDetailItem.setTmtb1DcAmt(leftTmtb1DcAmt);
								orderDetailItem.setTmtb2DcAmt(leftTmtb2DcAmt);
								orderDetailItem.setGoodsCpnDcAmt(leftGoodsCpnDcAmt);
								orderDetailItem.setCartCpnDcAmt(leftCartCpnDcAmt);
								orderDetailItem.setPrePntDcAmt(leftPrePntDcAmt);
								orderDetailItem.setPntDcAmt(leftPntDcAmt);
								orderDetailItem.setGfcdUseAmt(leftGfcdUseAmt);
								orderDetailItem.setRealOrdAmt(leftRealOrdAmt);
								orderDetailItem.setSavePntAmt(leftSavePntAmt);
								
							} else {
								orderDetailItem.setCnclRtnAmt((ordDtlCnclRtnAmt 		* tempDiv) / 100);
								orderDetailItem.setCpn1DcAmt((ordDtlCpn1DcAmt 			* tempDiv) / 100);
								orderDetailItem.setTmtb1DcAmt((ordDtlTmtb1DcAmt 		* tempDiv) / 100);
								orderDetailItem.setTmtb2DcAmt((ordDtlTmtb2DcAmt 		* tempDiv) / 100);
								orderDetailItem.setGoodsCpnDcAmt((ordDtlGoodsCpnDcAmt 	* tempDiv) / 100);
								orderDetailItem.setCartCpnDcAmt((ordDtlCartCpnDcAmt 	* tempDiv) / 100);
								orderDetailItem.setPrePntDcAmt((ordDtlPrePntDcAmt 		* tempDiv) / 100);
								orderDetailItem.setPntDcAmt((ordDtlPntDcAmt 			* tempDiv) / 100);
								orderDetailItem.setGfcdUseAmt((ordDtlGfcdUseAmt 		* tempDiv) / 100);
								orderDetailItem.setRealOrdAmt((ordDtlRealOrdAmt 		* tempDiv) / 100);
								orderDetailItem.setSavePntAmt((ordDtlSavePntAmt 		* tempDiv) / 100);

								leftCnclRtnAmt		-= ((ordDtlCnclRtnAmt 				* tempDiv) / 100);
								leftCpn1DcAmt 		-= ((ordDtlCpn1DcAmt 				* tempDiv) / 100);
								leftTmtb1DcAmt 		-= ((ordDtlTmtb1DcAmt 				* tempDiv) / 100);
								leftTmtb2DcAmt 		-= ((ordDtlTmtb2DcAmt 				* tempDiv) / 100);
								leftGoodsCpnDcAmt 	-= ((ordDtlGoodsCpnDcAmt 			* tempDiv) / 100);
								leftCartCpnDcAmt 	-= ((ordDtlCartCpnDcAmt 			* tempDiv) / 100);
								leftPrePntDcAmt 	-= ((ordDtlPrePntDcAmt 				* tempDiv) / 100);
								leftPntDcAmt 		-= ((ordDtlPntDcAmt 				* tempDiv) / 100);
								leftGfcdUseAmt 		-= ((ordDtlGfcdUseAmt 				* tempDiv) / 100);
								leftRealOrdAmt 		-= ((ordDtlRealOrdAmt 				* tempDiv) / 100);
								leftSavePntAmt 		-= ((ordDtlSavePntAmt 				* tempDiv) / 100);
							}

							orderDetailItem.setRegNo(userNo);
							orderDetailItem.setUpdNo(userNo);
							orderDetailItem.setOrdDtlStat(ordDtlStat);
							
							// 2021.06.25 취소완료 (취소) (정산구분값추가)
							// 품절취소
							if (TscConstants.OrderCancelReason.SOLDOUT_CANCEL.value().equals(chgReason)) {
								orderDetailItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_SOLDOUT_CANCEL.value());
							}
							// 일반취소
							else {
								orderDetailItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_CANCEL.value());
							}
							orderDetailItem.setCnclRtnQty(vo.getOrdCanChgQty());
							orderDetailItem.setOrdChgSq(ordChgSq);

							orderChangeDao.createOrderDetailItemHst(orderDetailItem);

							orderChangeDao.updateOrderDetailItem(orderDetailItem);

							index++;
						}

						// 5-2-4. 사용포인트원복
						int pntDcAmt = vo.getPntDcAmt();
						vo.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT.value());

						for (Order point : orderChangeDao.getCustPointHst(vo)) {
							if (pntDcAmt > 0) {
								int pntAmt = point.getPntAmt() * -1;

								if (pntDcAmt < pntAmt) {
									point.setPntAmt(pntDcAmt);
									pntDcAmt -= pntDcAmt;
								} else {
									point.setPntAmt(pntAmt);
									pntDcAmt -= pntAmt;
								}

								point.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT_CANCEL.value());
								point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_COMPLETE.value());
								point.setOccurDtlDesc("포인트사용취소");
								point.setRegNo(userNo);
								point.setUpdNo(userNo);

								// 포인트 사용 취소 이력 생성 및 포인트 수정
								orderChangeDao.createCustPointHstRollback(point);
								orderChangeDao.updateCustPointRollback(point);
							}
						}

						// 5-2-5. 적립예정포인트 수정
						int savePntAmt = vo.getSavePntAmt();
						vo.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT.value());

						for (Order point : orderChangeDao.getCustPointHst(vo)) {
							point.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT_CANCEL.value());
							point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_EXPECT.value());
							point.setOccurDtlDesc("예정포인트적립취소");
							point.setPntAmt(savePntAmt * -1);
							point.setRegNo(userNo);
							point.setUpdNo(userNo);

							// 적립예정포인트 취소 이력 생성
							orderChangeDao.createCustPointHstRollback(point);
						}

						// 5-2-6. 상품쿠폰원복
						if (leftQty == 0) {
							orderChangeDao.updateGoodsCpnRollback(vo);
						}

						// 5-2-7. 사용상품권 원복
						int gfcdUseAmt = vo.getGfcdUseAmt();
						sumGfcdUseAmt += gfcdUseAmt;

						for (Order giftCard : orderChangeDao.getCustGiftCardHst(vo)) {
							if (gfcdUseAmt > 0) {
								int gfcdAmt = giftCard.getGfcdAmt() * -1;

								if (gfcdUseAmt < gfcdAmt) {
									giftCard.setGfcdAmt(gfcdUseAmt);
									gfcdUseAmt -= gfcdUseAmt;
								} else {
									giftCard.setGfcdAmt(gfcdAmt);
									gfcdUseAmt -= gfcdAmt;
								}

								giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
								giftCard.setOccurDtlDesc("상품권사용취소");
								giftCard.setRegNo(userNo);
								giftCard.setUpdNo(userNo);

								// 포인트 사용 취소 이력 생성 및 포인트 수정
								orderChangeDao.createCustGiftCardHstRollback(giftCard);
								orderChangeDao.updateCustGiftCardRollback(giftCard);
							}
						}

						// 5-2-8. 주문변경상세정보 및 이력 등록
						OrderChange changeDetailPo = new OrderChange();
						changeDetailPo.setOrdChgSq(orderChange.getOrdChgSq());
						changeDetailPo.setOrdDtlNo(vo.getOrdDtlNo());
						changeDetailPo.setChgQty(vo.getOrdCanChgQty());
						changeDetailPo.setChgStat(chgStat);
						changeDetailPo.setRegNo(userNo);
						changeDetailPo.setUpdNo(userNo);

						// 신청구분 처리
						if ("cnclComplete".equals(reqGbn)) {
							// 취소완료 시 주문변경상세 정보 생성
							orderChangeDao.createOrderChangeDetail(changeDetailPo);
						} else {
							// 취소접수승인 시 주문변경상세 정보 수정
							Order order = new Order();
							order.setOrdNo(ordNo);
							order.setOrdChgSq(ordChgSq);
							order.setChgStat(chgStat);
							order.setUpdNo(userNo);
							order.setDelYn("N");

							orderChangeDao.updateOrderChangeDtlCancel(order);
						}

						orderChangeDao.createOrderChangeDetailHst(changeDetailPo);
					}
				}

				// 5-3. 상품재고원복
				if(!TscConstants.OrderCancelReason.SOLDOUT_CANCEL.value().equals(chgReason)) {
					orderChange.setSellGb(TscConstants.SellGb.ORDER_CANCEL.value());
					orderChangeDao.createSellQty(orderChange);
				}

				// 5-4. 추가배송비 처리
				int sumDeliveryFee = obj.getDelvFee();					// 배송비합계
				int spanDelvCpnDcAmt = obj.getDelvCpnDcAmt();			// 배송비쿠폰금액
				int spanDelvGfcdUseAmt = 0;								// 배송비상품권사용금액
				int spanTotDeliveryFee = obj.getAddDelvFee();			// 추가배송비합계

				// 5-4-1. 원주문 배송비 처리
				if ("Y".equals(obj.getLastCanYn())) {
					int delvFee = sumDeliveryFee - spanDelvCpnDcAmt;
					spanDelvGfcdUseAmt = obj.getDelvGfcdUseAmt();		// 배송비상품권사용금액
					payAmt -= spanDelvGfcdUseAmt;						// PG LEFT_AMT 설정

					// 원주문 배송비 사용상품권 원복
					obj.setOrdNo(ordNo);
					int gfcdUseAmt = spanDelvGfcdUseAmt;

					// TscOrderRefundService.cancelDelvRefundList(obj) 내 delvFeeCd 설정
					for (Order giftCard : orderChangeDao.getCustGiftCardDelvHst(obj)) {
						if (gfcdUseAmt > 0) {
							int gfcdAmt = giftCard.getGfcdAmt() * -1;

							if (gfcdUseAmt < gfcdAmt) {
								giftCard.setGfcdAmt(gfcdUseAmt);
								gfcdUseAmt -= gfcdUseAmt;
							} else {
								giftCard.setGfcdAmt(gfcdAmt);
								gfcdUseAmt -= gfcdAmt;
							}

							giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
							giftCard.setOccurDtlDesc("상품권사용취소");
							giftCard.setRegNo(userNo);
							giftCard.setUpdNo(userNo);

							// 상품권 사용 취소 이력 생성 및 포인트 수정
							orderChangeDao.createCustGiftCardHstRollback(giftCard);
							orderChangeDao.updateCustGiftCardRollback(giftCard);
						}
					}

					// 원주문 배송비 상품권 현금영수증 PG 취소 정보 설정
					GiftCard giftCardCashReceipts = orderDao.getGiftCardReceiptInfo(ordNo);

					if (giftCardCashReceipts != null && StringUtils.isNotBlank(giftCardCashReceipts.getTradeNo())) {
						giftCardCashReceipts.setModType("STPC");
						giftCardCashReceipts.setUsGfcdAmt(spanDelvGfcdUseAmt);

						cashReceiptsList.add(giftCardCashReceipts);
					}

					// 원주문 배송비 취소 처리
					Order cancelDelvFee = new Order();
					cancelDelvFee.setOrdNo(ordNo);
					cancelDelvFee.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
					cancelDelvFee.setDelvFeeCd(obj.getDelvFeeCd());
					cancelDelvFee.setDelvFee(sumDeliveryFee * -1);
					cancelDelvFee.setDelvCpnSq(0);
					cancelDelvFee.setDelvCpnDcAmt(spanDelvCpnDcAmt);
					cancelDelvFee.setDelvGfcdUseAmt(spanDelvGfcdUseAmt * -1);
					cancelDelvFee.setRealDelvAmt((delvFee - spanDelvGfcdUseAmt) * -1);
					cancelDelvFee.setOrdChgSq(orderChange.getOrdChgSq());
					cancelDelvFee.setSupplyCompCd(obj.getSupplyCompCd());
					cancelDelvFee.setRegNo(userNo);
					cancelDelvFee.setUpdNo(userNo);

					orderChangeDao.createDeliveryFee(cancelDelvFee);
				}
				// 5-4-2. 추가배송비 처리 (배송비허들무너짐)
				else {
					int delvGfcdUseAmt = refundInfo.getDelvGfcdUseAmt();
					int realDelvAmt = refundInfo.getRealDelvAmt();

					if ("G686_10".equals(chgReason) && spanTotDeliveryFee > 0) {
						Order delvFeeOrder = new Order();
						delvFeeOrder.setOrdNo(ordNo);
						delvFeeOrder.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
						delvFeeOrder.setDelvFeeCd(obj.getDelvFeeCd());
						delvFeeOrder.setDelvFee(spanTotDeliveryFee);
						delvFeeOrder.setDelvGfcdUseAmt(delvGfcdUseAmt);
						delvFeeOrder.setRealDelvAmt(realDelvAmt);
						delvFeeOrder.setOrdChgSq(orderChange.getOrdChgSq());
						delvFeeOrder.setSupplyCompCd(obj.getSupplyCompCd());
						delvFeeOrder.setRegNo(userNo);
						delvFeeOrder.setUpdNo(userNo);

						orderChangeDao.createDeliveryFee(delvFeeOrder);

						if (delvGfcdUseAmt > 0) {
							int rmGfcdAmt;
							int usGfcdAmt;

							// 반품배송비 배송비일련번호 조회 및 설정
							orderChange.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
							OrderChange orgDeliveryFeeInfo = orderChangeDao.getOrgDeliveryFeeInfo(orderChange);
							Integer delvFeeSq = orgDeliveryFeeInfo.getDelvFeeSq();

							Order dto = new Order();
							dto.setOrdNo(ordNo);
							dto.setCustNo(custNo);
							dto.setRegNo(regNo);
							dto.setUpdNo(updNo);
							dto.setDelvFeeSq(delvFeeSq);

							// 추가배송비 상품권 결제 처리
							// 환불컨펌 시점에서 상품권이 만료되어져 있을수 있어서 해당 주문건에 사용 후 취소했던 상품권 정보로 처리
							// Order 도메인 내 delvFeeSq 존재 여부로 구분 처리 진행
							for (Order custGiftcardInfo : orderDao.getCustGiftcardInfoList(dto)) {

								// 상품권사용금액 있으면 실행
								rmGfcdAmt = custGiftcardInfo.getRmGfcdAmt();

								// 남은상품권금액 > 사용상품권금액보다 크면 실행
								if (rmGfcdAmt > delvGfcdUseAmt) {
									rmGfcdAmt = rmGfcdAmt - delvGfcdUseAmt;
									usGfcdAmt = delvGfcdUseAmt;
									delvGfcdUseAmt = 0;
								} else {
									delvGfcdUseAmt = delvGfcdUseAmt - rmGfcdAmt;
									usGfcdAmt = rmGfcdAmt;
									rmGfcdAmt = 0;
								}

								if (usGfcdAmt > 0) {
									// 상품권 정보 수정
									custGiftcardInfo.setUsGfcdAmt(usGfcdAmt);
									custGiftcardInfo.setRmGfcdAmt(rmGfcdAmt);
									custGiftcardInfo.setCustNo(custNo);
									orderDao.updateCustGiftcard(custGiftcardInfo);

									// 상품권 사용 이력 생성
									custGiftcardInfo.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD.value());
									custGiftcardInfo.setOccurDtlDesc("상품권사용");
									custGiftcardInfo.setGfcdAmt(usGfcdAmt * -1);
									custGiftcardInfo.setOrdNo(ordNo);
									custGiftcardInfo.setOrdDtlNo(0);
									custGiftcardInfo.setDelvFeeSq(delvFeeSq);
									orderDao.createCustGiftcardHst(custGiftcardInfo);
								}
							}
						}
					}
				}

				// 환불금액이 추가배송비 보다 적을 시
				if ((refundAmt + sumGfcdUseAmt + refundInfo.getRfDeliveryFee()) < 0) {
					throw new IllegalStateException(message.getMessage("CANCEL_0002"));
				}

				// 5-5. PG 결제 취소 정보 설정 (상품권으로만 결제 시 PG점프)
				Payment pg = new Payment();
				pg.setOrdNo(ordNo);
				pg.setOrdChgSq(ordChgSq);
				pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
				pg.setPayGb("O");
				pg.setPgTid(pgTid);
				pg.setPayMeans(payMeans);
				pg.setPartCancelAmt(refundAmt);
				pg.setLeftAmt(payAmt);
				pg.setRegNo(userNo);
				pg.setUpdNo(userNo);

				log.info("pg.getPartCancelAmt() ::: {}", pg.getPartCancelAmt());
				log.info("pg.getLeftAmt() ::: {}", pg.getLeftAmt());

				pgList.add(pg);

				// 5-6. 환불정보 등록
				Order refundOrder = new Order();
				refundOrder.setOrdNo(ordNo);
				refundOrder.setPaySq(0);
				refundOrder.setOrdChgSq(orderChange.getOrdChgSq());
				refundOrder.setRefundAmt(refundAmt);
				refundOrder.setDepositAmt(depositAmt);
				refundOrder.setRfCpn1Amt(obj.getCpn1DcAmt());
				refundOrder.setRfTmtb1Amt(obj.getTmtb1DcAmt());
				refundOrder.setRfTmtb2Amt(obj.getTmtb2DcAmt());
				refundOrder.setRfGoodsCpnAmt(obj.getGoodsCpnDcAmt());
				refundOrder.setRfCartCpnAmt(obj.getCartCpnDcAmt());
				refundOrder.setRfDelvCpnAmt(obj.getDelvCpnDcAmt());
				refundOrder.setRfPntAmt(obj.getPntDcAmt());
				refundOrder.setRfPrePntAmt(obj.getPrePntDcAmt());
				refundOrder.setRfGfcdUseAmt(refundInfo.getGfcdUseAmt());
				refundOrder.setRfDelvGfcdUseAmt(spanDelvGfcdUseAmt);
				refundOrder.setRfCnclAmt(obj.getCnclRtnAmt());
				refundOrder.setRfDeliveryFee(refundInfo.getRfDeliveryFee());
				refundOrder.setRfRealCnclAmt((refundAmt + spanDelvGfcdUseAmt) - refundInfo.getRfDeliveryFee());
				// 2021.06.09 계좌번호 암호화
				//refundOrder.setRaNo(accountNo);
				refundOrder.setRaNo(CryptoUtils.encryptAES(accountNo));
				refundOrder.setRaNm(accountNm);
				refundOrder.setRaBank(bankCd);
				refundOrder.setRegNo(userNo);

				orderChangeDao.createRefund(refundOrder);

				// 5-7. 상품권 현금영수증 PG 취소 정보 설정
				GiftCard giftCardCashReceipts = orderDao.getGiftCardReceiptInfo(ordNo);

				if (giftCardCashReceipts != null && StringUtils.isNotBlank(giftCardCashReceipts.getTradeNo())) {
					giftCardCashReceipts.setModType("STPC");
					giftCardCashReceipts.setUsGfcdAmt(sumGfcdUseAmt - refundInfo.getRtnDelvGfcdUseAmt() - refundInfo.getDelvGfcdUseAmt());

					cashReceiptsList.add(giftCardCashReceipts);
				}
			}
		}

		// 6. 장바구니, 배송비 쿠폰 원복 및 사은품 전체 취소 처리 (마지막 취소 시)
		if ("Y".equals(allLastCanYn)) {
			// 2021.06.21  교환완료가 아닌상태의 변경신청값일때 실행
			if (!TscConstants.OrderChangeStat.EXCHANGE_CANCEL.value().equals(chgStat)) {
				// 6-1. 장바구니, 배송비 쿠폰 원복처리
				Order coupon = new Order();
				coupon.setOrdNo(ordNo);
				coupon.setUpdNo(userNo);
				orderChangeDao.updateCartCpnRollback(coupon);
				orderChangeDao.updateDeliveryCpnRollback(coupon);
	
				// 6-2. 사은품 전체 취소 (전체취소시 적용) 추후 사은품 관련 취소 로직 개발 예정
				Order freegiftOrder = new Order();
				freegiftOrder.setOrdNo(ordNo);
				freegiftOrder.setUpdNo(userNo);
				orderChangeDao.updateOrdFreegiftDel(freegiftOrder);
			}
		}

		// 7. WMS 취소 처리
		List<Order> wmsList = new ArrayList<>();
		for (Order cancelOrderRefund : cancelOrderRefundList) {
			int ordDtlNo = cancelOrderRefund.getOrdDtlNo();
			int chgQty = cancelOrderRefund.getOrdCanChgQty();

			Order wms = new Order();
			wms.setOrdNo(ordNo);
			wms.setOrdDtlNo(ordDtlNo);
			wms.setChgQty(chgQty);

			if (chgQty > 0) {
				wmsList.add(wms);
			}
		}

		if (wmsList.size() > 0) {
			wmsService.updateWmsCancel(wmsList);
		}

		// 8. PG 취소 처리
		for (Payment pg : pgList) {
			
			// 2021.09.02 (PAY_STAT = 'G016_30' AND PG_TID IS NULL AND PG_GB <> 'ISTYLE') 체크 후 없으면 제휴몰로 판단 로직
			if (orderDao.getExtmallOrderChk(pg) > 0) {
				payMeans = TscConstants.PayMeans.EXTMALL.value();
			}
			
			// 네이버페이주문형, 외부몰주문, PG점프, 100%상품권 결제는 PG점프 처리
			if (TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb) || TscConstants.PayMeans.EXTMALL.value().equals(payMeans) || "Y".equals(pgStat) || pg.getPartCancelAmt() == 0) {
				pg.setPayAmt(-pg.getPartCancelAmt());
				orderDao.insertPaymentCancel(pg);
			} else if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
				log.info("modType ::: {}", modType);
				
				pg.setModType(modType);
				pg.setModDesc("가맹점 취소 - 부분 취소");
				pg.setIpAddress(ipAddress);
				pg.setAccountNm(accountNm);
				pg.setAccountNo(accountNo);
				pg.setBankCd(bankCd);
				pg.setBatchYn(batchYn);
				
				kcpService.kcpCancel(pg);
			} else if (TscConstants.PgGb.NAVER.value().equals(pgGb)) {
				pg.setPayAmt(pg.getPartCancelAmt());
				pg.setPayMeans(payMeans);
				pg.setChgReasonNm(chgReasonNm);

				naverPayService.cancelNaverPayment(pg);
			} else if (TscConstants.PgGb.KAKAO.value().equals(pgGb)) {
				pg.setPayAmt(pg.getPartCancelAmt());
				
				kakaoPayService.cancelKakaoPayment(pg);
			}

			// 9. 환불정보 수정
			Order refundOrder = new Order();
			refundOrder.setOrdNo(ordNo);
			refundOrder.setPaySq(pg.getPaySq());
			refundOrder.setOrdChgSq(ordChgSq);
			refundOrder.setUpdNo(userNo);

			orderChangeDao.updateRefundInfo(refundOrder);
		}

		// 10. 현금영수증 취소 처리
		for (GiftCard cashReceipts : cashReceiptsList) {
			kcpService.kcpCashReceiptCancel(cashReceipts);
		}

		return map;
	}

	/**
	 * 마이페이지 반품 처리
	 * 
	 * @param GagaMap
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 04. 19
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap returnRequest(GagaMap map) {
		
		// 1. 변경정보목록 및 정보 설정
		List<Order> cancelOrderRefundList 	= (List<Order>) map.get("cancelOrderRefundList");				// 취소환불금액 목록 (주문상세단품 단위)
		List<Order> cancelDelvRefundList 	= (List<Order>) map.get("cancelDelvRefundList");				// 취소환불배송금액 목록 (DELV_FEE_CD 단위)
		
		int ordNo 							= map.getInt("ordNo");											// 주문번호
		int custNo							= map.getInt("custNo");											// 고객번호
		int regNo							= map.getInt("regNo");											// 등록자번호
		int updNo							= map.getInt("updNo");											// 수정자번호
		String pgGb							= map.getString("pgGb");										// 결제PG
		String chgReason 					= map.getString("chgReason");									// 변경사유
		String chgMemo 						= map.getString("chgMemo");										// 변경메모
		String chgerNm 						= map.getString("chgerNm");										// 변경자
		String chgerPhnno 					= map.getString("chgerPhnno");									// 변경핸드폰번호
		String chgerTelno 					= map.getString("chgerTelno");									// 변경전화번호
		String chgerEmail 					= map.getString("chgerEmail");									// 변경이메일
		String chgerZipcode 				= map.getString("chgerZipcode");								// 변경우편번호
		String chgerBaseAddr 				= map.getString("chgerBaseAddr");								// 변경기본주소
		String chgerDtlAddr 				= map.getString("chgerDtlAddr");								// 변경상세주소
		String chgerRtnMemo					= map.getString("chgerRtnMemo");								// 반품메모
		String isCustomer					= map.getString("isCustomer");									// 귀책사유 (고객, 회사)
		String accountNo					= map.getString("accountNo");									// 환불계좌번호
		String accountNm					= map.getString("accountNm");									// 환불계좌주명
		String bankCd						= map.getString("bankCd");										// 환불계좌은행코드
		String chgGb						= TscConstants.OrderChangeGb.RETURN.value(); 					// 반품요청 (공톹코드:G680)
		String wdGb							= map.getString("wdGb");										// 회수방법
		String wdInvoiceNo					= map.getString("wdInvoiceNo");									// 회수송장번호
		String shipCompCd					= map.getString("shipCompCd");									// 회수택배사코드
		String chgStat						= TscConstants.OrderChangeStat.RETURN.value();					// 주문변경상태
		int ordChgSq						= 0;															// 주문변경일련번호
		int addPayCost						= 0;															// 반품배송비
		String ordChgGb						= map.getString("ordChgGb");									// 주문변경요쳥변경구분
		int orgOrdChgSq						= map.getInt("orgOrdChgSq");									// 반품TO반품 기존 주문변경일련번호
		int orgAddPayCost					= map.getInt("orgAddPayCost");									// 반품TO반품 기존 추가배송비
		String wdTargetYn					= map.getString("wdTargetYn");									// 회수요청대상
		String npayChangeHoldYn				= "";															// 네이버페이 주문형 반품/교환 보류 여부

		// 네이버페이 주문형 반품/교환 보류 여부 설정
		if (TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb)) {
			npayChangeHoldYn = "N";
		}

		// 3. 주문변경정보, 주문정보, 환불정보 (배송정책코드 별)
		for (Order obj : cancelDelvRefundList) {
			// 환불금액 있을 시 처리
			if (obj.getCnclRtnAmt() > 0) {
				// 3-1. 환불정보 설정
				int spanRealCnclRtnAmt 		= obj.getRealOrdAmt();		// 취소금액합계
				int spanGfcdUseAmt			= obj.getGfcdAmt();			// 취소상품권금액합계
				int spanTotRtnDelvFee 		= obj.getRtnDelvFee();		// 반품배송비합계
				int addDelvFee				= spanTotRtnDelvFee;
				int spanRefundAmt 			= spanRealCnclRtnAmt;

				// 고객사유 : 환불금액계산 = 취소금액 - 추가배송비
				
				int leftAddDelvFee			= addDelvFee;
				int delvGfcdUseAmt			= 0;
				int realDelvAmt				= 0;
				if ("true".equals(isCustomer) && "W".equals(wdGb)) {
					// 2021.08.10 card007 상품권 100% 결제 관련 로직 변경
					int refundAmt = spanRealCnclRtnAmt + spanGfcdUseAmt;
					if (refundAmt < addDelvFee) {
						chgStat = TscConstants.OrderChangeStat.RETURN_WAIT.value();			// 추가배송비 처리 상태값 설정
						addPayCost = addDelvFee;
					} else {
						if (leftAddDelvFee > spanRefundAmt) {
							leftAddDelvFee -= spanRefundAmt;
							realDelvAmt = spanRefundAmt;
							spanRefundAmt = 0;
						} else {
							spanRefundAmt -= leftAddDelvFee;
							realDelvAmt = leftAddDelvFee;
							leftAddDelvFee = 0;
						}
						
						if (leftAddDelvFee > 0) {
							spanGfcdUseAmt -= leftAddDelvFee;
							delvGfcdUseAmt = leftAddDelvFee;
						}

						addDelvFee = 0;
					}
					// int refundAmt = spanRealCnclRtnAmt - addDelvFee;
					// if (refundAmt < 0) {
					// 	chgStat = TscConstants.OrderChangeStat.RETURN_WAIT.value();			// 추가배송비 처리 상태값 설정
					// 	addPayCost = addDelvFee;
					// } else {
					// 	spanRefundAmt = refundAmt;											// 추가배송비 제외 환불금액 설정
					// 	addDelvFee = 0;
					// }
				}
				// 회사사유 : 환불금액계산 = 취소금액
				else {
					// 추가배송비 0 처리
					// spanTotDeliveryFee = 0;  // (추가배송비 처리는 환불컨펌에서 진행)
					spanTotRtnDelvFee = 0;
					addDelvFee = 0;
				}

				// 3-2. 주문변경정보 생성
				OrderChange orderChange = new OrderChange();
				orderChange.setOrdNo(ordNo);
				orderChange.setChgGb(chgGb);
				orderChange.setChgReason(chgReason);
				orderChange.setChgMemo(chgMemo);
				orderChange.setChgerNm(chgerNm);
				orderChange.setChgerPhnno(chgerPhnno);
				orderChange.setChgerTelno(chgerTelno);
				orderChange.setChgerEmail(chgerEmail);
				orderChange.setChgerRtnMemo(chgerRtnMemo);
				orderChange.setChgerZipcode(chgerZipcode);
				orderChange.setChgerBaseAddr(chgerBaseAddr);
				orderChange.setChgerDtlAddr(chgerDtlAddr);
				orderChange.setWdGb(wdGb);
				orderChange.setWdTargetYn(wdTargetYn);
				orderChange.setWdInvoiceNo(wdInvoiceNo);
				orderChange.setShipCompCd(shipCompCd);
				orderChange.setAddPayCost(addDelvFee);
				orderChange.setAddPayAmt(0);
				orderChange.setNpayChangeHoldYn(npayChangeHoldYn);
				orderChange.setRegNo(regNo);
				orderChange.setUpdNo(updNo);

				orderChangeDao.createOrderChange(orderChange);

				// 3-3. TB_DELIVERY_FEE 추가배송비 등록
				// 반품배송비 등록
				Order deliveryFee = new Order();
				deliveryFee.setOrdNo(ordNo);
				deliveryFee.setDelvFeeCd(obj.getDelvFeeCd());
				deliveryFee.setOrdChgSq(orderChange.getOrdChgSq());
				deliveryFee.setSupplyCompCd(obj.getSupplyCompCd());
				deliveryFee.setDelvFeeGb(TscConstants.DeliveryFeeGb.RETURN_DELIVERY_FEE.value());
				deliveryFee.setDelvFee(spanTotRtnDelvFee);
				deliveryFee.setDelvGfcdUseAmt(delvGfcdUseAmt);
				deliveryFee.setRealDelvAmt(realDelvAmt);
				deliveryFee.setRegNo(regNo);
				deliveryFee.setUpdNo(updNo);

				// 2021.06.30 반품TO반품 추가배송비는 기존정보로 수정 처리
				// 기존 추가배송비X -> 반품TO반품 추가배송비O 인 경우 처리 필요
				if (TscConstants.ChangeGb.RETURN_TO_RETURN.value().equals(ordChgGb) && !(orgAddPayCost > 0 && addDelvFee == 0)) {
					deliveryFee.setOrgOrdChgSq(orgOrdChgSq);
					orderChangeDao.updateDeliveryFee(deliveryFee);

					// 반품TO반품은 추가배송비 기존정보로 처리하기 때문에 반품접수상태로 처리
					chgStat = TscConstants.OrderChangeStat.RETURN.value();
				} else {
					orderChangeDao.createDeliveryFee(deliveryFee);
				}

				// 3-4. 주문상세정보 수정
				ordChgSq = orderChange.getOrdChgSq();
				for (Order vo : cancelOrderRefundList) {
					// 배송정책코드 별 주문상세 처리
					if (obj.getDelvFeeCd().equals(vo.getDelvFeeCd()) && vo.getOrdCanChgQty() > 0) {
						// 3-2-2. 주문변경상세정보 및 이력 등록
						OrderChange changeDetailPo = new OrderChange();
						changeDetailPo.setOrdChgSq(ordChgSq);
						changeDetailPo.setOrdDtlNo(vo.getOrdDtlNo());
						changeDetailPo.setChgQty(vo.getOrdCanChgQty());
						changeDetailPo.setChgStat(chgStat);
						changeDetailPo.setRegNo(regNo);
						changeDetailPo.setUpdNo(updNo);

						orderChangeDao.createOrderChangeDetail(changeDetailPo);
						orderChangeDao.createOrderChangeDetailHst(changeDetailPo);
					}
				}

				// 3-5. 환불정보 등록
				Order refundOrder = new Order();
				refundOrder.setOrdNo(ordNo);
				refundOrder.setPaySq(0);
				refundOrder.setOrdChgSq(ordChgSq);
				refundOrder.setRefundAmt(spanRefundAmt);
				refundOrder.setDepositAmt(0);
				refundOrder.setRfCpn1Amt(obj.getCpn1DcAmt());
				refundOrder.setRfTmtb1Amt(obj.getTmtb1DcAmt());
				refundOrder.setRfTmtb2Amt(obj.getTmtb2DcAmt());
				refundOrder.setRfGoodsCpnAmt(obj.getGoodsCpnDcAmt());
				refundOrder.setRfCartCpnAmt(obj.getCartCpnDcAmt());
				refundOrder.setRfDelvCpnAmt(obj.getDelvCpnDcAmt());
				refundOrder.setRfPntAmt(obj.getPntDcAmt());
				refundOrder.setRfPrePntAmt(obj.getPrePntDcAmt());
				// 2021.08.10 card007 상품권 100% 결제 관련 로직 변경
				refundOrder.setRfGfcdUseAmt(spanGfcdUseAmt);
				// refundOrder.setRfGfcdUseAmt(obj.getGfcdAmt());
				refundOrder.setRfCnclAmt(obj.getCnclRtnAmt());
				refundOrder.setRfDeliveryFee(spanTotRtnDelvFee * -1);
				refundOrder.setRfRealCnclAmt(spanRefundAmt + spanTotRtnDelvFee);
				// 2021.06.09 계좌번호 암호화
				//refundOrder.setRaNo(accountNo);
				refundOrder.setRaNo(CryptoUtils.encryptAES(accountNo));
				refundOrder.setRaNm(accountNm);
				refundOrder.setRaBank(bankCd);
				refundOrder.setRegNo(regNo);

				orderChangeDao.createRefund(refundOrder);
			}
		}

		// 주문변경일련번호 설정
		map.setInt("ordChgSq", ordChgSq);
		map.setInt("addPayCost", addPayCost);

		return map;
	}

	/**
	 * 반품신청철회 (admin)
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 19
	 */
	@Transactional("shopTxnManager")
	public GagaMap rtnReqCancel(GagaMap mav, int userNo) {
		try {
			int ordChgSq = mav.getInt("ordChgSq");
			int ordNo = mav.getInt("ordNo");

			Order order = new Order();
			order.setOrdNo(ordNo);
			order.setOrdChgSq(ordChgSq);
			order.setChgStat(TscConstants.OrderChangeStat.RETURN_CANCEL.value());
			order.setRegNo(userNo);
			order.setUpdNo(userNo);
			order.setDelYn("Y");

			// 1. 주문변경정보 (TB_ORDER_CHANGE_DTL(수정))
			orderChangeDao.updateOrderChangeDtlCancel(order);

			// 2. 주문변경이력정보 (TB_ORDER_CHANGE_DETAIL_HST(수정))
			OrderChange orderChange = new OrderChange();
			orderChange.setOrdChgSq(ordChgSq);
			orderChange.setChgStat(TscConstants.OrderChangeStat.RETURN_CANCEL.value());
			orderChange.setRegNo(userNo);
			orderChange.setUpdNo(userNo);
			orderChangeDao.createOrderChangeDetailHstForAllCancel(orderChange);

			// 3. 주문정보 이력 등록 (TB_ORDER_DETAIL_HST(등록))
			// orderChangeDao.createOrderDtlHstCancel(order);

			// 4. PG 실행 (취소시 추가결제금액 취소처리)
			Collection<Order> paymentList = orderChangeDao.getAddDeliveryFeePayment(orderChange);

			// 추가배송비 존재 시
			int payAmt = 0;

			Payment pg = new Payment();
			if (paymentList != null && paymentList.size() > 0  && !TscConstants.ChangeGb.RETURN_TO_RETURN.value().equals(mav.getString("ordChgGb"))) {
				payAmt = paymentList.iterator().next().getPayAmt();

				// 추가배송비 취소 처리
				orderChangeDao.createAddDeliveryFeeCancel(orderChange);

				// 추가배송비 결제정보 조회
				pg.setOrdChgSq(ordChgSq);
				pg = orderChangeDao.getAddPayCostPaymentInfo(pg);

				// 추가배송비 취소 정보 설정
				if(pg != null && StringUtils.isNotBlank(pg.getPgTid()) && !TscConstants.PgGb.NAVER_ORDER.value().equals(pg.getPgGb())) {
					pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
					pg.setPayGb(TscConstants.PaymentGb.DELIVERY.value());
					pg.setModType("STSC");
					pg.setModDesc("가맹점 취소 - 전체 취소");
					pg.setIpAddress(mav.getString("ipAddress"));
					pg.setRegNo(userNo);
					pg.setUpdNo(userNo);
				}

				kcpService.kcpCancel(pg);
			}

			mav.setInt("orgAddPayCost", payAmt);

			if(pg != null && TscConstants.PgGb.NAVER_ORDER.value().equals(pg.getPgGb())) {
				Collection<Order> dtlList = naverPayDao.getOrderDetailInfoFromOrdChgSq(order);
				for(Order dtl : dtlList) {
					if("scm".equals(env.getProperty("server.site.name"))) {
						naverPayService.sendNaverPayRejectReturn(dtl, userNo);
					} else {
						// naverPayService.sendNaverPayRejectReturn(orderChange, userNo);
						String addUrl = "/naverpay/send/reject/return?ordDtlNo=" + dtl.getOrdDtlNo() + "&userNo=" + userNo;
						naverPayService.sendScmServerForNaverpay(addUrl);						// 반품 반려
					}
				}
			}

			// 5. WMS 취소 처리
			WmsDelivery wmsDelivery = new WmsDelivery();
			wmsDelivery.setOrderExceptionNo(ordChgSq);
			Collection<WmsDelivery> list = wmsService.getWmsWithdrawRequestInfo(wmsDelivery);

			if (list != null && list.size() > 0) {
				wmsService.updateWmsRecallCancel(ordNo, ordChgSq);
			}
		} catch(Exception e) {
			e.printStackTrace();
			throw new IllegalStateException(e.getMessage());
		}

		return mav;
	}

	/**
	 * 반품완료
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 19
	 */
	public GagaMap rtnComplete(List<Order> cnclRtnList) {
		GagaMap mav = new GagaMap();


		return mav;
	}

	/**
	 * 교환신청
	 *
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 19
	 */
	@Transactional("shopTxnManager")
	public GagaMap exchReq(OrderChange excReq) {
		GagaMap result = new GagaMap();

		// 교환 기본 정보
		int ordNo 			= excReq.getOrdNo();			// 주문번호
		int addPayCost 		= excReq.getAddPayCost();		// 추가배송비
		String wdGb 		= excReq.getWdGb();				// 회수구분
		String wdInvoiceNo 	= excReq.getWdInvoiceNo();		// 회수송장번호
		String shipCompCd 	= excReq.getShipCompCd();		// 회수택배사코드
		Integer regNo 		= excReq.getRegNo();			// 등록자번호
		Integer updNo 		= excReq.getUpdNo();			// 수정자번호
		String wdTargetYn 	= excReq.getWdTargetYn();		// 회수지시여부
		String selfGoodsYn 	= excReq.getSelfGoodsYn();		// 자사여부
		String wdBfSendYn 	= "N";							// 선발송여부
		int ordChgSq 		= 0;							// 주문변경일련번호

		// 교환신청 목록 설정
		Collection<Order> excReqList = excReq.getCancelReqList();

		// 추가배송비 관련 상태값 설정
		String orderChangeStat = TscConstants.OrderChangeStat.EXCHANGE.value();
		String ordDtlStat = TscConstants.OrderDetailStat.REFUND_CONFIRM_WAIT.value();

		if (addPayCost > 0) {
			orderChangeStat = TscConstants.OrderChangeStat.EXCHANGE_WAIT.value();
		}

		// 원주문 결제정보 조회
		Payment payment = new Payment();
		payment.setOrdNo(ordNo);
		payment = orderChangeDao.getPaymentInfo(payment);

		// 네이버페이는 추가 결제 금액이 있어도 취소접수로 변경
		String npayChangeHoldYn = "";
		if(StringUtils.isNotBlank(excReq.getPgGb()) && TscConstants.PgGb.NAVER_ORDER.value().equals(excReq.getPgGb())) {
			// 2021.08.18 card007 네이버페이 주문형 교환신청의 경우 교환접수승인대기로 변경
			orderChangeStat = TscConstants.OrderChangeStat.EXCHANGE_APPROVE_WAIT.value();
			npayChangeHoldYn = "N";
		}
		
		// 제휴몰 주문은 추가 결제 금액이 있어도 반품접수로 처리
		if (payment != null && TscConstants.PayMeans.EXTMALL.value().equals(payment.getPayMeans())) {
			orderChangeStat = TscConstants.OrderChangeStat.EXCHANGE.value();
		}

		// 선발송여부 설정
		if (StringUtils.isNotBlank(excReq.getWdBfSendYn())) {
			wdBfSendYn = excReq.getWdBfSendYn();
		}

		// 1. 재고 체크 (세트아이템 포함)
		String stockMsg = "";
		if (!TscConstants.ChangeGb.EXCHANGE_TO_EXCHANGE.value().equals(excReq.getOrdChgGb())) {
			for (Order order : excReqList) {
				Order currStockQty = orderChangeDao.getCurrStockQty(order);
				String goodsCd = currStockQty.getGoodsCd();	// 상품코드
				String ordChgOpt = order.getOrdChgOpt(); 	// 교환옵션

				// 1-1. 재고 정보 미존재
				if (currStockQty == null) {
					stockMsg += "상품코드 : " + goodsCd + "의 재고 정보가 존재 하지 않습니다.<br/>";
				} // 1-2. 재고 수량 부족
				else if (currStockQty.getCurrStockQty() < (order.getChgQty() * currStockQty.getItemQty())) {
					stockMsg += "상품코드 : " + goodsCd + " 교환옵션 : " + ordChgOpt + "의 재고가 부족합니다.<br/>";
				} // 1-3. 사이즈 품절
				else if ("Y".equals(currStockQty.getSoldoutYn())) {
					stockMsg += "상품코드 : " + goodsCd + " 교환옵션 : " + ordChgOpt + "의 재고가 품절입니다.<br/>";
				}
			}
		}

		if (StringUtils.isNotBlank(stockMsg)) {
			stockMsg += "위 사유로 재고가 부족하여 교환 신청이 취소되었습니다.";

			if ("front".equals(env.getProperty("server.site.name"))) {
				stockMsg = message.getMessage("EXCHANGE_0003");
			}
			throw new IllegalStateException(stockMsg);
		}

		// 2. TB_DELIVERY_ADDR 등록
		Order deliveryAddr = new Order();
		deliveryAddr.setRecipNm(excReq.getRecipNm());
		deliveryAddr.setRecipPhnno(excReq.getRecipPhnno());
		deliveryAddr.setRecipTelno(excReq.getRecipTelno());
		deliveryAddr.setRecipZipcode(excReq.getRecipZipcode());
		deliveryAddr.setRecipBaseAddr(excReq.getRecipBaseAddr());
		deliveryAddr.setRecipDtlAddr(excReq.getRecipDtlAddr());
		deliveryAddr.setDelvMemo(excReq.getDelvMemo());
		deliveryAddr.setRegNo(regNo);
		deliveryAddr.setUpdNo(updNo);

		orderChangeDao.createDeliveryAddr(deliveryAddr);

		// 생성된 delvAddrSq 등록
		int delvAddrSq = deliveryAddr.getDelvAddrSq();

		// 교환대상 정보 등록
		int preOrdDtlNo 			= 0;
		String preDelvFeeCd 		= "";
		int exchangeOrdDtlNo 		= 0;
		int ordDtlOrdAmt 			= 0;
		int ordDtlCnclRtnAmt	 	= 0;
		int ordDtlCpn1DcAmt 		= 0;
		int ordDtlTmtb1DcAmt 		= 0;
		int ordDtlTmtb2DcAmt 		= 0;
		int ordDtlGoodsCpnDcAmt 	= 0;
		int ordDtlCartCpnDcAmt 		= 0;
		int ordDtlPntDcAmt 			= 0;
		int ordDtlPrePntDcAmt 		= 0;
		int ordDtlSavePntAmt 		= 0;
		int ordDtlRealOrdAmt 		= 0;
		int ordDtlGfcdUseAmt 		= 0;
		int length					= 0;
		int index					= 0;
		int leftOrdAmt 				= 0;
		int leftCnclRtnAmt			= 0;
		int leftCpn1DcAmt 			= 0;
		int leftTmtb1DcAmt 			= 0;
		int leftTmtb2DcAmt 			= 0;
		int leftGoodsCpnDcAmt 		= 0;
		int leftCartCpnDcAmt 		= 0;
		int leftPntDcAmt 			= 0;
		int leftPrePntDcAmt 		= 0;
		int leftSavePntAmt 			= 0;
		int leftRealOrdAmt 			= 0;
		int leftGfcdUseAmt 			= 0;
		double currPrice 			= 0;

		for (Order order : excReqList) {
			String delvFeeCd = "Y".equals(selfGoodsYn) ? "WMS" : order.getDelvFeeCd();
			int chgQty = order.getChgQty();
			String ordChgOpt = order.getOrdChgOpt();
			int ordDtlNo = order.getOrdDtlNo();

			if (!preDelvFeeCd.equals(delvFeeCd)) {
				// 3. TB_ORDER_CHANGE 등록
				OrderChange orderChange = new OrderChange();
				orderChange.setChgGb(TscConstants.OrderChangeGb.EXCHANGE.value());
				orderChange.setChgReason(excReq.getChgReason());
				orderChange.setChgMemo(excReq.getChgMemo());
				orderChange.setWdGb(wdGb);
				orderChange.setWdTargetYn(wdTargetYn);
				orderChange.setWdInvoiceNo(wdInvoiceNo);
				orderChange.setShipCompCd(shipCompCd);
				orderChange.setChgerNm(excReq.getChgerNm());
				orderChange.setChgerPhnno(excReq.getChgerPhnno());
				orderChange.setChgerTelno(excReq.getChgerTelno());
				orderChange.setChgerEmail(excReq.getChgerEmail());
				orderChange.setChgerZipcode(excReq.getChgerZipcode());
				orderChange.setChgerBaseAddr(excReq.getChgerBaseAddr());
				orderChange.setChgerDtlAddr(excReq.getChgerDtlAddr());
				orderChange.setChgerRtnMemo(excReq.getChgerRtnMemo());
				orderChange.setAddPayCost(addPayCost);
				orderChange.setAddPayAmt(excReq.getAddPayAmt());
				orderChange.setWdBfSendYn(wdBfSendYn);
				orderChange.setNpayChangeHoldYn(npayChangeHoldYn);
				orderChange.setRegNo(regNo);
				orderChange.setUpdNo(updNo);

				orderChangeDao.createOrderChange(orderChange);

				preDelvFeeCd = delvFeeCd;

				// 생성된 ordChgSq 설정
				ordChgSq = orderChange.getOrdChgSq();

				log.info("############# ordChgSq >>> {} ##############", ordChgSq);

				// 4. TB_DELIVERY_FEE 추가배송비 등록
				int rtnDelvFee = 0;
				int excDelvFee = 0;

				Order deliveryFee = new Order();
				deliveryFee.setOrdNo(excReq.getOrdNo());
				deliveryFee.setDelvFeeCd(delvFeeCd);
				deliveryFee.setOrdChgSq(ordChgSq);
				deliveryFee.setSupplyCompCd(order.getSupplyCompCd());
				deliveryFee.setRegNo(regNo);
				deliveryFee.setUpdNo(updNo);

				// 반품, 교환 배송비 설정
				if (excReq.getIsCustomer()) {
					rtnDelvFee = order.getRtnDelvFee();
					excDelvFee = order.getExcDelvFee() - rtnDelvFee;

					if ("D".equals(wdGb)) {
						rtnDelvFee = 0;
					}
				}

				if(StringUtils.isNotBlank(excReq.getPgGb()) && TscConstants.PgGb.NAVER_ORDER.value().equals(excReq.getPgGb()) && addPayCost > 0) {
					rtnDelvFee = order.getRtnDelvFee();
					excDelvFee = order.getExcDelvFee();
				}

				// 반품배송비 등록
				deliveryFee.setDelvFeeGb(TscConstants.DeliveryFeeGb.RETURN_DELIVERY_FEE.value());
				deliveryFee.setDelvFee(rtnDelvFee);
				deliveryFee.setRealDelvAmt(rtnDelvFee);

				// 2021.06.30 교환TO교환 추가배송비는 기존정보로 수정 처리
				if (TscConstants.ChangeGb.EXCHANGE_TO_EXCHANGE.value().equals(excReq.getOrdChgGb())) {
					deliveryFee.setOrgOrdChgSq(excReq.getOrdChgSq());
					orderChangeDao.updateDeliveryFee(deliveryFee);

					// 교환TO교환은 추가배송비 기존정보로 처리하기 때문에 교환접수상태로 처리
					orderChangeStat = TscConstants.OrderChangeStat.EXCHANGE.value();
				} else {
					orderChangeDao.createDeliveryFee(deliveryFee);
				}

				// 교환배송비 등록
				deliveryFee.setDelvFeeGb(TscConstants.DeliveryFeeGb.EXCHANGE_DELIVERY_FEE.value());
				deliveryFee.setDelvFee(excDelvFee);
				deliveryFee.setRealDelvAmt(excDelvFee);

				// 2021.06.30 교환TO교환 추가배송비는 기존정보로 수정 처리
				if (TscConstants.ChangeGb.EXCHANGE_TO_EXCHANGE.value().equals(excReq.getOrdChgGb())) {
					orderChangeDao.updateDeliveryFee(deliveryFee);
				} else {
					orderChangeDao.createDeliveryFee(deliveryFee);
				}
			}

			if (preOrdDtlNo != ordDtlNo) {
				// 5. TB_ORDER_DETAIL 등록
				Order ordDtl = new Order();
				ordDtl.setOrdNo(ordNo);
				ordDtl.setOrdDtlNo(ordDtlNo);
				ordDtl.setOrdDtlStat(ordDtlStat);
				ordDtl.setOptCd2(ordChgOpt);
				ordDtl.setChgQty(chgQty);
				ordDtl.setDelvAddrSq(delvAddrSq);
				ordDtl.setRegNo(regNo);
				ordDtl.setUpdNo(updNo);

				// 선발송 처리
				if ("Y".equals(wdBfSendYn)) {
					// 주문상세단품정보조회
					Order orderDetailInfo = orderChangeDao.getOrderDetailInfo(ordDtl);

					currPrice				= orderDetailInfo.getOrgCurrPrice();
					int ordAmt				= orderDetailInfo.getOrdAmt();
					int cnclRtnAmt			= orderDetailInfo.getCnclRtnAmt();
					double ordQty			= orderDetailInfo.getOrdQty() - orderDetailInfo.getCnclRtnQty();
					double tempDivD			= ((double)chgQty / ordQty);

					// int tempDiv				= Integer.parseInt(String.valueOf(Math.round(tempDivD)));

					ordDtlOrdAmt			= (int)(ordAmt								* tempDivD);
					ordDtlCnclRtnAmt		= (int)((ordAmt - cnclRtnAmt)				* tempDivD);
					ordDtlCpn1DcAmt 		= (int)(orderDetailInfo.getCpn1DcAmt()		* tempDivD);
					ordDtlTmtb1DcAmt 		= (int)(orderDetailInfo.getTmtb1DcAmt()		* tempDivD);
					ordDtlTmtb2DcAmt 		= (int)(orderDetailInfo.getTmtb2DcAmt()		* tempDivD);
					ordDtlGoodsCpnDcAmt 	= (int)(orderDetailInfo.getGoodsCpnDcAmt()	* tempDivD);
					ordDtlCartCpnDcAmt 		= (int)(orderDetailInfo.getCartCpnDcAmt()	* tempDivD);
					ordDtlPntDcAmt 			= (int)(orderDetailInfo.getPntDcAmt()		* tempDivD);
					ordDtlPrePntDcAmt 		= (int)(orderDetailInfo.getPrePntDcAmt()	* tempDivD);
					ordDtlSavePntAmt 		= (int)(orderDetailInfo.getSavePntAmt()		* tempDivD);
					ordDtlRealOrdAmt 		= (int)(orderDetailInfo.getRealOrdAmt()		* tempDivD);
					ordDtlGfcdUseAmt 		= (int)(orderDetailInfo.getGfcdUseAmt()		* tempDivD);

					// 주문상세단품단위 금액 등록
					length					= orderDetailInfo.getItemCnt();
					index					= 1;
					leftOrdAmt 				= ordDtlOrdAmt;
					leftCnclRtnAmt			= cnclRtnAmt + ordDtlCnclRtnAmt;
					leftCpn1DcAmt 			= ordDtlCpn1DcAmt;
					leftTmtb1DcAmt 			= ordDtlTmtb1DcAmt;
					leftTmtb2DcAmt 			= ordDtlTmtb2DcAmt;
					leftGoodsCpnDcAmt 		= ordDtlGoodsCpnDcAmt;
					leftCartCpnDcAmt 		= ordDtlCartCpnDcAmt;
					leftPntDcAmt 			= ordDtlPntDcAmt;
					leftPrePntDcAmt 		= ordDtlPrePntDcAmt;
					leftSavePntAmt 			= ordDtlSavePntAmt;
					leftRealOrdAmt 			= ordDtlRealOrdAmt;
					leftGfcdUseAmt 			= ordDtlGfcdUseAmt;

					// TB_ORDER_DETAIL UPDATE
					ordDtl.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_AFTER_CANCEL.value());
					ordDtl.setOrdCanChgQty(chgQty);
					ordDtl.setCnclRtnAmt(ordDtlCnclRtnAmt);
					ordDtl.setCpn1DcAmt(ordDtlCpn1DcAmt);
					ordDtl.setTmtb1DcAmt(ordDtlTmtb1DcAmt);
					ordDtl.setTmtb2DcAmt(ordDtlTmtb2DcAmt);
					ordDtl.setGoodsCpnDcAmt(ordDtlGoodsCpnDcAmt);
					ordDtl.setCartCpnDcAmt(ordDtlCartCpnDcAmt);
					ordDtl.setPntDcAmt(ordDtlPntDcAmt);
					ordDtl.setPrePntDcAmt(ordDtlPrePntDcAmt);
					ordDtl.setSavePntAmt(ordDtlSavePntAmt);
					ordDtl.setRealOrdAmt(ordDtlRealOrdAmt);
					ordDtl.setGfcdUseAmt(ordDtlGfcdUseAmt);

					orderChangeDao.updateOrderDetail(ordDtl);
					orderChangeDao.createOrderDetailHstCnclRtn(ordDtl);

					// 선발송 결제완료 상태값 설정
					ordDtl.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());
				} else {
					ordDtl.setCnclRtnAmt(0);
					ordDtl.setCpn1DcAmt(0);
					ordDtl.setTmtb1DcAmt(0);
					ordDtl.setTmtb2DcAmt(0);
					ordDtl.setGoodsCpnDcAmt(0);
					ordDtl.setCartCpnDcAmt(0);
					ordDtl.setPntDcAmt(0);
					ordDtl.setPrePntDcAmt(0);
					ordDtl.setSavePntAmt(0);
					ordDtl.setRealOrdAmt(0);
					ordDtl.setGfcdUseAmt(0);
				}

				orderChangeDao.createOrderDetailForExchange(ordDtl);

				// 생성된 ordDtlNo 설정
				exchangeOrdDtlNo = ordDtl.getExchangeOrdDtlNo();

				log.info("############# exchangeOrdDtlNo >>> {} ##############", exchangeOrdDtlNo);

				// 6. TB_ORDER_DETAIL_HST 등록
				orderChangeDao.createOrderDetailHstForExchange(ordDtl);

				// 7. TB_ORDER_CHANGE_DETAIL 등록
				// 선발송은 회사귀책사유일때만 신청 가능하여 추가배송비 처리 안함(chgStat)
				// 정책이 바껴 고객귀착사유에도 선발송이 가능하게 되면 정책 수립 후 처리 필요함
				OrderChange orderChangeDetail = new OrderChange();
				orderChangeDetail.setOrdChgSq(ordChgSq);
				orderChangeDetail.setOrdDtlNo(ordDtlNo);
				orderChangeDetail.setChgQty(chgQty);
				orderChangeDetail.setChgStat(orderChangeStat);
				orderChangeDetail.setChgOrdDtlNo(exchangeOrdDtlNo);
				orderChangeDetail.setRegNo(regNo);
				orderChangeDetail.setUpdNo(updNo);

				orderChangeDao.createOrderChangeDetail(orderChangeDetail);
				orderChangeDao.createOrderChangeDetailHst(orderChangeDetail);

				preOrdDtlNo = ordDtlNo;
			}

			// 8. TB_ORDER_DETAIL_ITEM 등록
			Order ordDtlItem = new Order();
			ordDtlItem.setOrdDtlItemSq(order.getOrdDtlItemSq());
			ordDtlItem.setOrdNo(ordNo);
			ordDtlItem.setOrdDtlNo(exchangeOrdDtlNo);
			ordDtlItem.setOrdDtlStat(ordDtlStat);
			ordDtlItem.setOrdChgOpt(ordChgOpt);
			ordDtlItem.setRegNo(regNo);
			ordDtlItem.setUpdNo(updNo);

			// 선발송 처리
			if ("Y".equals(wdBfSendYn)) {
				// 원 주문상세단품 정보 조회
				Order orgOrderDetailItemInfo = orderChangeDao.getOrderDetailItemInfo(ordDtlItem);

				int itemPrice 		= order.getItemPrice();
				int optAddPrice 	= order.getOptAddPrice();
				int itemQty 		= order.getItemQty();

				double itemOrdAmt	= (itemPrice + optAddPrice) * itemQty;
				double tempDivD		= (itemOrdAmt / currPrice);

				// int tempDiv 		= Integer.parseInt(String.valueOf(Math.round(tempDivD)));

				if (index == length) {
					ordDtlItem.setOrdAmt(leftOrdAmt);
					ordDtlItem.setCnclRtnAmt(leftCnclRtnAmt);
					ordDtlItem.setCpn1DcAmt(leftCpn1DcAmt);
					ordDtlItem.setTmtb1DcAmt(leftTmtb1DcAmt);
					ordDtlItem.setTmtb2DcAmt(leftTmtb2DcAmt);
					ordDtlItem.setGoodsCpnDcAmt(leftGoodsCpnDcAmt);
					ordDtlItem.setCartCpnDcAmt(leftCartCpnDcAmt);
					ordDtlItem.setPrePntDcAmt(leftPrePntDcAmt);
					ordDtlItem.setPntDcAmt(leftPntDcAmt);
					ordDtlItem.setGfcdUseAmt(leftGfcdUseAmt);
					ordDtlItem.setRealOrdAmt(leftRealOrdAmt);
					ordDtlItem.setSavePntAmt(leftSavePntAmt);

				} else {
					ordDtlItem.setOrdAmt((int)(ordDtlOrdAmt 					* tempDivD));
					ordDtlItem.setCnclRtnAmt((int)(ordDtlCnclRtnAmt 			* tempDivD));
					ordDtlItem.setCpn1DcAmt((int)(ordDtlCpn1DcAmt 				* tempDivD));
					ordDtlItem.setTmtb1DcAmt((int)(ordDtlTmtb1DcAmt 			* tempDivD));
					ordDtlItem.setTmtb2DcAmt((int)(ordDtlTmtb2DcAmt 			* tempDivD));
					ordDtlItem.setGoodsCpnDcAmt((int)(ordDtlGoodsCpnDcAmt		* tempDivD));
					ordDtlItem.setCartCpnDcAmt((int)(ordDtlCartCpnDcAmt 		* tempDivD));
					ordDtlItem.setPrePntDcAmt((int)(ordDtlPrePntDcAmt 			* tempDivD));
					ordDtlItem.setPntDcAmt((int)(ordDtlPntDcAmt 				* tempDivD));
					ordDtlItem.setGfcdUseAmt((int)(ordDtlGfcdUseAmt 			* tempDivD));
					ordDtlItem.setRealOrdAmt((int)(ordDtlRealOrdAmt 			* tempDivD));
					ordDtlItem.setSavePntAmt((int)(ordDtlSavePntAmt 			* tempDivD));

					leftOrdAmt			-= ((int)(ordDtlOrdAmt 					* tempDivD));
					leftCnclRtnAmt		-= ((int)(ordDtlCnclRtnAmt 				* tempDivD));
					leftCpn1DcAmt 		-= ((int)(ordDtlCpn1DcAmt 				* tempDivD));
					leftTmtb1DcAmt 		-= ((int)(ordDtlTmtb1DcAmt 				* tempDivD));
					leftTmtb2DcAmt 		-= ((int)(ordDtlTmtb2DcAmt 				* tempDivD));
					leftGoodsCpnDcAmt 	-= ((int)(ordDtlGoodsCpnDcAmt 			* tempDivD));
					leftCartCpnDcAmt 	-= ((int)(ordDtlCartCpnDcAmt 			* tempDivD));
					leftPrePntDcAmt 	-= ((int)(ordDtlPrePntDcAmt 			* tempDivD));
					leftPntDcAmt 		-= ((int)(ordDtlPntDcAmt 				* tempDivD));
					leftGfcdUseAmt 		-= ((int)(ordDtlGfcdUseAmt 				* tempDivD));
					leftRealOrdAmt 		-= ((int)(ordDtlRealOrdAmt 				* tempDivD));
					leftSavePntAmt 		-= ((int)(ordDtlSavePntAmt 				* tempDivD));
				}

				// 원주문 TB_ORDER_DETAIL_ITEM_HST 반품완료 처리
				Order ordDtlItemHst = new Order();
				ordDtlItemHst.setOrdDtlItemSq(order.getOrdDtlItemSq());
				ordDtlItemHst.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_RETURN_COMPLETE.value());
				ordDtlItemHst.setCnclRtnQty(chgQty);
				ordDtlItemHst.setOrdChgSq(ordChgSq);
				ordDtlItemHst.setCnclRtnAmt(ordDtlItem.getCnclRtnAmt() + orgOrderDetailItemInfo.getCnclRtnAmt());
				ordDtlItemHst.setCpn1DcAmt(orgOrderDetailItemInfo.getCpn1DcAmt() - ordDtlItem.getCpn1DcAmt());
				ordDtlItemHst.setTmtb1DcAmt(orgOrderDetailItemInfo.getTmtb1DcAmt() - ordDtlItem.getTmtb1DcAmt());
				ordDtlItemHst.setTmtb2DcAmt(orgOrderDetailItemInfo.getTmtb2DcAmt() - ordDtlItem.getTmtb2DcAmt());
				ordDtlItemHst.setGoodsCpnDcAmt(orgOrderDetailItemInfo.getGoodsCpnDcAmt()- ordDtlItem.getGoodsCpnDcAmt());
				ordDtlItemHst.setCartCpnDcAmt(orgOrderDetailItemInfo.getCartCpnDcAmt() - ordDtlItem.getCartCpnDcAmt());
				ordDtlItemHst.setPrePntDcAmt(orgOrderDetailItemInfo.getPrePntDcAmt() - ordDtlItem.getPrePntDcAmt());
				ordDtlItemHst.setPntDcAmt(orgOrderDetailItemInfo.getPntDcAmt() - ordDtlItem.getPntDcAmt());
				ordDtlItemHst.setGfcdUseAmt(orgOrderDetailItemInfo.getGfcdUseAmt() - ordDtlItem.getGfcdUseAmt());
				ordDtlItemHst.setRealOrdAmt(orgOrderDetailItemInfo.getRealOrdAmt() - ordDtlItem.getRealOrdAmt());
				ordDtlItemHst.setSavePntAmt(orgOrderDetailItemInfo.getSavePntAmt() - ordDtlItem.getSavePntAmt());
				ordDtlItemHst.setRegNo(regNo);
				ordDtlItemHst.setUpdNo(updNo);
				
				orderChangeDao.createOrderDetailItemHst(ordDtlItemHst);

				// 원주문 TB_ORDER_DETAIL_ITEM 정보 수정
				orderChangeDao.updateOrderDetailItemForExchange(ordDtlItem);

				// 신규주문 TB_ORDER_DETAIL_ITEM 생성
				// 2021.08.20 card007 신규 주문에 취소금액은 0으로 처리
				ordDtlItem.setCnclRtnAmt(0);
				orderChangeDao.createOrderDetailItemForExchange(ordDtlItem);

				// 신규주문 TB_ORDER_DETAIL_ITEM_HST 결제완료 처리
				ordDtlItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_PAYMENT_COMPLETE.value());
				orderChangeDao.createOrderDetailItemHstForExchange(ordDtlItem);
			} else {
				ordDtlItem.setOrdAmt(0);
				ordDtlItem.setCnclRtnAmt(0);
				ordDtlItem.setCpn1DcAmt(0);
				ordDtlItem.setTmtb1DcAmt(0);
				ordDtlItem.setTmtb2DcAmt(0);
				ordDtlItem.setGoodsCpnDcAmt(0);
				ordDtlItem.setCartCpnDcAmt(0);
				ordDtlItem.setPrePntDcAmt(0);
				ordDtlItem.setPntDcAmt(0);
				ordDtlItem.setGfcdUseAmt(0);
				ordDtlItem.setRealOrdAmt(0);
				ordDtlItem.setSavePntAmt(0);
				orderChangeDao.createOrderDetailItemForExchange(ordDtlItem);

				// 9. TB_ORDER_DETAIL_ITEM_HST 등록 교환신청시에 등록하지 않음
				// orderChangeDao.createOrderDetailItemHstForExchange(ordDtlItem);
			}

			index++;
		}

		// 10. TB_SELL_QTY 등록
		OrderChange sellQty = new OrderChange();
		sellQty.setSellGb(TscConstants.SellGb.EXCHANGE.value());
		sellQty.setRegNo(regNo);
		sellQty.setOrdChgSq(ordChgSq);

		orderChangeDao.createSellQtyForExchange(sellQty);

		result.set("status", GagaResponseStatus.SUCCESS.getCode());
		result.set("ordNo", ordNo);
		result.set("ordChgSq", ordChgSq);
		result.setInt("addPayCost", addPayCost);

		return result;
	}

	/**
	 * 교환철회
	 *
	 * @param OrderChange
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 02. 01
	 */
	@Transactional("shopTxnManager")
	public GagaMap exchangeCancel(OrderChange orderChange) {
		GagaMap result = new GagaMap();

		int ordNo = orderChange.getOrdNo();					// 주문번호
		int ordChgSq = orderChange.getOrdChgSq();			// 주문변경번호
		String ordChgGb = orderChange.getOrdChgGb();		// 주문변경요청변경구분
		int regNo = orderChange.getRegNo();					// 등록자번호
		int updNo = orderChange.getUpdNo();					// 수정자번호

		// 1. 추가배송비 조회
		Collection<Order> paymentList = orderChangeDao.getAddDeliveryFeePayment(orderChange);

		// 2. 추가배송비 존재 시 PG취소 정보 설정
		Payment pg = new Payment();
		try {
			// 2021.06.30 교환TO교환 시 추가배송비 취소처리 안함
			if (paymentList != null && paymentList.size() > 0 && !TscConstants.ChangeGb.EXCHANGE_TO_EXCHANGE.value().equals(ordChgGb)) {
				// 추가배송비 취소 처리
				orderChangeDao.createAddDeliveryFeeCancel(orderChange);

				// 2-1. 추가배송비 결제정보 조회
				pg.setOrdChgSq(ordChgSq);
				pg = orderChangeDao.getAddPayCostPaymentInfo(pg);

				// 2-2. 추가배송비 취소 정보 설정
				if (pg != null && StringUtils.isNotBlank(pg.getPgTid())) {
					pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
					pg.setPayGb(TscConstants.PaymentGb.DELIVERY.value());
					pg.setModType("STSC");
					pg.setModDesc("가맹점 취소 - 전체 취소");
					pg.setIpAddress(orderChange.getIpAddress());
					pg.setRegNo(regNo);
					pg.setUpdNo(updNo);
				}
			}

			// 3. 교환철회 처리
			Order exchangeCancel = new Order();
			exchangeCancel.setOrdNo(ordNo);
			exchangeCancel.setOrdChgSq(ordChgSq);
			exchangeCancel.setOrdDtlStat(TscConstants.OrderDetailStat.EXCHANGE_CANCEL.value());
			exchangeCancel.setChgStat(TscConstants.OrderChangeStat.EXCHANGE_CANCEL.value());
			exchangeCancel.setDelYn("Y");
			exchangeCancel.setRegNo(regNo);
			exchangeCancel.setUpdNo(updNo);

			// 3-1. TB_ORDER_DETAIL 상태값 변경
			orderChangeDao.updateOrderDetailForExchangeCancel(exchangeCancel);

			// 3-2. TB_ORDER_DETAIL_HST 생성
			orderChangeDao.createOrderDtlHstCancel(exchangeCancel);

			// 3-3. TB_ORDER_DETAIL_ITEM 상태값 변경
			// orderChangeDao.updateOrderDetailItemForExchangeCancel(exchangeCancel);

			// 3-4. TB_ORDER_DETAIL_ITEM_HST 생성 사용하지않음
			// orderChangeDao.createOrderDetailItemHstForExchangeCancel(exchangeCancel);

			// 3-5. TB_ORDER_CHANGE_DETAIL 상태값 변경 및 DEL_YN Y로 업데이트
			orderChangeDao.updateOrderChangeDtlCancel(exchangeCancel);

			// 3-6. TB_ORDER_CHANGE_DETAIL_HST 생성
			orderChange.setChgStat(TscConstants.OrderChangeStat.EXCHANGE_CANCEL.value());
			orderChangeDao.createOrderChangeDetailHstForAllCancel(orderChange);

			// 4. PG 취소 처리
			if (pg != null && StringUtils.isNotBlank(pg.getPgTid())) {
				if(!TscConstants.PgGb.NAVER_ORDER.value().equals(pg.getPgGb())) {
					kcpService.kcpCancel(pg);
				}
			}

			// 5. 결과값 처리
			result.set("status", GagaResponseStatus.SUCCESS.getCode());

			// 6. 네이버페이 주문시 네이버페이 교환 반려 송부
			if(TscConstants.PgGb.NAVER_ORDER.value().equals(pg.getPgGb())) {
				// 반품 반려 정보 조회
				Order order = new Order();
				order.setOrdChgSq(ordChgSq);
				Collection<Order> rejectList = naverPayDao.getOrderDetailInfoFromOrdChgSq(order);

				String naverpayResult = "";
				for(Order param : rejectList) {
					if("scm".equals(env.getProperty("server.site.name"))) {
						naverpayResult = naverPayService.sendNaverPayRejectExchange(param, regNo);
					} else {
						// 네이버페이는 SCM을 통해서 송부
						String addUrl = "/naverpay/send/reject/exchange?ordDtlNo=" + param.getOrdDtlNo() + "&userNo=" + regNo;
						naverpayResult = naverPayService.sendScmServerForNaverpay(addUrl);
					}
				}
			}

			// 7. WMS 취소 처리
			WmsDelivery wmsDelivery = new WmsDelivery();
			wmsDelivery.setOrderExceptionNo(ordChgSq);
			Collection<WmsDelivery> list = wmsService.getWmsWithdrawRequestInfo(wmsDelivery);

			if (list != null && list.size() > 0) {
				wmsService.updateWmsRecallCancel(ordNo, ordChgSq);
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.set("status", GagaResponseStatus.FAIL.getCode());
		}

		return result;
	}

	/**
	 * 교환접수 승인
	 * 
	 * @param Collection<OrderChange>
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 08. 18
	 */
	@Transactional("shopTxnManager")
	public GagaMap exchangeApproval(OrderChange orderChange) {
		GagaMap result = new GagaMap();

		// 교환 기본 정보
		int ordChgSq					= orderChange.getOrdChgSq();						// 주문변경일련번호
		Integer regNo					= orderChange.getRegNo();							// 등록자번호
		Integer updNo					= orderChange.getUpdNo();							// 수정자번호
		String orderChangeStat			= TscConstants.OrderChangeStat.EXCHANGE.value();	// 주문변경상태코드

		// 교환신청 목록 설정
		Collection<Order> excReqList	= orderChange.getCancelReqList();
		if (excReqList.size() < 1) {
			throw new IllegalStateException(message.getMessage("FAIL_0004"));
		}

		int preOrdDtlNo = 0;
		for (Order order : excReqList) {
			String ordChgOpt = order.getOrdChgOpt();
			int ordDtlNo = order.getOrdDtlNo();

			// 1. 재고 체크 (세트아이템 포함)
			Order currStockQty			= orderChangeDao.getCurrStockQty(order);

			if ((currStockQty.getCurrStockQty() < (order.getChgQty() * currStockQty.getItemQty()))
				|| "Y".equals(currStockQty.getSoldoutYn())) {
				throw new IllegalStateException(message.getMessage("EXCHANGE_0003"));
			}

			if (preOrdDtlNo != ordDtlNo) {
				// 2. 주문변경상세 정보 수정
				Order orderChangeDetail = new Order();
				orderChangeDetail.setOrdChgSq(ordChgSq);
				orderChangeDetail.setChgStat(orderChangeStat);
				orderChangeDetail.setDelYn("N");
				orderChangeDetail.setUpdNo(updNo);
				orderChangeDao.updateOrderChangeDtlCancel(orderChangeDetail);
				
				// 3. 주문변경상세 이력 정보 등록
				OrderChange orderChangeDetailHst = new OrderChange();
				orderChangeDetailHst.setOrdChgSq(ordChgSq);
				orderChangeDetailHst.setOrdDtlNo(ordDtlNo);
				orderChangeDetailHst.setRegNo(regNo);
				orderChangeDetailHst.setUpdNo(updNo);
				orderChangeDetailHst.setChgStat(orderChangeStat);
				orderChangeDao.createOrderChangeDetailHst(orderChangeDetailHst);

				preOrdDtlNo = ordDtlNo;
			}

			// 4. TB_ORDER_DETAIL_ITEM 변경옵션 UPDATE
			OrderChange orderDetailItem = new OrderChange();
			orderDetailItem.setOrdDtlItemSq(order.getOrdDtlItemSq());
			orderDetailItem.setChgOptCd(ordChgOpt);
			orderChangeDao.updateExchangeApprovalOption(orderDetailItem);
		}
		
		result.set("status", GagaResponseStatus.SUCCESS.getCode());
		result.set("message", message.getMessage("SUCC_0004"));
		
		return result;
	}

	/**
	 * 교환회수
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 19
	 */
	public GagaMap exchRtn(List<Order> cnclRtnList) {
		GagaMap mav = new GagaMap();


		return mav;
	}

	/**
	 * 교환발송완료
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 19
	 */
	public GagaMap exchComplete(List<Order> cnclRtnList) {
		GagaMap mav = new GagaMap();


		return mav;
	}

	/**
	 * 취소 접수
	 * 
	 * @param OrderChange
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 04. 22
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap cancelRequest(OrderChange orderChange) {
		GagaMap result = new GagaMap();
		int userNo = orderChange.getUserNo();

		// 1. 주문변경 등록
		// ordNo				: 주문번호
		// chgGb				: 변경구분
		// chgReason			: 변경사유
		// chgMemo				: 변경메모
		// userNo				: 회원번호
		// ordDtlNoArr			: 주문상세번호배열
		// cnclRtnReqQtyArr		: 변경수량배열

		orderChange.setRegNo(userNo);
		orderChange.setUpdNo(userNo);
		orderChangeDao.createOrderChange(orderChange);

		for (int i = 0; i < orderChange.getOrdDtlNoArr().length; i++) {
			Integer ordDtlNo = orderChange.getOrdDtlNoArr()[i];
			int chgQty = orderChange.getCnclRtnReqQtyArr()[i];

			// 2. 주문변경상세정보 등록
			OrderChange changeDetailPo = new OrderChange();
			changeDetailPo.setOrdChgSq(orderChange.getOrdChgSq());
			changeDetailPo.setOrdDtlNo(ordDtlNo);
			changeDetailPo.setChgQty(chgQty);
			changeDetailPo.setChgStat(TscConstants.OrderChangeStat.CANCEL.value());
			changeDetailPo.setRegNo(userNo);
			changeDetailPo.setUpdNo(userNo);
			
			// 주문변경상세정보등록
			orderChangeDao.createOrderChangeDetail(changeDetailPo);
			
			// 주문변경상세정보이력등록
			orderChangeDao.createOrderChangeDetailHst(changeDetailPo);
		}
		
		result.setInt("status", GagaResponseStatus.SUCCESS.getCode());
		
		return result;
	}

	/**
	 * 취소접수승인
	 * 
	 * @param GagaMap, int
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 04. 22
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap approveCancelRequest(OrderChange orderChange, Integer userNo) {
		GagaMap result = new GagaMap();
		Integer ordChgSq;
		try {
			// 1. 환불 사전 정보 조회
			// ordChgSq, accountNo, accountNm, bankCd, ipAddress
			List<Integer> ordDtlNoList = new ArrayList<>();
			List<Integer> chgQtyList = new ArrayList<>();
			for (OrderChange preInfo : orderChangeDao.approveCancelRequestInfo(orderChange)) {
				ordDtlNoList.add(preInfo.getOrdDtlNo());
				chgQtyList.add(preInfo.getChgQty());
			}

			orderChange.setOrdDtlNoArr(ordDtlNoList.stream().mapToInt(Integer::intValue).toArray());
			orderChange.setCnclRtnReqQtyArr(chgQtyList.stream().mapToInt(Integer::intValue).toArray());
			orderChange.setReqGbn("cnclReqComplete");
			// 전체취소 분기처리
			// 부분취소 신청구분 처리

			GagaMap refundPreInfo = getRefundPreInfo(orderChange);
			List<Order> cnclReqList = (List<Order>)refundPreInfo.get("cnclReqList");
			String allCanYn = refundPreInfo.getString("allCanYn");
			String allLastCanYn = refundPreInfo.getString("allLastCanYn");

			int ordNo = orderChange.getOrdNo();
			String pgGb = refundPreInfo.getString("pgGb");
			String pgStat = orderChange.getPgStat();

			// 2. 전체취소, 부분취소 구분 처리 진행
			if ("Y".equals(allCanYn)) {
				orderChange.setChgGb(TscConstants.OrderChangeGb.CANCEL.value());
				orderChange.setRegNo(userNo);
				orderChange.setUpdNo(userNo);

				// 전체 취소 처리
				ordChgSq = allCnclComplete(orderChange);
				result.setInt("ordChgSq", ordChgSq);
				result.setString("pgGb", refundPreInfo.getString("pgGb"));			// PG구분
			} else {
				// 3. 환불금액계산
				// 2021.01.19 취소신청정보를 목록 (주문상세번호, 취소/반품수량) 으로 표현
				result = orderRefundService.cnclRtnRefundAmt(cnclReqList);

				// 4. 부분취소 처리 정보 설정
				result.setInt("ordNo"			, ordNo);									// 주문번호
				result.setInt("ordChgSq"		, orderChange.getOrdChgSq());				// 주문번호
				result.setString("chgReason"	, orderChange.getChgReason());				// 변경사유
				result.setString("chgReasonNm"	, orderChange.getChgReasonNm());			// 변경사유명
				result.setString("chgMemo"		, orderChange.getChgMemo());				// 변경메모
				result.setString("accountNo"	, orderChange.getAccountNo());				// 환불계좌번호
				result.setString("accountNm"	, orderChange.getAccountNm());				// 환불계좌예금주명
				result.setString("bankCd"		, orderChange.getBankCd());					// 환불계좌은행코드
				result.setString("allLastCanYn"	, allLastCanYn);							// 전체 마지막 취소 여부
				result.setString("reqGbn"		, orderChange.getReqGbn());					// 신청구분
				result.setString("ipAddress"	, orderChange.getIpAddress());				// IP주소
				result.setInt("custNo"			, orderChange.getCustNo());					// 고객번호
				result.setString("pgTid"		, refundPreInfo.getString("pgTid"));		// PG거래ID
				result.setString("payMeans"		, refundPreInfo.getString("payMeans"));		// 결제수단
				result.setString("pgGb"			, pgGb);									// PG구분
				result.setString("cashAuthNo"	, refundPreInfo.getString("cashAuthNo"));	// 현금영수증 승인번호
				result.setString("pgStat"		, pgStat);									// PG점프
				result.setInt("depositAmt"		, orderChange.getDepositAmt());				// PG점프 입금액

				// 부분취소 처리
				result = partialCancel(result, userNo);
				result.setString("pgGb", pgGb);												// PG구분
			}

			// 네이버페이 취소 승인 송부
			if(StringUtils.isNotBlank(pgGb) && TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb) && "N".equals(pgStat)) {
				Order order = new Order();
				order.setOrdChgSq(result.getInt("ordChgSq"));
				order.setRegNo(userNo);

				Collection<Order> dtlList = naverPayDao.getOrderDetailInfoFromOrdChgSq(order);

				for(Order dtl : dtlList) {
					dtl.setRegNo(userNo);
					if("scm".equals(env.getProperty("server.site.name"))) {
						// scm은 즉시 송부
						String naverReturn = naverPayService.sendNaverPayOrderCancelConfirm(order);

						if("SUCCESS".equals(naverReturn)) {
							throw new IllegalStateException("취소 승인 실패");
						}
					} else {
						// 네이버페이는 SCM을 통해서 송부
						String addUrl = "/naverpay/send/cancel/complete?ordNo=" + dtl.getOrdNo() + "&ordDtlNo=" + dtl.getOrdDtlNo() + "&npayOrdDtlNo=" + dtl.getNpayOrdDtlNo() + "&userNo=" + userNo;
						log.info("CHECK addUrl ::::: {}", addUrl);
						String scmResult = naverPayService.sendScmServerForNaverpay(addUrl);

						if(!"SUCCESS".equals(scmResult)) {
							throw new IllegalStateException("취소 승인 실패");
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new IllegalStateException("취소 승인 실패");
		}

		return result;
	}


	/**
	 * 주문 환불계좌
	 *
	 * @param order - 주문정보
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 01. 04.
	 */
	public Collection<Order> getRefundAccount(Order order) {
		return orderChangeDao.getRefundAccount(order);
	}

	/**
	 * 환불계좌 저장
	 *
	 * @param order - 주문정보
	 * @return TsaOrder
	 * @author jsh77b
	 * @since 2021. 01. 05.
	 */
	public int saveRefundAccount(Order order) {
		// 환불계좌 유무 체크 후 등록
		order.encryptData(); // 계좌번호 암호화
		
		// 2021.07.21 환불계좌존재하면 수정, 없으면 등록
		if (orderChangeDao.getCustAccountChk(order) < 1) {
			orderChangeDao.saveRefundAccount(order);
		} else {
			orderChangeDao.updateRefundAccount(order);
		}
		
		return 1;
	}

	/**
	 * 교환 정보 조회
	 *
	 * @param OrderChange - 주문 변경 정보
	 * @return Collection<OrderChange>
	 * @author card007
	 * @since 2021. 02. 01
	 */
	public Collection<Order> getExchangeInfo(Order order) {
		return orderChangeDao.getExchangeInfo(order);
	}

	/**
	 * 전체취소 요청
	 *
	 * @param GagaMap, int
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 04. 15
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public Integer allCnclComplete(OrderChange orderChange) {
		Integer ordNo = orderChange.getOrdNo();											// 주문번호
		String chgReason = orderChange.getChgReason();									// G686_10:고객변심, G686_20:관리자취소, G686_30:품절취소
		String chgReasonNm = orderChange.getChgReasonNm();								// 고객변심, 관리자취소, 품절취소
		String chgGb = TscConstants.OrderChangeGb.CANCEL.value();						// 변경구분
		String chgMemo = orderChange.getChgMemo();										// 상세사유
		String accountNo = orderChange.getAccountNo();									// 환불계좌번호
		String accountNm = orderChange.getAccountNm();									// 환불계좌주명
		String bankCd = orderChange.getBankCd();										// 환불은행
		String ipAddress = orderChange.getIpAddress();									// IP주소
		String reqGbn = orderChange.getReqGbn();										// 신청구분
		Integer ordChgSq = orderChange.getOrdChgSq();									// 주문변경일련번호
		int regNo = orderChange.getRegNo();												// 등록자번호
		int updNo = orderChange.getUpdNo();												// 등록자번호
		String pgStat = orderChange.getPgStat();										// PG점프 여부
		int depositAmt = orderChange.getDepositAmt();									// PG점프 입금액

		// 원주문 결제정보 조회
		Payment payment = new Payment();
		payment.setOrdNo(ordNo);
		payment = orderChangeDao.getPaymentInfo(payment);

		// 환불금액 설정
		int refundAmt = payment.getPayAmt();
		String pgGb = payment.getPgGb();
		String payMeans = payment.getPayMeans();
		String payStat = payment.getPayStat();

		// 상태값 설정
		String ordDtlStat = TscConstants.OrderDetailStat.PAYMENT_AFTER_CANCEL.value();	// 주문상세상태
		String chgStat = TscConstants.OrderChangeStat.PAYMENT_AFTER_CANCEL.value();		// 주문변경상태
		String modType = "STSC";														// KCP 전체취소

		// 무통장입금 결제 주문 전체취소 상태값 처리
		if (TscConstants.PgGb.KCP.value().equals(pgGb)
			&& TscConstants.PayMeans.BANK_DEPOSIT.value().equals(payMeans)
			&& TscConstants.PaymentStat.DEPOSIT_BEFORE_BANKING.value().equals(payStat)) {

			ordDtlStat = TscConstants.OrderDetailStat.PAYMENT_BEFORE_CANCEL.value();
			chgStat = TscConstants.OrderChangeStat.PAYMENT_BEFORE_CANCEL.value();
		} else if (TscConstants.PgGb.KCP.value().equals(pgGb)
			&& TscConstants.PayMeans.BANK_DEPOSIT.value().equals(payMeans)
			&& TscConstants.PaymentStat.PAYMENT_COMPLETE.value().equals(payStat)){

			modType = "STHD";															// KCP 무통장입금 전체취소
		}

		// 1. 주문변경 및 변경상세 정보 설정
		OrderChange orderChangeDetail = new OrderChange();
		orderChangeDetail.setOrdNo(ordNo);
		orderChangeDetail.setChgGb(chgGb);
		orderChangeDetail.setChgReason(chgReason);
		orderChangeDetail.setChgStat(chgStat);
		orderChangeDetail.setRegNo(regNo);
		orderChangeDetail.setUpdNo(updNo);
		orderChangeDetail.setChgMemo(chgMemo);

		// 주문변경정보 등록
		if ("cnclComplete".equals(reqGbn)) {
			// 취소 완료 시 생성
			orderChangeDao.createOrderChange(orderChangeDetail);
			ordChgSq = orderChangeDetail.getOrdChgSq();
		} else {
			// 취소접수승인 시 ordChgSq 설정
			orderChangeDetail.setOrdChgSq(ordChgSq);
		}

		// 주문변경상세 및 이력정보 등록
		if ("cnclComplete".equals(reqGbn)) {
			// 취소완료 시 주문변경상세 정보 생성
			orderChangeDao.createOrderChangeDetailForAllCancel(orderChangeDetail);
		} else {
			// 취소접수승인 시 주문변경상세 정보 수정
			Order order = new Order();
			order.setOrdNo(ordNo);
			order.setOrdChgSq(ordChgSq);
			order.setChgStat(chgStat);
			order.setUpdNo(updNo);
			order.setDelYn("N");

			orderChangeDao.updateOrderChangeDtlCancel(order);
		}

		orderChangeDao.createOrderChangeDetailHstForAllCancel(orderChangeDetail);

		// 2. 사용포인트원복
		Order vo = new Order();
		vo.setOrdNo(ordNo);
		vo.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT.value());
		vo.setUpdNo(updNo);

		for (Order point : orderChangeDao.getCustPointHst(vo)) {
			point.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT_CANCEL.value());
			point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_COMPLETE.value());
			point.setOccurDtlDesc("포인트사용취소");
			point.setPntAmt(point.getPntAmt() * -1);
			point.setRegNo(regNo);
			point.setUpdNo(updNo);

			// 포인트 사용 취소 이력 생성 및 포인트 수정
			orderChangeDao.createCustPointHstRollback(point);
			orderChangeDao.updateCustPointRollback(point);
		}

		// 3. 적립예정포인트 취소
		vo.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT.value());

		for (Order point : orderChangeDao.getCustPointHst(vo)) {
			point.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT_CANCEL.value());
			point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_EXPECT.value());
			point.setOccurDtlDesc("예정포인트적립취소");
			point.setPntAmt(point.getPntAmt() * -1);
			point.setRegNo(regNo);
			point.setUpdNo(updNo);

			// 적립예정포인트 취소 이력 생성
			orderChangeDao.createCustPointHstRollback(point);
		}

		// 4-1. 사용상품권 원복
		for (Order giftCard : orderChangeDao.getCustGiftCardHst(vo)) {
			giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
			giftCard.setOccurDtlDesc("상품권사용취소");
			giftCard.setGfcdAmt(giftCard.getGfcdAmt() * -1);
			giftCard.setRegNo(regNo);
			giftCard.setUpdNo(updNo);

			// 상품권 사용 취소 이력 생성 및 상품권 수정
			orderChangeDao.createCustGiftCardHstRollback(giftCard);
			orderChangeDao.updateCustGiftCardRollback(giftCard);
		}

		// 4-2. 배송비 사용 상품권 원복
		// 전체취소 시 배송비 전체 사용 상품권 원복이므로 delvFeeCd설정 안하고 전체 조회 한다.
		for (Order giftCard : orderChangeDao.getCustGiftCardDelvHst(vo)) {
			giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
			giftCard.setOccurDtlDesc("상품권사용취소");
			giftCard.setGfcdAmt(giftCard.getGfcdAmt() * -1);
			giftCard.setRegNo(regNo);
			giftCard.setUpdNo(updNo);

			// 상품권 사용 취소 이력 생성 및 상품권 수정
			orderChangeDao.createCustGiftCardHstRollback(giftCard);
			orderChangeDao.updateCustGiftCardRollback(giftCard);
		}

		// 5. 상품재고원복 (품절취소가 아닐 경우)
		if(!TscConstants.OrderCancelReason.SOLDOUT_CANCEL.value().equals(chgReason)) {
			OrderChange sellQty = new OrderChange();
			sellQty.setOrdChgSq(orderChangeDetail.getOrdChgSq());
			sellQty.setSellGb("11");
			sellQty.setRegNo(regNo);
			orderChangeDao.createSellQty(sellQty);
		}

		// 6. 쿠폰 원복처리
		Order coupon = new Order();
		coupon.setOrdNo(ordNo);
		coupon.setUpdNo(updNo);
		orderChangeDao.updateGoodsCpnRollback(coupon);
		orderChangeDao.updateCartCpnRollback(coupon);
		orderChangeDao.updateDeliveryCpnRollback(coupon);

		// 7. 사은품 전체 취소 (전체취소시 적용) 추후 사은품 관련 취소 로직 개발 예정
		Order freegiftOrder = new Order();
		freegiftOrder.setOrdNo(ordNo);
		freegiftOrder.setUpdNo(updNo);
		orderChangeDao.updateOrdFreegiftDel(freegiftOrder);

		// 8. 환불금액 등록
		Order refundOrder = orderChangeDao.getRefundInfoForAllCancel(vo);
		refundOrder.setOrdNo(ordNo);
		refundOrder.setPaySq(0);
		refundOrder.setOrdChgSq(orderChangeDetail.getOrdChgSq());
		refundOrder.setRefundAmt(refundAmt);
		refundOrder.setRfRealCnclAmt(refundAmt - refundOrder.getRfDeliveryFee());
		refundOrder.setDepositAmt(depositAmt);
		// 2021.06.09 계좌번호 암호화
		//refundOrder.setRaNo(accountNo);
		refundOrder.setRaNo(CryptoUtils.encryptAES(accountNo));
		refundOrder.setRaNm(accountNm);
		refundOrder.setRaBank(bankCd);
		refundOrder.setRegNo(regNo);

		orderChangeDao.createRefund(refundOrder);

		// 9. 주문상세 및 주문상세단품 정보 설정
		OrderChange orderDetail = new OrderChange();
		orderDetail.setOrdNo(ordNo);
		orderDetail.setOrdDtlStat(ordDtlStat);
		orderDetail.setRegNo(regNo);
		orderDetail.setUpdNo(updNo);

		// 주문상세정보 수정 및 이력 등록
		orderChangeDao.updateOrderDetailForAllCancel(orderDetail);
		orderChangeDao.createOrderDetailHstForAllCancel(orderDetail);

		// 주문상세단품정보 수정 및 이력 등록
		// 2021.06.25 전체취소 (취소완료) (정산구분값추가)
		orderDetail.setOrdChgSq(ordChgSq);
		orderDetail.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_CANCEL.value());
		orderChangeDao.createOrderDetailItemHstForAllCancel(orderDetail);
		
		orderChangeDao.updateOrderDetailItemForAllCancel(orderDetail);
		
		// 10. WMS 취소 처리
		List<Order> wmsList = new ArrayList<>();
		if(orderChange.getOrdDtlNoArr() != null && orderChange.getOrdDtlNoArr().length > 0) {
			for (int i = 0; i < orderChange.getOrdDtlNoArr().length; i++) {
				Order wms = new Order();
				wms.setOrdNo(ordNo);
				wms.setOrdDtlNo(orderChange.getOrdDtlNoArr()[i]);
				wms.setChgQty(orderChange.getCnclRtnReqQtyArr()[i]);

				wmsList.add(wms);
			}

			if(wmsList.size() > 0) {
				wmsService.updateWmsCancel(wmsList);
			}
		}
		
		// 11. 배송비 취소 처리
		OrderChange deliveryFee = new OrderChange();
		deliveryFee.setOrdNo(ordNo);
		deliveryFee.setOrdChgSq(ordChgSq);
		deliveryFee.setRegNo(regNo);
		deliveryFee.setUpdNo(updNo);
		orderChangeDao.createDeliveryFeeForAllCancel(deliveryFee);

		// 12. PG 연동
		Payment pg = new Payment();
		pg.setOrdNo(ordNo);
		pg.setOrdChgSq(ordChgSq);
		pg.setPayMeans(payMeans);
		pg.setPayGb("O");
		pg.setPgTid(payment.getPgTid());
		pg.setPayAmt(refundAmt);
		pg.setLeftAmt(refundAmt);
		pg.setRegNo(regNo);
		pg.setUpdNo(updNo);
		if(TscConstants.PaymentStat.DEPOSIT_BEFORE_BANKING.value().equals(payment.getPayStat())) {
			pg.setPayStat(TscConstants.PaymentStat.PAY_BEFORE_CANCEL.value());
		} else {
			pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
		}
		
		// 2021.09.02 (PAY_STAT = 'G016_30' AND PG_TID IS NULL AND PG_GB <> 'ISTYLE') 체크 후 없으면 제휴몰로 판단 로직
		if (orderDao.getExtmallOrderChk(pg) > 0) {
			payMeans = TscConstants.PayMeans.EXTMALL.value();
		}
		
		// PG처리
		if (TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb) || TscConstants.PayMeans.EXTMALL.value().equals(payMeans) || "Y".equals(pgStat) || refundAmt == 0) {
			// 상품권 100%, 제휴몰, PG점프처리, 네이버페이주문은 PG점프 처리
			pg.setPayAmt(pg.getPayAmt() * -1);
			orderDao.insertPaymentCancel(pg);
		} else if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
			pg.setModType(modType);
			pg.setModDesc("가맹점 취소 - 전체 취소");
			pg.setIpAddress(ipAddress);
			pg.setAccountNm(accountNm);
			pg.setAccountNo(accountNo);
			pg.setBankCd(bankCd);
			pg.setBatchYn(orderChange.getBatchYn());

			kcpService.kcpCancel(pg);
		} else if (TscConstants.PgGb.NAVER.value().equals(pgGb)) {
			pg.setPayMeans(payMeans);
			pg.setChgReasonNm(chgReasonNm);

			naverPayService.cancelNaverPayment(pg);
		} else if (TscConstants.PgGb.KAKAO.value().equals(pgGb)) {
			pg.setPayMeans(payMeans);
			kakaoPayService.cancelKakaoPayment(pg);
		}

		// 11. 환불금액 정보 수정
		refundOrder.setPaySq(pg.getPaySq());

		orderChangeDao.updateRefundInfo(refundOrder);

		// 12. 보증보험 취소 처리 (무통장입금 전 전체취소 시 처리)
		if (TscConstants.OrderChangeStat.PAYMENT_BEFORE_CANCEL.value().equals(chgStat)) {
			Order guarantee = new Order();
			guarantee.setOrdNo(ordNo);

			orderService.uSafeGuaranteePayedBeforeCancel(guarantee);
		}

		// 13. 상품권 현금영수증 취소 처리
		GiftCard giftCardCashReceipts = orderDao.getGiftCardReceiptInfo(ordNo);

		if (giftCardCashReceipts != null && StringUtils.isNotBlank(giftCardCashReceipts.getTradeNo())) {
			giftCardCashReceipts.setModType("STSC");
			giftCardCashReceipts.setUsGfcdAmt(giftCardCashReceipts.getAmt());

			kcpService.kcpCashReceiptCancel(giftCardCashReceipts);
		}
		
		return ordChgSq;
	}

	/**
	 * 취소완료 요청
	 *
	 * @param OrderChange
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 04. 21
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap orderCancelPreInfo(OrderChange orderChange, Integer userNo) {
		GagaMap result = new GagaMap();
		Integer ordChgSq;

		// 1. 환불 사전 정보 조회
		GagaMap refundPreInfo = getRefundPreInfo(orderChange);
		List<Order> cnclReqList = (List<Order>)refundPreInfo.get("cnclReqList");
		String allCanYn = refundPreInfo.getString("allCanYn");
		String allLastCanYn = refundPreInfo.getString("allLastCanYn");

		// 2. 전체취소, 부분취소 구분 처리 진행
		orderChange.setReqGbn("cnclComplete");

		if ("Y".equals(allCanYn)) {
			orderChange.setChgGb(TscConstants.OrderChangeGb.CANCEL.value());
			orderChange.setPgStat("N");
			orderChange.setRegNo(userNo);
			orderChange.setUpdNo(userNo);

			// 전체 취소 처리
			ordChgSq = allCnclComplete(orderChange);
			result.setInt("ordChgSq", ordChgSq);
		} else {
			// 3. 환불금액계산
			// 2021.01.19 취소신청정보를 목록 (주문상세번호, 취소/반품수량) 으로 표현
			result = orderRefundService.cnclRtnRefundAmt(cnclReqList);

			// 4. 부분취소 처리 정보 설정
			result.setInt("ordNo", orderChange.getOrdNo());							// 주문번호
			result.setString("chgReason", orderChange.getChgReason());				// 변경사유
			result.setString("chgReasonNm", orderChange.getChgReasonNm());			// 변경사유명
			result.setString("chgMemo", orderChange.getChgMemo());					// 변경메모
			result.setString("accountNo", orderChange.getAccountNo());				// 환불계좌번호
			result.setString("accountNm", orderChange.getAccountNm());				// 환불계좌예금주명
			result.setString("bankCd", orderChange.getBankCd());					// 환불계좌은행코드
			result.setString("allLastCanYn", allLastCanYn);							// 전체 마지막 취소 여부
			result.setString("reqGbn", orderChange.getReqGbn());					// 신청구분
			result.setString("ipAddress", orderChange.getIpAddress());				// IP주소
			result.setInt("custNo", orderChange.getCustNo());						// 고객번호
			result.setString("pgTid", refundPreInfo.getString("pgTid"));			// PG거래ID
			result.setString("payMeans", refundPreInfo.getString("payMeans"));		// 결제수단
			result.setString("pgGb", refundPreInfo.getString("pgGb"));				// PG구분
			result.setString("cashAuthNo", refundPreInfo.getString("cashAuthNo"));	// 현금영수증 승인번호
			result.setString("pgStat", "N");										// PG점프
			result.setString("batchYn", orderChange.getBatchYn());

			// 부분취소 처리
			result = partialCancel(result, userNo);
		}

		return result;
	}

	/**
	 * 취소/반품 환불 사전 정보 조회
	 *
	 * @param Order
	 * @return Collection<Order>
	 * @author jsh77b
	 * @since 2021. 05. 24
	 */
	public GagaMap getRefundPreInfo(OrderChange orderChange) {
		GagaMap result 			= new GagaMap();
		List<Order> cnclReqList = new ArrayList<>();

		// 취소,반품 신청 정보 설정
		int[] ordDtlNoArr 			= orderChange.getOrdDtlNoArr();
		int[] cnclRtnReqQtyArr 		= orderChange.getCnclRtnReqQtyArr();
		List<Integer> ordDtlNoList 	= Arrays.stream(ordDtlNoArr).boxed().collect(Collectors.toList());

		// 환불 사전 정보 조회 (주문상세단위)
		Collection<Order> cnclRtnList = orderChangeDao.getRefundPreInfo(orderChange);
		Order cnclRtn = cnclRtnList.iterator().next();

		// 전체 및 마지막 취소여부 설정
		int cnt						= 0;
		int sumCnclRtnQty			= 0;
		int totOrdQty				= 0;
		String delvFeeCd 			= "";
		String delvFeeCd2			= "";
		String allCanYn 			= "Y";
		String allLastCanYn 		= "Y";
		String allDelvCanYn			= "Y";
		List<String> delvFeeCdList 	= new ArrayList<>();
		GagaMap delvCanYn			= new GagaMap();
		List<String> delvFeeCdCanList = new ArrayList<>();
		List<String> allDelvCanYnList = new ArrayList<>();

		for (Order order : cnclRtnList) {
			int index 		= ordDtlNoList.indexOf(order.getOrdDtlNo());
			int ordQty 		= order.getOrdQty();
			int cnclRtnQty 	= order.getCnclRtnQty();

			// 전체 주문 수량
			totOrdQty		= order.getTotOrdQty();

			// 취소 요청 수량 합계
			if (index >= 0) {
				sumCnclRtnQty += cnclRtnReqQtyArr[index];
			}

			// 전체 취소 여부 설정
			// if ("Y".equals(allCanYn) && (index < 0 || cnclRtnReqQtyArr[index] != ordQty)) {
			// 	allCanYn = "N";
			// }

			// 배송비 코드 별 전체 취소/반품 여부 처리
			if (!delvFeeCd2.equals(order.getDelvFeeCd())) {
				if (cnt > 0) {
					delvFeeCdCanList.add(delvFeeCd2);
					allDelvCanYnList.add(allDelvCanYn);

					allDelvCanYn = "Y";
				}

				delvFeeCd2 = order.getDelvFeeCd();
			}

			if ("Y".equals(allDelvCanYn) && (index < 0 || cnclRtnReqQtyArr[index] != ordQty)) {
				allDelvCanYn = "N";
			}

			// 취소신청
			// 2021.08.10 card007 환불컨펌 시에 배송비 허들 깨지는거 체크하기 위해 조건 추가
			if (!TscConstants.OrderChangeGb.RETURN.value().equals(orderChange.getChgGb())
				|| (TscConstants.OrderChangeGb.RETURN.value().equals(orderChange.getChgGb()) && StringUtils.isNotBlank(orderChange.getChgStat()) && TscConstants.OrderChangeStat.RETURN_ING.value().equals(orderChange.getChgStat()))) {
				// 잔여 수량 여부 체크
				if (ordQty - cnclRtnQty > 0) {
					// 배송비정책코드 등록 여부 체크
					if (!delvFeeCd.equals(order.getDelvFeeCd())) {
						// 취반 신청 목록 내 주문한 상품 존재 여부 체크 (없으면 남은 상품이 있으므로 마지막 취소여부는 N 처리)
						// 취반 신청 수량과 잔여 수량 차이 체크 (차이가 발생하면 남은 상품이 있으므로 마지막 취소여부는 N 처리) 
						if ((index < 0 || cnclRtnReqQtyArr[index] != (ordQty - cnclRtnQty))) { 
							delvFeeCdList.add(order.getDelvFeeCd());
							delvFeeCd = order.getDelvFeeCd();

							if ("Y".equals(allLastCanYn)) {
								allLastCanYn = "N";
							}
						}
					}
				}
			}
			// 반품신청
			else {
				// 반품은 원주문 배송비를 돌려주지 않기 때문에 마지막 취소 여부를 N 처리하여 refundSerivce에서 돌려줘야할 배송비를 0으로 만든다.
				if (!delvFeeCd.equals(order.getDelvFeeCd())) {
					delvFeeCdList.add(order.getDelvFeeCd());
					delvFeeCd = order.getDelvFeeCd();
				}
			}
			
			cnt++;
		}

		// 배송비 코드 별 전체 취소/반품 여부 설정
		if (delvFeeCdCanList.size() == 0) {
			delvFeeCdCanList.add(delvFeeCd2);
			allDelvCanYnList.add(allDelvCanYn);
		}
		delvCanYn.set("delvFeeCdCanList", delvFeeCdCanList);
		delvCanYn.set("allDelvCanYnList", allDelvCanYnList);

		// 전체 취소 여부 설정
		if (totOrdQty != sumCnclRtnQty) {
			allCanYn = "N";
		}

		// 무통장입금전 전체취소여부 설정
		String allCanYnBeforePayment = "N";
		if ("Y".equals(allCanYnBeforePayment)
				&& TscConstants.PayMeans.BANK_DEPOSIT.value().equals(cnclRtn.getPayMeans())
				&& TscConstants.PaymentStat.DEPOSIT_BEFORE_BANKING.value().equals(cnclRtn.getPayStat())) {
			allCanYnBeforePayment = "Y";
		}

		// 전체취소여부 및 취소,반품 수량 설정
		for (Order order : cnclRtnList) {
			int index = ordDtlNoList.indexOf(order.getOrdDtlNo());
			
			// 마지막 취소 여부 설정
			if (delvFeeCdList.contains(order.getDelvFeeCd())) {
				order.setLastCanYn("N");
			} else {
				order.setLastCanYn("Y");
			}
			
			// 변경 수량 설정
			if (index >= 0) {
				order.setOrdCanChgQty(cnclRtnReqQtyArr[index]);
			} else {
				order.setOrdCanChgQty(0);
				// 2021.07.07 jsh77b 반품배송비 설정
				//order.setRtnDelvFee(0);
			}

			// 배송비 정책 별 전체 취소/반품 여부
			int idx = delvFeeCdCanList.indexOf(order.getDelvFeeCd());
			if (idx >= 0) {
				order.setAllDelvCanYn(allDelvCanYnList.get(idx));
			}

			cnclReqList.add(order);
		}

		result.setString("allCanYn"					, allCanYn);					// 전체 취소 여부
		result.setString("allLastCanYn"				, allLastCanYn);				// 전체 마지막 취소 여부
		result.setString("allCanYnBeforePayment"	, allCanYnBeforePayment);		// 무통장입금전 전체 취소 여부
		result.setString("pgTid"					, cnclRtn.getPgTid());			// PG거래ID
		result.setString("payMeans"					, cnclRtn.getPayMeans());		// 결제수단
		result.setString("pgGb"						, cnclRtn.getPgGb());			// PG구분
		result.setString("cashAuthNo"				, cnclRtn.getCashAuthNo());		// 현금영수증 승인번호
		result.set("cnclReqList"					, cnclReqList);					// 취소신청목록
		result.set("delvCanYn"						, delvCanYn);					// 배송비 코드 별 전체 취소/반품 여부

		return result;
	}

	/**
	 * 환불 컨펌 환불 정보
	 * 
	 * @param OrderChange (ordChgSq, userNo)
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 05. 24
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap refundConfirmPreInfo(OrderChange orderChange) {
		GagaMap result = new GagaMap();
		Integer ordChgSq = orderChange.getOrdChgSq();
		Integer userNo   = orderChange.getUserNo();
		
		// 주문변경상세정보 조회
		Collection<OrderChange> orderChangeList = orderChangeDao.getOrderChangeDetailInfo(orderChange);

		if (orderChangeList.size() > 0) {
			// 환불 사전 정보 설정
			int index 				= 0;
			int size 				= orderChangeList.size();
			String chgGb 			= orderChangeList.iterator().next().getChgGb();
			Integer ordNo 			= orderChangeList.iterator().next().getOrdNo();
			Integer custNo 			= orderChangeList.iterator().next().getCustNo();
			String ordNm 			= orderChangeList.iterator().next().getOrdNm();
			String ordPhnno 		= orderChangeList.iterator().next().getOrdPhnno();
			String chgStat 			= orderChangeList.iterator().next().getChgStat();
			String delvFeeCd 		= orderChangeList.iterator().next().getDelvFeeCd();
			String supplyCompCd		= orderChangeList.iterator().next().getSupplyCompCd();
			int[] ordDtlNoArr 		= new int[size];
			int[] cnclRtnReqQtyArr 	= new int[size];
			
			// 2021.07.07 jsh77b 추가배송비용 TB_ORDER_CHANGE.ADD_PAY_COST
			int addPayCost = orderChangeList.iterator().next().getAddPayCost();

			for (OrderChange param : orderChangeList) {
				ordDtlNoArr[index] = param.getOrdDtlNo();
				cnclRtnReqQtyArr[index] = param.getChgQty();
				index++;
			}

			// 회원/비회원 정보 설정
			if (custNo > 0) {
				orderChange.setCustNo(custNo);
			} else {
				orderChange.setOrdNm(ordNm);
				orderChange.setOrdPhnno(ordPhnno);
			}

			orderChange.setOrdNo(ordNo);
			orderChange.setChgGb(chgGb);
			orderChange.setChgStat(chgStat);
			orderChange.setDelvFeeCdGrp(delvFeeCd);
			orderChange.setOrdDtlNoArr(ordDtlNoArr);
			orderChange.setCnclRtnReqQtyArr(cnclRtnReqQtyArr);

			// 환불 사전 정보 조회
			GagaMap refundPreInfo = getRefundPreInfo(orderChange);
			List<Order> cnclReqList = (List<Order>)refundPreInfo.get("cnclReqList");
			
			result = orderRefundService.cnclRtnRefundAmt(cnclReqList);
			
			result.set("allCanYn",              refundPreInfo.get("allCanYn"));
			result.set("allLastCanYn",          refundPreInfo.get("allLastCanYn"));
			result.set("allCanYnBeforePayment", refundPreInfo.get("allCanYnBeforePayment"));
			result.set("pgTid",                 refundPreInfo.get("pgTid"));
			result.set("payMeans",              refundPreInfo.get("payMeans"));
			result.set("pgGb",                  refundPreInfo.get("pgGb"));
			result.set("cashAuthNo",            refundPreInfo.get("cashAuthNo"));
			result.set("addPayCost",            addPayCost);
			result.set("delvFeeCd",             delvFeeCd);
			result.set("delvCanYn",             refundPreInfo.get("delvCanYn"));
			result.set("supplyCompCd",          supplyCompCd);
		}
		return result;
	}
	

	/**
	 * 환불컨펌 부분 취소 처리
	 *
	 * @param GagaMap, Integer
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 08. 12
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap partialRefund(GagaMap map, Integer userNo) {
		// 1. 취소요청목록 및 정보 설정
		List<Order> cancelOrderRefundList 	= (List<Order>) map.get("cancelOrderRefundList");	// 취소환불금액 목록 (주문상세단품 단위)
		List<Order> cancelDelvRefundList 	= (List<Order>) map.get("cancelDelvRefundList");	// 취소환불배송금액 목록 (DELV_FEE_CD 단위)

		Integer ordNo 			= map.getInt("ordNo");											// 주문번호
		Integer custNo			= map.getInt("custNo");											// 고객번호
		Integer ordChgSq		= map.getInt("ordChgSq");										// 주문변경일련번호
		String chgReason 		= map.getString("chgReason");									// 변경사유
		String chgReasonNm 		= map.getString("chgReasonNm");									// 변경사유명
		String chgMemo 			= map.getString("chgMemo");										// 변경메모
		String pgTid			= map.getString("pgTid");										// PG거래ID
		String payMeans			= map.getString("payMeans");									// 결제수단
		String pgGb				= map.getString("pgGb");										// PG구분
		String accountNo		= map.getString("accountNo");									// 환불계좌번호
		String accountNm		= map.getString("accountNm");									// 환불계좌주명
		String bankCd			= map.getString("bankCd");										// 환불계좌은행코드
		String chgGb			= TscConstants.OrderChangeGb.CANCEL.value(); 					// 취소요청 (공톹코드:G680)
		String ordDtlStat		= TscConstants.OrderDetailStat.PAYMENT_AFTER_CANCEL.value();	// 주문상세상태
		String chgStat			= TscConstants.OrderChangeStat.RETURN_COMPLETE.value();			// 주문변경상태
		String pgStat			= map.getString("pgStat");										// PG 점프
		int depositAmt			= map.getInt("depositAmt");										// PG 점프 입금액
		int codFee				= map.getInt("codFee");											// 착불비 
		String codFeeYn			= map.getString("codFeeYn");									// 착불비여부
		int enCloseFee 			= map.getInt("enCloseFee");										// 동봉비
		String enCloseFeeYn 	= map.getString("enCloseFeeYn");								// 동봉비여부
		String wdInvoiceNo		= map.getString("wdInvoiceNo");									// 회수송장번호
		String delvFeeCd		= map.getString("delvFeeCd");									// 배송비정책코드
		String supplyCompCd		= map.getString("supplyCompCd");								// 공급업체코드
		int regNo				= userNo;														// 등록자번호
		int updNo				= userNo;														// 수정자번호
		
		
		// 2. 무통장입금 결제 주문 전체취소 상태값 처리
		String modType			= "";
		// 2021.09.09 페이코 조건 누락 추가
		if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
			if (TscConstants.PayMeans.BANK_DEPOSIT.value().equals(payMeans)) {
				modType = "STPD";																// KCP 무통장입금 부분취소
			} else {
				modType = "STPC";																// KCP 부분취소
			}
		}
		
		// 3. 환불정보 설정
		Order returnOrderInfo = new Order();
		returnOrderInfo.setOrdNo(ordNo);
		returnOrderInfo.setDelvFeeCd(delvFeeCd);
		map.set("returnOrderInfo", this.getReturnOrderInfo(returnOrderInfo));

		OrderChange refundInfo			= this.calculateRefundAmt(map);
		int refundAmt					= refundInfo.getRefundAmt();
		int rfGfcdUseAmt				= refundInfo.getGfcdUseAmt();
		int rfDeliveryFee				= refundInfo.getRfDeliveryFee();

		// 4. 주문변경정보, 주문정보, 환불정보 (배송정책코드 별)
		List<Payment> pgList			= new ArrayList<>();
		List<GiftCard> cashReceiptsList	= new ArrayList<>();

		for (Order obj : cancelDelvRefundList) {
			
			// 취소금액 있을 시 처리
			if (obj.getCnclRtnAmt() > 0) {
				// 4-1. 주문변경정보 생성
				OrderChange orderChange	= new OrderChange();
				orderChange.setOrdNo(ordNo);
				orderChange.setChgGb(chgGb);
				orderChange.setChgReason(chgReason);
				orderChange.setChgMemo(chgMemo);
				orderChange.setAddPayCost(0);
				orderChange.setAddPayAmt(0);
				orderChange.setRegNo(userNo);
				orderChange.setUpdNo(userNo);
				orderChange.setOrdChgSq(ordChgSq);

				// 4-2. 주문상세정보 수정
				int sumGfcdUseAmt = 0;
				for (Order vo : cancelOrderRefundList) {
					vo.setRegNo(userNo);
					vo.setUpdNo(userNo);
					vo.setOrdDtlStat(ordDtlStat);
					
					// 배송정책코드 별 주문상세 처리
					if (obj.getDelvFeeCd().equals(vo.getDelvFeeCd()) && vo.getOrdCanChgQty() > 0) {
						// 주문상세 별 전체취소여부 설정
						int leftQty = vo.getOrdQty() - vo.getCnclRtnQty() - vo.getOrdCanChgQty();

						// 4-2-1. 주문상세정보 수정
						orderChangeDao.updateOrderDetail(vo);

						// 4-2-2. 주문상세 이력 등록
						orderChangeDao.createOrderDetailHstCnclRtn(vo);

						// 4-2-3. 주문상세단품정보 수정 및 주문상세단품이력 등록
						// 주문상세단품정보조회
						Collection<Order> orderDetailItemList = orderChangeDao.getOrderDetailItemForCnclRtn(vo);
						int ordDtlCnclRtnAmt	 	= orderDetailItemList.iterator().next().getCnclRtnAmt();
						int ordDtlCpn1DcAmt 		= orderDetailItemList.iterator().next().getCpn1DcAmt();
						int ordDtlTmtb1DcAmt 		= orderDetailItemList.iterator().next().getTmtb1DcAmt();
						int ordDtlTmtb2DcAmt 		= orderDetailItemList.iterator().next().getTmtb2DcAmt();
						int ordDtlGoodsCpnDcAmt 	= orderDetailItemList.iterator().next().getGoodsCpnDcAmt();
						int ordDtlCartCpnDcAmt 		= orderDetailItemList.iterator().next().getCartCpnDcAmt();
						int ordDtlPntDcAmt 			= orderDetailItemList.iterator().next().getPntDcAmt();
						int ordDtlPrePntDcAmt 		= orderDetailItemList.iterator().next().getPrePntDcAmt();
						int ordDtlSavePntAmt 		= orderDetailItemList.iterator().next().getSavePntAmt();
						int ordDtlRealOrdAmt 		= orderDetailItemList.iterator().next().getRealOrdAmt();
						int ordDtlGfcdUseAmt 		= orderDetailItemList.iterator().next().getGfcdUseAmt();

						// 주문상세단품단위 금액 등록
						int length					= orderDetailItemList.size();
						int index					= 1;
						int leftCnclRtnAmt			= ordDtlCnclRtnAmt;
						int leftCpn1DcAmt 			= ordDtlCpn1DcAmt;
						int leftTmtb1DcAmt 			= ordDtlTmtb1DcAmt;
						int leftTmtb2DcAmt 			= ordDtlTmtb2DcAmt;
						int leftGoodsCpnDcAmt 		= ordDtlGoodsCpnDcAmt;
						int leftCartCpnDcAmt 		= ordDtlCartCpnDcAmt;
						int leftPntDcAmt 			= ordDtlPntDcAmt;
						int leftPrePntDcAmt 		= ordDtlPrePntDcAmt;
						int leftSavePntAmt 			= ordDtlSavePntAmt;
						int leftRealOrdAmt 			= ordDtlRealOrdAmt;
						int leftGfcdUseAmt 			= ordDtlGfcdUseAmt;

						for (Order orderDetailItem : orderDetailItemList) {
							double dtlOrdAmt		= orderDetailItem.getDtlOrdAmt();
							double dtlItemOrdAmt	= orderDetailItem.getDtlItemOrdAmt();
							double tempDivD			= (dtlItemOrdAmt / dtlOrdAmt) * 100;
							
							int tempDiv				= Integer.parseInt(String.valueOf(Math.round(tempDivD)));

							if (index == length) {
								orderDetailItem.setCnclRtnAmt(leftCnclRtnAmt);
								orderDetailItem.setCpn1DcAmt(leftCpn1DcAmt);
								orderDetailItem.setTmtb1DcAmt(leftTmtb1DcAmt);
								orderDetailItem.setTmtb2DcAmt(leftTmtb2DcAmt);
								orderDetailItem.setGoodsCpnDcAmt(leftGoodsCpnDcAmt);
								orderDetailItem.setCartCpnDcAmt(leftCartCpnDcAmt);
								orderDetailItem.setPrePntDcAmt(leftPrePntDcAmt);
								orderDetailItem.setPntDcAmt(leftPntDcAmt);
								orderDetailItem.setGfcdUseAmt(leftGfcdUseAmt);
								orderDetailItem.setRealOrdAmt(leftRealOrdAmt);
								orderDetailItem.setSavePntAmt(leftSavePntAmt);
								
							} else {
								orderDetailItem.setCnclRtnAmt((ordDtlCnclRtnAmt 		* tempDiv) / 100);
								orderDetailItem.setCpn1DcAmt((ordDtlCpn1DcAmt 			* tempDiv) / 100);
								orderDetailItem.setTmtb1DcAmt((ordDtlTmtb1DcAmt 		* tempDiv) / 100);
								orderDetailItem.setTmtb2DcAmt((ordDtlTmtb2DcAmt 		* tempDiv) / 100);
								orderDetailItem.setGoodsCpnDcAmt((ordDtlGoodsCpnDcAmt 	* tempDiv) / 100);
								orderDetailItem.setCartCpnDcAmt((ordDtlCartCpnDcAmt 	* tempDiv) / 100);
								orderDetailItem.setPrePntDcAmt((ordDtlPrePntDcAmt 		* tempDiv) / 100);
								orderDetailItem.setPntDcAmt((ordDtlPntDcAmt 			* tempDiv) / 100);
								orderDetailItem.setGfcdUseAmt((ordDtlGfcdUseAmt 		* tempDiv) / 100);
								orderDetailItem.setRealOrdAmt((ordDtlRealOrdAmt 		* tempDiv) / 100);
								orderDetailItem.setSavePntAmt((ordDtlSavePntAmt 		* tempDiv) / 100);

								leftCnclRtnAmt		-= ((ordDtlCnclRtnAmt 				* tempDiv) / 100);
								leftCpn1DcAmt 		-= ((ordDtlCpn1DcAmt 				* tempDiv) / 100);
								leftTmtb1DcAmt 		-= ((ordDtlTmtb1DcAmt 				* tempDiv) / 100);
								leftTmtb2DcAmt 		-= ((ordDtlTmtb2DcAmt 				* tempDiv) / 100);
								leftGoodsCpnDcAmt 	-= ((ordDtlGoodsCpnDcAmt 			* tempDiv) / 100);
								leftCartCpnDcAmt 	-= ((ordDtlCartCpnDcAmt 			* tempDiv) / 100);
								leftPrePntDcAmt 	-= ((ordDtlPrePntDcAmt 				* tempDiv) / 100);
								leftPntDcAmt 		-= ((ordDtlPntDcAmt 				* tempDiv) / 100);
								leftGfcdUseAmt 		-= ((ordDtlGfcdUseAmt 				* tempDiv) / 100);
								leftRealOrdAmt 		-= ((ordDtlRealOrdAmt 				* tempDiv) / 100);
								leftSavePntAmt 		-= ((ordDtlSavePntAmt 				* tempDiv) / 100);
							}

							orderDetailItem.setRegNo(userNo);
							orderDetailItem.setUpdNo(userNo);
							orderDetailItem.setOrdDtlStat(ordDtlStat);
							
							// 2021.06.25 환불컨펌 (반품완료) (정산구분값추가)
							// 환불컨펌시 확정후반품 처리 체크 로직 추가 (TB_ORDER_DETAIL_ITEM_HST 배송중 일때 반품완료, 결제완료일때 취소완료) 
							// 2021.07.07 확정후반품 로직 추가
							int cnt = orderChangeDao.getOrderDetailItem20Cnt(orderDetailItem);
							if (cnt > 0) {
								orderDetailItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_RETURN_COMPLETE.value());
							} else {
								orderDetailItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_SOLDOUT_CANCEL.value());
							}
							
							orderDetailItem.setCnclRtnQty(vo.getOrdCanChgQty());
							orderDetailItem.setOrdChgSq(ordChgSq);
							orderChangeDao.createOrderDetailItemHst(orderDetailItem);

							orderChangeDao.updateOrderDetailItem(orderDetailItem);

							index++;
						}

						// 4-2-4. 사용포인트원복
						int pntDcAmt = vo.getPntDcAmt();
						vo.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT.value());

						for (Order point : orderChangeDao.getCustPointHst(vo)) {
							if (pntDcAmt > 0) {
								int pntAmt = point.getPntAmt() * -1;

								if (pntDcAmt < pntAmt) {
									point.setPntAmt(pntDcAmt);
									pntDcAmt -= pntDcAmt;
								} else {
									point.setPntAmt(pntAmt);
									pntDcAmt -= pntAmt;
								}

								point.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT_CANCEL.value());
								point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_COMPLETE.value());
								point.setOccurDtlDesc("포인트사용취소");
								point.setRegNo(userNo);
								point.setUpdNo(userNo);

								// 포인트 사용 취소 이력 생성 및 포인트 수정
								orderChangeDao.createCustPointHstRollback(point);
								orderChangeDao.updateCustPointRollback(point);
							}
						}

						// 4-2-5. 적립예정포인트 수정
						int savePntAmt = vo.getSavePntAmt();
						vo.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT.value());

						for (Order point : orderChangeDao.getCustPointHst(vo)) {
							point.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT_CANCEL.value());
							point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_EXPECT.value());
							point.setOccurDtlDesc("예정포인트적립취소");
							point.setPntAmt(savePntAmt * -1);
							point.setRegNo(userNo);
							point.setUpdNo(userNo);

							// 적립예정포인트 취소 이력 생성
							orderChangeDao.createCustPointHstRollback(point);
						}

						// 4-2-6. 상품쿠폰원복
						if (leftQty == 0) {
							orderChangeDao.updateGoodsCpnRollback(vo);
						}

						// 4-2-7. 사용상품권 원복
						int gfcdUseAmt = vo.getGfcdUseAmt();
						sumGfcdUseAmt += gfcdUseAmt;

						for (Order giftCard : orderChangeDao.getCustGiftCardHst(vo)) {
							if (gfcdUseAmt > 0) {
								int gfcdAmt = giftCard.getGfcdAmt() * -1;

								if (gfcdUseAmt < gfcdAmt) {
									giftCard.setGfcdAmt(gfcdUseAmt);
									gfcdUseAmt -= gfcdUseAmt;
								} else {
									giftCard.setGfcdAmt(gfcdAmt);
									gfcdUseAmt -= gfcdAmt;
								}

								giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
								giftCard.setOccurDtlDesc("상품권사용취소");
								giftCard.setRegNo(userNo);
								giftCard.setUpdNo(userNo);

								// 상품권 사용 취소 이력 생성 및 상품권 수정
								orderChangeDao.createCustGiftCardHstRollback(giftCard);
								orderChangeDao.updateCustGiftCardRollback(giftCard);
							}
						}

						// 4-2-8. 주문변경상세정보 및 이력 등록
						OrderChange changeDetailPo = new OrderChange();
						changeDetailPo.setOrdChgSq(ordChgSq);
						changeDetailPo.setOrdDtlNo(vo.getOrdDtlNo());
						changeDetailPo.setChgQty(vo.getOrdCanChgQty());
						changeDetailPo.setChgStat(chgStat);
						changeDetailPo.setRegNo(userNo);
						changeDetailPo.setUpdNo(userNo);

						orderChangeDao.updateOrderChangeDtl(changeDetailPo);
						orderChangeDao.createOrderChangeDetailHst(changeDetailPo);
					}
				}

				// 4-3. 환불금액 설정
				Order dto = new Order();
				dto.setOrdNo(ordNo);
				dto.setCustNo(custNo);
				dto.setRegNo(regNo);
				dto.setUpdNo(updNo);

				// 4-4. 반품배송비 처리
				int rtnDelvGfcdUseAmt = refundInfo.getRtnDelvGfcdUseAmt();
				int rtnRealDelvAmt = refundInfo.getRtnRealDelvAmt();

				OrderChange rtnDelvFee = new OrderChange();
				rtnDelvFee.setOrdChgSq(ordChgSq);
				rtnDelvFee.setDelvGfcdUseAmt(rtnDelvGfcdUseAmt);
				rtnDelvFee.setRealDelvAmt(rtnRealDelvAmt);
				rtnDelvFee.setUpdNo(updNo);
				orderChangeDao.updateReturnDeliveryFee(rtnDelvFee);

				if (rtnDelvGfcdUseAmt > 0) {
					int rmGfcdAmt;
					int usGfcdAmt;

					// 반품배송비 배송비일련번호 조회 및 설정
					OrderChange returnDeliveryFeeInfo = orderChangeDao.getReturnDeliveryFeeInfo(rtnDelvFee);
					Integer delvFeeSq = returnDeliveryFeeInfo.getDelvFeeSq();
					dto.setDelvFeeSq(delvFeeSq);

					// 추가배송비 상품권 결제 처리
					// 환불컨펌 시점에서 상품권이 만료되어져 있을수 있어서 해당 주문건에 사용 후 취소했던 상품권 정보로 처리
					// Order 도메인 내 delvFeeSq 존재 여부로 구분 처리 진행
					for (Order custGiftcardInfo : orderDao.getCustGiftcardInfoList(dto)) {

						// 상품권사용금액 있으면 실행
						rmGfcdAmt = custGiftcardInfo.getRmGfcdAmt();

						// 남은상품권금액 > 사용상품권금액보다 크면 실행
						if (rmGfcdAmt > rtnDelvGfcdUseAmt) {
							rmGfcdAmt = rmGfcdAmt - rtnDelvGfcdUseAmt;
							usGfcdAmt = rtnDelvGfcdUseAmt;
							rtnDelvGfcdUseAmt = 0;
						} else {
							rtnDelvGfcdUseAmt = rtnDelvGfcdUseAmt - rmGfcdAmt;
							usGfcdAmt = rmGfcdAmt;
							rmGfcdAmt = 0;
						}

						if (usGfcdAmt > 0) {
							// 상품권 정보 수정
							custGiftcardInfo.setUsGfcdAmt(usGfcdAmt);
							custGiftcardInfo.setRmGfcdAmt(rmGfcdAmt);
							custGiftcardInfo.setCustNo(custNo);
							orderDao.updateCustGiftcard(custGiftcardInfo);

							// 상품권 사용 이력 생성
							custGiftcardInfo.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD.value());
							custGiftcardInfo.setOccurDtlDesc("상품권사용");
							custGiftcardInfo.setGfcdAmt(usGfcdAmt * -1);
							custGiftcardInfo.setOrdNo(ordNo);
							custGiftcardInfo.setOrdDtlNo(0);
							custGiftcardInfo.setDelvFeeSq(delvFeeSq);
							orderDao.createCustGiftcardHst(custGiftcardInfo);
						}
					}
				}

				// 4-5. 추가배송비 처리 (배송비허들무너짐)
				// 2021.09.11 card007 전체반품 원주문 배송비 차감 추가
				// 2021.09.23 card007 회사사유 배송비 정책 단위 전체 반품 시 원주문배송비 환불 추가
				int delvGfcdUseAmt = refundInfo.getDelvGfcdUseAmt();
				int realDelvAmt = refundInfo.getRealDelvAmt();
				if (refundInfo.getSpanTotDeliveryFee() > 0 || refundInfo.getOrgDelvFee() > 0) {
					int delvFee;

					if (refundInfo.getSpanTotDeliveryFee() > 0) {
						delvFee = refundInfo.getSpanTotDeliveryFee();
					} else {
						delvFee = refundInfo.getOrgDelvFee();
					}

					Order delvFeeOrder = new Order();
					delvFeeOrder.setOrdNo(ordNo);
					delvFeeOrder.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
					delvFeeOrder.setDelvFeeCd(obj.getDelvFeeCd());
					delvFeeOrder.setDelvFee(delvFee);
					delvFeeOrder.setDelvGfcdUseAmt(delvGfcdUseAmt);
					delvFeeOrder.setRealDelvAmt(realDelvAmt);
					delvFeeOrder.setOrdChgSq(ordChgSq);
					delvFeeOrder.setSupplyCompCd(obj.getSupplyCompCd());
					delvFeeOrder.setRegNo(userNo);
					delvFeeOrder.setUpdNo(userNo);

					orderChangeDao.createDeliveryFee(delvFeeOrder);

					if (delvGfcdUseAmt > 0) {
						int rmGfcdAmt;
						int usGfcdAmt;

						// 반품배송비 배송비일련번호 조회 및 설정
						rtnDelvFee.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
						OrderChange orgDeliveryFeeInfo = orderChangeDao.getOrgDeliveryFeeInfo(rtnDelvFee);
						Integer delvFeeSq = orgDeliveryFeeInfo.getDelvFeeSq();
						dto.setDelvFeeSq(delvFeeSq);

						// 추가배송비 상품권 결제 처리
						// 환불컨펌 시점에서 상품권이 만료되어져 있을수 있어서 해당 주문건에 사용 후 취소했던 상품권 정보로 처리
						// Order 도메인 내 delvFeeSq 존재 여부로 구분 처리 진행
						for (Order custGiftcardInfo : orderDao.getCustGiftcardInfoList(dto)) {

							// 상품권사용금액 있으면 실행
							rmGfcdAmt = custGiftcardInfo.getRmGfcdAmt();

							// 남은상품권금액 > 사용상품권금액보다 크면 실행
							if (rmGfcdAmt > delvGfcdUseAmt) {
								rmGfcdAmt = rmGfcdAmt - delvGfcdUseAmt;
								usGfcdAmt = delvGfcdUseAmt;
								delvGfcdUseAmt = 0;
							} else {
								delvGfcdUseAmt = delvGfcdUseAmt - rmGfcdAmt;
								usGfcdAmt = rmGfcdAmt;
								rmGfcdAmt = 0;
							}

							if (usGfcdAmt > 0) {
								// 상품권 정보 수정
								custGiftcardInfo.setUsGfcdAmt(usGfcdAmt);
								custGiftcardInfo.setRmGfcdAmt(rmGfcdAmt);
								custGiftcardInfo.setCustNo(custNo);
								orderDao.updateCustGiftcard(custGiftcardInfo);

								// 상품권 사용 이력 생성
								custGiftcardInfo.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD.value());
								custGiftcardInfo.setOccurDtlDesc("상품권사용");
								custGiftcardInfo.setGfcdAmt(usGfcdAmt * -1);
								custGiftcardInfo.setOrdNo(ordNo);
								custGiftcardInfo.setOrdDtlNo(0);
								custGiftcardInfo.setDelvFeeSq(delvFeeSq);
								orderDao.createCustGiftcardHst(custGiftcardInfo);
							}
						}
					}
				}

				// 4-6. 원주문배송비 환불 처리
				int orgRefundDelvFee = refundInfo.getOrgRefundDelvFee();
				if (orgRefundDelvFee > 0) {
					rfDeliveryFee += orgRefundDelvFee;

					// 원주문 배송비 환불
					OrderChange ordDelvFee = new OrderChange();
					ordDelvFee.setOrdNo(ordNo);
					ordDelvFee.setOrdChgSq(ordChgSq);
					ordDelvFee.setDelvFeeCd(delvFeeCd);
					ordDelvFee.setSupplyCompCd(supplyCompCd);
					ordDelvFee.setRegNo(regNo);
					ordDelvFee.setUpdNo(updNo);

					orderChangeDao.insertTbDeliveryFeeMinus(ordDelvFee);

					// 배송비 사용 상품권 원복
					dto.setDelvFeeCd(delvFeeCd);
					for (Order giftCard : orderChangeDao.getCustGiftCardDelvHst(dto)) {
						giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
						giftCard.setOccurDtlDesc("상품권사용취소");
						giftCard.setGfcdAmt(giftCard.getGfcdAmt() * -1);
						giftCard.setRegNo(regNo);
						giftCard.setUpdNo(updNo);

						// 상품권 사용 취소 이력 생성 및 상품권 수정
						orderChangeDao.createCustGiftCardHstRollback(giftCard);
						orderChangeDao.updateCustGiftCardRollback(giftCard);
					}
				}

				// 4-6. 환불 정보 등록
				OrderChange chgRefund = new OrderChange();
				chgRefund.setRefundAmt(refundAmt);
				chgRefund.setDepositAmt(depositAmt);
				chgRefund.setOrdNo(ordNo);
				chgRefund.setOrdChgSq(ordChgSq);
				chgRefund.setRfGfcdUseAmt(rfGfcdUseAmt);
				chgRefund.setRfDelvGfcdUseAmt(refundInfo.getRfDelvGfcdUseAmt());
				chgRefund.setRfDeliveryFee(rfDeliveryFee);
				chgRefund.setRfRealCnclAmt(refundAmt - rfDeliveryFee);
				orderChangeDao.updateRefundChange(chgRefund);

				// 착불비 처리 
				if("Y".equals(codFeeYn)) {
					// OrderChange ordDelvFee = new OrderChange();
					// ordDelvFee.setOrdNo(ordNo);
					// ordDelvFee.setRegNo(userNo);
					// ordDelvFee.setCodFee(codFee);
					// ordDelvFee.setOrdChgSq(ordChgSq);
					// ordDelvFee.setDelvFeeCd(delvFeeCd);
					// orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);

					// 환불   
					chgRefund.setRfDeliveryFee(codFee*-1);
					chgRefund.setCodFeeYn(codFeeYn);
					chgRefund.setRfRealCnclAmt(chgRefund.getRfRealCnclAmt() + codFee);
					orderChangeDao.updateRefundChange(chgRefund);
				}

				// 동봉비 처리 
				if("Y".equals(enCloseFeeYn)) {
					// OrderChange ordDelvFee = new OrderChange();
					// ordDelvFee.setOrdNo(ordNo);
					// ordDelvFee.setRegNo(userNo);
					// ordDelvFee.setCodFee(enCloseFee*-1);
					// ordDelvFee.setOrdChgSq(ordChgSq);
					// ordDelvFee.setDelvFeeCd(delvFeeCd);
					// orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);

					// 환불   
					chgRefund.setRfDeliveryFee(enCloseFee);
					chgRefund.setEnCloseFeeYn(enCloseFeeYn);
					chgRefund.setRfRealCnclAmt(chgRefund.getRfRealCnclAmt() - enCloseFee);
					orderChangeDao.updateRefundChange(chgRefund);
				}

				// 4-7. TB_WITHDRAW  업데이트 (동봉비 착불비)
				OrderChange chgFee = new OrderChange();
				chgFee.setWdInvoiceNo(wdInvoiceNo);
				chgFee.setOrdChgSq(ordChgSq);
				chgFee.setCodFee(codFee);
				chgFee.setEncloseFee(enCloseFee);
				chgFee.setUpdNo(userNo);
				orderChangeDao.updateWithdrawFee(chgFee);

				// 환불금액이 추가배송비 보다 적을 시
				if ((refundAmt + rfGfcdUseAmt) < 0) {
					throw new IllegalStateException(message.getMessage("CANCEL_0002"));
				}

				// 4-8. PG 정보 설정
				Payment pg = new Payment();
				pg.setOrdNo(ordNo);
				pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
				pg.setPayGb("O");
				pg.setPgTid(pgTid);
				pg.setPayMeans(payMeans);
				pg.setPartCancelAmt(refundAmt);
				pg.setOrdChgSq(ordChgSq);
				pg.setRegNo(userNo);
				pg.setUpdNo(userNo);
				
				// 2021.07.07 payAmt 금액 TB_PAYMENT.PAY_AMT 수정
				int payAmt = orderChangeDao.getPaymentPayamt(pg);
				pg.setLeftAmt(payAmt);
				
				log.info("cancelAmt >>> {}", pg.getPartCancelAmt());
				log.info("leftAmt >>> {}", pg.getLeftAmt());
				
				pgList.add(pg);

				// 4-9. 상품권 현금영수증 PG 취소 정보 설정
				GiftCard giftCardCashReceipts = orderDao.getGiftCardReceiptInfo(ordNo);

				if (giftCardCashReceipts != null && StringUtils.isNotBlank(giftCardCashReceipts.getTradeNo())) {
					giftCardCashReceipts.setModType("STPC");
					giftCardCashReceipts.setUsGfcdAmt(sumGfcdUseAmt - refundInfo.getRtnDelvGfcdUseAmt() - refundInfo.getDelvGfcdUseAmt());

					cashReceiptsList.add(giftCardCashReceipts);
				}
			}
		}

		// 5. PG 취소 처리
		for (Payment pg : pgList) {
			
			// 2021.09.02 (PAY_STAT = 'G016_30' AND PG_TID IS NULL AND PG_GB <> 'ISTYLE') 체크 후 없으면 제휴몰로 판단 로직
			if (orderDao.getExtmallOrderChk(pg) > 0) {
				payMeans = TscConstants.PayMeans.EXTMALL.value();
			}
						
			// 상품권 100%, 제휴몰, PG점프처리, 네이버페이주문은 PG점프 처리
			if (TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb) || TscConstants.PayMeans.EXTMALL.value().equals(payMeans) || "Y".equals(pgStat) || refundAmt == 0) {
				pg.setPayAmt(pg.getPayAmt() * -1);
				orderDao.insertPaymentCancel(pg);
			}
			// KCP 및 PAYCO 결제 취소 처리
			else if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
				pg.setModType(modType);
				pg.setModDesc("가맹점 취소 - 전체 취소");
				pg.setAccountNm(accountNm);
				pg.setAccountNo(accountNo);
				pg.setBankCd(bankCd);
				pg.setBatchYn("N");

				kcpService.kcpCancel(pg);
			}
			// 네이버페이 결제형 결제 취소 처리
			else if (TscConstants.PgGb.NAVER.value().equals(pgGb)) {
				pg.setPayAmt(pg.getPartCancelAmt());
				pg.setPayMeans(payMeans);
				pg.setChgReasonNm(chgReasonNm);

				naverPayService.cancelNaverPayment(pg);
			}
			// 카카오페이 결제 취소 처리
			else if (TscConstants.PgGb.KAKAO.value().equals(pgGb)) {
				pg.setPayAmt(pg.getPartCancelAmt());
				pg.setPayMeans(payMeans);
				kakaoPayService.cancelKakaoPayment(pg);
			}

			// 6. 환불정보 수정
			Order refundOrder = new Order();
			refundOrder.setOrdNo(ordNo);
			refundOrder.setPaySq(pg.getPaySq());
			refundOrder.setOrdChgSq(ordChgSq);
			refundOrder.setUpdNo(userNo);

			orderChangeDao.updateRefundInfo(refundOrder);
		}

		// 7. 현금영수증 취소 처리
		for (GiftCard cashReceipts : cashReceiptsList) {
			kcpService.kcpCashReceiptCancel(cashReceipts);
		}

		return map;
	}

	/**
	 * 마이페이지 부분취소 처리
	 *
	 * @param GagaMap
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 05. 24
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap partialRefundBak(GagaMap map, Integer userNo) {

		// 1. 취소요청목록 및 정보 설정
		List<Order> cancelOrderRefundList 	= (List<Order>) map.get("cancelOrderRefundList");				// 취소환불금액 목록 (주문상세단품 단위)
		List<Order> cancelDelvRefundList 	= (List<Order>) map.get("cancelDelvRefundList");				// 취소환불배송금액 목록 (DELV_FEE_CD 단위)

		int ordNo 				= map.getInt("ordNo");											// 주문번호
		int ordChgSq			= map.getInt("ordChgSq");										// 주문변경일련번호
		String chgReason 		= map.getString("chgReason");									// 변경사유
		String chgReasonNm 		= map.getString("chgReasonNm");									// 변경사유명
		String chgMemo 			= map.getString("chgMemo");										// 변경메모
		String allLastCanYn		= map.getString("allLastCanYn");								// 마지막 취소 여부
		String ipAddress		= map.getString("ipAddress");									// IP주소
		String pgTid			= map.getString("pgTid");										// PG거래ID
		String payMeans			= map.getString("payMeans");									// 결제수단
		String pgGb				= map.getString("pgGb");										// PG구분
		String cashAuthNo		= map.getString("cashAuthNo");									// 현금영수증 승인번호
		String accountNo		= map.getString("accountNo");									// 환불계좌번호
		String accountNm		= map.getString("accountNm");									// 환불계좌주명
		String bankCd			= map.getString("bankCd");										// 환불계좌은행코드
		String reqGbn			= map.getString("reqGbn");										// 신청구분
		String chgGb			= TscConstants.OrderChangeGb.CANCEL.value(); 					// 취소요청 (공톹코드:G680)
		String ordDtlStat		= TscConstants.OrderDetailStat.PAYMENT_AFTER_CANCEL.value();	// 주문상세상태
		String chgStat			= TscConstants.OrderChangeStat.RETURN_COMPLETE.value();			// 주문변경상태
		String modType			= "";
		String batchYn			= map.getString("batchYn");										// 배치여부
		String delvExpnYn		= map.getString("delvExpnYn");									// 출고예외여부 
		String mallGb			= map.getString("mallGb");										// 몰구분
		String pgStat			= map.getString("pgStat");										// PG 점프 
		int codFee				= map.getInt("codFee");											// 착불비 
		String codFeeYn			= map.getString("codFeeYn");									// 착불비여부
		String enCloseFeeYn 	= map.getString("enCloseFeeYn");								// 동봉비여부
		int enCloseFee 			= map.getInt("enCloseFee");										// 동봉비
		String wdInvoiceNo		= map.getString("codFeeYn");									// 회수송장번호
		String wdGb				= map.getString("wdGb");										// 회수구분
		int addPayCost			= map.getInt("addPayCost");										// 추갸배송비

		// 무통장입금 결제 주문 전체취소 상태값 처리
		// 2021.09.09 페이코 조건 누락 추가
		if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
			if (TscConstants.PayMeans.BANK_DEPOSIT.value().equals(payMeans)) {
				modType = "STPD";																				// KCP 무통장입금 부분취소
			} else {
				modType = "STPC";																				// KCP 부분취소
			}
		}

		log.info("cancelDelvRefundList {}", cancelDelvRefundList.iterator().next());
		log.info("cancelOrderRefundList {}",cancelOrderRefundList.iterator().next());

		// 3. 주문변경정보, 주문정보, 환불정보 (배송정책코드 별)
		List<Payment> pgList = new ArrayList<>();
		List<GiftCard> cashReceiptsList = new ArrayList<>();
		for (Order obj : cancelDelvRefundList) {

			// 취소금액 있을 시 처리
			if (obj.getCnclRtnAmt() > 0) {
				// 3-1. 주문변경정보 생성
				OrderChange orderChange = new OrderChange();
				orderChange.setOrdNo(ordNo);
				orderChange.setChgGb(chgGb);
				orderChange.setChgReason(chgReason);
				orderChange.setChgMemo(chgMemo);
				orderChange.setAddPayCost(0);
				orderChange.setAddPayAmt(0);
				orderChange.setRegNo(userNo);
				orderChange.setUpdNo(userNo);
				orderChange.setOrdChgSq(ordChgSq);

				// 3-2. 주문상세정보 수정
				for (Order vo : cancelOrderRefundList) {
					vo.setRegNo(userNo);
					vo.setUpdNo(userNo);
					vo.setOrdDtlStat(ordDtlStat);

					// 배송정책코드 별 주문상세 처리
					if (obj.getDelvFeeCd().equals(vo.getDelvFeeCd()) && vo.getOrdCanChgQty() > 0) {
						// 주문상세 별 전체취소여부 설정
						int leftQty = vo.getOrdQty() - vo.getCnclRtnQty() - vo.getOrdCanChgQty();

						// 3-2-1. 주문상세정보 수정
						orderChangeDao.updateOrderDetail(vo);

						// 3-2-2. 주문상세 이력 등록
						orderChangeDao.createOrderDetailHstCnclRtn(vo);

						// 3-2-3. 주문상세단품정보 수정 및 주문상세단품이력 등록
						// 주문상세단품정보조회
						Collection<Order> orderDetailItemList = orderChangeDao.getOrderDetailItemForCnclRtn(vo);
						int ordDtlOrdAmt 			= orderDetailItemList.iterator().next().getOrdAmt();
						int ordDtlCnclRtnAmt	 	= orderDetailItemList.iterator().next().getCnclRtnAmt();
						int ordDtlCpn1DcAmt 		= orderDetailItemList.iterator().next().getCpn1DcAmt();
						int ordDtlTmtb1DcAmt 		= orderDetailItemList.iterator().next().getTmtb1DcAmt();
						int ordDtlTmtb2DcAmt 		= orderDetailItemList.iterator().next().getTmtb2DcAmt();
						int ordDtlGoodsCpnDcAmt 	= orderDetailItemList.iterator().next().getGoodsCpnDcAmt();
						int ordDtlCartCpnDcAmt 		= orderDetailItemList.iterator().next().getCartCpnDcAmt();
						int ordDtlPntDcAmt 			= orderDetailItemList.iterator().next().getPntDcAmt();
						int ordDtlPrePntDcAmt 		= orderDetailItemList.iterator().next().getPrePntDcAmt();
						int ordDtlSavePntAmt 		= orderDetailItemList.iterator().next().getSavePntAmt();
						int ordDtlRealOrdAmt 		= orderDetailItemList.iterator().next().getRealOrdAmt();
						int ordDtlGfcdUseAmt 		= orderDetailItemList.iterator().next().getGfcdUseAmt();

						// 주문상세단품단위 금액 등록
						int length					= orderDetailItemList.size();
						int index					= 1;
						int leftOrdAmt 				= ordDtlOrdAmt;
						int leftCnclRtnAmt			= ordDtlCnclRtnAmt;
						int leftCpn1DcAmt 			= ordDtlCpn1DcAmt;
						int leftTmtb1DcAmt 			= ordDtlTmtb1DcAmt;
						int leftTmtb2DcAmt 			= ordDtlTmtb2DcAmt;
						int leftGoodsCpnDcAmt 		= ordDtlGoodsCpnDcAmt;
						int leftCartCpnDcAmt 		= ordDtlCartCpnDcAmt;
						int leftPntDcAmt 			= ordDtlPntDcAmt;
						int leftPrePntDcAmt 		= ordDtlPrePntDcAmt;
						int leftSavePntAmt 			= ordDtlSavePntAmt;
						int leftRealOrdAmt 			= ordDtlRealOrdAmt;
						int leftGfcdUseAmt 			= ordDtlGfcdUseAmt;

						for (Order orderDetailItem : orderDetailItemList) {
							double dtlOrdAmt		= orderDetailItem.getDtlOrdAmt();
							double dtlItemOrdAmt	= orderDetailItem.getDtlItemOrdAmt();
							double tempDivD			= (dtlItemOrdAmt / dtlOrdAmt) * 100;

							int tempDiv				= Integer.parseInt(String.valueOf(Math.round(tempDivD)));

							if (index == length) {
								orderDetailItem.setCnclRtnAmt(leftCnclRtnAmt);
								orderDetailItem.setCpn1DcAmt(leftCpn1DcAmt);
								orderDetailItem.setTmtb1DcAmt(leftTmtb1DcAmt);
								orderDetailItem.setTmtb2DcAmt(leftTmtb2DcAmt);
								orderDetailItem.setGoodsCpnDcAmt(leftGoodsCpnDcAmt);
								orderDetailItem.setCartCpnDcAmt(leftCartCpnDcAmt);
								orderDetailItem.setPrePntDcAmt(leftPrePntDcAmt);
								orderDetailItem.setPntDcAmt(leftPntDcAmt);
								orderDetailItem.setGfcdUseAmt(leftGfcdUseAmt);
								orderDetailItem.setRealOrdAmt(leftRealOrdAmt);
								orderDetailItem.setSavePntAmt(leftSavePntAmt);

							} else {
								orderDetailItem.setCnclRtnAmt((ordDtlCnclRtnAmt 		* tempDiv) / 100);
								orderDetailItem.setCpn1DcAmt((ordDtlCpn1DcAmt 			* tempDiv) / 100);
								orderDetailItem.setTmtb1DcAmt((ordDtlTmtb1DcAmt 		* tempDiv) / 100);
								orderDetailItem.setTmtb2DcAmt((ordDtlTmtb2DcAmt 		* tempDiv) / 100);
								orderDetailItem.setGoodsCpnDcAmt((ordDtlGoodsCpnDcAmt 	* tempDiv) / 100);
								orderDetailItem.setCartCpnDcAmt((ordDtlCartCpnDcAmt 	* tempDiv) / 100);
								orderDetailItem.setPrePntDcAmt((ordDtlPrePntDcAmt 		* tempDiv) / 100);
								orderDetailItem.setPntDcAmt((ordDtlPntDcAmt 			* tempDiv) / 100);
								orderDetailItem.setGfcdUseAmt((ordDtlGfcdUseAmt 		* tempDiv) / 100);
								orderDetailItem.setRealOrdAmt((ordDtlRealOrdAmt 		* tempDiv) / 100);
								orderDetailItem.setSavePntAmt((ordDtlSavePntAmt 		* tempDiv) / 100);

								leftCnclRtnAmt		-= ((ordDtlCnclRtnAmt 				* tempDiv) / 100);
								leftCpn1DcAmt 		-= ((ordDtlCpn1DcAmt 				* tempDiv) / 100);
								leftTmtb1DcAmt 		-= ((ordDtlTmtb1DcAmt 				* tempDiv) / 100);
								leftTmtb2DcAmt 		-= ((ordDtlTmtb2DcAmt 				* tempDiv) / 100);
								leftGoodsCpnDcAmt 	-= ((ordDtlGoodsCpnDcAmt 			* tempDiv) / 100);
								leftCartCpnDcAmt 	-= ((ordDtlCartCpnDcAmt 			* tempDiv) / 100);
								leftPrePntDcAmt 	-= ((ordDtlPrePntDcAmt 				* tempDiv) / 100);
								leftPntDcAmt 		-= ((ordDtlPntDcAmt 				* tempDiv) / 100);
								leftGfcdUseAmt 		-= ((ordDtlGfcdUseAmt 				* tempDiv) / 100);
								leftRealOrdAmt 		-= ((ordDtlRealOrdAmt 				* tempDiv) / 100);
								leftSavePntAmt 		-= ((ordDtlSavePntAmt 				* tempDiv) / 100);
							}

							orderDetailItem.setRegNo(userNo);
							orderDetailItem.setUpdNo(userNo);
							orderDetailItem.setOrdDtlStat(ordDtlStat);

							// 2021.06.25 환불컨펌 (반품완료) (정산구분값추가)
							// TODO 환불컨펌시 확정후반품 처리 체크 로직 추가 (TB_ORDER_DETAIL_ITEM_HST 배송중 일때 반품완료, 결제완료일때 취소완료) 
							// 2021.07.07 확정후반품 로직 추가
							int cnt = orderChangeDao.getOrderDetailItem20Cnt(orderDetailItem);
							if (cnt > 0) {
								orderDetailItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_RETURN_COMPLETE.value());
							} else {
								orderDetailItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_SOLDOUT_CANCEL.value());
							}

							orderDetailItem.setCnclRtnQty(vo.getOrdCanChgQty());
							orderDetailItem.setOrdChgSq(ordChgSq);
							orderChangeDao.createOrderDetailItemHst(orderDetailItem);

							orderChangeDao.updateOrderDetailItem(orderDetailItem);

							index++;
						}

						// 3-2-4. 사용포인트원복
						int pntDcAmt = vo.getPntDcAmt();
						vo.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT.value());

						for (Order point : orderChangeDao.getCustPointHst(vo)) {
							if (pntDcAmt > 0) {
								int pntAmt = point.getPntAmt() * -1;

								if (pntDcAmt < pntAmt) {
									point.setPntAmt(pntDcAmt);
									pntDcAmt -= pntDcAmt;
								} else {
									point.setPntAmt(pntAmt);
									pntDcAmt -= pntAmt;
								}

								point.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT_CANCEL.value());
								point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_COMPLETE.value());
								point.setOccurDtlDesc("포인트사용취소");
								point.setRegNo(userNo);
								point.setUpdNo(userNo);

								// 포인트 사용 취소 이력 생성 및 포인트 수정
								orderChangeDao.createCustPointHstRollback(point);
								orderChangeDao.updateCustPointRollback(point);
							}
						}

						// 3-2-5. 적립예정포인트 수정
						int savePntAmt = vo.getSavePntAmt();
						vo.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT.value());

						for (Order point : orderChangeDao.getCustPointHst(vo)) {
							point.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT_CANCEL.value());
							point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_EXPECT.value());
							point.setOccurDtlDesc("예정포인트적립취소");
							point.setPntAmt(savePntAmt * -1);
							point.setRegNo(userNo);
							point.setUpdNo(userNo);

							// 적립예정포인트 취소 이력 생성
							orderChangeDao.createCustPointHstRollback(point);
						}

						// 3-2-6. 상품쿠폰원복
						if (leftQty == 0) {
							orderChangeDao.updateGoodsCpnRollback(vo);
						}

						// 3-2-7. 사용상품권 원복
						int gfcdUseAmt = vo.getGfcdUseAmt();

						for (Order giftCard : orderChangeDao.getCustGiftCardHst(vo)) {
							if (gfcdUseAmt > 0) {
								int gfcdAmt = giftCard.getGfcdAmt() * -1;

								if (gfcdUseAmt < gfcdAmt) {
									giftCard.setGfcdAmt(gfcdUseAmt);
									gfcdUseAmt -= gfcdUseAmt;
								} else {
									giftCard.setGfcdAmt(gfcdAmt);
									gfcdUseAmt -= gfcdAmt;
								}

								giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
								giftCard.setOccurDtlDesc("상품권사용취소");
								giftCard.setRegNo(userNo);
								giftCard.setUpdNo(userNo);

								// 포인트 사용 취소 이력 생성 및 포인트 수정
								orderChangeDao.createCustGiftCardHstRollback(giftCard);
								orderChangeDao.updateCustGiftCardRollback(giftCard);
							}
						}

						// 3-2-8. 상품권 현금영수증 PG 취소 정보 설정
						GiftCard giftCardCashReceipts = orderDao.getGiftCardReceiptInfo(ordNo);

						if (giftCardCashReceipts != null && StringUtils.isNotBlank(giftCardCashReceipts.getTradeNo())) {
							giftCardCashReceipts.setModType("STPC");
							giftCardCashReceipts.setUsGfcdAmt(vo.getGfcdUseAmt());

							cashReceiptsList.add(giftCardCashReceipts);
						}

						// 3-2-9. 주문변경상세정보 및 이력 등록
						OrderChange changeDetailPo = new OrderChange();
						changeDetailPo.setOrdChgSq(orderChange.getOrdChgSq());
						changeDetailPo.setOrdDtlNo(vo.getOrdDtlNo());
						changeDetailPo.setChgQty(vo.getOrdCanChgQty());
						changeDetailPo.setChgStat(chgStat);
						changeDetailPo.setRegNo(userNo);
						changeDetailPo.setUpdNo(userNo);

						// 신청구분 처리

						// 취소접수승인 시 주문변경상세 정보 수정
						OrderChange orChange = new OrderChange();
						orChange.setOrdNo(ordNo);
						orChange.setOrdChgSq(ordChgSq);
						orChange.setChgStat(chgStat);
						orChange.setUpdNo(userNo);
						orderChangeDao.updateOrderChangeDtl(orChange);

						orderChangeDao.createOrderChangeDetailHst(changeDetailPo);
					}
				}

				// 3-3. 상품재고원복
				/*  삭제 !!!
				if(!TscConstants.OrderCancelReason.SOLDOUT_CANCEL.value().equals(chgReason)) {
					orderChange.setSellGb(TscConstants.SellGb.ORDER_CANCEL.value());
					orderChangeDao.createSellQty(orderChange);
				}
				*/

				// 3-4. PG 결제 취소 정보 설정 (상품권으로만 결제 시 PG점프)
				int spanRealCnclRtnAmt 	= obj.getRealOrdAmt();			// 취소금액합계
				int sumDeliveryFee 		= obj.getDelvFee();				// 배송비합계
				int spanDelvCpnDcAmt 	= obj.getDelvCpnDcAmt();		// 배송비쿠폰금액
				int spanTotDeliveryFee 	= obj.getAddDelvFee();			// 추가배송비합계
				int spanTotRtnDelvFee 	= obj.getRtnDelvFee();			// 반품배송비합계
				int spanRefundAmt		= 0;							// 환불금액
				int delvFee				= (sumDeliveryFee - spanDelvCpnDcAmt);	// 배송비

				// codFee // 착불비
				// enCloseFee // 동봉비

				// 마지막 취소일때 배송비 추가
				if ("Y".equals(obj.getLastCanYn())) {
					// 귀책사유고객
					if ("G688_10".equals(chgReason)) {
						// 회수요청
						if ("W".equals(wdGb)) {
							// 환불비용 = (취소상품실결제금액 + 동봉비 + 추가결제비) - 반품배송비 - 착불비
							spanRefundAmt = (spanRealCnclRtnAmt + enCloseFee + addPayCost) - spanTotRtnDelvFee - codFee;
						}
						// 직접배송
						else {
							// 환불비용 = (취소상품실결제금액 + 동봉비 + 추가결제비) - 착불비
							spanRefundAmt = (spanRealCnclRtnAmt + enCloseFee + addPayCost) - codFee;
						}
					}
					// 귀책사유회사
					else {
						// 환불비용 = (취소상품실결제금액) + (원주문배송비- 배송비쿠폰할인금액)
						spanRefundAmt = spanRealCnclRtnAmt + (sumDeliveryFee - spanDelvCpnDcAmt);
					}
				}
				// 부분취소
				else {
					// 귀책사유고객
					if ("G688_10".equals(chgReason)) {
						// 회수요청
						if ("W".equals(wdGb)) {
							// 환불금액  = (취소상품실결제금액 + 동봉비 + 추가결제비) - (추가배송비 + 반품배송비)
							spanRefundAmt = (spanRealCnclRtnAmt + enCloseFee + addPayCost) - (spanTotDeliveryFee + spanTotRtnDelvFee);
						}
						// 직접배송
						else {
							// 환불금액  = (취소상품실결제금액 + 동봉비 + 추가결제비) - (추가배송비)
							spanRefundAmt = (spanRealCnclRtnAmt + enCloseFee + addPayCost) - (spanTotDeliveryFee);
						}
					}
					// 귀책사유회사
					else {
						// 환불금액  = 취소상품실결제금액
						spanRefundAmt = spanRealCnclRtnAmt;
					}
				}

				// 전체취소일때 TB_DELIVERY_FEE 배송비 취소 처리
				if ("Y".equals(obj.getLastCanYn())) {
					Order cancelDelvFee = new Order();
					cancelDelvFee.setOrdNo(ordNo);
					cancelDelvFee.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
					cancelDelvFee.setDelvFeeCd(obj.getDelvFeeCd());
					cancelDelvFee.setDelvFee(sumDeliveryFee * -1);
					cancelDelvFee.setDelvCpnSq(0);
					cancelDelvFee.setDelvCpnDcAmt(spanDelvCpnDcAmt);
					cancelDelvFee.setRealDelvAmt(delvFee * -1);
					cancelDelvFee.setOrdChgSq(orderChange.getOrdChgSq());
					cancelDelvFee.setSupplyCompCd(obj.getSupplyCompCd());
					cancelDelvFee.setRegNo(userNo);
					cancelDelvFee.setUpdNo(userNo);

					orderChangeDao.createDeliveryFee(cancelDelvFee);
				}

				// 환불   
				OrderChange chgRefund = new OrderChange();

				// 3-6. 결제금액이 무료배송금액보다 작으면 배송비 신규 등록 (배송비허들무너짐)
				if (spanTotDeliveryFee > 0) {
					Order delvFeeOrder = new Order();
					delvFeeOrder.setOrdNo(ordNo);
					delvFeeOrder.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
					delvFeeOrder.setDelvFeeCd(obj.getDelvFeeCd());
					delvFeeOrder.setDelvFee(spanTotDeliveryFee);
					delvFeeOrder.setRealDelvAmt(spanTotDeliveryFee);
					delvFeeOrder.setOrdChgSq(orderChange.getOrdChgSq());
					delvFeeOrder.setSupplyCompCd(obj.getSupplyCompCd());
					delvFeeOrder.setRegNo(userNo);
					delvFeeOrder.setUpdNo(userNo);

					orderChangeDao.createDeliveryFee(delvFeeOrder);
				}

				// 착불비 처리 
				if("Y".equals(codFeeYn)) {
					// 10. 배송비  
					OrderChange ordDelvFee = new OrderChange();
					ordDelvFee.setOrdNo(ordNo);
					ordDelvFee.setRegNo(userNo);
					ordDelvFee.setCodFee(codFee);
					ordDelvFee.setOrdChgSq(ordChgSq);
					orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);

					// 10-1. 환불
					chgRefund.setRfDeliveryFee(codFee*-1);
				}

				// 동봉비 처리 
				if("Y".equals(enCloseFeeYn)) {
					// 배송비  
					OrderChange ordDelvFee = new OrderChange();
					ordDelvFee.setOrdNo(ordNo);
					ordDelvFee.setRegNo(userNo);
					ordDelvFee.setCodFee(enCloseFee*-1);
					ordDelvFee.setOrdChgSq(ordChgSq);
					orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);

					// 환불   
					chgRefund.setRfDeliveryFee(enCloseFee);
					chgRefund.setEnCloseFeeYn(enCloseFeeYn);
				}

				chgRefund.setRefundAmt(spanRefundAmt);
				chgRefund.setOrdNo(ordNo);
				chgRefund.setOrdChgSq(ordChgSq);
				orderChangeDao.updateRefundChange(chgRefund);

				// tb_withdraw  업데이트 (동봉비 착불비)
				OrderChange chgFee = new OrderChange();
				chgFee.setWdInvoiceNo(wdInvoiceNo);
				chgFee.setOrdChgSq(ordChgSq);
				chgFee.setCodFee(codFee);
				chgFee.setEncloseFee(enCloseFee);
				chgFee.setUpdNo(userNo);
				orderChangeDao.updateWithdrawFee(chgFee);

				// 환불금액이 추가배송비 보다 적을 시
				if (spanRefundAmt < 0) {
					throw new IllegalStateException(message.getMessage("CANCEL_0002"));
				}

				Payment pg = new Payment();

				pg.setOrdNo(ordNo);
				pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
				pg.setPayGb("O");
				pg.setPgTid(pgTid);
				pg.setPayMeans(payMeans);
				pg.setPartCancelAmt(spanRefundAmt);
				pg.setOrdChgSq(ordChgSq);
				pg.setRegNo(userNo);
				pg.setUpdNo(userNo);

				// 2021.07.07 payAmt 금액 TB_PAYMENT.PAY_AMT 수정
				int payAmt = orderChangeDao.getPaymentPayamt(pg);
				pg.setLeftAmt(payAmt);

				log.info("cancelAmt >>> {}", pg.getPartCancelAmt());
				log.info("leftAmt >>> {}", pg.getLeftAmt());

				if (spanRefundAmt > 0) {
					pgList.add(pg);
				}
			}
		}

		// 4. 장바구니, 배송비 쿠폰 원복 및 사은품 전체 취소 처리 (마지막 취소 시)
		if ("Y".equals(allLastCanYn)) {
			// 4-1. 장바구니, 배송비 쿠폰 원복처리
			Order coupon = new Order();
			coupon.setOrdNo(ordNo);
			coupon.setUpdNo(userNo);
			orderChangeDao.updateCartCpnRollback(coupon);
			orderChangeDao.updateDeliveryCpnRollback(coupon);

			// 4-2. 사은품 전체 취소 (전체취소시 적용) 추후 사은품 관련 취소 로직 개발 예정

			/*
			 * Order freegiftOrder = new Order(); freegiftOrder.setOrdNo(ordNo);
			 * freegiftOrder.setUpdNo(userNo);
			 * orderChangeDao.updateOrdFreegiftDel(freegiftOrder);
			 */
		}


		if("G011_10".equals(mallGb)) {
			if("N".equals(pgStat)) {
				// 6. PG 취소 처리
				for (Payment pg : pgList) {
					if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
						pg.setModType(modType);
						pg.setModDesc("가맹점 취소 - 부분 취소");
						pg.setIpAddress(ipAddress);
						pg.setAccountNm(accountNm);
						pg.setAccountNo(accountNo);
						pg.setBankCd(bankCd);
						pg.setBatchYn(batchYn);
						kcpService.kcpCancel(pg);
					} else if (TscConstants.PgGb.NAVER.value().equals(pgGb)) {
						pg.setPayAmt(pg.getPartCancelAmt());
						pg.setPayMeans(payMeans);
						pg.setChgReasonNm(chgReasonNm);

						naverPayService.cancelNaverPayment(pg);
					} else if (TscConstants.PgGb.KAKAO.value().equals(pgGb)) {
						pg.setPayAmt(pg.getPartCancelAmt());
						kakaoPayService.cancelKakaoPayment(pg);
					}

					// 7. 환불정보 수정
					Order refundOrder = new Order();
					refundOrder.setOrdNo(ordNo);
					refundOrder.setPaySq(pg.getPaySq());
					refundOrder.setOrdChgSq(ordChgSq);
					refundOrder.setUpdNo(userNo);

					orderChangeDao.updateRefundInfo(refundOrder);
				}

				// 8. 현금영수증 취소 처리
				for (GiftCard cashReceipts : cashReceiptsList) {
					kcpService.kcpCashReceiptCancel(cashReceipts);
				}
			}
		}
		return map;
	}

	/**
	 * 전체 환불 처리
	 *
	 * @param GagaMap, Integer
	 * @author card007
	 * @since 2021. 08. 12
	 */
	@SuppressWarnings("unchecked")
	public void allRefund(GagaMap map, Integer userNo) {
		// 1. 변수 설정
		Integer ordNo			= map.getInt("ordNo");							// 주문번호
		Integer custNo			= map.getInt("custNo");							// 고객번호
		String chgReasonNm		= map.getString("chgReasonNm");					// 변경사유명
		String chgGb			= TscConstants.OrderChangeGb.RETURN.value();	// 변경구분
		String accountNo		= map.getString("accountNo");					// 환불계좌번호
		String accountNm		= map.getString("accountNm");					// 환불계좌주명
		String bankCd			= map.getString("bankCd");						// 환불은행
		Integer ordChgSq		= map.getInt("ordChgSq");						// 주문변경일련번호
		int regNo				= userNo;										// 등록자번호
		int updNo				= userNo;										// 수정자번호
		String pgStat			= map.getString("pgStat");						// PG 점프
		int depositAmt			= map.getInt("depositAmt");						// PG 점프 입금액
		String codFeeYn			= map.getString("codFeeYn");					// 착불비여부
		int codFee				= map.getInt("codFee");							// 착불비
		String enCloseFeeYn		= map.getString("enCloseFeeYn");				// 동봉비여부
		int enCloseFee			= map.getInt("enCloseFee");						// 동봉비
		String wdInvoiceNo		= map.getString("wdInvoiceNo");					// 회수송장번호
		String delvFeeCd		= map.getString("delvFeeCd");					// 배송비정책코드
		String supplyCompCd		= "";

		List<Order> cancelDelvRefundList 	= (List<Order>) map.get("cancelDelvRefundList");	// 취소환불배송금액 목록 (DELV_FEE_CD 단위)
		if (cancelDelvRefundList != null && cancelDelvRefundList.size() > 0) {
			supplyCompCd = cancelDelvRefundList.iterator().next().getSupplyCompCd();
		}

		// 2. 상태값 설정
		String ordDtlStat = TscConstants.OrderDetailStat.PAYMENT_AFTER_CANCEL.value();
		String chgStat = TscConstants.OrderChangeStat.RETURN_COMPLETE.value();
		map.setString("chgGb", chgGb);

		// 3. 주문변경상세 수정
		OrderChange orderChange = new OrderChange();
		orderChange.setOrdChgSq(ordChgSq);
		orderChange.setChgStat(chgStat);
		orderChange.setRegNo(regNo);
		orderChange.setUpdNo(updNo);
		orderChangeDao.updateOrderChangeDtl(orderChange);
		orderChangeDao.createOrderChangeDetailHstForAllCancel(orderChange);

		// 4. 원주문 결제정보 조회
		Payment payment = new Payment();
		payment.setOrdNo(ordNo);
		payment = orderChangeDao.getPaymentInfo(payment);

		// 5. 환불금액 설정
		Order returnOrderInfo = new Order();
		returnOrderInfo.setOrdNo(ordNo);
		returnOrderInfo.setDelvFeeCd(delvFeeCd);
		map.set("returnOrderInfo", this.getReturnOrderInfo(returnOrderInfo));
		OrderChange refundInfo = this.calculateRefundAmt(map);
		int refundAmt = refundInfo.getRefundAmt();

		// 6. 주문 전체취소 상태값 설정
		String modType;
		if (TscConstants.PgGb.KCP.value().equals(payment.getPgGb())
			&& TscConstants.PayMeans.BANK_DEPOSIT.value().equals(payment.getPayMeans())
			&& TscConstants.PaymentStat.PAYMENT_COMPLETE.value().equals(payment.getPayStat())) {

			modType = "STHD";											// KCP 무통장입금 전체취소
		} else {
			modType = "STSC";											// KCP 전체취소
		}

		// 7. 사용포인트원복
		Order vo = new Order();
		vo.setOrdNo(ordNo);
		vo.setCustNo(custNo);
		vo.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT.value());
		vo.setUpdNo(updNo);

		for (Order point : orderChangeDao.getCustPointHst(vo)) {
			point.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT_CANCEL.value());
			point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_COMPLETE.value());
			point.setOccurDtlDesc("포인트사용취소");
			point.setPntAmt(point.getPntAmt() * -1);
			point.setRegNo(regNo);
			point.setUpdNo(updNo);

			// 포인트 사용 취소 이력 생성 및 포인트 수정
			orderChangeDao.createCustPointHstRollback(point);
			orderChangeDao.updateCustPointRollback(point);
		}

		// 8. 적립예정포인트 취소
		vo.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT.value());

		for (Order point : orderChangeDao.getCustPointHst(vo)) {
			point.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT_CANCEL.value());
			point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_EXPECT.value());
			point.setOccurDtlDesc("예정포인트적립취소");
			point.setPntAmt(point.getPntAmt() * -1);
			point.setRegNo(regNo);
			point.setUpdNo(updNo);

			// 적립예정포인트 취소 이력 생성
			orderChangeDao.createCustPointHstRollback(point);
		}

		// 9. 사용상품권 원복
		for (Order giftCard : orderChangeDao.getCustGiftCardHst(vo)) {
			giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
			giftCard.setOccurDtlDesc("상품권사용취소");
			giftCard.setGfcdAmt(giftCard.getGfcdAmt() * -1);
			giftCard.setRegNo(regNo);
			giftCard.setUpdNo(updNo);

			// 상품권 사용 취소 이력 생성 및 상품권 수정
			orderChangeDao.createCustGiftCardHstRollback(giftCard);
			orderChangeDao.updateCustGiftCardRollback(giftCard);
		}

		// 10. 배송비 사용 상품권 원복
		if (refundInfo.getOrgRefundDelvFee() > 0) {
			vo.setDelvFeeCd(delvFeeCd);
			for (Order giftCard : orderChangeDao.getCustGiftCardDelvHst(vo)) {
				giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
				giftCard.setOccurDtlDesc("상품권사용취소");
				giftCard.setGfcdAmt(giftCard.getGfcdAmt() * -1);
				giftCard.setRegNo(regNo);
				giftCard.setUpdNo(updNo);

				// 상품권 사용 취소 이력 생성 및 상품권 수정
				orderChangeDao.createCustGiftCardHstRollback(giftCard);
				orderChangeDao.updateCustGiftCardRollback(giftCard);
			}
		}

		// 11. 쿠폰 원복처리
		Order coupon = new Order();
		coupon.setOrdNo(ordNo);
		coupon.setUpdNo(updNo);
		orderChangeDao.updateGoodsCpnRollback(coupon);
		// 2021. 08. 11 card007 반품시에는 장바구니 및 배송비 쿠폰을 돌려주지 않는다.
		// orderChangeDao.updateCartCpnRollback(coupon);
		// orderChangeDao.updateDeliveryCpnRollback(coupon);

		// 12. 반품배송비 수정
		int rtnDelvGfcdUseAmt = refundInfo.getRtnDelvGfcdUseAmt();
		int rtnRealDelvAmt = refundInfo.getRtnRealDelvAmt();

		OrderChange rtnDelvFee = new OrderChange();
		rtnDelvFee.setOrdChgSq(ordChgSq);
		rtnDelvFee.setDelvGfcdUseAmt(rtnDelvGfcdUseAmt);
		rtnDelvFee.setRealDelvAmt(rtnRealDelvAmt);
		rtnDelvFee.setUpdNo(updNo);
		orderChangeDao.updateReturnDeliveryFee(rtnDelvFee);

		if (rtnDelvGfcdUseAmt > 0) {
			int rmGfcdAmt;
			int usGfcdAmt;

			// 반품배송비 배송비일련번호 조회 및 설정
			OrderChange returnDeliveryFeeInfo = orderChangeDao.getReturnDeliveryFeeInfo(rtnDelvFee);
			Integer delvFeeSq = returnDeliveryFeeInfo.getDelvFeeSq();
			vo.setDelvFeeSq(delvFeeSq);

			// 반품배송비 상품권 결제 처리
			// 환불컨펌 시점에서 상품권이 만료되어져 있을수 있어서 해당 주문건에 사용 후 취소했던 상품권 정보로 처리
			// Order 도메인 내 delvFeeSq 존재 여부로 구분 처리 진행
			for (Order custGiftcardInfo : orderDao.getCustGiftcardInfoList(vo)) {

				// 상품권사용금액 있으면 실행
				rmGfcdAmt = custGiftcardInfo.getRmGfcdAmt();

				// 남은상품권금액 > 사용상품권금액보다 크면 실행
				if (rmGfcdAmt > rtnDelvGfcdUseAmt) {
					rmGfcdAmt = rmGfcdAmt - rtnDelvGfcdUseAmt;
					usGfcdAmt = rtnDelvGfcdUseAmt;
					rtnDelvGfcdUseAmt = 0;
				} else {
					rtnDelvGfcdUseAmt = rtnDelvGfcdUseAmt - rmGfcdAmt;
					usGfcdAmt = rmGfcdAmt;
					rmGfcdAmt = 0;
				}

				if (usGfcdAmt > 0) {
					// 상품권 정보 수정
					custGiftcardInfo.setUsGfcdAmt(usGfcdAmt);
					custGiftcardInfo.setRmGfcdAmt(rmGfcdAmt);
					custGiftcardInfo.setCustNo(custNo);
					orderDao.updateCustGiftcard(custGiftcardInfo);

					// 상품권 사용 이력 생성
					custGiftcardInfo.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD.value());
					custGiftcardInfo.setOccurDtlDesc("상품권사용");
					custGiftcardInfo.setGfcdAmt(usGfcdAmt * -1);
					custGiftcardInfo.setOrdNo(ordNo);
					custGiftcardInfo.setOrdDtlNo(0);
					custGiftcardInfo.setDelvFeeSq(delvFeeSq);
					orderDao.createCustGiftcardHst(custGiftcardInfo);
				}
			}
		}

		// 13. 원주문 배송비 차감 처리
		// 2021.09.11 card007 전체반품 원주문 배송비 차감 추가
		int delvGfcdUseAmt = refundInfo.getDelvGfcdUseAmt();
		int realDelvAmt = refundInfo.getRealDelvAmt();
		if (refundInfo.getOrgDelvFee() > 0) {
			Order delvFeeOrder = new Order();
			delvFeeOrder.setOrdNo(ordNo);
			delvFeeOrder.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
			delvFeeOrder.setDelvFeeCd(delvFeeCd);
			delvFeeOrder.setDelvFee(refundInfo.getOrgDelvFee());
			delvFeeOrder.setDelvGfcdUseAmt(delvGfcdUseAmt);
			delvFeeOrder.setRealDelvAmt(realDelvAmt);
			delvFeeOrder.setOrdChgSq(ordChgSq);
			delvFeeOrder.setSupplyCompCd(supplyCompCd);
			delvFeeOrder.setRegNo(userNo);
			delvFeeOrder.setUpdNo(userNo);

			orderChangeDao.createDeliveryFee(delvFeeOrder);

			if (delvGfcdUseAmt > 0) {
				int rmGfcdAmt;
				int usGfcdAmt;

				// 원주문 배송비 배송비일련번호 조회 및 설정
				rtnDelvFee.setDelvFeeGb(TscConstants.DeliveryFeeGb.ORIGIN_DELIVERY_FEE.value());
				OrderChange orgDeliveryFeeInfo = orderChangeDao.getOrgDeliveryFeeInfo(rtnDelvFee);
				Integer delvFeeSq = orgDeliveryFeeInfo.getDelvFeeSq();
				vo.setDelvFeeSq(delvFeeSq);

				// 원주문 배송비 상품권 결제 처리
				// 환불컨펌 시점에서 상품권이 만료되어져 있을수 있어서 해당 주문건에 사용 후 취소했던 상품권 정보로 처리
				// Order 도메인 내 delvFeeSq 존재 여부로 구분 처리 진행
				for (Order custGiftcardInfo : orderDao.getCustGiftcardInfoList(vo)) {

					// 상품권사용금액 있으면 실행
					rmGfcdAmt = custGiftcardInfo.getRmGfcdAmt();

					// 남은상품권금액 > 사용상품권금액보다 크면 실행
					if (rmGfcdAmt > delvGfcdUseAmt) {
						rmGfcdAmt = rmGfcdAmt - delvGfcdUseAmt;
						usGfcdAmt = delvGfcdUseAmt;
						delvGfcdUseAmt = 0;
					} else {
						delvGfcdUseAmt = delvGfcdUseAmt - rmGfcdAmt;
						usGfcdAmt = rmGfcdAmt;
						rmGfcdAmt = 0;
					}

					if (usGfcdAmt > 0) {
						// 상품권 정보 수정
						custGiftcardInfo.setUsGfcdAmt(usGfcdAmt);
						custGiftcardInfo.setRmGfcdAmt(rmGfcdAmt);
						custGiftcardInfo.setCustNo(custNo);
						orderDao.updateCustGiftcard(custGiftcardInfo);

						// 상품권 사용 이력 생성
						custGiftcardInfo.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD.value());
						custGiftcardInfo.setOccurDtlDesc("상품권사용");
						custGiftcardInfo.setGfcdAmt(usGfcdAmt * -1);
						custGiftcardInfo.setOrdNo(ordNo);
						custGiftcardInfo.setOrdDtlNo(0);
						custGiftcardInfo.setDelvFeeSq(delvFeeSq);
						orderDao.createCustGiftcardHst(custGiftcardInfo);
					}
				}
			}
		}
		
		// 14. 주문상세정보 수정 및 이력 등록
		OrderChange orderDetail = new OrderChange();
		orderDetail.setOrdNo(ordNo);
		orderDetail.setOrdDtlStat(ordDtlStat);
		orderDetail.setOrdChgSq(ordChgSq);
		orderDetail.setRegNo(regNo);
		orderDetail.setUpdNo(updNo);

		orderChangeDao.updateOrderDetailForAllCancel(orderDetail);
		orderChangeDao.createOrderDetailHstForAllCancel(orderDetail);

		// 15. 주문상세단품정보 수정 및 이력 등록

		orderChangeDao.updateOrderDetailItemForAllCancel(orderDetail);

		// 2021.06.25 환불컨펌 (반품완료) (정산구분값추가)
		// 환불컨펌시 확정후반품 처리 체크 로직 추가 (TB_ORDER_DETAIL_ITEM_HST 배송중 일때 반품완료, 결제완료일때 취소완료) 
		// 2021.07.07 확정후반품 로직 추가
		int cnt = orderChangeDao.getOrderDetailItem20CntAll(orderDetail);
		if (cnt > 0) {
			orderDetail.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_RETURN_COMPLETE.value());
		} else {
			orderDetail.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_SOLDOUT_CANCEL.value());
		}

		orderChangeDao.createOrderDetailItemHstForAllCancel(orderDetail);
		
		// 16. 배송비 환불
		// Order refundOrder = orderChangeDao.getRefundInfoForAllCancel(vo);
		OrderChange chgRefund = new OrderChange();
		chgRefund.setOrdNo(ordNo);
		chgRefund.setOrdChgSq(ordChgSq);
		chgRefund.setRefundAmt(refundAmt);
		chgRefund.setDepositAmt(depositAmt);
		chgRefund.setRfGfcdUseAmt(refundInfo.getGfcdUseAmt());
		chgRefund.setRfDelvGfcdUseAmt(refundInfo.getRfDelvGfcdUseAmt());

		if(refundInfo.getOrgRefundDelvFee() > 0 || refundInfo.getRfDeliveryFee() != 0) {
			int rfDeliveryFee = refundInfo.getOrgRefundDelvFee() + refundInfo.getRfDeliveryFee();

			// 원주문 배송비 환불
			if (refundInfo.getOrgRefundDelvFee() > 0) {
				// 배송비
				OrderChange ordDelvFee = new OrderChange();
				ordDelvFee.setOrdNo(ordNo);
				ordDelvFee.setOrdChgSq(ordChgSq);
				ordDelvFee.setRegNo(regNo);
				ordDelvFee.setUpdNo(updNo);

				orderChangeDao.insertTbDeliveryFeeMinus(ordDelvFee);
			}

			// 환불
			// chgRefund.setRfDeliveryFee(addDeliveryFee);
			chgRefund.setRfDeliveryFee(rfDeliveryFee);
			chgRefund.setRfRealCnclAmt(refundAmt - rfDeliveryFee);
			orderChangeDao.updateRefundChange(chgRefund);
			
		}
		
		// 17. 착불비 처리 
		if("Y".equals(codFeeYn)) {
			// 착불비  
			// OrderChange ordDelvFee = new OrderChange();
			// ordDelvFee.setOrdNo(ordNo);
			// ordDelvFee.setRegNo(regNo);
			// ordDelvFee.setCodFee(codFee);
			// ordDelvFee.setOrdChgSq(ordChgSq);
			// ordDelvFee.setDelvFeeCd(delvFeeCd);
			// orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);
			
			// 환불
			chgRefund.setRfDeliveryFee(codFee*-1);
			chgRefund.setCodFeeYn(codFeeYn);
			chgRefund.setRfRealCnclAmt(refundAmt - (codFee*-1));
			orderChangeDao.updateRefundChange(chgRefund);
		}
		
		// 18. 동봉비 처리 
		if("Y".equals(enCloseFeeYn)) {
			// 배송비  
			// OrderChange ordDelvFee = new OrderChange();
			// ordDelvFee.setOrdNo(ordNo);
			// ordDelvFee.setRegNo(regNo);
			// ordDelvFee.setCodFee(enCloseFee*-1);
			// ordDelvFee.setOrdChgSq(ordChgSq);
			// ordDelvFee.setDelvFeeCd(delvFeeCd);
			// orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);
			
			// 환불
			chgRefund.setRfDeliveryFee(enCloseFee);
			chgRefund.setEnCloseFeeYn(enCloseFeeYn);
			chgRefund.setRfRealCnclAmt(refundAmt - enCloseFee);
			orderChangeDao.updateRefundChange(chgRefund);
		}
		
		// 19. TB_WITHDRAW 정보 수정 (동봉비 착불비)
		OrderChange chgFee = new OrderChange();
		chgFee.setWdInvoiceNo(wdInvoiceNo);
		chgFee.setOrdChgSq(ordChgSq);
		chgFee.setCodFee(codFee);
		chgFee.setEncloseFee(enCloseFee);
		chgFee.setUpdNo(regNo);
		orderChangeDao.updateWithdrawFee(chgFee);
		
		// 20. PG 연동
		String pgGb = payment.getPgGb();
		String payMeans = payment.getPayMeans();

		Payment pg = new Payment();
		pg.setOrdNo(ordNo);
		pg.setOrdChgSq(ordChgSq);
		pg.setPayMeans(payMeans);
		pg.setPayGb("O");
		pg.setPgTid(payment.getPgTid());
		pg.setPayAmt(refundAmt);
		pg.setLeftAmt(payment.getPayAmt());
		pg.setRegNo(regNo);
		pg.setUpdNo(updNo);
		pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
		
		// 2021.09.02 (PAY_STAT = 'G016_30' AND PG_TID IS NULL AND PG_GB <> 'ISTYLE') 체크 후 없으면 제휴몰로 판단 로직
		if (orderDao.getExtmallOrderChk(pg) > 0) {
			payMeans = TscConstants.PayMeans.EXTMALL.value();
		}

		// 상품권 100%, 제휴몰, PG점프처리, 네이버페이주문은 PG점프 처리
		if (TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb) || TscConstants.PayMeans.EXTMALL.value().equals(payMeans) || "Y".equals(pgStat) || refundAmt == 0) {
			pg.setPayAmt(pg.getPayAmt() * -1);
			orderDao.insertPaymentCancel(pg);
		}
		// KCP 및 PAYCO 결제 취소 처리
		else if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
			// 2021.09.02 card007 전체반품일때 결제금액과 환불금액이 다르면 부분취소 처리
			if (refundAmt != payment.getPayAmt()) {
				// 전체취소
				if ("STSC".equals(modType)) {
					modType = "STPC";
					pg.setPartCancelAmt(refundAmt);
				}
				// 무통장입금 입금 후 전체 취소
				else if ("STHD".equals(modType)) {
					modType = "STPD";
					pg.setPartCancelAmt(refundAmt);
				}
			}
			pg.setModType(modType);
			pg.setModDesc("가맹점 취소 - 전체 취소");
			pg.setAccountNm(accountNm);
			pg.setAccountNo(accountNo);
			pg.setBankCd(bankCd);
			pg.setBatchYn("N");

			kcpService.kcpCancel(pg);
		}
		// 네이버페이 결제형 결제 취소 처리
		else if (TscConstants.PgGb.NAVER.value().equals(pgGb)) {
			pg.setPayMeans(payment.getPayMeans());
			pg.setChgReasonNm(chgReasonNm);

			naverPayService.cancelNaverPayment(pg);
		}
		// 카카오페이 결제 취소 처리
		else if (TscConstants.PgGb.KAKAO.value().equals(pgGb)) {
			pg.setPayMeans(payment.getPayMeans());
			kakaoPayService.cancelKakaoPayment(pg);
		}

		// 21. 환불 정보 수정
		Order refundUpdate = new Order();
		refundUpdate.setOrdNo(ordNo);
		refundUpdate.setPaySq(pg.getPaySq());
		refundUpdate.setOrdChgSq(ordChgSq);
		orderChangeDao.updateRefundInfo(refundUpdate);

		// 22. 상품권 현금영수증 취소 처리
		GiftCard giftCardCashReceipts = orderDao.getGiftCardReceiptInfo(ordNo);

		if (giftCardCashReceipts != null && StringUtils.isNotBlank(giftCardCashReceipts.getTradeNo())) {
			giftCardCashReceipts.setModType("STSC");
			giftCardCashReceipts.setUsGfcdAmt(giftCardCashReceipts.getAmt() - refundInfo.getRtnDelvGfcdUseAmt());

			kcpService.kcpCashReceiptCancel(giftCardCashReceipts);
		}

	}

	/**
	 * 전체 환불 처리
	 *
	 * @param OrderChange (ordChgSq, userNo)
	 * @author card007
	 * @since 2021. 05. 24
	 */
	public void allRefundBak(OrderChange orderChange) {
		Integer ordNo = orderChange.getOrdNo();											// 주문번호
		String chgGb = orderChange.getChgGb();											// 변경구분
		String chgReasonNm = orderChange.getChgReasonNm();								// 변경사유명
		String accountNo = orderChange.getAccountNo();									// 환불계좌번호
		String accountNm = orderChange.getAccountNm();									// 환불계좌주명
		String bankCd = orderChange.getBankCd();										// 환불은행
		Integer ordChgSq = orderChange.getOrdChgSq();									// 주문변경일련번호
		int regNo = orderChange.getUserNo();											// 등록자번호
		int updNo = orderChange.getUserNo();											// 수정자번호
		Integer delvAddrSq = orderChange.getDelvAddrSq();
		String addDeliveryFeeYn =  orderChange.getAddDeliveryFeeYn();					// 배송비추가 환불여부 
		int addDeliveryFee = orderChange.getAddDeliveryFee();							// 배송비추가 환불금액 
		int spanRefundAmt = orderChange.getSpanRefundAmt();
		String mallGb = orderChange.getMallGb();										// 몰구분 
		String pgStat = orderChange.getPgStat();										// PG 점프 
		String codFeeYn = orderChange.getCodFeeYn();									// 착불비여부
		int codFee = orderChange.getCodFee();											// 착불비
		String enCloseFeeYn = orderChange.getEnCloseFeeYn();							// 동봉비여부
		int enCloseFee = orderChange.getEncloseFee();									// 동봉비
		String wdInvoiceNo = orderChange.getWdInvoiceNo();								// 회수송장번호

		// 상태값 설정
		String ordDtlStat = TscConstants.OrderDetailStat.PAYMENT_AFTER_CANCEL.value();
		String chgStat = TscConstants.OrderChangeStat.RETURN_COMPLETE.value();
		String ordDtlItemStat = TscConstants.OrdDtlItemStat.SALE_RETURN_RETURN_COMPLETE.value(); // G720_50 환입-반품완료

		// 1. 주문변경상세 수정
		orderChange.setChgStat(chgStat);
		orderChangeDao.updateOrderChangeDtl(orderChange);
		orderChangeDao.createOrderChangeDetailHstForAllCancel(orderChange);

		// 반품일때 환불처리
		// 원주문 결제정보 조회
		Payment payment = new Payment();
		payment.setOrdNo(ordNo);
		payment = orderChangeDao.getPaymentInfo(payment);

		// 환불금액 설정
		int refundAmt = payment.getPayAmt();
		refundAmt = spanRefundAmt;

		// 주문 전체취소 상태값 처리
		String modType;
		if (TscConstants.PgGb.KCP.value().equals(payment.getPgGb())
			&& TscConstants.PayMeans.BANK_DEPOSIT.value().equals(payment.getPayMeans())
			&& TscConstants.PaymentStat.PAYMENT_COMPLETE.value().equals(payment.getPayStat())) {

			modType = "STHD";														// KCP 무통장입금 전체취소
		} else {
			modType = "STSC";														// KCP 전체취소
		}

		// 2. 사용포인트원복
		Order vo = new Order();
		vo.setOrdNo(ordNo);
		vo.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT.value());
		vo.setUpdNo(updNo);

		for (Order point : orderChangeDao.getCustPointHst(vo)) {
			point.setOccurGb(TscConstants.PointOccurGb.ORD_USE_POINT_CANCEL.value());
			point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_COMPLETE.value());
			point.setOccurDtlDesc("포인트사용취소");
			point.setPntAmt(point.getPntAmt() * -1);
			point.setRegNo(regNo);
			point.setUpdNo(updNo);

			// 포인트 사용 취소 이력 생성 및 포인트 수정
			orderChangeDao.createCustPointHstRollback(point);
			orderChangeDao.updateCustPointRollback(point);
		}

		// 3. 적립예정포인트 취소
		vo.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT.value());

		for (Order point : orderChangeDao.getCustPointHst(vo)) {
			point.setOccurGb(TscConstants.PointOccurGb.EXPECT_POINT_CANCEL.value());
			point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_EXPECT.value());
			point.setOccurDtlDesc("예정포인트적립취소");
			point.setPntAmt(point.getPntAmt() * -1);
			point.setRegNo(regNo);
			point.setUpdNo(updNo);

			// 적립예정포인트 취소 이력 생성
			orderChangeDao.createCustPointHstRollback(point);
		}

		// 4. 사용상품권 원복
		for (Order giftCard : orderChangeDao.getCustGiftCardHst(vo)) {
			giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
			giftCard.setOccurDtlDesc("상품권사용취소");
			giftCard.setGfcdAmt(giftCard.getGfcdAmt() * -1);
			giftCard.setRegNo(regNo);
			giftCard.setUpdNo(updNo);

			// 포인트 사용 취소 이력 생성 및 포인트 수정
			orderChangeDao.createCustGiftCardHstRollback(giftCard);
			orderChangeDao.updateCustGiftCardRollback(giftCard);
		}

		// 4-2. 배송비 사용 상품권 원복
		for (Order giftCard : orderChangeDao.getCustGiftCardDelvHst(vo)) {
			giftCard.setOccurGb(TscConstants.GiftCardOccurGb.USE_GIFTCARD_CANCEL.value());
			giftCard.setOccurDtlDesc("상품권사용취소");
			giftCard.setGfcdAmt(giftCard.getGfcdAmt() * -1);
			giftCard.setRegNo(regNo);
			giftCard.setUpdNo(updNo);

			// 상품권 사용 취소 이력 생성 및 상품권 수정
			orderChangeDao.createCustGiftCardHstRollback(giftCard);
			orderChangeDao.updateCustGiftCardRollback(giftCard);
		}

		// 5. 상품재고원복 (품절취소가 아닐 경우)
		//		OrderChange sellQty = new OrderChange();
		//		sellQty.setOrdChgSq(ordChgSq);
		//		sellQty.setSellGb("11");
		//		sellQty.setRegNo(regNo);
		//		orderChangeDao.createSellQty(sellQty);

		// 6. 쿠폰 원복처리
		Order coupon = new Order();
		coupon.setOrdNo(ordNo);
		coupon.setUpdNo(updNo);
		orderChangeDao.updateGoodsCpnRollback(coupon);
		orderChangeDao.updateCartCpnRollback(coupon);
		orderChangeDao.updateDeliveryCpnRollback(coupon);

		// 7. 사은품 전체 취소 (전체취소시 적용) 추후 사은품 관련 취소 로직 개발 예정
		//TODO: skip 
		//		Order freegiftOrder = new Order();
		//		freegiftOrder.setOrdNo(ordNo);
		//		freegiftOrder.setUpdNo(updNo);
		//		orderChangeDao.updateOrdFreegiftDel(freegiftOrder);
		//		

		// 9. 주문상세 및 주문상세단품 정보 설정
		OrderChange orderDetail = new OrderChange();
		orderDetail.setOrdNo(ordNo);
		orderDetail.setOrdDtlStat(ordDtlStat);
		orderDetail.setRegNo(regNo);
		orderDetail.setUpdNo(updNo);

		// 주문상세정보 수정 및 이력 등록
		orderChangeDao.updateOrderDetailForAllCancel(orderDetail);
		orderChangeDao.createOrderDetailHstForAllCancel(orderDetail);

		// 주문상세단품정보 수정 및 이력 등록
		// 2021.06.25 환불컨펌 (반품완료) (정산구분값추가)
		// TODO 환불컨펌시 확정후반품 처리 체크 로직 추가 (TB_ORDER_DETAIL_ITEM_HST 배송중 일때 반품완료, 결제완료일때 취소완료) 
		// 2021.07.07 확정후반품 로직 추가
		int cnt = orderChangeDao.getOrderDetailItem20CntAll(orderDetail);
		if (cnt > 0) {
			orderDetail.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_RETURN_COMPLETE.value());
		} else {
			orderDetail.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_RETURN_SOLDOUT_CANCEL.value());
		}

		orderChangeDao.updateOrderDetailItemForAllCancel(orderDetail);
		orderChangeDao.createOrderDetailItemHstForAllCancel(orderDetail);

		// 10. 배송비 환불
		Order refundOrder = orderChangeDao.getRefundInfoForAllCancel(vo);
		OrderChange chgRefund = new OrderChange();
		chgRefund.setOrdNo(ordNo);
		chgRefund.setOrdChgSq(ordChgSq);
		chgRefund.setRfDelvGfcdUseAmt(refundOrder.getRfDelvGfcdUseAmt());

		if("Y".equals(addDeliveryFeeYn)) {
			// 배송비
			OrderChange ordDelvFee = new OrderChange();
			ordDelvFee.setOrdNo(ordNo);
			ordDelvFee.setOrdChgSq(ordChgSq);
			ordDelvFee.setRegNo(regNo);
			ordDelvFee.setUpdNo(updNo);
			// orderChangeDao.insertTbDeliveryFeeMinus(ordDelvFee);
			orderChangeDao.createDeliveryFeeForAllCancel(ordDelvFee);

			// 환불
			chgRefund.setRefundAmt(refundAmt);
			chgRefund.setRfDeliveryFee(addDeliveryFee);
			chgRefund.setRfRealCnclAmt(refundAmt - addDeliveryFee);
			orderChangeDao.updateRefundChange(chgRefund);

		}

		// 10-1. 착불비 처리 
		if("Y".equals(codFeeYn)) {
			// 배송비  
			OrderChange ordDelvFee = new OrderChange();
			ordDelvFee.setOrdNo(ordNo);
			ordDelvFee.setRegNo(regNo);
			ordDelvFee.setCodFee(codFee);
			ordDelvFee.setOrdChgSq(ordChgSq);
			orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);

			// 환불   
			chgRefund.setRefundAmt(refundAmt);
			chgRefund.setRfDeliveryFee(codFee*-1);
			chgRefund.setRfRealCnclAmt(refundAmt - (codFee*-1));
			orderChangeDao.updateRefundChange(chgRefund);
		}

		// 10-2. 동봉비 처리 
		if("Y".equals(enCloseFeeYn)) {
			// 배송비  
			OrderChange ordDelvFee = new OrderChange();
			ordDelvFee.setOrdNo(ordNo);
			ordDelvFee.setRegNo(regNo);
			ordDelvFee.setCodFee(enCloseFee*-1);
			ordDelvFee.setOrdChgSq(ordChgSq);
			orderChangeDao.insertTbDeliveryFeeCodFee(ordDelvFee);

			// 환불   
			chgRefund.setRefundAmt(refundAmt);
			chgRefund.setRfDeliveryFee(enCloseFee);
			chgRefund.setEnCloseFeeYn(enCloseFeeYn);
			chgRefund.setRfRealCnclAmt(refundAmt - enCloseFee);
			orderChangeDao.updateRefundChange(chgRefund);
		}

		// 10-3. tb_withdraw  업데이트 (동봉비 착불비)
		OrderChange chgFee = new OrderChange();
		chgFee.setWdInvoiceNo(wdInvoiceNo);
		chgFee.setOrdChgSq(ordChgSq);
		chgFee.setCodFee(codFee);
		chgFee.setEncloseFee(enCloseFee);
		chgFee.setUpdNo(regNo);
		orderChangeDao.updateWithdrawFee(chgFee);

		// 11. PG 연동
		String pgGb = payment.getPgGb();
		String payMeans = payment.getPayMeans();

		Payment pg = new Payment();
		pg.setOrdNo(ordNo);
		pg.setOrdChgSq(ordChgSq);
		pg.setPayMeans(payMeans);
		pg.setPayGb("O");
		pg.setPgTid(payment.getPgTid());
		pg.setPayAmt(refundAmt);
		pg.setLeftAmt(refundAmt);
		pg.setRegNo(regNo);
		pg.setUpdNo(updNo);
		pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
		
		// 2021.09.02 (PAY_STAT = 'G016_30' AND PG_TID IS NULL AND PG_GB <> 'ISTYLE') 체크 후 없으면 제휴몰로 판단 로직
		if (orderDao.getExtmallOrderChk(pg) > 0) {
			payMeans = TscConstants.PayMeans.EXTMALL.value();
		}

		// 상품권으로만 결제 시 PG점프
		if (TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb) || TscConstants.PayMeans.EXTMALL.value().equals(payMeans) || "Y".equals(pgStat) || refundAmt == 0) {
			// 상품권 100%, 제휴몰, PG점프처리, 네이버페이주문은 PG점프 처리
			pg.setPayAmt(pg.getPayAmt() * -1);
			orderDao.insertPaymentCancel(pg);
		} else if (TscConstants.PgGb.KCP.value().equals(pgGb) || TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
			pg.setModType(modType);
			pg.setModDesc("가맹점 취소 - 전체 취소");
			pg.setAccountNm(accountNm);
			pg.setAccountNo(accountNo);
			pg.setBankCd(bankCd);
			pg.setBatchYn(orderChange.getBatchYn());

			kcpService.kcpCancel(pg);
		} else if (TscConstants.PgGb.NAVER.value().equals(pgGb)) {
			pg.setPayMeans(payment.getPayMeans());
			pg.setChgReasonNm(chgReasonNm);

			naverPayService.cancelNaverPayment(pg);
		} else if (TscConstants.PgGb.KAKAO.value().equals(pgGb)) {
			pg.setPayMeans(payment.getPayMeans());
			kakaoPayService.cancelKakaoPayment(pg);
		}

		// 11. 환불금액 정보 수정
		refundOrder.setPaySq(pg.getPaySq());
		orderChangeDao.updateRefundInfo(refundOrder);

		// 13. 상품권 현금영수증 취소 처리
		GiftCard giftCardCashReceipts = orderDao.getGiftCardReceiptInfo(ordNo);

		if (giftCardCashReceipts != null && StringUtils.isNotBlank(giftCardCashReceipts.getTradeNo())) {
			giftCardCashReceipts.setModType("STSC");
			giftCardCashReceipts.setUsGfcdAmt(giftCardCashReceipts.getAmt());

			kcpService.kcpCashReceiptCancel(giftCardCashReceipts);
		}

	}

	/**
	 * 취소 알림톡 정보 조회
	 *
	 * @param Integer
	 * @return OrderChange
	 * @author card007
	 * @since 2021. 06. 08
	 */
	public OrderChange getKakaoOrderCancelInfo(Integer ordChgSq) {
		return orderChangeDao.getKakaoOrderCancelInfo(ordChgSq);
	}

	/**
	 * 반품 알림톡 정보 조회
	 *
	 * @param Integer
	 * @return OrderChange
	 * @author card007
	 * @since 2021. 06. 08
	 */
	public OrderChange getKakaoOrderReturnInfo(Integer ordChgSq) {
		return orderChangeDao.getKakaoOrderReturnInfo(ordChgSq);
	}

	/**
	 * 마이페이지 취소 상세 정보 조회
	 *
	 * @param OrderChange
	 * @return Collection<OrderChange>
	 * @author card007
	 * @since 2021. 04. 08
	 */
	public GagaMap getCreCancelDetailInfo(OrderChange orderChange) {
		GagaMap map = new GagaMap();
		Collection<OrderChange> result = new ArrayList<>();
		String refundYn = "N";

		for (OrderChange tmpOrderChange : orderChangeDao.getCreCancelDetailInfo(orderChange)) {
			// 세트상품 옵션별 배열로 담기
			if (tmpOrderChange.getItemNm().contains("!@!")) {
				tmpOrderChange.setItemNmArr(tmpOrderChange.getItemNm().split("!@!"));
				tmpOrderChange.setColorNmArr(tmpOrderChange.getColorNm().split(","));
				tmpOrderChange.setOptCd1Arr(tmpOrderChange.getOptCd1().split(","));
				tmpOrderChange.setOptCd2Arr(tmpOrderChange.getOptCd2().split(","));
			} else {
				String[] arr = {tmpOrderChange.getItemNm()}, arr2 = {tmpOrderChange.getColorNm()}, arr3 = {tmpOrderChange.getOptCd1()}, arr4 = {tmpOrderChange.getOptCd2()};
				tmpOrderChange.setItemNmArr(arr);
				tmpOrderChange.setColorNmArr(arr2);
				tmpOrderChange.setOptCd1Arr(arr3);
				tmpOrderChange.setOptCd2Arr(arr4);
			}

			// 취소 전표 확인 용 환불 여부 설정
			String chgStat = tmpOrderChange.getChgStat();
			if ("N".equals(refundYn) && (TscConstants.OrderChangeStat.PAYMENT_BEFORE_CANCEL.value().equals(chgStat) || TscConstants.OrderChangeStat.PAYMENT_AFTER_CANCEL.value().equals(chgStat))) {
				refundYn = "Y";
			}

			result.add(tmpOrderChange);
		}

		OrderChange oneData = new OrderChange();
		if (result.size() > 0) {
			oneData = result.iterator().next();
		}

		map.set("refundYn", refundYn);
		map.set("oneData", oneData);
		map.set("cancelDetailList", result);

		return map;
	}

	/**
	 * 마이페이지 반품 상세 정보 조회
	 *
	 * @param OrderChange
	 * @return Collection<OrderChange>
	 * @author card007
	 * @since 2021. 04. 13
	 */
	public GagaMap getCreReturnDetailInfo(OrderChange orderChange) {
		GagaMap map = new GagaMap();
		Collection<OrderChange> result = new ArrayList<>();
		String refundYn = "N";

		for (OrderChange tmpOrderChange : orderChangeDao.getCreReturnDetailInfo(orderChange)) {
			// 세트상품 옵션별 배열로 담기
			if (tmpOrderChange.getItemNm().contains("!@!")) {
				tmpOrderChange.setItemNmArr(tmpOrderChange.getItemNm().split("!@!"));
				tmpOrderChange.setColorNmArr(tmpOrderChange.getColorNm().split(","));
				tmpOrderChange.setOptCd1Arr(tmpOrderChange.getOptCd1().split(","));
				tmpOrderChange.setOptCd2Arr(tmpOrderChange.getOptCd2().split(","));
			} else {
				String[] arr = {tmpOrderChange.getItemNm()}, arr2 = {tmpOrderChange.getColorNm()}, arr3 = {tmpOrderChange.getOptCd1()}, arr4 = {tmpOrderChange.getOptCd2()};
				tmpOrderChange.setItemNmArr(arr);
				tmpOrderChange.setColorNmArr(arr2);
				tmpOrderChange.setOptCd1Arr(arr3);
				tmpOrderChange.setOptCd2Arr(arr4);
			}

			// 취소 전표 확인 용 환불 여부 설정
			String chgStat = tmpOrderChange.getChgStat();
			if ("N".equals(refundYn) && TscConstants.OrderChangeStat.RETURN_COMPLETE.value().equals(chgStat)) {
				refundYn = "Y";
			}

			result.add(tmpOrderChange);
		}

		OrderChange oneData = new OrderChange();
		if (result.size() > 0) {
			oneData = result.iterator().next();
		}

		map.set("refundYn", refundYn);
		map.set("oneData", oneData);
		map.set("returnDetailList", result);

		return map;
	}

	/**
	 * 마이페이지 교환 상세 정보 조회
	 *
	 * @param OrderChange
	 * @return Collection<OrderChange>
	 * @author card007
	 * @since 2021. 04. 13
	 */
	public GagaMap getCreExchangeDetailInfo(OrderChange orderChange) {
		GagaMap map = new GagaMap();
		Collection<OrderChange> result = new ArrayList<>();

		for (OrderChange tmpOrderChange : orderChangeDao.getCreExchangeDetailInfo(orderChange)) {
			// 세트상품 옵션별 배열로 담기
			if (tmpOrderChange.getItemNm().contains("!@!")) {
				tmpOrderChange.setItemNmArr(tmpOrderChange.getItemNm().split("!@!"));
				tmpOrderChange.setColorNmArr(tmpOrderChange.getColorNm().split(","));
				tmpOrderChange.setOptCd1Arr(tmpOrderChange.getOptCd1().split(","));
				tmpOrderChange.setOptCd2Arr(tmpOrderChange.getOptCd2().split(","));
			} else {
				String[] arr = {tmpOrderChange.getItemNm()}, arr2 = {tmpOrderChange.getColorNm()}, arr3 = {tmpOrderChange.getOptCd1()}, arr4 = {tmpOrderChange.getOptCd2()};
				tmpOrderChange.setItemNmArr(arr);
				tmpOrderChange.setColorNmArr(arr2);
				tmpOrderChange.setOptCd1Arr(arr3);
				tmpOrderChange.setOptCd2Arr(arr4);
			}

			// 교환상품 옵션 정보 조회 및 설정
			OrderChange changeOptionInfo = orderChangeDao.getExchangeGoodsOptionInfoList(tmpOrderChange);
			if (changeOptionInfo.getItemNm().contains("!@!")) {
				tmpOrderChange.setChgItemNmArr(changeOptionInfo.getItemNm().split("!@!"));
				tmpOrderChange.setChgColorNmArr(changeOptionInfo.getColorNm().split(","));
				tmpOrderChange.setChgOptCd1Arr(changeOptionInfo.getOptCd1().split(","));
				tmpOrderChange.setChgOptCd2Arr(changeOptionInfo.getOptCd2().split(","));
			} else {
				tmpOrderChange.setChgItemNm(changeOptionInfo.getItemNm());
				tmpOrderChange.setChgColorNm(changeOptionInfo.getColorNm());
				tmpOrderChange.setChgOptCd1(changeOptionInfo.getOptCd1());
				tmpOrderChange.setChgOptCd2(changeOptionInfo.getOptCd2());
			}

			result.add(tmpOrderChange);
		}

		OrderChange oneData = new OrderChange();
		if (result.size() > 0) {
			oneData = result.iterator().next();
		}

		map.set("oneData", oneData);
		map.set("exchangeDetailList", result);

		return map;
	}

	/**
	 * 주문변경정보 조회
	 *
	 * @param OrderChange
	 * @return Collection<OrderChange>
	 * @author card007
	 * @since 2021. 05. 24
	 */
	public Collection<OrderChange> getOrderChangeDetailInfo(OrderChange orderChange) {
		return orderChangeDao.getOrderChangeDetailInfo(orderChange);
	}

	/**
	 * 주문 취소 자동메일 정보 조회
	 * 
	 * @param OrderChange
	 * @return Gagamap
	 * @author card007
	 * @since 2021. 06. 10
	 */
	public GagaMap getMailOrderCancelReplaceInfo(OrderChange orderChange) {
		GagaMap result = new GagaMap();
		DecimalFormat df = new DecimalFormat("###,###");

		// 취소 상세 정보 조회
		Collection<OrderChange> cancelList = orderChangeDao.getCreCancelDetailInfo(orderChange);

		if (cancelList.size() == 0) {
			throw new IllegalStateException(message.getMessage("FAIL_0005"));
		}

		OrderChange oneData = cancelList.iterator().next();

		// 주문 정보 설정
		result.setString("ordNm", oneData.getOrdNm());
		result.setInt("ordNo", oneData.getOrdNo());
		result.setString("ordDate", oneData.getOrdDate());
		result.setString("ordDt", oneData.getOrdDt());
		result.setString("ordEmail", oneData.getOrdEmail());
		result.setInt("custNo", oneData.getCustNo());

		if (StringUtils.isBlank(oneData.getOrdEmail())) {
			return result;
		}

		// 취소 정보 설정
		String cancelInfo = this.getMailOrderCancelInfo(cancelList);
		result.setString("cancelInfo", cancelInfo);

		// 사은품 정보 조회
		orderChange.setDelYn("Y");
		String freeGiftInfo = this.getMailFreeGiftCancelInfo(orderChange);
		result.setString("freeGiftInfo", freeGiftInfo);

		// 결제 정보 조회
		int dcAmt = oneData.getRfCpn1Amt() + oneData.getRfTmtb1Amt() + oneData.getRfTmtb2Amt() + oneData.getRfGoodsCpnAmt() + oneData.getRfCartCpnAmt() + oneData.getRfDelvCpnAmt() + oneData.getRfPrePntAmt();

		result.setString("cnclRtnAmt", df.format(oneData.getRfCnclAmt()));
		result.setString("delvFee", df.format(oneData.getRfDeliveryFee()));
		result.setString("dcAmt", dcAmt == 0 ? "0" : "-" + df.format(dcAmt));

		// 버튼 URL 설정
		String hasSsl = env.getProperty("has-ssl");
		String protocol;

		if ("true".equals(hasSsl)) {
			protocol = "https:";
		} else {
			protocol = "http:";
		}

		String url = protocol + env.getProperty("domain.front");
		if (orderChange.getCustNo() > 0) {
			url += "/mypage/cre/list/form";
		} else {
			url += "/customer/noncust/order/confirm/form";
		}

		result.setString("creButtonUrl", url);
		return result;
	}

	/**
	 * 주문 취소 자동메일 취소 상품 정보 설정
	 * 
	 * @param Collection<OrderChange>
	 * @return String
	 * @author card007
	 * @since 2021.06.10
	 */
	@SuppressWarnings("unchecked")
	public String getMailOrderCancelInfo(Collection<OrderChange> cancelList) {
		List<GagaMap> cancelDelvList = new ArrayList<>();
		List<OrderChange> cancelDetailList = new ArrayList<>();
		GagaMap cancelMap = new GagaMap();
		DecimalFormat df = new DecimalFormat("###,###");

		OrderChange oneData = cancelList.iterator().next();
		Integer ordNo = oneData.getOrdNo();
		Integer ordChgSq = oneData.getOrdChgSq();

		String selfGoodsYn = oneData.getSelfGoodsYn();
		String delvFeeCd = "Y".equals(selfGoodsYn) ? "WMS" : oneData.getDelvFeeCd();
		String supplyCompNm = oneData.getSupplyCompNm();
		
		for (OrderChange cancelInfo : cancelList) {
			String delvFeeCdTemp = "Y".equals(cancelInfo.getSelfGoodsYn()) ? "WMS" : cancelInfo.getDelvFeeCd();
			if (!delvFeeCd.equals(delvFeeCdTemp)) {
				// 취소 배송비 정보 조회
				DeliveryFee deliveryFee = new DeliveryFee();
				deliveryFee.setOrdNo(ordNo);
				deliveryFee.setDelvFeeCd(delvFeeCd);
				
				// 2021.06.23 주문완료에서 같이 사용하려고 추가 하였음
				if (ordChgSq != null) {
					deliveryFee.setOrdChgSq(ordChgSq);
				}

				Collection<DeliveryFee> deliveryFeeList = deliveryService.getDeliveryFee(deliveryFee);

				// 취소 배송비 설정
				int delvFee = 0;
				if (deliveryFeeList != null && deliveryFeeList.size() > 0) {
					delvFee = deliveryFeeList.iterator().next().getRealDelvAmt();
				}

				cancelMap.setInt("delvFee", delvFee);
				cancelMap.set("cancelDetailList", cancelDetailList);
				cancelMap.setString("delvFeeCd", delvFeeCd);
				cancelMap.setString("supplyCompNm", supplyCompNm);
				cancelMap.setString("selfGoodsYn", selfGoodsYn);
				cancelDelvList.add(cancelMap);

				cancelDetailList = new ArrayList<>();
				cancelMap = new GagaMap();
				delvFeeCd = delvFeeCdTemp;
				supplyCompNm = cancelInfo.getSupplyCompNm();
				selfGoodsYn = cancelInfo.getSelfGoodsYn();
			}

			// 세트상품 옵션별 배열로 담기
			if (cancelInfo.getItemNm().contains("!@!")) {
				cancelInfo.setItemNmArr(cancelInfo.getItemNm().split("!@!"));
				cancelInfo.setColorNmArr(cancelInfo.getColorNm().split(","));
				cancelInfo.setOptCd1Arr(cancelInfo.getOptCd1().split(","));
				cancelInfo.setOptCd2Arr(cancelInfo.getOptCd2().split(","));
			} else {
				String[] arr = {cancelInfo.getItemNm()}, arr2 = {cancelInfo.getColorNm()}, arr3 = {cancelInfo.getOptCd1()}, arr4 = {cancelInfo.getOptCd2()};
				cancelInfo.setItemNmArr(arr);
				cancelInfo.setColorNmArr(arr2);
				cancelInfo.setOptCd1Arr(arr3);
				cancelInfo.setOptCd2Arr(arr4);
			}

			cancelDetailList.add(cancelInfo);
		}

		DeliveryFee deliveryFee = new DeliveryFee();
		deliveryFee.setOrdNo(ordNo);
		deliveryFee.setDelvFeeCd(delvFeeCd);
		
		// 2021.06.23 주문완료에서 같이 사용하려고 추가 하였음
		if (ordChgSq != null) {
			deliveryFee.setOrdChgSq(ordChgSq);
		}

		Collection<DeliveryFee> deliveryFeeList = deliveryService.getDeliveryFee(deliveryFee);

		int delvFee = 0;
		if (deliveryFeeList != null && deliveryFeeList.size() > 0) {
			delvFee = deliveryFeeList.iterator().next().getRealDelvAmt();
		}

		cancelMap.setInt("delvFee", delvFee);
		cancelMap.set("cancelDetailList", cancelDetailList);
		cancelMap.setString("delvFeeCd", delvFeeCd);
		cancelMap.setString("supplyCompNm", supplyCompNm);
		cancelMap.setString("selfGoodsYn", selfGoodsYn);
		cancelDelvList.add(cancelMap);

		StringBuilder sb = new StringBuilder();

		sb.append("											<table style=\"width:100%;margin:0;padding:0;font-size: 14px;\" cellspacing=\"0\" cellpadding=\"0\">\n");
		sb.append("												<tbody>\n");
		sb.append("													<tr>\n");
		sb.append("														<td height=\"50px;\" style=\"height: 50px;\"></td>\n");
		sb.append("													</tr>\n");
		sb.append("													<tr>\n");
		sb.append("														<th colspan=\"2\" style=\"text-align: left;font-size: 18px;color: #222222;\" align=\"left\">\n");
		
		// 2021.06.23 주문완료에서 같이 사용하려고 추가 하였음
		if (ordChgSq != null) {
			sb.append("															주문취소 상품정보\n");
		} else {
			sb.append("															주문 상품 정보\n");
		}
		
		sb.append("														</th>\n");
		sb.append("													</tr>\n");

		for (GagaMap map : cancelDelvList) {
			sb.append("													<tr>\n");
			sb.append("														<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("													</tr>\n");
			sb.append("													<tr>\n");
			sb.append("														<td>\n");
			sb.append("															<table style=\"border: 1px; border-color: #dddddd; border-style: solid; box-sizing: border-box; width:100%;margin:0;padding:0\" cellspacing=\"0\" cellpadding=\"0\">\n");
			sb.append("																<tbody>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td colspan=\"5\" height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																		<td colspan=\"3\" style=\"text-align: left;font-size: 18px;font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:600;color: #222222;\" align=\"left\">\n");
			if ("Y".equals(map.getString("selfGoodsYn"))) {
				sb.append("																			STYLE24 배송\n");
			} else {
				sb.append("																			");
				sb.append(map.getString("supplyCompNm"));
				sb.append(" 업체직배송\n");
			}
			sb.append("																		</td>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td colspan=\"5\" height=\"20px;\" style=\"height: 20px;border:0; border-bottom: 1px; border-color: #dddddd; border-style: solid; box-sizing: border-box;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append(this.getMailCreListInfo((List<OrderChange>) map.get("cancelDetailList")));
			sb.append("																	<!-- 배송비 시작 -->\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																		<td colspan=\"3\" height=\"20px;\" style=\"height: 45px; background: #f5f5f5;\" bgcolor=\"#f5f5f5\">\n");
			sb.append("																			<span style=\"width: 12px;padding-left:12px;\"></span>\n");
			sb.append("																			<span>배송비</span>\n");
			sb.append("																			<span style=\"width: 12px;padding-right:12px;\"></span>\n");
			sb.append("																			<span style=\"font-weight: bold;\">\n");
			sb.append("																				<span>");
			sb.append(df.format(map.getInt("delvFee")));
			sb.append("</span>원\n");
			sb.append("																			</span>\n");
			sb.append("																		</td>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td height=\"30px;\" style=\"height: 30px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<!-- 배송비 종료 -->\n");
			sb.append("																</tbody>\n");
			sb.append("															</table>\n");
			sb.append("														</td>\n");
			sb.append("													</tr>\n");
		}

		sb.append("												</tbody>\n");
		sb.append("											</table>\n");

		return sb.toString();
	}

	/**
	 * 취반교 자동메일 취반교 정보 설정
	 *
	 * @param OrderChange
	 * @return String
	 * @author card007
	 * @since 2021.06.10
	 */
	public String getMailCreListInfo(List<OrderChange> creListInfo) {
		StringBuilder sb = new StringBuilder();

		// 이미지 URL 설정
		String hasSsl = env.getProperty("has-ssl");
		String protocol;

		if ("true".equals(hasSsl)) {
			protocol = "https:";
		} else {
			protocol = "http:";
		}

		String imgUrl = protocol + env.getProperty("upload.goods.view") + "/";

		int idx = 0;
		for (OrderChange orderChange : creListInfo) {
			if (idx > 0) {
				sb.append("																	<!-- 점선 -->\n");
				sb.append("																	<tr>\n");
				sb.append("																		<td width=\"30px;\"></td>\n");
				sb.append("																		<td colspan=\"3\" height=\"1\" style=\"border: 1px; border-top-color: #ddd; border-top-style: dashed;\"></td>\n");
				sb.append("																		<td width=\"30px;\"></td>\n");
				sb.append("																	</tr>\n");
				sb.append("																	<!-- 점선 끝 -->\n");
				sb.append("																	\n");
			}
			sb.append("																	<!-- 아이템 테이블 시작 -->\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td colspan=\"5\" style=\"text-align: left;font-size: 18px;font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;color: #222222;\">\n");
			sb.append("																			<!-- 아이템 컨텐츠 시작 -->\n");
			sb.append("																			<table style=\"width:100%;height:100%;margin:0;padding:0;font-size: 14px;\" cellspacing=\"0\" cellpadding=\"0\">\n");
			sb.append("																				<tbody>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td height=\"30px;\" style=\"height: 30px;\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td width=\"40px;\" rowspan=\"10\"></td>\n");
			sb.append("																						<td width=\"100px;\" height=\"150px;\" rowspan=\"10\" valign=\"top\" style=\"margin:0;padding:0\">\n");
			sb.append("																							<a href=\"#none\" target=\"_blank\" style=\"margin:0;padding:0\">\n");
			sb.append("																								<span style=\"background: #f5f5f5;width: 100px;height: 150px;margin:0;padding:0\">\n");
			sb.append("																									<img src=\"");
			sb.append(imgUrl);
			sb.append(orderChange.getSysImgNm());
			sb.append("?RS=100\" alt=\"이미지\" style=\"width: 100px;height: auto;margin:0;padding:0\">\n");
			sb.append("																								</span>\n");
			sb.append("																							</a>\n");
			sb.append("																						</td>\n");
			sb.append("																						<td width=\"30px;\" rowspan=\"10\"></td>\n");
			sb.append("																						<td width=\"370px;\" height=\"10px;\"></td>\n");
			sb.append("																						<td width=\"40px;\" rowspan=\"10\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td style=\"font-family:'Apple SD Gothic Neo',verdana,Arial,'나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;\">\n");
			sb.append("																							");
			sb.append(orderChange.getBrandNm());
			sb.append("\n");
			sb.append("																						</td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td height=\"10px;\" style=\"height: 10px;\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td style=\"color: #222222;font-size: 16px;font-weight: bold;letter-spacing: -0.05em;\">\n");
			sb.append("																							<a href=\"#none\" target=\"_blank\" style=\"display: block; color: #222222; font-size: 16px; font-weight: bold; letter-spacing: -0.025em; text-decoration: none;\">\n");
			sb.append("																								");
			sb.append(orderChange.getGoodsNm());
			sb.append("\n");
			sb.append("																							</a>\n");
			sb.append("																						</td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td height=\"10px;\" style=\"height: 10px;\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td>\n");
			if ("G056_S".equals(orderChange.getGoodsType())) {
				for (int i=0; i < orderChange.getColorNmArr().length; i++) {
					sb.append("																							<p style=\"margin: 0; padding: 0; font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:200;color: #666666; line-height: 2;\">");
					sb.append(orderChange.getItemNmArr()[i]);
					sb.append(" / ");
					sb.append(orderChange.getColorNmArr()[i]);
					sb.append(" / ");
					sb.append(orderChange.getOptCd2Arr()[i]);
					sb.append("</p>\n");
				}
			} else {
				sb.append("																							<p style=\"margin: 0; padding: 0; font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:200;color: #666666; line-height: 2;\">");
				sb.append(orderChange.getColorNm());
				sb.append(" / ");
				sb.append(orderChange.getOptCd2());
				sb.append("</p>\n");
			}
			sb.append("																						</td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td>\n");
			if (TscConstants.OrderChangeGb.EXCHANGE.value().equals(orderChange.getChgGb())) {
				sb.append("																							<p style=\"margin: 0; padding: 0; font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:500;color: #fd4802; line-height: 2;\">교환 옵션</p>\n");
				if ("G056_S".equals(orderChange.getGoodsType())) {
					for (int i=0; i < orderChange.getChgColorNmArr().length; i++) {
						sb.append("																							<p style=\"margin: 0; padding: 0; font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:200;color: #666666; line-height: 2;\">");
						sb.append(orderChange.getChgItemNmArr()[i]);
						sb.append(" / ");
						sb.append(orderChange.getChgColorNmArr()[i]);
						sb.append(" / ");
						sb.append(orderChange.getChgOptCd2Arr()[i]);
						sb.append("</p>\n");
					}
				} else {
					sb.append("																							<p style=\"margin: 0; padding: 0; font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:200;color: #666666; line-height: 2;\">");
					sb.append(orderChange.getChgColorNm());
					sb.append(" / ");
					sb.append(orderChange.getChgOptCd2());
					sb.append("</p>\n");
				}
			}
			sb.append("																						</td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td height=\"5px;\" style=\"height: 5px;\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td height=\"10px;\" style=\"height: 10px;\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td>\n");
			sb.append("																							<span>");
			sb.append(orderChange.getChgQty());
			sb.append("개</span>\n");
			
			// 2021.06.24 주문완료메일에서 사용하기위해서 적용
			if (orderChange.getListPrice() > 0) {
				sb.append("																							<span style=\"width: 12px;padding-left:12px;\"></span>\n");
				sb.append("																							<span style=\"display: inline-block; vertical-align: middle; width: 1px; height: 14px; background: #ddd;\"></span>\n");
				sb.append("																							<span style=\"width: 12px;padding-right:12px;\"></span>\n");
				
				// 2021.08.24
				if (orderChange.getListPrice() > orderChange.getOrdAmt()) {
					sb.append("<span style=\"text-decoration: line-through;color: #888888;\"><span>");
					sb.append(NumberFormat.getInstance().format(orderChange.getListPrice()));
					sb.append("</span>원</span>");
					sb.append("&nbsp;&nbsp;<span style=\"font-weight: 500;\"><span>");
					sb.append(NumberFormat.getInstance().format(orderChange.getOrdAmt()));
					sb.append("</span>원</span>");
				} else {
					sb.append("&nbsp;&nbsp;<span style=\"font-weight: 500;\"><span>");
					sb.append(NumberFormat.getInstance().format(orderChange.getOrdAmt()));
					sb.append("</span>원</span>");
				}
			}
			
			sb.append("																						</td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td height=\"10px;\" style=\"height: 10px;\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																					<tr>\n");
			sb.append("																						<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("																					</tr>\n");
			sb.append("																				</tbody>\n");
			sb.append("																				<!-- // 아이템 컨텐츠 종료 -->\n");
			sb.append("																			</table>\n");
			sb.append("																		</td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<!-- // 아이템 테이블 종료 -->\n");
			idx++;
		}

		return sb.toString();
	}

	/**
	 * 주문 취소 자동메일 취소 사은품 정보 설정
	 *
	 * @param OrderChange
	 * @return String
	 * @author card007
	 * @since 2021.06.10
	 */
	public String getMailFreeGiftCancelInfo(OrderChange orderChange) {
		Collection<OrderChange> freeGiftList = orderChangeDao.getCancelFreeGiftList(orderChange);

		StringBuilder sb = new StringBuilder();

		if (freeGiftList.size() > 0) {
			sb.append("											<table style=\"width:100%;margin:0;padding:0\" cellspacing=\"0\" cellpadding=\"0\">\n");
			sb.append("												<tbody>\n");
			sb.append("													<tr>\n");
			sb.append("														<td height=\"50px;\" style=\"height: 50px;\"></td>\n");
			sb.append("													</tr>\n");
			sb.append("													<tr>\n");
			sb.append("														<th colspan=\"4\" style=\"text-align: left;font-size: 18px;color: #222222;\" align=\"left\">\n");
			sb.append("															사은품 정보\n");
			sb.append("														</th>\n");
			sb.append("													</tr>\n");
			sb.append("													<tr>\n");
			sb.append("														<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("													</tr>\n");
			sb.append("													<tr>\n");
			sb.append("														<td colspan=\"4\" height=\"1\" bgcolor=\"#000000\" style=\"height: 1px; background: #000000;\"></td>\n");
			sb.append("													</tr>\n");
			sb.append("													<tr>\n");
			sb.append("														<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("													</tr>\n");
			for (OrderChange tmp : freeGiftList) {
				sb.append("													<tr>\n");
				sb.append("														<td width=\"40px;\"></td>\n");
				sb.append("														<td width=\"250px;\" align=\"left\" style=\"text-align: left;\">\n");
				sb.append("															");
				sb.append(tmp.getGoodsNm());
				sb.append("\n");
				sb.append("														</td>\n");
				sb.append("														<td width=\"250px;\" align=\"left\" style=\"text-align: left;\">\n");
				sb.append("															<span style=\"color:#fd4802;font-family:verdana,Arial, Helvetica, sans-serif;\">\n");
				sb.append("																<span>");
				
				// 2021.07.28 사은품 무료 수정
				if (tmp.getUsePoint() > 0) {
					sb.append("-");
					sb.append(tmp.getUsePoint());
					sb.append("</span> P\n");
				} else {
					sb.append("무료");
					sb.append("</span>\n");
				}
				
				sb.append("															</span>\n");
				sb.append("														</td>\n");
				sb.append("														<td width=\"40px;\"></td>\n");
				sb.append("													</tr>\n");
				sb.append("													<tr>\n");
				sb.append("														<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
				sb.append("													</tr>\n");
			}
			sb.append("													<tr>\n");
			sb.append("														<td colspan=\"4\" height=\"1\" bgcolor=\"#dddddd\" style=\"height: 1px; background: #dddddd;\"></td>\n");
			sb.append("													</tr>\n");
			sb.append("												</tbody>\n");
			sb.append("											 </table>\n");
		}

		return sb.toString();
	}

	/**
	 * 반품 안내 메일 정보 조회
	 *
	 * @param OrderChange
	 * @return Gagamap
	 * @author card007
	 * @since 2021. 06. 10
	 */
	public GagaMap getMailOrderReturnReplaceInfo(OrderChange orderChange) {
		GagaMap result = new GagaMap();
		DecimalFormat df = new DecimalFormat("###,###");

		// 반품 상세 정보 조회
		Collection<OrderChange> returnList = orderChangeDao.getCreReturnDetailInfo(orderChange);

		if (returnList.size() == 0) {
			throw new IllegalStateException(message.getMessage("FAIL_0005"));
		}

		OrderChange oneData = returnList.iterator().next();

		// 주문 정보 설정
		result.setString("ordNm", oneData.getOrdNm());
		result.setInt("ordNo", oneData.getOrdNo());
		result.setString("ordDate", oneData.getOrdDate());
		result.setString("ordDt", oneData.getOrdDt());
		result.setString("ordEmail", oneData.getOrdEmail());
		result.setInt("custNo", oneData.getCustNo());
		result.setString("wdGbNm", "W".equals(oneData.getWdGb()) ? "회수요청" : "직접배송");

		if (StringUtils.isBlank(oneData.getOrdEmail())) {
			return result;
		}

		// 회수지 정보 설정
		if ("W".equals(oneData.getWdGb())) {
			result.setString("chgerInfo", this.getMailChgerInfo(oneData));
		}

		// 반품 정보 설정
		result.setString("returnInfo", this.getMailOrderReturnInfo(returnList));

		// 결제 정보 조회
		int dcAmt = oneData.getRfCpn1Amt() + oneData.getRfTmtb1Amt() + oneData.getRfTmtb2Amt() + oneData.getRfGoodsCpnAmt() + oneData.getRfCartCpnAmt() + oneData.getRfDelvCpnAmt() + oneData.getRfPrePntAmt();
		int totalRefundAmt = oneData.getRefundAmt() + oneData.getRfPntAmt() + oneData.getRfGfcdUseAmt();

		String pgGb = oneData.getPgGb();
		String payMeansNm;
		if (TscConstants.PgGb.KCP.value().equals(pgGb)) {
			payMeansNm = oneData.getPayMeansNm();
		} else if (TscConstants.PgGb.NAVER.value().equals(pgGb)) {
			payMeansNm = "네이버페이";
		} else if (TscConstants.PgGb.KAKAO.value().equals(pgGb)) {
			payMeansNm = "카카오페이";
		} else if (TscConstants.PgGb.ISTYLE.value().equals(pgGb)) {
			payMeansNm = "상품권";
		} else if (TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
			payMeansNm = "PAYCO";
		} else {
			payMeansNm = "";
		}

		result.setString("cnclRtnAmt", df.format(oneData.getRfCnclAmt()));
		result.setString("dcAmt", dcAmt == 0 ? "0" : "-" + df.format(dcAmt));
		result.setString("payMeansNm", payMeansNm);
		result.setString("refundAmt", df.format(oneData.getRefundAmt()));
		result.setString("rfPntAmt", df.format(oneData.getRfPntAmt()));
		result.setString("rfGfcdUseAmt", df.format(oneData.getRfGfcdUseAmt()));
		result.setString("totalRefundAmt", df.format(totalRefundAmt));

		// 추가배송비 조회
		int addpayCost = oneData.getAddPayCost();
		Collection<Order> addPayCostOrder = orderChangeDao.getAddDeliveryFeePayment(orderChange);
		if (addPayCostOrder != null && addPayCostOrder.size() > 0 && addPayCostOrder.iterator().next().getPayAmt() > 0) {
			addpayCost = 0;
		}

		result.setString("addPayCost", df.format(addpayCost));

		// 버튼 URL 설정
		String hasSsl = env.getProperty("has-ssl");
		String protocol;

		if ("true".equals(hasSsl)) {
			protocol = "https:";
		} else {
			protocol = "http:";
		}

		String url = protocol + env.getProperty("domain.front");
		if (orderChange.getCustNo() > 0) {
			url += "/mypage/cre/list/form";
		} else {
			url += "/customer/noncust/order/confirm/form";
		}

		result.setString("creButtonUrl", url);
		return result;
	}

	/**
	 * 반품 안내 메일 상품 정보 설정
	 *
	 * @param Collection<OrderChange>
	 * @return String
	 * @author card007
	 * @since 2021.06.10
	 */
	@SuppressWarnings("unchecked")
	public String getMailOrderReturnInfo(Collection<OrderChange> returnList) {
		List<GagaMap> returnDelvList = new ArrayList<>();
		List<OrderChange> returnDetailList = new ArrayList<>();
		GagaMap returnMap = new GagaMap();

		OrderChange oneData = returnList.iterator().next();

		String selfGoodsYn = oneData.getSelfGoodsYn();
		String delvFeeCd = "Y".equals(selfGoodsYn) ? "WMS" : oneData.getDelvFeeCd();
		String supplyCompNm = oneData.getSupplyCompNm();
		for (OrderChange returnInfo : returnList) {
			String delvFeeCdTemp = "Y".equals(returnInfo.getSelfGoodsYn()) ? "WMS" : returnInfo.getDelvFeeCd();
			if (!delvFeeCd.equals(delvFeeCdTemp)) {
				returnMap.set("returnDetailList", returnDetailList);
				returnMap.setString("delvFeeCd", delvFeeCd);
				returnMap.setString("supplyCompNm", supplyCompNm);
				returnMap.setString("selfGoodsYn", selfGoodsYn);
				returnDelvList.add(returnMap);

				returnDetailList = new ArrayList<>();
				returnMap = new GagaMap();
				delvFeeCd = delvFeeCdTemp;
				supplyCompNm = returnInfo.getSupplyCompNm();
				selfGoodsYn = returnInfo.getSelfGoodsYn();
			}

			// 세트상품 옵션별 배열로 담기
			if (returnInfo.getItemNm().contains("!@!")) {
				returnInfo.setItemNmArr(returnInfo.getItemNm().split("!@!"));
				returnInfo.setColorNmArr(returnInfo.getColorNm().split(","));
				returnInfo.setOptCd1Arr(returnInfo.getOptCd1().split(","));
				returnInfo.setOptCd2Arr(returnInfo.getOptCd2().split(","));
			} else {
				String[] arr = {returnInfo.getItemNm()}, arr2 = {returnInfo.getColorNm()}, arr3 = {returnInfo.getOptCd1()}, arr4 = {returnInfo.getOptCd2()};
				returnInfo.setItemNmArr(arr);
				returnInfo.setColorNmArr(arr2);
				returnInfo.setOptCd1Arr(arr3);
				returnInfo.setOptCd2Arr(arr4);
			}

			returnDetailList.add(returnInfo);
		}

		returnMap.set("returnDetailList", returnDetailList);
		returnMap.setString("delvFeeCd", delvFeeCd);
		returnMap.setString("supplyCompNm", supplyCompNm);
		returnMap.setString("selfGoodsYn", selfGoodsYn);
		returnDelvList.add(returnMap);

		StringBuilder sb = new StringBuilder();

		sb.append("<table style=\"width:100%;margin:0;padding:0;font-size: 14px;\" cellspacing=\"0\" cellpadding=\"0\">\n");
        sb.append("											<tbody>\n");
        sb.append("												<tr>\n");
        sb.append("													<td height=\"50px;\" style=\"height: 50px;\"></td>\n");
        sb.append("												</tr>\n");
        sb.append("												<tr>\n");
        sb.append("													<th colspan=\"2\" style=\"text-align: left;font-size: 18px;color: #222222;\" align=\"left\">\n");
		sb.append("														반품신청 상품 정보\n");
        sb.append("													</th>\n");
        sb.append("												</tr>\n");
        sb.append("												<tr>\n");
        sb.append("													<td height=\"30px;\" style=\"height: 30px;\"></td>\n");
        sb.append("												</tr>\n");
		for (GagaMap map : returnDelvList) {
			sb.append("													<tr>\n");
			sb.append("														<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("													</tr>\n");
			sb.append("													<tr>\n");
			sb.append("														<td>\n");
			sb.append("															<table style=\"border: 1px; border-color: #dddddd; border-style: solid; box-sizing: border-box; width:100%;margin:0;padding:0\" cellspacing=\"0\" cellpadding=\"0\">\n");
			sb.append("																<tbody>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td colspan=\"5\" height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																		<td colspan=\"3\" style=\"text-align: left;font-size: 18px;font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:600;color: #222222;\" align=\"left\">\n");
			if ("Y".equals(map.getString("selfGoodsYn"))) {
				sb.append("																			STYLE24 배송\n");
			} else {
				sb.append("																			");
				sb.append(map.getString("supplyCompNm"));
				sb.append(" 업체직배송\n");
			}
			sb.append("																		</td>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td colspan=\"5\" height=\"20px;\" style=\"height: 20px;border:0; border-bottom: 1px; border-color: #dddddd; border-style: solid; box-sizing: border-box;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append(this.getMailCreListInfo(returnDetailList));
			sb.append("																</tbody>\n");
			sb.append("															</table>\n");
			sb.append("														</td>\n");
			sb.append("													</tr>\n");
		}
        sb.append("											</tbody>\n");
        sb.append("										</table>\n");

		return sb.toString();
	}

	/**
	 * 취반교 메일 회수지 정보 설정
	 *
	 * @param Collection<OrderChange>
	 * @return String
	 * @author card007
	 * @since 2021.06.10
	 */
	@SuppressWarnings("unchecked")
	public String getMailChgerInfo(OrderChange orderChange) {
		StringBuilder sb = new StringBuilder();

		sb.append("<table style=\"width:100%;margin:0;padding:0;font-size: 14px;\" cellspacing=\"0\" cellpadding=\"0\">\n");
		sb.append("											<tbody>\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"50px;\" style=\"height: 50px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<th colspan=\"6\" style=\"text-align: left;font-size: 18px;color: #222222;\" align=\"left\">\n");
		sb.append("														회수지 정보\n");
		sb.append("													</th>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td colspan=\"6\" height=\"1\" bgcolor=\"#000000\" style=\"height: 1px; background: #000000;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("												    <td height=\"20px;\" style=\"height: 20px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("													<td width=\"160px;\" align=\"left\" style=\"text-align: left;\">\n");
		sb.append("														보내는 분\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"340px;\" align=\"left\" style=\"text-align: left;\" colspan=\"3\">\n");
		sb.append("														");
		sb.append(orderChange.getChgerNm());
		sb.append("\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("													<td width=\"160px;\" rowspan=\"2\" align=\"left\" style=\"text-align: left;\" valign=\"top\">\n");
		sb.append("														연락처\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"340px;\" align=\"left\" style=\"text-align: left; line-height: 20px;\" colspan=\"3\">\n");
		sb.append("														");
		sb.append(orderChange.getChgerPhnno());
		sb.append("\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr> <!-- 210611_ 주소테이블 수정 -->\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("													<td width=\"160px;\" align=\"left\" style=\"text-align: left;\" valign=\"middle\">\n");
		sb.append("														주소\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"280px;\" align=\"left\" style=\"text-align: left; line-height: 20px;\" colspan=\"3\">\n");
		sb.append("														<span>\n");
		sb.append("															(");
		sb.append(orderChange.getChgerZipcode());
		sb.append(") ");
		sb.append(orderChange.getChgerBaseAddr());
		sb.append(" ");
		sb.append(orderChange.getChgerDtlAddr());
		sb.append("\n");
		sb.append("														</span>\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("													<td width=\"160px;\" align=\"left\" style=\"text-align: left;\">\n");
		sb.append("														배송요청 사항\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"340px;\" align=\"left\" style=\"text-align: left;\" colspan=\"3\">\n");
		sb.append("														");
		sb.append(orderChange.getChgerRtnMemo());
		sb.append("\n");
		sb.append("													</td>\n");
		sb.append("													<td width=\"40px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td colspan=\"6\" height=\"1\" bgcolor=\"#dddddd\" style=\"height: 1px; background: #dddddd;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("											</tbody>\n");
		sb.append("										</table>\n");
		
		return sb.toString();
	}

	/**
	 * 교환 안내 메일 정보 조회
	 *
	 * @param OrderChange
	 * @return Gagamap
	 * @author card007
	 * @since 2021. 06. 14
	 */
	public GagaMap getMailOrderExchangeReplaceInfo(OrderChange orderChange) {
		GagaMap result = new GagaMap();

		// 반품 상세 정보 조회
		Collection<OrderChange> exchangeList = orderChangeDao.getCreExchangeDetailInfo(orderChange);

		if (exchangeList.size() == 0) {
			throw new IllegalStateException(message.getMessage("FAIL_0005"));
		}

		OrderChange oneData = exchangeList.iterator().next();

		// 주문 정보 설정
		result.setString("ordNm", oneData.getOrdNm());
		result.setInt("ordNo", oneData.getOrdNo());
		result.setString("ordDate", oneData.getOrdDate());
		result.setString("ordDt", oneData.getOrdDt());
		result.setString("ordEmail", oneData.getOrdEmail());
		result.setInt("custNo", oneData.getCustNo());
		result.setString("wdGbNm", "W".equals(oneData.getWdGb()) ? "회수요청" : "직접배송");

		if (StringUtils.isBlank(oneData.getOrdEmail())) {
			return result;
		}

		// 회수지 정보 설정
		if ("W".equals(oneData.getWdGb())) {
			result.setString("chgerInfo", this.getMailChgerInfo(oneData));
		}

		// 교환 정보 설정
		result.setString("exchangeInfo", this.getMailOrderExchangeInfo(exchangeList));

		// 교환 배송지 정보 설정
		result.setString("recipNm", oneData.getRecipNm());
		result.setString("recipPhnno", oneData.getRecipPhnno());
		result.setString("recipBaseAddr", oneData.getRecipBaseAddr());
		result.setString("recipDtlAddr", oneData.getRecipDtlAddr());
		result.setString("recipZipcode", oneData.getRecipZipcode());
		result.setString("delvMemo", oneData.getDelvMemo());

		// 버튼 URL 설정
		String hasSsl = env.getProperty("has-ssl");
		String protocol;

		if ("true".equals(hasSsl)) {
			protocol = "https:";
		} else {
			protocol = "http:";
		}

		String url = protocol + env.getProperty("domain.front");
		if (orderChange.getCustNo() > 0) {
			url += "/mypage/cre/list/form";
		} else {
			url += "/customer/noncust/order/confirm/form";
		}

		result.setString("creButtonUrl", url);
		return result;
	}

	/**
	 * 교환 안내 메일 상품 정보 설정
	 *
	 * @param Collection<OrderChange>
	 * @return String
	 * @author card007
	 * @since 2021.06.14
	 */
	@SuppressWarnings("unchecked")
	public String getMailOrderExchangeInfo(Collection<OrderChange> exchangeList) {
		List<GagaMap> exchangeDelvList = new ArrayList<>();
		List<OrderChange> exchangeDetailList = new ArrayList<>();
		GagaMap exchangeMap = new GagaMap();
		DecimalFormat df = new DecimalFormat("###,###");

		OrderChange oneData = exchangeList.iterator().next();

		String selfGoodsYn = oneData.getSelfGoodsYn();
		String delvFeeCd = "Y".equals(selfGoodsYn) ? "WMS" : oneData.getDelvFeeCd();
		String supplyCompNm = oneData.getSupplyCompNm();
		for (OrderChange exchangeInfo : exchangeList) {
			String delvFeeCdTemp = "Y".equals(exchangeInfo.getSelfGoodsYn()) ? "WMS" : exchangeInfo.getDelvFeeCd();
			if (!delvFeeCd.equals(delvFeeCdTemp)) {
				exchangeMap.set("exchangeDetailList", exchangeDetailList);
				exchangeMap.setString("delvFeeCd", delvFeeCd);
				exchangeMap.setString("supplyCompNm", supplyCompNm);
				exchangeMap.setString("selfGoodsYn", selfGoodsYn);
				exchangeDelvList.add(exchangeMap);

				exchangeDetailList = new ArrayList<>();
				exchangeMap = new GagaMap();
				delvFeeCd = delvFeeCdTemp;
				supplyCompNm = exchangeInfo.getSupplyCompNm();
				selfGoodsYn = exchangeInfo.getSelfGoodsYn();
			}

			// 세트상품 옵션별 배열로 담기
			if (exchangeInfo.getItemNm().contains("!@!")) {
				exchangeInfo.setItemNmArr(exchangeInfo.getItemNm().split("!@!"));
				exchangeInfo.setColorNmArr(exchangeInfo.getColorNm().split(","));
				exchangeInfo.setOptCd1Arr(exchangeInfo.getOptCd1().split(","));
				exchangeInfo.setOptCd2Arr(exchangeInfo.getOptCd2().split(","));
			} else {
				String[] arr = {exchangeInfo.getItemNm()}, arr2 = {exchangeInfo.getColorNm()}, arr3 = {exchangeInfo.getOptCd1()}, arr4 = {exchangeInfo.getOptCd2()};
				exchangeInfo.setItemNmArr(arr);
				exchangeInfo.setColorNmArr(arr2);
				exchangeInfo.setOptCd1Arr(arr3);
				exchangeInfo.setOptCd2Arr(arr4);
			}

			// 교환상품 옵션 정보 조회 및 설정
			OrderChange changeOptionInfo = orderChangeDao.getExchangeGoodsOptionInfoList(exchangeInfo);
			if (changeOptionInfo.getItemNm().contains("!@!")) {
				exchangeInfo.setChgItemNmArr(changeOptionInfo.getItemNm().split("!@!"));
				exchangeInfo.setChgColorNmArr(changeOptionInfo.getColorNm().split(","));
				exchangeInfo.setChgOptCd1Arr(changeOptionInfo.getOptCd1().split(","));
				exchangeInfo.setChgOptCd2Arr(changeOptionInfo.getOptCd2().split(","));
			} else {
				exchangeInfo.setChgItemNm(changeOptionInfo.getItemNm());
				exchangeInfo.setChgColorNm(changeOptionInfo.getColorNm());
				exchangeInfo.setChgOptCd1(changeOptionInfo.getOptCd1());
				exchangeInfo.setChgOptCd2(changeOptionInfo.getOptCd2());
			}

			exchangeDetailList.add(exchangeInfo);
		}

		exchangeMap.set("exchangeDetailList", exchangeDetailList);
		exchangeMap.setString("delvFeeCd", delvFeeCd);
		exchangeMap.setString("supplyCompNm", supplyCompNm);
		exchangeMap.setString("selfGoodsYn", selfGoodsYn);
		exchangeDelvList.add(exchangeMap);

		// 추가배송비 설정
		// int addpayCost = oneData.getAddPayCost();
		// Order addPayCostOrder = orderChangeDao.getAddDeliveryFeePayment(oneData);
		// if (addPayCostOrder != null && addPayCostOrder.getPayAmt() > 0) {
		// 	addpayCost = 0;
		// }

		StringBuilder sb = new StringBuilder();

		sb.append("<table style=\"width:100%;margin:0;padding:0;font-size: 14px;\" cellspacing=\"0\" cellpadding=\"0\">\n");
		sb.append("											<tbody>\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"50px;\" style=\"height: 50px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<th colspan=\"2\" style=\"text-align: left;font-size: 18px;color: #222222;\" align=\"left\">\n");
		sb.append("														교환신청 상품 정보\n");
		sb.append("													</th>\n");
		sb.append("												</tr>\n");
		sb.append("												<tr>\n");
		sb.append("													<td height=\"30px;\" style=\"height: 30px;\"></td>\n");
		sb.append("												</tr>\n");
		for (GagaMap map : exchangeDelvList) {
			sb.append("													<tr>\n");
			sb.append("														<td height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("													</tr>\n");
			sb.append("													<tr>\n");
			sb.append("														<td>\n");
			sb.append("															<table style=\"border: 1px; border-color: #dddddd; border-style: solid; box-sizing: border-box; width:100%;margin:0;padding:0\" cellspacing=\"0\" cellpadding=\"0\">\n");
			sb.append("																<tbody>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td colspan=\"5\" height=\"20px;\" style=\"height: 20px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																		<td colspan=\"3\" style=\"text-align: left;font-size: 18px;font-family:'Apple SD Gothic Neo','나눔고딕',NanumGothic,'맑은고딕',Malgun Gothic, Helvetica, sans-serif;font-weight:600;color: #222222;\" align=\"left\">\n");
			if ("Y".equals(map.getString("selfGoodsYn"))) {
				sb.append("																			STYLE24 배송\n");
			} else {
				sb.append("																			");
				sb.append(map.getString("supplyCompNm"));
				sb.append(" 업체직배송\n");
			}
			sb.append("																		</td>\n");
			sb.append("																		<td width=\"40px;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append("																	<tr>\n");
			sb.append("																		<td colspan=\"5\" height=\"20px;\" style=\"height: 20px;border:0; border-bottom: 1px; border-color: #dddddd; border-style: solid; box-sizing: border-box;\"></td>\n");
			sb.append("																	</tr>\n");
			sb.append(this.getMailCreListInfo(exchangeDetailList));
			// sb.append("																	<!-- 배송비 시작 -->\n");
			// sb.append("																	<tr>\n");
			// sb.append("																		<td width=\"40px;\"></td>\n");
			// sb.append("																		<td colspan=\"3\" height=\"20px;\" style=\"height: 45px; background: #f5f5f5;\" bgcolor=\"#f5f5f5\">\n");
			// sb.append("																			<span style=\"width: 12px;padding-left:12px;\"></span>\n");
			// sb.append("																			<span>배송비</span>\n");
			// sb.append("																			<span style=\"width: 12px;padding-right:12px;\"></span>\n");
			// sb.append("																			<span>\n");
			// sb.append("																				<span>");
			// sb.append(df.format(addpayCost));
			// sb.append("</span>원\n");
			// sb.append("																			</span>\n");
			// sb.append("																		</td>\n");
			// sb.append("																		<td width=\"40px;\"></td>\n");
			// sb.append("																	</tr>\n");
			// sb.append("																	<tr>\n");
			// sb.append("																		<td height=\"30px;\" style=\"height: 30px;\"></td>\n");
			// sb.append("																	</tr>\n");
			// sb.append("																	<!-- 배송비 종료 -->\n");
			sb.append("																</tbody>\n");
			sb.append("															</table>\n");
			sb.append("														</td>\n");
			sb.append("													</tr>\n");
		}
		sb.append("												<tr>\n");
		sb.append("													<td height=\"50px;\" style=\"height: 50px;\"></td>\n");
		sb.append("												</tr>\n");
		sb.append("											</tbody>\n");
		sb.append("										</table>\n");

		return sb.toString();
	}
	
	/**
	 * 교환추가배송비 취소처리
	 *
	 * @param OrderChange (ordChgSq, userNo)
	 * @author jsh77b
	 * @since 2021. 06. 21
	 */
	public void addPayCostCncl(OrderChange orderChange) {

		// 2021.06.21
		int ordQty = orderChangeDao.getExchangeDelvFailQty(orderChange);

		if (ordQty < 1) {
			// PG 실행 (취소시 추가결제금액 취소처리)
			Collection<Order> paymentList = orderChangeDao.getAddDeliveryFeePayment(orderChange);

			// 추가배송비 존재 시
			if (paymentList != null && paymentList.size() > 0) {

				// 추가배송비 결제정보 조회
				Payment pg = new Payment();
				pg.setOrdChgSq(orderChange.getOrdChgSq());
				pg = orderChangeDao.getAddPayCostPaymentInfo(pg);

				// 2021.06.21 추가배송비 취소 처리
				// 회수구분 회수일때는 부분취소 (W)
				if ("W".equals(orderChange.getWdGb())) {
					orderChangeDao.createAddDeliveryFeeCancelPart(orderChange);

					// 추가배송비 취소 정보 설정
					if (StringUtils.isNotBlank(pg.getPgTid())) {
						pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
						pg.setPayGb(TscConstants.PaymentGb.DELIVERY.value());
						pg.setModType("STSC");
						pg.setModDesc("가맹점 취소 - 부분 취소");
						pg.setIpAddress(orderChange.getIpAddress());
						pg.setRegNo(orderChange.getUserNo());
						pg.setUpdNo(orderChange.getUserNo());

						int leftAmt = orderChange.getAddPayCost() / 2;

						pg.setLeftAmt(leftAmt);
						pg.setPartCancelAmt(leftAmt);
					}
				}
				// 회수구분 직접일때는 전체취소 (D)
				else {
					orderChangeDao.createAddDeliveryFeeCancel(orderChange);

					// 추가배송비 취소 정보 설정
					if (StringUtils.isNotBlank(pg.getPgTid())) {
						pg.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
						pg.setPayGb(TscConstants.PaymentGb.DELIVERY.value());
						pg.setModType("STSC");
						pg.setModDesc("가맹점 취소 - 전체 취소");
						pg.setIpAddress(orderChange.getIpAddress());
						pg.setRegNo(orderChange.getUserNo());
						pg.setUpdNo(orderChange.getUserNo());
					}
				}

				// KCP 취소 처리
				kcpService.kcpCancel(pg);
			}
		}
	}

	public Payment getPaymentInfo(Payment param) {
		return orderChangeDao.getPaymentInfo(param);
	}

	/**
	 * 반품 신청
	 * @param orderChange
	 * @return
	 * @author card007
	 * @since 2021. 03. 30
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap returnReq(OrderChange orderChange) {
		// 2. 환불 사전 정보 조회
		GagaMap refundPreInfo = getRefundPreInfo(orderChange);
		List<Order> returnReqList = (List<Order>)refundPreInfo.get("cnclReqList");
		String allLastCanYn = refundPreInfo.getString("allLastCanYn");
		String supplyCompCd = refundPreInfo.getString("supplyCompCd");

		// 3. 환불금액계산
		GagaMap result = orderRefundService.cnclRtnRefundAmt(returnReqList);

		// 4. 주문변경 기본정보 설정
		result.set("ordNo"			, orderChange.getOrdNo());				// 주문번호
		result.set("custNo"			, orderChange.getCustNo());				// 고객번호
		result.set("regNo"			, orderChange.getRegNo());				// 등록자번호
		result.set("updNo"			, orderChange.getUpdNo());				// 수정자번호
		result.set("pgGb"			, orderChange.getPgGb());				// PG구분
		// result.set("ordChgSq"		, orderChange.getOrdChgSq());			// 주문변경번호
		result.set("chgReason"		, orderChange.getChgReason());			// 변경사유
		result.set("chgMemo"		, orderChange.getChgMemo());			// 변경메모

		result.set("accountNo"		, orderChange.getAccountNo());			// 환불계좌번호
		result.set("accountNm"		, orderChange.getAccountNm());			// 환불계좌예금주명
		result.set("bankCd"			, orderChange.getBankCd());				// 환불계좌은행코드

		result.set("allLastCanYn"	, allLastCanYn);						// 전체 마지막 취소 여부
		result.set("isCustomer"		, orderChange.getIsCustomer());			// 변경사유 (고객, 회사)
		result.set("wdGb"			, orderChange.getWdGb());				// 회수방법
		result.set("wdInvoiceNo"	, orderChange.getWdInvoiceNo());		// 회수송장번호
		result.set("shipCompCd"		, orderChange.getShipCompCd());			// 회수택배사코드

		// 5. 주문변경 회수지정보 추가
		result.set("chgerNm"		, orderChange.getChgerNm());			// 변경자명
		result.set("chgerEmail"		, orderChange.getChgerEmail());			// 변경자이메일주소
		result.set("chgerZipcode"	, orderChange.getChgerZipcode());		// 회수지우편번호
		result.set("chgerBaseAddr"	, orderChange.getChgerBaseAddr());		// 회수지기본주소
		result.set("chgerDtlAddr"	, orderChange.getChgerDtlAddr());		// 회수지상세주소
		result.set("chgerPhnno"		, orderChange.getChgerPhnno());			// 변경자핸드폰번호
		result.set("chgerTelno"		, orderChange.getChgerTelno());			// 변경자전화번호
		result.set("chgerRtnMemo"	, orderChange.getChgerRtnMemo());		// 반품메모

		// 6. 주문변경 DB 등록 (TB_ORDER_CHANGE, TB_ORDER_CHANGE_DETAIL, TB_REFUND)
		GagaMap map = returnRequest(result);

		return map;
	}

	/**
	 * 마이페이지 회수지 수정
	 *
	 * @param OrderChange
	 * @return int
	 * @author card007
	 * @since 2021. 04. 13
	 */
	public int updateChgerAddr(OrderChange orderChange) {
		return orderChangeDao.updateChgerAddr(orderChange);
	}

	/**
	 * 마이페이지 반품메모 수정
	 *
	 * @param OrderChange
	 * @return int
	 * @author card007
	 * @since 2021. 04. 13
	 */
	public int updateChgerRtnMemo(OrderChange orderChange) {
		return orderChangeDao.updateChgerRtnMemo(orderChange);
	}

	/**
	 * 미착 정보 조회
	 *
	 * @param Order
	 * @return Collection<Order>
	 * @author card007
	 * @since 2021. 06. 28
	 */
	public Collection<Order> getNonArrivalInfo(Order order) {
		return orderChangeDao.getNonArrivalInfo(order);
	}
	
	/**
	 * 주문변경신청 완료 정보 조회(취소,반품)
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 06. 30
	 */
	public List<Order> getCnclRtnCompleteList(Order order) {
		return orderChangeDao.getCnclRtnCompleteList(order);
	}

	/**
	 * 회수 예외 정보 조회
	 *
	 * @param Order
	 * @return Order
	 * @author card007
	 * @since 2021. 07. 13
	 */
	public Order getRecallExceptionInfo(Order order) {
		return orderChangeDao.getRecallExceptionInfo(order);
	}

	/**
	 * 반송지 주소 조회
	 * 
	 * @param Order
	 * @return Order
	 * @author card007
	 * @since 2021. 07. 19
	 */
	public Collection<Order> getRtnLocInfo(Order order) {
		return orderChangeDao.getRtnLocInfo(order);
	}

	/**
	 * 환불금액 계산
	 * 
	 * @param OrderChange
	 * @return OrderChange
	 * @author card007
	 * @since 2021. 08. 11
	 */
	@SuppressWarnings("unchecked")
	private OrderChange calculateRefundAmt(GagaMap map) {
		OrderChange result = new OrderChange();
		String[] chgReasonCustomer	= {"G686_10", "G688_10"};						// 고객귀책사유 배열
		List<String> chgReasonCustomerList = Arrays.asList(chgReasonCustomer);		// 고객귀책사유 리스트
		String chgReason			= map.getString("chgReason");					// 변경사유코드
		String chgGb				= chgReason.split("_")[0];						// 취소/반품 구분
		String wdGb					= map.getString("wdGb");						// 회수구분
		String delvFeeCd			= map.getString("delvFeeCd");					// 배송비정책코드
		String allCanYn				= map.getString("allCanYn");					// 전체취소/반품여부
		String delvExpnYn			= map.getString("delvExpnYn");					// 출고예외여부
		int enCloseFee				= map.getInt("enCloseFee");						// 동봉비
		int addPayCost				= map.getInt("addPayCost");						// 반품배송비 결제 금액
		int codFee					= map.getInt("codFee");							// 착불비
		int spanTotDeliveryFee		= map.getInt("spanTotDeliveryFee");				// 추가배송비(배송비 허들 깨짐)
		int spanTotRtnDelvFee		= map.getInt("spanTotRtnDelvFee");				// 반품배송비
		int spanRealCnclRtnAmt		= map.getInt("spanRealCnclRtnAmt");				// 취소/반품 상품 실결제 금액
		int spanSumDeliveryFee		= map.getInt("spanSumDeliveryFee");				// 원주문배송비
		int spanDelvCpnDcAmt		= map.getInt("spanDelvCpnDcAmt");				// 원주문배송비 쿠폰 사용 금액
		int spanDelvGfcdUseAmt		= map.getInt("spanDelvGfcdUseAmt");				// 원주문배송비 상품권 사용 금액
		int spanGfcdUseAmt			= map.getInt("spanGfcdUseAmt");					// 취소/반품 상품권 사용 금액
		int sumDeliveryFee			= map.getInt("sumDeliveryFee");
		int spanRefundDelvCpnAmt	= map.getInt("spanRefundDelvCpnAmt");
		boolean isCustomer			= chgReasonCustomerList.contains(chgReason);	// 고객귀책 여부

		int orgRefundDelvFee		= 0;											// 원주문배송비 환불 금액
		int orgDeductionDelvFee		= 0;											// 원주문배송비 차감 금액 (전체반품 고객사유)
		int rfDeliveryFee			= 0;											// 환불 배송비
		int rfDelvGfcdUseAmt		= 0;											// 환불 배송비 상품권
		int totDeliveryFee			= 0;											// 추가배송비 계산
		int totRtnDelvFee			= 0;											// 반품배송비 계산
		int refundAmt;																// 환불금액
		int addDelvFee				= 0;											// 추가배송비 (배송비 허들 깨짐) - 사유계산
		
		// 전체반품 원주문 배송비 처리
		String allDelvCanYn			= "";											// 배송비정책 별 전체반품 여부
		int orgDelvFee				= 0;											// 원주문배송비 차감 금액

		// 배송비정책 별 전체반품 여부 설정
		if (map.get("delvCanYn") instanceof GagaMap) {
			GagaMap delvCanYn = (GagaMap)map.get("delvCanYn");
			if (delvCanYn != null) {
				List<String> delvFeeCdCanList = (ArrayList<String>)delvCanYn.get("delvFeeCdCanList");
				List<String> allDelvCanYnList = (ArrayList<String>)delvCanYn.get("allDelvCanYnList");

				int index = delvFeeCdCanList.indexOf(delvFeeCd);

				if (index >= 0) {
					allDelvCanYn = allDelvCanYnList.get(index);
				}

				if ("Y".equals(allDelvCanYn)) {
					List<Order> returnOrderInfo = (ArrayList<Order>)map.get("returnOrderInfo");

					if (returnOrderInfo != null && returnOrderInfo.size() > 0 && returnOrderInfo.get(0).getDelvGfcdUseAmt() + returnOrderInfo.get(0).getRealDelvAmt() == 0) {
						orgDelvFee = returnOrderInfo.get(0).getOrgDelvFee();
					}
				}
			}
		}

		// 출고예외(확정후 품절,불량)일 경우
		if ("Y".equals(delvExpnYn)) {
			// 전체취소
			// 2021.09.23 card007 전체취소 -> 배송비정책 단위 전체취소로 변경
			if ("Y".equals(allDelvCanYn)) {
				// 환불금액 = 취소/반품 상품 실결제 금액 + (원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액)
				refundAmt = spanRealCnclRtnAmt + spanSumDeliveryFee - spanDelvCpnDcAmt - spanDelvGfcdUseAmt;
				
				// 환불 원주문 배송비 = 원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액
				orgRefundDelvFee = spanSumDeliveryFee - spanDelvCpnDcAmt - spanDelvGfcdUseAmt;
				
				// 환불 배송비 상품권 = 원주문배송비 상품권 사용 금액
				rfDelvGfcdUseAmt = spanDelvGfcdUseAmt;
			}
			// 부분취소
			else {
				// 환불금액 = 취소/반품 상품 실결제 금액
				refundAmt = spanRealCnclRtnAmt;
			}
		}
		// 취소/반품일 경우
		else {
			// 전체 취소/반품
			if ("Y".equals(allCanYn)) {
				// 고객귀책사유
				if (isCustomer) {
					// 회수요청 (반품)
					if ("W".equals(wdGb)) {
						// 환불금액 = 취소/반품 상품 실결제 금액 + 동봉비 + 반품배송비 결제 금액
						refundAmt = spanRealCnclRtnAmt + enCloseFee + addPayCost;

						// 반품배송비
						// 2021.08.12 회수요청시에 착불비가 발생하면 철회 후 직접배송으로 재접수해야 환불금액에 이상이 없을듯 (모니터링 필요)
						// 2021.09.07 card007 착불비 등록 처리
						totRtnDelvFee = spanTotRtnDelvFee + codFee;
						// totRtnDelvFee = spanTotRtnDelvFee;

						// 배송비정책 원주문 배송비 차감 처리
						orgDeductionDelvFee = orgDelvFee;

						// 환불 배송비 = 반품배송비 + 원주문 배송비 차감
						rfDeliveryFee = (totRtnDelvFee + orgDeductionDelvFee) * -1;
					}
					// 직접배송 (취소/반품)
					else {
						// 반품
						if ("G688".equals(chgGb)) {
							// 환불금액 = 취소/반품 상품 실결제 금액 + 동봉비 + 반품배송비 결제 금액
							refundAmt = spanRealCnclRtnAmt + enCloseFee + addPayCost;

							// 배송비정책 원주문 배송비 차감 처리
							orgDeductionDelvFee = orgDelvFee;
						}
						// 취소
						else {
							// 환불금액 = 취소/반품 상품 실결제 금액 + (원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액)
							refundAmt = spanRealCnclRtnAmt + sumDeliveryFee - spanRefundDelvCpnAmt - spanDelvGfcdUseAmt;

							// 환불 원주문 배송비 = 원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액
							orgRefundDelvFee = spanSumDeliveryFee - spanDelvCpnDcAmt - spanDelvGfcdUseAmt;

							// 환불 배송비 상품권 = 원주문배송비 상품권 사용 금액
							rfDelvGfcdUseAmt = spanDelvGfcdUseAmt;
						}
						
						// 반품배송비 = 착불비
						totRtnDelvFee = codFee;

						// 환불배송비 = 착불비 + 원주문 배송비 차감 - 원주문 배송비 환불
						rfDeliveryFee = (totRtnDelvFee + orgDeductionDelvFee - orgRefundDelvFee) * -1;
					}
				}
				// 회사귀책사유
				else {
					// 환불금액 = 취소/반품 상품 실결제 금액 + (원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액)
					refundAmt = spanRealCnclRtnAmt + spanSumDeliveryFee - spanDelvCpnDcAmt - spanDelvGfcdUseAmt;

					// 환불 원주문 배송비 = 원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액
					orgRefundDelvFee = spanSumDeliveryFee - spanDelvCpnDcAmt - spanDelvGfcdUseAmt;

					// 환불 배송비 상품권 = 원주문배송비 상품권 사용 금액
					rfDelvGfcdUseAmt = spanDelvGfcdUseAmt;

					// 환불배송비 = 원주문 배송비 환불
					rfDeliveryFee = orgRefundDelvFee;
				}
			}
			// 부분 취소/반품
			else {
				// 고객귀책사유
				if (isCustomer) {
					// 회수요청 (반품)
					if ("W".equals(wdGb)) {
						// 환불금액 = 취소/반품 상품 실결제 금액 + 동봉비 + 반품배송비 결제 금액
						refundAmt = spanRealCnclRtnAmt + enCloseFee + addPayCost;

						// 추가배송비 = 추가배송비(배송비 허들 깨짐)
						totDeliveryFee = spanTotDeliveryFee;
						addDelvFee = spanTotDeliveryFee;

						// 배송비정책 원주문 배송비 차감 처리
						orgDeductionDelvFee = orgDelvFee;

						// 반품배송비 = 반품배송비 + 착불비
						totRtnDelvFee = spanTotRtnDelvFee + codFee;
						
						// 환불배송비 = 추가배송비 + 반품배송비 + 착불비 + 원주문 배송비 차감
						rfDeliveryFee = (totDeliveryFee + totRtnDelvFee + orgDeductionDelvFee) * -1;
					}
					// 직접배송 (취소/반품)
					else {
						// 반품
						if ("G688".equals(chgGb)) {
							// 환불금액 = 취소/반품 상품 실결제 금액 + 동봉비 + 반품배송비 결제 금액
							refundAmt = spanRealCnclRtnAmt + enCloseFee + addPayCost;

							// 배송비정책 원주문 배송비 차감 처리
							orgDeductionDelvFee = orgDelvFee;
						}
						// 취소
						else {
							// 환불금액 = 취소/반품 상품 실결제 금액 + (원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액)
							refundAmt = spanRealCnclRtnAmt + sumDeliveryFee - spanRefundDelvCpnAmt - spanDelvGfcdUseAmt;

							// 환불 원주문 배송비 = 원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액
							orgRefundDelvFee = sumDeliveryFee - spanRefundDelvCpnAmt - spanDelvGfcdUseAmt;

							// 환불 배송비 상품권 = 원주문배송비 상품권 사용 금액
							rfDelvGfcdUseAmt = spanDelvGfcdUseAmt;
						}

						// 추가배송비 = 추가배송비(배송비 허들 깨짐)
						totDeliveryFee = spanTotDeliveryFee;
						addDelvFee = spanTotDeliveryFee;

						// 반품배송비 = 착불비
						totRtnDelvFee = codFee;
						
						// 환불배송비 = 추가배송비 + 착불비 + 원주문 배송비 차감 - 원주문 배송비 환불
						rfDeliveryFee = (totDeliveryFee + totRtnDelvFee + orgDeductionDelvFee - orgRefundDelvFee) * -1;
					}
				}
				// 회사귀책사유
				else {
					// 배송비정책 단위 부분반품
					if ("G688".equals(chgGb) && !"Y".equals(allDelvCanYn)) {
						// 환불금액 = 취소/반품 상품 실결제 금액
						refundAmt = spanRealCnclRtnAmt;
					}
					// 배송비정책 단위 전체반품 및 취소
					else {
						// 환불금액 = 취소/반품 상품 실결제 금액 + (원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액)
						refundAmt = spanRealCnclRtnAmt + sumDeliveryFee - spanRefundDelvCpnAmt - spanDelvGfcdUseAmt;

						// 환불 원주문 배송비 = 원주문배송비 - 원주문배송비 쿠폰 사용 금액 - 원주문배송비 상품권 사용 금액
						orgRefundDelvFee = sumDeliveryFee - spanRefundDelvCpnAmt - spanDelvGfcdUseAmt;

						// 환불 배송비 상품권 = 원주문배송비 상품권 사용 금액
						rfDelvGfcdUseAmt = spanDelvGfcdUseAmt;
					}

					// 환불배송비 = 원주문 배송비 환불
					rfDeliveryFee = orgRefundDelvFee;
				}
			}
		}

		// 원주문 배송비 차감 처리
		int realDelvAmt = 0;

		// 배송비 허들 깨짐
		if (totDeliveryFee > 0) {
			realDelvAmt = totDeliveryFee;
		}
		// 전체반품 고객사유로 원주문배송비 차감
		else if (orgDeductionDelvFee > 0) {
			realDelvAmt = orgDeductionDelvFee;
			totDeliveryFee = orgDeductionDelvFee;
		}

		int delvGfcdUseAmt = 0;

		if (totDeliveryFee > 0) {
			if (refundAmt < totDeliveryFee) {
				totDeliveryFee -= refundAmt;
				realDelvAmt = refundAmt;
				refundAmt = 0;
			} else {
				refundAmt -= totDeliveryFee;
				realDelvAmt = totDeliveryFee;
				totDeliveryFee = 0;
			}
			
			if (totDeliveryFee > 0) {
				spanGfcdUseAmt -= totDeliveryFee;
				delvGfcdUseAmt = totDeliveryFee;
			}
		}

		// 반품배송비 처리
		int rtnRealDelvAmt = totRtnDelvFee;
		int rtnDelvGfcdUseAmt = 0;
		if (totRtnDelvFee > 0) {
			if (refundAmt < totRtnDelvFee) {
				totRtnDelvFee -= refundAmt;
				rtnRealDelvAmt = refundAmt;
				refundAmt = 0;
			} else {
				refundAmt -= totRtnDelvFee;
				rtnRealDelvAmt = totRtnDelvFee;
				totRtnDelvFee = 0;
			}

			if (totRtnDelvFee > 0) {
				spanGfcdUseAmt -= totRtnDelvFee;
				rtnDelvGfcdUseAmt = totRtnDelvFee;
			}
		}

		result.setRefundAmt(refundAmt);					// PG 환불 금액
		result.setGfcdUseAmt(spanGfcdUseAmt);			// 상품권 환불 금액
		result.setOrgDelvFee(orgDeductionDelvFee);		// 원주문 배송비 차감 금액(전체반품 고객사유)
		result.setOrgRefundDelvFee(orgRefundDelvFee);	// 원주문 배송비 환불 금액
		result.setRfDeliveryFee(rfDeliveryFee);			// 배송비 환불 금액
		result.setRfDelvGfcdUseAmt(rfDelvGfcdUseAmt);	// 배송비 상품권 환불 금액
		result.setRealDelvAmt(realDelvAmt);				// 추가배송비 실결제 금액
		result.setDelvGfcdUseAmt(delvGfcdUseAmt);		// 추가배송비 상품권 사용 금액
		result.setRtnRealDelvAmt(rtnRealDelvAmt);		// 반품배송비 실결제 금액
		result.setRtnDelvGfcdUseAmt(rtnDelvGfcdUseAmt);	// 반품배송비 상품권 사용 금액
		result.setSpanTotDeliveryFee(addDelvFee);		// 추가배송비 계산 금액

		return result;
	}

	/**
	 * 마이페이지 반품 주문 정보 조회
	 *
	 * @param Order
	 * @return Collection<Order>
	 * @author card007
	 * @since 2021. 09. 07
	 */
	public Collection<Order> getReturnOrderInfo(Order order) {
		return orderChangeDao.getReturnOrderInfo(order);
	}
}
