package com.style24.admin.biz.web;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.rest.server.GagaResponse;
import com.gagaframework.web.rest.server.GagaResponseStatus;
import com.style24.admin.biz.service.TsaOrderChangeService;
import com.style24.admin.biz.service.TsaRendererService;
import com.style24.admin.support.controller.TsaBaseController;
import com.style24.admin.support.security.session.TsaSession;
import com.style24.core.biz.service.TscKakaotalkService;
import com.style24.core.biz.service.TscKcpService;
import com.style24.core.biz.service.TscMailService;
import com.style24.core.biz.service.TscNaverPayService;
import com.style24.core.biz.service.TscOrderChangeService;
import com.style24.core.biz.service.TscOrderRefundService;
import com.style24.core.biz.service.TscOrderService;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.persistence.domain.CustAccount;
import com.style24.persistence.domain.Order;
import com.style24.persistence.domain.OrderChange;
import com.style24.persistence.domain.Payment;

import lombok.extern.slf4j.Slf4j;

/**
 * 취소관리 Controller
 *
 * @author jsh77b
 * @since 2020. 11. 16
 */
@Controller
@RequestMapping("/orderChange")
@Slf4j
public class TsaOrderChangeController extends TsaBaseController {
	
	@Autowired
	private TscMessageByLocale message;
	
	@Autowired
	private TsaRendererService rendererService;
	
	@Autowired
	private TscOrderService coreOrderService;

	@Autowired
	private TsaOrderChangeService orderChangeService;

	@Autowired
	private TscOrderChangeService coreOrderChangeService;
	
	@Autowired
	private TscOrderRefundService coreOrderRefundService;
	
	@Autowired
	private TscKcpService coreKcpService;

	@Autowired
	private TscNaverPayService coreNaverPayService;

	@Autowired
	private TscKakaotalkService coreKakaotalkService;

	@Autowired
	private TscMailService coreMailService;
	
	/**
	 * 취소요청, 취소완료 통합 화면 (관리자)
	 * 
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2020. 12. 22
	 */
	@GetMapping("/cncl/req/form")
	public ModelAndView cnclReqForm(@RequestParam(value = "ordNo") int ordNo, @RequestParam(value = "ordDtlNo") int ordDtlNo
			, @RequestParam(value = "delvFeeCd") String delvFeeCd, @RequestParam(value = "delvFeeCdGrp") String delvFeeCdGrp
			, @RequestParam(value = "ordChgSq") int ordChgSq) {

		Order order = new Order();
		order.setOrdNo(ordNo);
		order.setOrdDtlNo(ordDtlNo);
		order.setDelvFeeCd(delvFeeCd);
		order.setDelvFeeCdGrp(delvFeeCdGrp);
		order.setOrdChgSq(ordChgSq);
		
		String userId = TsaSession.getInfo().getUserId();

		// 1. 취소가능 주문상세상탭값 설정
		String[] ordDtlStatArr = new String[4];
		ordDtlStatArr[0] = TscConstants.OrderDetailStat.DEPOSIT_WAIT.value();
		ordDtlStatArr[1] = TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value();
		ordDtlStatArr[2] = TscConstants.OrderDetailStat.GOODS_PREPARE.value();
		ordDtlStatArr[3] = TscConstants.OrderDetailStat.DELIVERY_PREPARE.value();
		order.setOrdDtlStatArr(ordDtlStatArr);
		
		// 2. 변경신청된 주문상세번호를 체크 후 있으면 해당 취소가능수량값 업데이트 
		List<Order> cancelRequestTargetList 		= coreOrderChangeService.getCancelRequestTargetList2(order);
		List<Order> orderChangeDetailList 			= coreOrderChangeService.getOrderChangeDetailList(order);
		Collection<Order> orderInfoList 			= coreOrderService.getOrderInfoList(order);
		
		// 3. 화면으로 데이타 전송
		// 2021.01.26 취소요청 화면, 취소요청정보확인 화면 통합
		ModelAndView mav = new ModelAndView();
		mav.addObject("chgReasonList"				, rendererService.getAvailCommonCodeList("G686"));				// 취소사유
		mav.addObject("cancelRequestTargetList"		, cancelRequestTargetList);										// 변경신청대상목록 (취소/반품/교환)
		mav.addObject("orderInfoList"				, orderInfoList);												// 주문정보
		mav.addObject("ordNo"						, ordNo);														// 주문번호
		mav.addObject("ordChgSq"					, ordChgSq);													// 주문변경번호
		mav.addObject("delvFeeCd"					, delvFeeCd);													// 배송지정책코드
		mav.addObject("orderChangeDetailList"		, orderChangeDetailList);										// 변경신청목록 (취소/반품/교환)
		mav.addObject("userId"						, userId);														// 관리자ID
		
		String viewName = "";
		
		viewName = "order/CnclReqForm";		// 변경요청화면, 변경요청확인화면 (취소요청화면) (통합)

		mav.setViewName(viewName);
		
		return mav;
	}

	/**
	 * 취소요청철회 (관리자)
	 * @param OrderChange - 주문취소신청정보
	 * @return
	 * @author jsh77b
	 * @since 2021. 01. 20
	 */
	@PostMapping("/cnclReqCancel")
	@ResponseBody
	public GagaResponse cnclReqCancel(@RequestBody OrderChange cnclReq) {
		
		if (cnclReq== null) {
			throw new IllegalStateException(message.getMessage("FAIL_1001"));
		}
		
		// 1. 세션회원조회
		int userNo = TsaSession.getInfo().getUserNo();
		
		GagaMap mav = new GagaMap();
		mav.set("ordNo"			, cnclReq.getOrdNo());
		mav.set("ordChgSq"		, cnclReq.getOrdChgSq());
		
		// 2.취소요청철회
		mav = coreOrderChangeService.cnclReqCancel(mav, userNo);
		// coreNaverPayService.sendNaverPayRejectReturn(cnclReq, userNo);

		return super.ok("성공");
	}
	
	/**
	 * 취소요청, 취소요청완료, 취소완료 기능 통합 (관리자)
	 * @param Collection<Order> - 주문취소신청목록
	 * @return
	 * @author jsh77b
	 * @since 2020. 12. 29
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/cnclComplete")
	@ResponseBody
	public GagaResponse cnclComplete(@RequestBody OrderChange cnclReq) {
		GagaMap result = new GagaMap();
		if (cnclReq== null) {
			throw new IllegalStateException(message.getMessage("FAIL_1001"));
		}

		// 1. 세션회원조회
		int userNo = TsaSession.getInfo().getUserNo();

		cnclReq.setIpAddress(TsaSession.getIpAddress());
		cnclReq.setRegNo(userNo);
		cnclReq.setUserNo(userNo);
				
		// 2021.05.14 FRONT 정보 선주문정보조회
		GagaMap refundPreInfo = coreOrderChangeService.getRefundPreInfo(cnclReq);
		List<Order> cnclReqList = (List<Order>) refundPreInfo.get("cnclReqList");
		
		// 2. 환불금액계산
		// 2021.01.19 취소신청정보를 목록 (주문상세번호, 취소/반품수량) 으로 표현
		GagaMap map = coreOrderRefundService.cnclRtnRefundAmt(cnclReqList);
		
		// 3. 주문변경 기본정보 설정
		map.set("ordNo"						, cnclReq.getOrdNo());						// 주문번호
		map.set("ordChgSq"					, cnclReq.getOrdChgSq());					// 주문변경번호
		map.set("chgReason"					, cnclReq.getChgReason());					// 변경사유
		map.set("chgReasonNm"				, cnclReq.getChgReasonNm());				// 변경사유명 (2021.05.13 추가)
		map.set("chgMemo"					, cnclReq.getChgMemo());					// 변경메모
		map.set("accountNo"					, cnclReq.getAccountNo());					// 환불계좌번호
		map.set("accountNm"					, cnclReq.getAccountNm());					// 환불계좌예금주명
		map.set("bankCd"					, cnclReq.getBankCd());						// 환불계좌은행코드
		map.set("allCanYnBeforePayment"		, cnclReq.getAllCanYnBeforePayment());		// 무통장입금전 전체취소 여부
		map.set("allCanYn"					, cnclReq.getAllCanYn());					// 전체취소 여부
		map.set("allLastCanYn"				, refundPreInfo.get("allLastCanYn"));		// 전체 마지막 취소 여부 (2021.05.13 추가)
		map.set("isCustomer"				, cnclReq.getIsCustomer());					// 변경사유 (고객, 회사)
		map.set("chgerNm"					, cnclReq.getChgerNm());					// 변경자명
		map.set("chgerEmail"				, cnclReq.getChgerEmail());					// 변경자이메일주소
		map.set("chgerPhnno"				, cnclReq.getChgerPhnno());					// 변경자핸드폰번호
		map.set("chgerTelno"				, cnclReq.getChgerTelno());					// 변경자전화번호
		map.set("reqGbn"					, cnclReq.getReqGbn());						// 신청구분
		map.set("ipAddress"					, cnclReq.getIpAddress());					// IP주소 (2021.05.13 추가)
		map.set("custNo"					, cnclReq.getCustNo());						// 고객번호 (2021.05.13 추가)
		map.set("pgTid"						, refundPreInfo.getString("pgTid"));		// PG거래ID
		map.set("payMeans"					, refundPreInfo.getString("payMeans"));		// 결제수단
		map.set("pgGb"						, refundPreInfo.getString("pgGb"));			// PG구분
		map.set("cashAuthNo"				, refundPreInfo.getString("cashAuthNo"));	// 현금영수증 승인번호
		map.set("chgStat"					, cnclReq.getChgStat());					// 변경상태
		map.set("pgStat"					, cnclReq.getPgStat());						// PG점프

		// 4. 부분취소 처리 2021.05.13
		// 2021.06.09 취소접수
		if ("cnclReq".equals(cnclReq.getReqGbn())) {
			// 1. 주문변경 등록
			// ordNo				: 주문번호
			// chgGb				: 변경구분
			// chgReason			: 변경사유
			// chgMemo				: 변경메모
			// userNo				: 회원번호
			// ordDtlNoArr			: 주문상세번호배열
			// cnclRtnReqQtyArr		: 변경수량배열
			
			cnclReq.setChgGb(TscConstants.OrderChangeGb.CANCEL.value());
			coreOrderChangeService.cancelRequest(cnclReq);
		}
		// 2021.06.09 취소접수승인
		else if ("cnclReqComplete".equals(cnclReq.getReqGbn())) {
			result = coreOrderChangeService.approveCancelRequest(cnclReq, userNo);
		}
		// 2021.06.09 취소접수철회
		else if ("cnclReqCancel".equals(cnclReq.getReqGbn())) {
			coreOrderChangeService.cnclReqCancel(map, userNo);
		}
		// 취소완료
		else {
			result = coreOrderChangeService.partialCancel(map, userNo);
		}
		
		// 2021.06.21 교환TO취소 교환배송비 취소처리
		if (cnclReq.getAddPayCost() > 0) {
			cnclReq.setUserNo(userNo);
			cnclReq.setRegNo(userNo);
			cnclReq.setUpdNo(userNo);
			coreOrderChangeService.addPayCostCncl(cnclReq);
		}
		
		// 5. 취소 알림톡 및 메일 발송
		int ordChgSq = result.getInt("ordChgSq");

		if (ordChgSq > 0) {
			Payment payment = new Payment();
			payment.setOrdNo(cnclReq.getOrdNo());
			payment = coreOrderChangeService.getPaymentInfo(payment);

			// 네이버페이 주문형 데이터는 알림톡, 메일 송부X
			if(TscConstants.PgGb.NAVER_ORDER.value().equals(payment.getPgGb())) {
				return super.ok("성공");
			}

			// 취소 알림톡 관련 정보 조회
			OrderChange orderChange = coreOrderChangeService.getKakaoOrderCancelInfo(ordChgSq);

			try {
				// 취소 알림톡 발송
				if (StringUtils.isNotBlank(orderChange.getOrdPhnno())) {
					coreKakaotalkService.sendOrderCancelComplete(orderChange, userNo);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			try {
				// 취소 안내 메일 정보 조회
				GagaMap replaceInfo = coreOrderChangeService.getMailOrderCancelReplaceInfo(orderChange);

				// 취소 안내 메일 발송
				if (StringUtils.isNotBlank(replaceInfo.getString("ordEmail"))) {
					coreMailService.sendOrderCancel(replaceInfo, userNo);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return super.ok("성공");
	}
	
	/**
	 * 취소완료 상세 화면 (관리자)
	 * 
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2021. 06. 30
	 */
	@GetMapping("/cnclRtn/complete/view")
	public ModelAndView cnclCompleteView(@RequestParam(value = "ordNo") int ordNo, @RequestParam(value = "ordDtlNo") int ordDtlNo
			, @RequestParam(value = "delvFeeCd") String delvFeeCd, @RequestParam(value = "delvFeeCdGrp") String delvFeeCdGrp
			, @RequestParam(value = "chgStat") String chgStat, @RequestParam(value = "ordChgSq") int ordChgSq) {
		
		ModelAndView mav = new ModelAndView();
		
		// 2021.01.26 취소요청 화면, 취소요청정보확인 화면 통합
		Order order = new Order();
		order.setOrdChgSq(ordChgSq);
		order.setOrdNo(ordNo);
		
		// 결제전취소, 결제후취소 일때 상태값 환입 취소완료 변경
		if ("G685_17".equals(chgStat) || "G685_18".equals(chgStat)) {
			order.setChgStat("G720_30");
		}
		else if ("G685_60".equals(chgStat)) {
			order.setChgStat("G720_50");
		}
		
		List<Order> cnclRtnCompleteList 	= coreOrderChangeService.getCnclRtnCompleteList(order);
		Collection<Order> orderInfoList 	= coreOrderService.getOrderInfoList(order);
		
		mav.addObject("cnclRtnCompleteList"		, cnclRtnCompleteList);			// 취소완료목록
		mav.addObject("orderInfoList"			, orderInfoList);				// 주문기본정보
		mav.addObject("chgStat"					, order.getChgStat());			// 변경요청상태값(정산상태구분)
		mav.setViewName("order/CnclCompleteView");
		
		return mav;
	}
	
	/**
	 * 반품신청화면 (관리자)
	 * 
	 * @param ordNo - 주문번호
	 * @param cncWait - 취소대기요청 구분
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2020. 12. 22
	 */
	@GetMapping("/rtn/req/form")
	public ModelAndView rtnReqForm(Order order) {

		ModelAndView mav = new ModelAndView();

		// 1. 반품가능 주문상세상탭값 설정
		String[] ordDtlStatArr = new String[4];
		ordDtlStatArr[0] = TscConstants.OrderDetailStat.SHIPPING.value();
		ordDtlStatArr[1] = TscConstants.OrderDetailStat.SHIP_COMPLETE.value();
		ordDtlStatArr[2] = TscConstants.OrderDetailStat.DELIVERY_COMPLETE.value();
		ordDtlStatArr[3] = TscConstants.OrderDetailStat.DELIVERY_PREPARE.value();
		order.setOrdDtlStatArr(ordDtlStatArr);

		// 2. 변경신청된 주문상세번호를 체크 후 있으면 해당 취소가능수량값 업데이트
		order.setChgGb(TscConstants.OrderChangeGb.RETURN.value());
		List<Order> cancelRequestTargetList 		= coreOrderChangeService.getCancelRequestTargetList2(order);
		List<Order> orderChangeDetailList 			= coreOrderChangeService.getOrderChangeDetailList(order);
		Collection<Order> orderInfoList 			= coreOrderService.getOrderInfoList(order);

		String chgStat = "";
		if (order.getOrdChgSq() > 0) {
			// 교환TO교환 처리 시 미착 수량 설정
			Collection<Order> returnDetailList;
			String ordChgGb = order.getOrdChgGb();

			if (StringUtils.isNotBlank(ordChgGb) && TscConstants.ChangeGb.RETURN_TO_RETURN.value().equals(ordChgGb.toUpperCase())) {
				returnDetailList = coreOrderChangeService.getNonArrivalInfo(order);
			} else {
				returnDetailList = orderChangeDetailList;
			}

			// Collection<Order> exchangeInfoList = coreOrderChangeService.getExchangeInfo(order);
			// mav.addObject("exchangeInfoList"		, exchangeInfoList);											// 교환정보
			mav.addObject("ordChgGb"				, StringUtils.isBlank(ordChgGb) ? "" : ordChgGb.toUpperCase());	// 주문변경요쳥변경구분
			mav.addObject("recallExceptionInfo"		, coreOrderChangeService.getRecallExceptionInfo(order));		// 회수 예외 정보

			// 반품상세 정보 설정
			List<Integer> ordDtlNoList = new ArrayList<>();
			List<Integer> chgQtyList = new ArrayList<>();
			if (returnDetailList != null && returnDetailList.size() > 0) {
				for (Order tmp : returnDetailList) {
					if (tmp.getChgQty() > 0 && !ordDtlNoList.contains(tmp.getOrdDtlNo())) {
						ordDtlNoList.add(tmp.getOrdDtlNo());
						chgQtyList.add(tmp.getChgQty());

						if (StringUtils.isNotBlank(tmp.getChgStat())) {
							chgStat = tmp.getChgStat();
						}
					}
				}

				List<Order> tmpList = new ArrayList<>();
				for (Order tmp : cancelRequestTargetList) {
					if(ordDtlNoList.contains(tmp.getOrdDtlNo())) {
						int chgQty = chgQtyList.get(ordDtlNoList.indexOf(tmp.getOrdDtlNo()));
						tmp.setChgQty(chgQty);

						if (StringUtils.isNotBlank(ordChgGb) && TscConstants.ChangeGb.RETURN_TO_RETURN.value().equals(ordChgGb.toUpperCase())) {
							tmp.setOrdCanChgQty(chgQty);
						}

						tmpList.add(tmp);
					}
				}

				cancelRequestTargetList = tmpList;
			}
		}

		// 2021.01.26 취소요청 화면, 취소요청정보확인 화면 통합
		mav.addObject("chgReasonList"				, rendererService.getAvailCommonCodeList("G688"));				// 취소사유
		mav.addObject("cancelRequestTargetList"		, cancelRequestTargetList);										// 취소요청대상 목록
		mav.addObject("orderInfoList"				, orderInfoList);												// 주문정보
		mav.addObject("ordNo"						, order.getOrdNo());											// 주문번호
		mav.addObject("ordChgSq"					, order.getOrdChgSq());											// 주문변경번호
		mav.addObject("delvFeeCd"					, order.getDelvFeeCd());										// 배송정책코드
		mav.addObject("delvFeeCdGrp"				, order.getDelvFeeCdGrp());										// 배송정책그룹코드
		mav.addObject("orderChangeDetailList"		, orderChangeDetailList);										// 변경신청목록 (취소/반품/교환)
		mav.addObject("orderDelvRtnAddrInfo"		, coreOrderService.getDeliveryAddrList(order));					// 배송정보
		mav.addObject("TelExcNoList"				, rendererService.getAvailCommonCodeList("G095"));				// 전화번호국번
		mav.addObject("PhnExcNoList"				, rendererService.getAvailCommonCodeList("G096"));				// (휴대전화)번호국번
		mav.addObject("chgStat"						, chgStat);														// 변경상태

		mav.setViewName("order/RtnReqForm");
		
		return mav;
	}
	
	/**
	 * 반품신청실행 (관리자)
	 * @param Collection<Order> - 주문취소신청목록
	 * @return
	 * @author jsh77b
	 * @since 2020. 12. 29
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/rtnReq")
	@ResponseBody
	public GagaResponse rtnReq(@RequestBody OrderChange rtnReq) {
		
		// 1. 반품신청정보체크
		if (rtnReq== null) {
			throw new IllegalStateException(message.getMessage("FAIL_1001"));
		}

		// 2. 관리자정보설정
		int userNo = TsaSession.getInfo().getUserNo();
		rtnReq.setRegNo(userNo);
		rtnReq.setIpAddress(TsaSession.getIpAddress());

		// 2021.05.14 FRONT 정보 선주문정보조회
		GagaMap refundPreInfo 		= coreOrderChangeService.getRefundPreInfo(rtnReq);
		List<Order> cnclReqList 	= (List<Order>) refundPreInfo.get("cnclReqList");
		
		GagaMap map = new GagaMap();
		
		// 3. 환불예상금액계산
		map = coreOrderRefundService.cnclRtnRefundAmt(cnclReqList);
		
		// 4. 주문변경기본정보설정
		map.set("ordNo"						, rtnReq.getOrdNo());						// 주문번호
		map.set("ordChgSq"					, rtnReq.getOrdChgSq());					// 주문변경번호
		map.set("chgReason"					, rtnReq.getChgReason());					// 변경사유
		map.set("chgReasonNm"				, rtnReq.getChgReasonNm());					// 변경사유명 (2021.05.13 추가)
		map.set("chgMemo"					, rtnReq.getChgMemo());						// 변경메모
		map.set("accountNo"					, rtnReq.getAccountNo());					// 환불계좌번호
		map.set("accountNm"					, rtnReq.getAccountNm());					// 환불계좌예금주명
		map.set("bankCd"					, rtnReq.getBankCd());						// 환불계좌은행코드
		map.set("allCanYnBeforePayment"		, rtnReq.getAllCanYnBeforePayment());		// 무통장입금전 전체취소 여부
		map.set("allCanYn"					, rtnReq.getAllCanYn());					// 전체취소 여부
		map.set("allLastCanYn"				, refundPreInfo.get("allLastCanYn"));		// 전체 마지막 취소 여부 (2021.05.13 추가)
		map.set("isCustomer"				, rtnReq.getIsCustomer());					// 변경사유 (고객, 회사)
		map.set("chgerNm"					, rtnReq.getChgerNm());						// 변경자명
		map.set("chgerEmail"				, rtnReq.getChgerEmail());					// 변경자이메일주소
		map.set("chgerPhnno"				, rtnReq.getChgerPhnno());					// 변경자핸드폰번호
		map.set("chgerTelno"				, rtnReq.getChgerTelno());					// 변경자전화번호
		map.set("chgerRtnMemo"				, rtnReq.getChgerRtnMemo());				// 변경메모사항
		map.set("reqGbn"					, rtnReq.getReqGbn());						// 신청구분
		map.set("ipAddress"					, rtnReq.getIpAddress());					// IP주소 (2021.05.13 추가)
		map.set("custNo"					, rtnReq.getCustNo());						// 고객번호 (2021.05.13 추가)
		
		// 2021.05.24 추가
		map.set("chgerZipcode"				, rtnReq.getChgerZipcode());				// 회수지우편번호
		map.set("chgerBaseAddr"				, rtnReq.getChgerBaseAddr());				// 회수지기본주소
		map.set("chgerDtlAddr"				, rtnReq.getChgerDtlAddr());				// 회수지상세주소
		map.set("wdGb"						, rtnReq.getWdGb());						// 회수구분

		map.set("pgTid"						, refundPreInfo.getString("pgTid"));		// PG거래ID
		map.set("payMeans"					, refundPreInfo.getString("payMeans"));		// 결제수단
		map.set("pgGb"						, refundPreInfo.getString("pgGb"));			// PG구분
		map.set("cashAuthNo"				, refundPreInfo.getString("cashAuthNo"));	// 현금영수증 승인번호
		map.set("regNo"						, userNo);	
		map.set("updNo"						, userNo);	
		
		
		
		// 4. 주문변경 DB 등록 (TB_ORDER_CHANGE, TB_ORDER_CHANGE_DETAIL, TB_REFUND)
		GagaMap result = coreOrderChangeService.returnRequest(map);
		int ordChgSq = result.getInt("ordChgSq");

		if (ordChgSq > 0) {
			// 반품 알림톡 관련 정보 조회
			OrderChange orderChange = coreOrderChangeService.getKakaoOrderReturnInfo(ordChgSq);

			try {
				// 반품 알림톡 발송
				if (StringUtils.isNotBlank(orderChange.getOrdPhnno())) {
					coreKakaotalkService.sendOrderReturnRequest(orderChange, userNo);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			try {
				// 반품 안내 메일 정보 조회
				GagaMap replaceInfo = coreOrderChangeService.getMailOrderReturnReplaceInfo(orderChange);

				// 반품 안내 메일 발송
				if (StringUtils.isNotBlank(replaceInfo.getString("ordEmail"))) {
					coreMailService.sendOrderReturn(replaceInfo, userNo);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return super.ok("성공");
	}
	
	/**
	 * 반품요청철회 (관리자)
	 * @param OrderChange - 주문취소신청정보
	 * @return
	 * @author jsh77b
	 * @since 2021. 01. 20
	 */
	@PostMapping("/rtnReqCancel")
	@ResponseBody
	public GagaResponse rtnReqCancel(@RequestBody OrderChange cnclReq) {
		
		if (cnclReq== null) {
			throw new IllegalStateException(message.getMessage("FAIL_1001"));
		}
		
		// 1. 세션회원조회
		int userNo = TsaSession.getInfo().getUserNo();
		
		GagaMap mav = new GagaMap();
		mav.set("ordNo"			, cnclReq.getOrdNo());
		mav.set("ordChgSq"		, cnclReq.getOrdChgSq());
		
		// 2.취소요청철회 
		mav = coreOrderChangeService.rtnReqCancel(mav, userNo);
		
		return super.ok("성공");
	}
	
	/**
	 * 주문 취소/반품 신청환불금액 계산
	 * @param Collection<Order>- 주문취소신청목록
	 * @return
	 * @author jsh77b
	 * @since 2020. 12. 29
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/cancel/refundAmt")
	@ResponseBody
	public GagaMap orderCancelRefundAmt(@RequestBody OrderChange cnclReq) {
		
		GagaMap mav = new GagaMap();
		
		int userNo = TsaSession.getInfo().getUserNo();
		cnclReq.setIpAddress(TsaSession.getIpAddress());
		cnclReq.setRegNo(userNo);

		// 1. 환불 사전 정보 조회
		GagaMap refundPreInfo = coreOrderChangeService.getRefundPreInfo(cnclReq);
		List<Order> cnclReqList = (List<Order>) refundPreInfo.get("cnclReqList");
		
		// 2. 환불금액정보 계산 & 조회
		mav = coreOrderRefundService.cnclRtnRefundAmt(cnclReqList);
		
		return mav;
	}
	
	/**
	 * 환불계좌목록
	 *
	 * @param ordNo - 주문번호
	 * @param custNo - 고객고유번호
	 * @return Collection<TsaOrder>
	 * @author jsshin
	 * @since 2020. 10. 16.
	 */
	@PostMapping("/refund/account/info/list")
	@ResponseBody
	public GagaMap getRefundAccountInfoList(@RequestBody Order order) {
		GagaMap mav = new GagaMap();

		Collection<Order> orderRfAccountInfo = coreOrderChangeService.getRefundAccount(order);
		mav.put("orderRfAccountInfo", orderRfAccountInfo);

		return mav;
	}
	
	/**
	 * 환불계좌등록 화면
	 *
	 * @param ordNo - 주문번호
	 * @param custNo - 고객고유번호
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2021. 01. 04.
	 */
	@GetMapping("/refund/account/create/form")
	public ModelAndView refundAccountCreateForm(@RequestParam(value = "ordNo") int ordNo) {
		ModelAndView mav = new ModelAndView();
		Order order = new Order();
		order.setOrdNo(ordNo);

		Collection<Order> orderInfoList 		= coreOrderService.getOrderInfoList(order);
		Collection<Order> orderRfAccountInfo 	= coreOrderChangeService.getRefundAccount(order);

		mav.addObject("bankList"				, rendererService.getCommonCodeList("G940"));
		mav.addObject("orderRfAccountInfo"		, orderRfAccountInfo);
		mav.addObject("orderInfoList"			, orderInfoList);

		mav.setViewName("order/RefundAccountRegistForm");
		
		return mav;
	}
	
	/**
	 * 환불계좌등록
	 *
	 * @param order - 환불계좌정보
	 * @return GagaResponse
	 * @author jsh77b
	 * @since 2021. 01. 04.
	 */
	@PostMapping("/account/save")
	@ResponseBody
	public GagaResponse saveRefundAccount(@RequestBody Order order) {
		
		int userNo = TsaSession.getInfo().getUserNo();
		order.setUpdNo(userNo);
		order.setRegNo(userNo);

		Boolean isValid 		= true;

		// @ 환불계좌인증
		CustAccount custAccount = new CustAccount();
		custAccount.setAccountNm(order.getAccountNm());
		custAccount.setBankCd(order.getBankCd());
		custAccount.setAccountNo(order.getAccountNo());
		
		GagaMap result = coreKcpService.checkAccount(custAccount);
		
		if ("0000".equals(result.get("resCd"))) {
			isValid = true;
		}
		
		if (isValid) {
			// 2021.06.09 비회원이 아닌경우만 고객 계좌에 등록
			if (order.getCustNo() > 0) {
				coreOrderChangeService.saveRefundAccount(order);
			}
		} else {
			throw new IllegalStateException("환불계좌정보가 맞지 않습니다!");
		}

		return super.ok(message.getMessage("SUCC_0001"));
	}

	/**
	 * 교환요청 화면
	 *
	 * @param ordNo - 주문번호
	 * @return ModelAndView
	 * @author card007
	 * @since 2021. 01. 14
	 */
	@GetMapping("/exchange/request/form")
	public ModelAndView exchangeRequestFrom(Order order) {
		ModelAndView mav = new ModelAndView();

		// 교환가능 주문상세상탭값 설정
		String[] ordDtlStatArr = new String[3];
		ordDtlStatArr[0] = TscConstants.OrderDetailStat.SHIPPING.value();
		ordDtlStatArr[1] = TscConstants.OrderDetailStat.SHIP_COMPLETE.value();
		ordDtlStatArr[2] = TscConstants.OrderDetailStat.DELIVERY_COMPLETE.value();
		order.setOrdDtlStatArr(ordDtlStatArr);

		order.setChgGb(TscConstants.OrderChangeGb.EXCHANGE.value());
		Collection<Order> cancelRequestTargetList = coreOrderChangeService.getCancelRequestTargetList(order);
		Collection<Order> orderChangeDetailList = coreOrderChangeService.getOrderChangeDetailList(order);
		Collection<Order> orderInfoList = coreOrderService.getOrderInfoList(order);

		String chgStat = "";
		if (order.getOrdChgSq() > 0) {
			Collection<Order> exchangeInfoList = coreOrderChangeService.getExchangeInfo(order);

			// 교환TO교환 처리 시 미착 수량 설정
			Collection<Order> exchangeDetailList;
			String ordChgGb = order.getOrdChgGb();
			if (StringUtils.isNotBlank(ordChgGb) && TscConstants.ChangeGb.EXCHANGE_TO_EXCHANGE.value().equals(ordChgGb.toUpperCase())) {
				exchangeDetailList = coreOrderChangeService.getNonArrivalInfo(order);
			} else {
				exchangeDetailList = orderChangeDetailList;
			}

			// 교환상세 정보 설정
			List<Integer> ordDtlNoList = new ArrayList<>();
			List<Integer> chgQtyList = new ArrayList<>();
			if (exchangeDetailList != null && exchangeDetailList.size() > 0) {
				for (Order tmp : exchangeDetailList) {
					if (tmp.getChgQty() > 0 && !ordDtlNoList.contains(tmp.getOrdDtlNo())) {
						ordDtlNoList.add(tmp.getOrdDtlNo());
						chgQtyList.add(tmp.getChgQty());

						if (StringUtils.isNotBlank(tmp.getChgStat())) {
							chgStat = tmp.getChgStat();
						}
					}
				}

				Collection<Order> tmpList = new ArrayList<>();
				for (Order tmp : cancelRequestTargetList) {
					if(ordDtlNoList.contains(tmp.getOrdDtlNo())) {
						int chgQty = chgQtyList.get(ordDtlNoList.indexOf(tmp.getOrdDtlNo()));
						tmp.setChgQty(chgQty);
						tmpList.add(tmp);
					}
				}

				cancelRequestTargetList = tmpList;
			}

			String chgOrdDtlStat = "";
			if (exchangeInfoList != null && exchangeInfoList.size() > 0) {
				chgOrdDtlStat = exchangeInfoList.iterator().next().getOrdDtlStat();
			}

			mav.addObject("exchangeInfoList"		, exchangeInfoList);											// 교환정보
			mav.addObject("ordChgGb"				, StringUtils.isBlank(ordChgGb) ? "" : ordChgGb.toUpperCase());	// 주문변경요쳥변경정보
			mav.addObject("chgOrdDtlStat"			, chgOrdDtlStat);												// 교환상품상세상태
			mav.addObject("recallExceptionInfo"		, coreOrderChangeService.getRecallExceptionInfo(order));		// 회수 예외 정보
		}

		mav.addObject("chgReasonList"				, rendererService.getAvailCommonCodeList("G689"));				// 교환사유
		mav.addObject("cancelRequestTargetList"		, cancelRequestTargetList);										// 교환요청대상 목록
		mav.addObject("orderChangeDetailList"		, orderChangeDetailList);										// 변경신청목록 (취소/반품/교환)
		mav.addObject("orderInfoList"				, orderInfoList);												// 주문정보
		mav.addObject("ordNo"						, order.getOrdNo());											// 주문번호
		mav.addObject("ordChgSq"					, order.getOrdChgSq());											// 주문변경번호
		mav.addObject("orderDelvAddrInfo"			, coreOrderService.getDeliveryAddrList(order));					// 배송정보
		mav.addObject("TelExcNoList"				, rendererService.getAvailCommonCodeList("G095"));				// 전화번호국번
		mav.addObject("PhnExcNoList"				, rendererService.getAvailCommonCodeList("G096"));				// (휴대전화)번호국번
		mav.addObject("chgStat"						, chgStat);														// 변경상태

		mav.setViewName("order/ExchangeRequestForm");

		return mav;
	}

	/**
	 * 교환신청 (관리자)
	 *
	 * @param Collection<OrderChange>
	 * @return
	 * @author card007
	 * @since 2021. 01. 22
	 */
	@PostMapping("/exchange/request")
	@ResponseBody
	public GagaMap orderExchangeRequest(@RequestBody OrderChange excReq) {
		GagaMap result = new GagaMap();
		result.set("status", GagaResponseStatus.FAIL.getCode());

		// 교환요청 데이터 확인
		if (excReq == null) {
			result.set("message", message.getMessage("FAIL_1001"));
			return result;
		}

		// 세션 회원번호 설정
		int userNo = TsaSession.getInfo().getUserNo();
		excReq.setUpdNo(userNo);
		excReq.setRegNo(userNo);

		// 교환처리
		result = coreOrderChangeService.exchReq(excReq);
		int ordChgSq = result.getInt("ordChgSq");

		if (ordChgSq > 0) {
			// 교환 알림톡 관련 정보 조회
			OrderChange orderChange = coreOrderChangeService.getKakaoOrderReturnInfo(ordChgSq);

			try {
				// 교환 알림톡 발송
				if (StringUtils.isNotBlank(orderChange.getOrdPhnno())) {
					coreKakaotalkService.sendOrderExchangeRequest(orderChange, userNo);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			try {
				// 교환 안내 메일 정보 조회
				GagaMap replaceInfo = coreOrderChangeService.getMailOrderExchangeReplaceInfo(orderChange);

				// 교환 안내 메일 발송
				if (StringUtils.isNotBlank(replaceInfo.getString("ordEmail"))) {
					coreMailService.sendOrderExchange(replaceInfo, userNo);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		// 처리 결과 코드에 따른 메세지 설정
		if (result.get("status").equals(GagaResponseStatus.SUCCESS.getCode())) {
			result.set("message", message.getMessage("SUCC_0004"));
		} else {
			result.set("message", message.getMessage("FAIL_0004"));
		}
		
		return result;
	}

	/**
	 * 교환철회 (관리자)
	 *
	 * @param Collection<OrderChange>
	 * @return
	 * @author card007
	 * @since 2021. 01. 22
	 */
	@PostMapping("/exchangeCancelRequest")
	@ResponseBody
	public GagaMap orderExchangeCancelRequest(@RequestBody OrderChange excReq) {
		GagaMap result = new GagaMap();
		result.set("status", GagaResponseStatus.FAIL.getCode());

		// 교환철회 요청 데이터 확인
		if (excReq == null) {
			result.set("message", message.getMessage("FAIL_1001"));
			return result;
		}

		// 세션 회원번호 설정
		int userNo = TsaSession.getInfo().getUserNo();
		excReq.setUpdNo(userNo);
		excReq.setRegNo(userNo);

		// IP주소 설정
		String ipAddress = TsaSession.getIpAddress();
		excReq.setIpAddress(ipAddress);

		// 교환철회 처리
		result = coreOrderChangeService.exchangeCancel(excReq);

		// 처리 결과 코드에 따른 메세지 설정
		if (result.get("status").equals(GagaResponseStatus.SUCCESS.getCode())) {
			result.set("message", message.getMessage("SUCC_0004"));
		} else {
			result.set("message", message.getMessage("FAIL_0004"));
		}

		return result;
	}

	/**
	 * 반품TO교환 처리
	 * 
	 * @param OrderChange
	 * @return GagaResponse
	 * @author card007
	 * @since 2021. 06. 17
	 */
	@PostMapping("/return/to/exchange")
	@ResponseBody
	public GagaResponse returnToExchange(@RequestBody OrderChange orderChange) {
		int userNo = TsaSession.getInfo().getUserNo();
		orderChange.setUserNo(userNo);
		orderChange.setRegNo(userNo);
		orderChange.setUpdNo(userNo);

		orderChangeService.returnToExchange(orderChange);

		return super.ok();
	}

	/**
	 * 반품TO반품 처리
	 *
	 * @param OrderChange
	 * @return GagaResponse
	 * @author card007
	 * @since 2021. 06. 24
	 */
	@PostMapping("/return/to/return")
	@ResponseBody
	public GagaResponse returnToReturn(@RequestBody OrderChange orderChange) {
		int userNo = TsaSession.getInfo().getUserNo();
		orderChange.setUserNo(userNo);
		orderChange.setRegNo(userNo);
		orderChange.setUpdNo(userNo);
		orderChange.setOrdChgGb(TscConstants.ChangeGb.RETURN_TO_RETURN.value());

		orderChangeService.returnToReturn(orderChange);

		return super.ok();
	}

	/**
	 * 교환TO교환 처리
	 *
	 * @param OrderChange
	 * @return GagaResponse
	 * @author card007
	 * @since 2021. 06. 24
	 */
	@PostMapping("/exchange/to/exchange")
	@ResponseBody
	public GagaResponse exchangeToExchange(@RequestBody OrderChange orderChange) {
		int userNo = TsaSession.getInfo().getUserNo();
		orderChange.setUserNo(userNo);
		orderChange.setRegNo(userNo);
		orderChange.setUpdNo(userNo);
		orderChange.setOrdChgGb(TscConstants.ChangeGb.EXCHANGE_TO_EXCHANGE.value());

		orderChangeService.exchangeToExchange(orderChange);

		return super.ok();
	}

	/**
	 * 회수지 정보 수정
	 *
	 * @param OrderChange
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 04. 13
	 */
	@PostMapping("/change/chger/addr")
	@ResponseBody
	public GagaMap changeChgerAddr(@RequestBody OrderChange orderChange) {
		GagaMap result = new GagaMap();
		result.set("status", GagaResponseStatus.SUCCESS.getCode());
		result.set("message", message.getMessage("DELV_0003"));

		try {
			orderChange.setUpdNo(TsaSession.getInfo().getUserNo());
			coreOrderChangeService.updateChgerAddr(orderChange);

			// TODO
			// WMS IF TABLE 내 정보 업데이트 처리 필요
		} catch (Exception e) {
			result.set("status", GagaResponseStatus.FAIL.getCode());
			result.set("message", message.getMessage("FAIL_0002"));
		}

		return result;
	}
}










