Просмотр исходного кода

Merge branch 'develop' into bin2107

# Conflicts:
#	src/main/java/com/style24/admin/biz/web/TsaMarketingController.java
bin2107 5 лет назад
Родитель
Сommit
5a5a376691
26 измененных файлов с 1136 добавлено и 560 удалено
  1. 36 0
      src/main/java/com/style24/admin/biz/dao/TsaCardPromotionDao.java
  2. 0 6
      src/main/java/com/style24/admin/biz/dao/TsaExchDao.java
  3. 0 6
      src/main/java/com/style24/admin/biz/dao/TsaPgDao.java
  4. 0 6
      src/main/java/com/style24/admin/biz/dao/TsaRefundDao.java
  5. 0 6
      src/main/java/com/style24/admin/biz/dao/TsaReturnDao.java
  6. 49 0
      src/main/java/com/style24/admin/biz/service/TsaCardPromotionService.java
  7. 11 0
      src/main/java/com/style24/admin/biz/service/TsaCouponService.java
  8. 3 3
      src/main/java/com/style24/admin/biz/web/TsaCustomerController.java
  9. 99 4
      src/main/java/com/style24/admin/biz/web/TsaMarketingController.java
  10. 1 20
      src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java
  11. 38 0
      src/main/java/com/style24/persistence/domain/CardPromotion.java
  12. 26 0
      src/main/java/com/style24/persistence/domain/CardPromotionCondition.java
  13. 20 0
      src/main/java/com/style24/persistence/domain/CardPromotionTarget.java
  14. 2 0
      src/main/java/com/style24/persistence/domain/CustCoupon.java
  15. 0 405
      src/main/java/com/style24/persistence/domain/Order.java
  16. 76 0
      src/main/java/com/style24/persistence/mybatis/shop/TsaCardPromotion.xml
  17. 22 22
      src/main/java/com/style24/persistence/mybatis/shop/TsaCoupon.xml
  18. 37 42
      src/main/java/com/style24/persistence/mybatis/shop/TsaCustomer.xml
  19. 2 3
      src/main/webapp/WEB-INF/views/customer/CellphoneChangePopupForm.html
  20. 19 7
      src/main/webapp/WEB-INF/views/customer/CustomerDetailForm.html
  21. 319 0
      src/main/webapp/WEB-INF/views/marketing/CardInterestForm.html
  22. 336 0
      src/main/webapp/WEB-INF/views/marketing/CouponIssuePopupForm.html
  23. 19 8
      src/main/webapp/WEB-INF/views/marketing/PointGrantPopupForm.html
  24. 15 16
      src/main/webapp/WEB-INF/views/order/ExchangeRequestForm.html
  25. 5 5
      src/main/webapp/WEB-INF/views/order/OrderDetailForm.html
  26. 1 1
      src/main/webapp/ux/css/admin.ui.css

+ 36 - 0
src/main/java/com/style24/admin/biz/dao/TsaCardPromotionDao.java

@@ -0,0 +1,36 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.CardPromotion;
+
+/**
+ * 카드프로모션 Dao
+ *
+ * @author eskim
+ * @since 2021. 01. 29
+ */
+@ShopDs
+public interface TsaCardPromotionDao {
+
+	/**
+	 * 카드무이자할부 목록  건수
+	 * @param cardPromotion
+	 * @return
+	 * @author eskim
+	 * @since 2021. 1. 29
+	 */
+	int getCardInterestListCount(CardPromotion cardPromotion);
+
+	/**
+	 * 카드무이자할부 목록
+	 * @param cardPromotion
+	 * @return
+	 * @author eskim
+	 * @since 2021. 1. 29
+	 */
+	Collection<CardPromotion> getCardInterestList(CardPromotion cardPromotion);
+
+
+}

+ 0 - 6
src/main/java/com/style24/admin/biz/dao/TsaExchDao.java

@@ -1,12 +1,6 @@
 package com.style24.admin.biz.dao;
 
-import java.util.Collection;
-
-import org.apache.ibatis.session.ResultHandler;
-
 import com.style24.core.support.annotation.ShopDs;
-import com.style24.persistence.domain.Order;
-import com.style24.persistence.domain.OrderChange;
 
 /**
  * 교환관리 Dao

+ 0 - 6
src/main/java/com/style24/admin/biz/dao/TsaPgDao.java

@@ -1,12 +1,6 @@
 package com.style24.admin.biz.dao;
 
-import java.util.Collection;
-
-import org.apache.ibatis.session.ResultHandler;
-
 import com.style24.core.support.annotation.ShopDs;
-import com.style24.persistence.domain.Order;
-import com.style24.persistence.domain.OrderChange;
 
 /**
  * 주문관리 Dao

+ 0 - 6
src/main/java/com/style24/admin/biz/dao/TsaRefundDao.java

@@ -1,12 +1,6 @@
 package com.style24.admin.biz.dao;
 
-import java.util.Collection;
-
-import org.apache.ibatis.session.ResultHandler;
-
 import com.style24.core.support.annotation.ShopDs;
-import com.style24.persistence.domain.Order;
-import com.style24.persistence.domain.OrderChange;
 
 /**
  * 주문관리 Dao

+ 0 - 6
src/main/java/com/style24/admin/biz/dao/TsaReturnDao.java

@@ -1,12 +1,6 @@
 package com.style24.admin.biz.dao;
 
-import java.util.Collection;
-
-import org.apache.ibatis.session.ResultHandler;
-
 import com.style24.core.support.annotation.ShopDs;
-import com.style24.persistence.domain.Order;
-import com.style24.persistence.domain.OrderChange;
 
 /**
  * 반품관리 Dao

+ 49 - 0
src/main/java/com/style24/admin/biz/service/TsaCardPromotionService.java

@@ -0,0 +1,49 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.style24.admin.biz.dao.TsaCardPromotionDao;
+import com.style24.persistence.domain.CardPromotion;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 카드프로모션 Service
+ *
+ * @author eskim
+ * @since 2021. 01. 29
+ */
+@Service
+@Slf4j
+public class TsaCardPromotionService {
+
+	@Autowired
+	private TsaCardPromotionDao cardPromotionDao;
+
+	/**
+	 * 카드무이자할부 목록 건ㄴ수
+	 * @param cardPromotion
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 29
+	 */
+	public int getCardInterestListCount(CardPromotion cardPromotion) {
+		return cardPromotionDao.getCardInterestListCount(cardPromotion);
+	}
+
+	/**
+	 * 카드무이자할부 목록
+	 * @param cardPromotion
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 29
+	 */
+	public Collection<CardPromotion> getCardInterestList(CardPromotion cardPromotion) {
+		return cardPromotionDao.getCardInterestList(cardPromotion);
+	}
+
+
+}

+ 11 - 0
src/main/java/com/style24/admin/biz/service/TsaCouponService.java

@@ -409,4 +409,15 @@ public class TsaCouponService {
 	public ArrayList<CustCoupon> getRandomCouponInfo(int cpnId) {
 		return couponDao.getRandomCouponInfo(cpnId);
 	}
+
+	/**
+	 * 회원상세 - 쿠폰발급
+	 * @param coupon - 쿠폰정보
+	 * @author jsshin
+	 * @since 2021. 1. 29
+	 */
+	@Transactional("shopTxnManager")
+	public void saveCouponIssue(CustCoupon coupon) {
+		couponDao.saveCouponCustPub(coupon);
+	}
 }

+ 3 - 3
src/main/java/com/style24/admin/biz/web/TsaCustomerController.java

@@ -10,7 +10,6 @@ import com.style24.admin.biz.service.TsaKakaoService;
 import com.style24.admin.biz.service.TsaSystemService;
 import com.style24.core.support.env.TscConstants;
 import com.style24.core.support.session.TscSession;
-import com.style24.core.support.util.CryptoUtils;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.CustContactHst;
 import com.style24.persistence.domain.CustGrade;
@@ -18,7 +17,7 @@ import com.style24.persistence.domain.Customer;
 import com.style24.persistence.domain.CustomerSearch;
 import com.style24.persistence.domain.Delivery;
 import com.style24.persistence.domain.GiftCard;
-import com.style24.persistence.domain.Order;
+
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
@@ -43,6 +42,7 @@ import com.style24.persistence.domain.Counsel;
 import lombok.extern.slf4j.Slf4j;
 
 import com.gagaframework.web.rest.server.GagaResponse;
+import com.style24.persistence.domain.Order;
 import com.style24.persistence.domain.Point;
 import com.style24.persistence.domain.Review;
 
@@ -372,7 +372,7 @@ public class TsaCustomerController extends TsaBaseController {
 		//mav.addObject("dcWayList", rendererService.getCommonCodeList("G240"));
 
 		// 쿠폰발행사유
-		mav.addObject("pubReasonList", rendererService.getCommonCodeList("G597"));
+		mav.addObject("pubReasonList", rendererService.getCommonCodeList("G068"));
 
 		// 포인트반영상태
 		mav.addObject("pntOccurGbList", rendererService.getCommonCodeList("G069"));

+ 99 - 4
src/main/java/com/style24/admin/biz/web/TsaMarketingController.java

@@ -3,7 +3,12 @@ package com.style24.admin.biz.web;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.style24.admin.biz.service.TsaSystemService;
+import com.style24.core.biz.service.TscPointService;
+import com.style24.core.support.env.TscConstants;
+import com.style24.persistence.domain.Point;
+import com.style24.persistence.domain.User;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
@@ -16,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 
+import com.style24.admin.biz.service.TsaCardPromotionService;
 import com.style24.admin.biz.service.TsaCommonService;
 import com.style24.admin.biz.service.TsaCouponService;
 import com.style24.admin.biz.service.TsaFreegiftPromotionService;
@@ -29,6 +35,7 @@ import com.style24.core.biz.service.TscPointService;
 import com.style24.core.support.env.TscConstants;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.TscPageRequest;
+import com.style24.persistence.domain.CardPromotion;
 import com.style24.persistence.domain.CommonCode;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.CouponRefval;
@@ -88,6 +95,9 @@ public class TsaMarketingController extends TsaBaseController {
 	@Autowired
 	private TscPointService corePointService;
 
+	@Autowired
+	private TsaCardPromotionService cardPromotionService;
+
 	/**
 	 * 상품평관리 화면
 	 * @return
@@ -908,6 +918,7 @@ public class TsaMarketingController extends TsaBaseController {
 		ModelAndView mav = new ModelAndView();
 
 		mav.addObject("elementCustNo", elementCustNo);
+
 		// 사이트 목록
 		mav.addObject("siteCdList", rendererService.getAvailCommonCodeList("G000"));
 
@@ -941,18 +952,102 @@ public class TsaMarketingController extends TsaBaseController {
 		point.setPntUploadStat(TscConstants.PntUploadStat.APPLY_COMPLETE.value());
 		point.setGvPntAmt(point.getPntAmt());
 		point.setRmPntAmt(point.getPntAmt());
-		String expBedt = point.getExpBeDt().replace("-","");
-		String time = "235959";
-		point.setExpBeDt(expBedt+time);
 		corePointService.saveCustomerPoint(point);
 		return super.ok(message.getMessage("SUCC_0004"));
 	}
 
+	/**
+	 * 쿠폰발급 팝업
+	 * @param elementCustNo - 고객일련번호
+	 * @return ModelAndView
+	 * @author jsshin
+	 * @since 2021. 1. 28
+	 */
+	@GetMapping("/coupon/issue/popup/form")
+	@ResponseBody
+	public ModelAndView couponIssuePopupForm(@RequestParam(value = "elementCustNo") String elementCustNo) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("elementCustNo", elementCustNo);
+
+		// 사이트 목록
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 사용가능고객구분 목록
+		mav.addObject("usableCustGbList", rendererService.getAvailCommonCodeList("G100"));
+
+		// 쿠폰유형 목록
+		mav.addObject("cpnTypeList", rendererService.getAvailCommonCodeList("G230"));
+
+		// 할인방식 목록
+		mav.addObject("dcWayList", rendererService.getAvailCommonCodeList("G240"));
+
+		// 쿠폰발행사유 조회
+		mav.addObject("cpnPubReasonList", rendererService.getCommonCodeList("G068"));
+
+		mav.setViewName("marketing/CouponIssuePopupForm");
+
+		return mav;
+	}
+
+	/**
+	 * 회원상세 - 쿠폰발급
+	 * @param custCoupon - 쿠폰정보
+	 * @return GagaResponse
+	 * @author jsshin
+	 * @since 2021. 1. 29
+	 */
+	@PostMapping("/coupon/issue/save")
+	@ResponseBody
+	public GagaResponse saveCouponIssue(@RequestBody CustCoupon custCoupon) {
+		Integer userNo = TsaSession.getInfo().getUserNo();
+		custCoupon.setRegNo(userNo);
+		custCoupon.setUpdNo(userNo);
+		couponService.saveCouponIssue(custCoupon);
+		return super.ok(message.getMessage("SUCC_0006"));
+	}
+
 	/**
 	 *   카드관련 작업 시작 - eskim
 	 */
 
+	/**
+	 * 카드무이자할부 관리
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2021. 1. 29
+	 */
+	@GetMapping("/card/interest/form")
+	@ResponseBody
+	public ModelAndView pointGrantPopupForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("marketing/CardInterestForm");
+		return mav;
+	}
+
+	/**
+	 * 카드무이자할부 목록
+	 * @param cardPromotion
+	 * @return
+	 * @author eskim
+	 * @since 2021. 1. 29
+	 */
+	@PostMapping("/card/interest/list")
+	@ResponseBody
+	public GagaMap getCardInterestList(@RequestBody CardPromotion cardPromotion) {
+
+		GagaMap result = new GagaMap();
 
+		cardPromotion.setPageable(new TscPageRequest(cardPromotion.getPageNo() - 1, cardPromotion.getPageSize()));
+		cardPromotion.getPageable().setTotalCount(cardPromotionService.getCardInterestListCount(cardPromotion));
+
+		result.set("pageing", cardPromotion);
+		result.set("cardPromotionList", cardPromotionService.getCardInterestList(cardPromotion));
+
+		return result;
+	}
 
 	/**
 	 *   카드관련 작업 종료 - eskim

+ 1 - 20
src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java

@@ -522,26 +522,7 @@ public class TsaOrderChangeController extends TsaBaseController {
 		
 		return result;
 	}
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
+
 	/**
 	 * 취소요청 (ADMIN, NAPY, 외부몰) (배치) (사용안함)
 	 * 

+ 38 - 0
src/main/java/com/style24/persistence/domain/CardPromotion.java

@@ -0,0 +1,38 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+import com.style24.persistence.TscPageRequest;
+
+import lombok.Data;
+
+/**
+ * 카드프로모션 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 29
+ */
+@SuppressWarnings("serial")
+@Data
+public class CardPromotion extends TscBaseDomain {
+
+	private Integer cardPrmtSq;	// 카드프로모션일련번호
+	private String prmtNm;	// 프로모션명
+	private String prmtStd;	// 프로모션시작일
+	private String prmtEdd;	// 프로모션종료일
+	private String prmtGb;	// 프로모션구분(A:할인, B:무이자)
+	private String dcGb;	// 행사구분(프로모션구분이 A:할인인 경우)
+	private String linkUrl;	// 연결URL
+	private String note;	// 안내
+	private String dispYn;	// 표시여부
+
+	// 검색조건
+	private String stDate;
+	private String edDate;
+	private String beforSkipFlag;
+
+	// Pagination
+	private TscPageRequest pageable;
+	private int pageNo = 1;
+	private int pageSize = 50;
+	private int pageUnit = 10;
+}

+ 26 - 0
src/main/java/com/style24/persistence/domain/CardPromotionCondition.java

@@ -0,0 +1,26 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 카드프로모션 행사조건 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 29
+ */
+@SuppressWarnings("serial")
+@Data
+public class CardPromotionCondition extends TscBaseDomain {
+
+	private Integer cardPrmtCdtSq;	// 카드프로모션행사조건일련번호
+	private int cardPrmtSq;	// 카드프로모션일련번호
+	private int minPayAmt;	// 최소결제금액
+	private String dcWay;	// 할인구분할인방식(공통코드G240, 프로모션구분이 A:할인인 경우)
+	private int dcVal;	// 할인값(프로모션구분이 A:할인인 경우, 할인방식이 금액이면 할인금액, 율이면 할인율)
+	private int maxDcAmt;	// 최대할인금액(프로모션구분이 A:할인인 경우)
+	private String minNoItrt;	// 최소무이자월수(프로모션구분이 B:무이자 인경우)
+	private String maxNoItrt;	// 최대무이자월수(프로모션구분이 B:무이자 인경우)
+
+}

+ 20 - 0
src/main/java/com/style24/persistence/domain/CardPromotionTarget.java

@@ -0,0 +1,20 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 카드프로모션 대상 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 29
+ */
+@SuppressWarnings("serial")
+@Data
+public class CardPromotionTarget extends TscBaseDomain {
+
+	private Integer cardPrmtCdtSq;	// 카드프로모션행사조건일련번호
+	private String prmtTargetCd;	// 포로모션대상카드(공통코드G941)
+
+}

+ 2 - 0
src/main/java/com/style24/persistence/domain/CustCoupon.java

@@ -29,4 +29,6 @@ public class CustCoupon extends TscBaseDomain {
 
     // 그리드 컬럼
     private String  custList;
+    private String  cpnNm;                  // 쿠폰명
+    private Integer ordNo;                  // 주문번호
 }

+ 0 - 405
src/main/java/com/style24/persistence/domain/Order.java

@@ -1,405 +0,0 @@
-package com.style24.persistence.domain;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.style24.persistence.TscBaseDomain;
-
-import com.style24.persistence.TscPageRequest;
-import lombok.Data;
-
-/**
- * 주문 Domain
- *
- * @author jsh77b
- * @since 2020. 11. 16
- */
-@SuppressWarnings("serial")
-@Data
-public class Order extends TscBaseDomain {
-	
-	// 주문마스터
-	private int ordNo;
-	private String mallGb;
-	private String mallGbNm;
-	private String ordDt;
-	private String payDt;
-	private int custNo;
-	private String ordNm;
-	private String ordTelno;
-	private String siteCd;
-	private String siteCdNm;
-	private int npayOrdNo;
-	private String frontGb;
-	private String frontGbNm;
-	private String extmallNm;
-
-	// 주문상세
-	private int ordDtlNo;
-	private String ordExchGb;
-	private String ordDtlStat;
-	private int orgOrdDtlNo;
-	private String supplyCompCd;
-	private String goodsCd;
-	private String formalGb;
-	private String formalGbNm;
-	private String goodsType;
-	private int listPrice;
-	private int currPrice;
-	private double dcRate;
-	private int optAddPrice;
-	private int ordQty;
-	private int ordAmt;
-	private int cnclRtnQty;
-	private int cnclRtnAmt;
-	private int cpn1CpnSq;
-	private int cpn1DcAmt;
-	private int tmtb1Sq;
-	private int tmtb1DcAmt;
-	private int tmtb2Sq;
-	private int tmtb2DcAmt;
-	private int goodsCpnSq;
-	private int goodsCpnDcAmt;
-	private int cartCpnSq;
-	private int cartCpnDcAmt;
-	
-	private int pntDcAmt;
-	private int prePntDcAmt;
-	private int savePntAmt;
-	
-	private int realOrdAmt;
-	private String venderId;
-	private String extmallId;
-	private String agentOrderId;
-	private String extmallOrderId;
-	private String changeableYn;
-	private String changeFeeFreeYn;
-	private String returnableYn;
-	private String returnFeeFreeYn;
-	
-	private String soldoutYn;
-	private String soldoutMemo;
-	private String soldoutRegNo;
-	private String soldoutRegDt;
-	private int delvAddrSq;
-	private String shotDelvYn;
-	private String giftPackYn;
-	
-	private String delvLocCd;
-	private String delvAssigngDt;
-	private String delvAddignStat;
-	private String dstrbtMemo;
-	private String delvStdt;
-	private String delvEddt;
-	
-	private String shipCompCd;
-	private String invoiceNo;
-	private String invoiceSendYn;
-	private String sellStoreCd;
-	private double sellFeeRate;
-	
-	private String afLinkCd;
-	private String ithrCd;
-	private String contentsLoc;
-	
-	private int planDtlsq;
-	private int socialSq;
-	
-	private String condition;
-	private String[] conditions = null;
-	
-	private String stDate;
-	private String edDate;
-	private String searchDateGb;
-	private String orderNm;
-	private int custId;
-	private String orderPhnno;
-	private String vendorId;
-	private String sizeCd;
-	private String goodsNm;
-	private String payMeans;
-	private String chgStat;
-	private String recipNm;
-	private String chgGb;
-	private String wdInvoiceSendYn;
-	
-	// 상품정보
-	private String imgPath1;
-	private String sysImgNm;
-	private String brandCd;
-	private String optCd1;
-	private String optCd2;
-	private String goodsTypeNm;
-	private String brandEnm;
-	private String itemCd;
-	private String goodsNum;
-	private String supplyGoodsCd;
-	private String optCd2s;
-	private int currStockQty;
-	private String currStockQtys;
-	
-	private int totDcAmt;
-	private String dateGbn;
-	private String mallCd;
-	private String search;
-	
-	/* Multi CheckBox 항목*/
-	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
-	private String[] multiBrand;
-
-	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
-	private String[] multiOrdStat;
-
-	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
-	private String[] multiOrdDtlStat;
-	
-	private int sumOrdAmt;
-	private int sumOrdCnclAmt;
-	private int sumRealPayAmt;
-	private int ordNoCnt;
-	private int sumOrdQty;
-	private int sumOrdCnclQty;
-	
-	private String excelFileNm;
-	
-	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
-	private int[] ordNoList;
-	
-	private String delYn;
-	private String recipPhnno;
-	private String recipTelno;
-	private String recipZipcode;
-	private String recipBaseAddr;
-	private String recipDtlAddr;
-	private String ordEmail;
-	private String delvMemo;
-	private String delvAddrEditYn;
-	private String exchGbNm;
-	
-	private String escrowYn;
-	private String payMeansNm;
-	private String cardNm;
-	private String vaBank;
-	private String pgTradeNo;
-	private String payStat;
-	private String payStatNm;
-	private int payAmt;
-	private String vaDeadLine;
-	
-	private String delvFeeGb;
-	private String delvFeeGbNm;
-	private int delvFee;
-	private String delvUsacYn;
-	private String delvUsacDt;
-	private int delvFeeSq;
-	
-	private String coundelClsf;
-	private String relGoodsCd;
-	private String questTitle;
-	private String questDt;
-	private String ansDt;
-	private int andNo;
-	
-	private int ordChgSq;
-	private String chgGbNm;
-	private String chgStatNm;
-	private String chgReason;
-	private String chgReasonNm;
-	private String chgMemo;
-	private String chgerNm;
-	private String chgerPhnno;
-	private String chgerZipcode;
-	private String chgerBaseAddr;
-	private String chgerDtlAddr;
-	private String wdInvoiceNo;
-	
-	private String supplyCompNm;
-	private String brandKnm;
-	private String ordDtlStatNm;	
-	private String ordPhnno;
-	
-	private String custGrade;
-	private String custGradeNm;
-	private String custGb;
-	private String custGbNm;
-	private String managedRsn;
-	private String managedRsnNm;
-	
-	private int itemQty;
-	private int itemPrice;
-	private String itemNm;
-	private int gfcdUseAmt;
-	
-	// Pagination
-	private TscPageRequest pageable;
-	private int pageNo = 1;
-	private int pageSize = 50;
-	private int pageUnit = 10;
-	
-	// 주문문의 1:1 응답 칼럼
-	private String counselClsfNm;
-	private String ansNo;
-	private String ansNm;
-	private String regNm;
-	private String updNm;
-	
-	// 주문메모칼럼
-	private int orderMemoSq;
-	private String memo;
-	private String orgFileNm;
-	private String sysFileNm;
-	
-	// 사은품칼럼
-	private int ordFreegiftSq;
-	private int freegiftSq;
-	private String freegiftNm;
-	private int freegiftValSq;
-	private int usePoint;
-	private int seq;
-	private String userNm;
-	
-	// 환불계좌칼럼
-	private String raBank;
-	private String raBankNm;
-	private String raNo;
-	private String raNm;
-	private String defaultYn;
-	
-	// 주문상세변경내역칼럼
-	private String userId;
-	private String updId;
-	private String shipCompNm;
-	private String shipCompId;
-	
-	// 주문쿠폰
-	private int cpnSq;
-	private int cpnId;
-	private int cpnDcAmt;
-	private String cpnType;
-	private String targetCd1;
-	private String targetCd2;
-	private String cpnNm;
-	private String dcWay;
-	private int dcPval;
-	private int dcMval;
-	private int dcAval;
-	
-	// 주문포인트
-	private int pntPrate;
-	private int pntMrate;
-	private int pntAmt;
-	private String occurGb;
-	private String occurGbNm;
-	private String occurDtlDesc;
-	
-	// 주문상품권
-	private String gfcdNm;
-	private String gfcdNo;
-	private int gfcdAmt;
-	private int chgGfcdAmt;
-	private int usGfcdAmt;
-	private int rmGfcdAmt;
-	
-	// 다다익선
-	private int tmtbSq;
-	private String tmtbNm;
-	private int tmtbDcAmt;
-	
-	// 상태변경
-	private String g20;
-	private String g30;
-	private String g40;
-	private String g50;
-	private String g55;
-	private String g60;
-	
-	// 취소요청
-	private String cncWait;
-	private int ordReqChgQty;
-	private int itemReqChgQty;
-	private int itemOrdPrice;
-	private int minOrdAmt;
-	private int orgDelvFee;
-	private String delvFeeCd;
-	private int ordCanChgQty;
-	private String allCanYn;
-	
-	private String addDelvFeeYn;
-	private int addDelvFee;
-	private int ordDtlItemSq;
-	
-	private int paySq;
-	private int refundAmt;
-	private int rfCpn1Amt;
-	private int rfTmtb1Amt;
-	private int rfTmtb2Amt;
-	private int rfGoodsCpnAmt;
-	private int rfCartCpnAmt;
-	private int rfPntAmt;
-	private int rfPrePntAmt;
-	private int rfGfcdUseAmt;
-
-	private int pgCpnAmt;
-	private int npayPntAmt;
-	private String payGb;
-	private String pgGb;
-	private String pgTid;
-	private String cardType;
-	private String cardKind;
-	private String cardBank;
-	private String cardMips;
-	private String cardPcableYn;
-	private String vaNo;
-	private String vaNm;
-	private String vaDeadline;
-	private String telecom;
-
-	private String accountNo;
-	private String accountNm;
-	private String bankCd;
-	private String bankNm;
-
-	private int realDelvAmt;
-	private int delvCpnSq;
-	private int delvCpnDcAmt;
-
-	private int chgQty;
-	private int rtnDelvFee;
-	private int excDelvFee;
-
-	private String[] ordDtlStatArr;
-	
-	// 교환요청
-	private String ordChgOpt;
-	private String rtnLocZipcode;
-	private String rtnLocBaseAddr;
-	private String rtnLocDtlAddr;
-	private String rtnLocTelno;
-	private String rtnLocNm;
-	private int exchangeOrdDtlNo;
-	private int exchangeOrdDtlItemSq;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

+ 76 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsaCardPromotion.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.style24.admin.biz.dao.TsaCardPromotionDao">
+
+	<!-- 목록 페이징 정보 -->
+	<sql id="getListPagingCondition_sql">
+		<choose>
+		<when test="pageable != null">
+		    ) A
+		)Z
+		WHERE RNUM BETWEEN  #{pageable.startRow} AND #{pageable.endRow}
+		</when>
+		<otherwise>
+		    ) A
+		)Z
+		</otherwise>
+		</choose>
+	</sql>
+	
+	<!-- 카드무이자할부 목록 건수-->
+	<select id="getCardInterestListCount" parameterType="CardPromotion" resultType="int">
+		/* TsaCardPromotionDao.getCardInterestListCount */
+		SELECT COUNT(1)
+		FROM TB_CARD_PROMOTION 
+		WHERE PRMT_GB = #{prmtGb}
+		<if test="stDate != null and stDate != ''">
+		AND PRMT_EDD >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		</if>
+		<if test="edDate != null and edDate != ''">
+		<![CDATA[
+		AND PRMT_STD < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		]]>
+		</if>
+		<if test='beforSkipFlag != null and beforSkipFlag == "Y"'>
+		AND PRMT_EDD >= NOW() 
+		</if>
+	</select>
+	
+	<!-- 카드무이자할부 목록 -->
+	<select id="getCardInterestList" parameterType="CardPromotion" resultType="CardPromotion">
+		/* TsaCardPromotionDao.getCardInterestList */
+		SELECT Z.*
+		FROM (
+		    SELECT A.*, @rownum := @rownum + 1 AS RNUM 
+		    FROM (
+		        SELECT CARD_PRMT_SQ
+		             , PRMT_NM
+		             , DATE_FORMAT(PRMT_STD, '%Y%m%d%H%i%S') AS PRMT_STD
+		             , DATE_FORMAT(PRMT_EDD, '%Y%m%d%H%i%S') AS PRMT_EDD
+		             , PRMT_GB
+		             , DC_GB
+		             , LINK_URL
+		             , NOTE
+		             , DISP_YN
+		             , FN_GET_USER_NM(REG_NO) AS REG_NM
+		             , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S') AS REG_DT
+		             , FN_GET_USER_NM(UPD_NO) AS UPD_NM
+		             , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S') AS UPD_DT
+		        FROM TB_CARD_PROMOTION 
+		        WHERE PRMT_GB = #{prmtGb}
+		        <if test="stDate != null and stDate != ''">
+		        AND PRMT_EDD >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		        </if>
+		        <if test="edDate != null and edDate != ''">
+		        <![CDATA[
+		        AND PRMT_STD < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		        ]]>
+		        </if>
+		        <if test='beforSkipFlag != null and beforSkipFlag == "Y"'>
+		        AND PRMT_EDD >= NOW() 
+		        </if>
+		<include refid="getListPagingCondition_sql"/>
+	</select>
+	
+	
+</mapper>

+ 22 - 22
src/main/java/com/style24/persistence/mybatis/shop/TsaCoupon.xml

@@ -543,29 +543,29 @@
 	<insert id="saveCouponCustPub" parameterType="CustCoupon">
 		/* TsaCoupon.saveCouponCustPub */
 		INSERT INTO TB_CUST_COUPON (
-			CUST_NO
-		  , CPN_ID
-		  , AVAIL_STDT
-		  , AVAIL_EDDT
-		  , PUB_REASON
-		  , PUB_REASON_DTL
-          , END_ALIM_SEND_YN
-          , REG_NO
-          , REG_DT
-          , UPD_NO
-          , UPD_DT
+		       CUST_NO
+		     , CPN_ID
+		     , AVAIL_STDT
+		     , AVAIL_EDDT
+		     , PUB_REASON
+		     , PUB_REASON_DTL
+		     , END_ALIM_SEND_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
 		) VALUES (
-		    #{custNo}
-		  , #{cpnId}
-		  , DATE_FORMAT(#{availStdt} , '%Y-%m-%d')
-		  , DATE_FORMAT(#{availEddt} , '%Y-%m-%d')
-		  , #{pubReason}
-		  , #{pubReasonDtl}
-		  , #{endAlimSendYn}
-		  , #{regNo}
-		  , now()
-		  , #{updNo}
-		  , now()
+		       #{custNo}
+		     , #{cpnId}
+		     , DATE_FORMAT(#{availStdt} , '%Y%m%d%H%i%S')
+		     , DATE_FORMAT(#{availEddt} , '%Y%m%d%H%i%S')
+		     , #{pubReason}
+		     , #{pubReasonDtl}
+		     , #{endAlimSendYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
 		)
 	</insert>
 

+ 37 - 42
src/main/java/com/style24/persistence/mybatis/shop/TsaCustomer.xml

@@ -307,7 +307,7 @@
 	</update>
 
 	<!--회원 쿠폰내역  -->
-	<select id="getCustomerCouponList" parameterType="Integer" resultType="Coupon">
+	<select id="getCustomerCouponList" parameterType="Integer" resultType="CustCoupon">
 		/* TsaCustomer.getCustomerCounponList */
 		WITH TAB1 AS (
 		              SELECT O.ORD_NO             AS ORD_NO
@@ -349,11 +349,12 @@
 		     , DATE_FORMAT(CC.AVAIL_EDDT, '%Y%m%d%H%i%S')            AS AVAIL_EDDT
 		     , CC.PUB_REASON
 		     , CC.PUB_REASON_DTL
+		     , CC.END_ALIM_SEND_YN
+		     , E.ORD_NO
 		     , DATE_FORMAT(CC.USED_DT, '%Y%m%d%H%i%S')               AS USED_DT
 		     , FN_GET_USER_NM(CC.REG_NO)                             AS REG_NM
 		     , FN_GET_USER_NM(CC.UPD_NO)                             AS USER_NM
 		     , DATE_FORMAT(CC.REG_DT, '%Y%m%d%H%i%S')                AS REG_DT
-		     , E.ORD_NO
 		FROM   TB_COUPON C
 		INNER JOIN
 		       TB_CUST_COUPON CC
@@ -427,46 +428,40 @@
 	<!--회원 포인트내역  -->
 	<select id="getCustomerPointList" parameterType="Integer" resultType="Point">
 		/* TsaCustomer.getCustomerPointList */
-		SELECT CC.*
-		FROM (
-		      SELECT DATE_FORMAT(CASE WHEN CPH.PNT_UPLOAD_STAT = 'G070_30'
-		                              THEN CPH.PNT_UPLOAD_DT
-		                          ELSE CPH.REG_DT END, '%Y-%m-%d' ) AS DT
-		           , CPH.PNT_HST_SQ
-		           , C.CUST_ID
-		           , C.CUST_NO
-		           , C.SITE_CD
-		           , CPH.OCCUR_GB
-		           , CPH.OCCUR_DTL_DESC
-		           , CPH.PNT_AMT
-		           , CPH.ORD_DTL_NO
-		           , CPH.REVIEW_SQ
-		           , DATE_FORMAT(CPH.SWITCH_DUE_DT, '%Y%m%d%H%i%S')  AS SWITCH_DUE_DT
-		           , CPH.PNT_UPLOAD_STAT
-		           , DATE_FORMAT(CPH.PNT_UPLOAD_DT, '%Y%m%d%H%i%S')  AS PNT_UPLOAD_DT
-		           , IFNULL(FN_GET_USER_NM(CPH.REG_NO), CPH.REG_NO)  AS REG_NM
-		           , DATE_FORMAT(CPH.REG_DT, '%Y%m%d%H%i%S')         AS REG_DT
-		           , IFNULL(FN_GET_USER_NM(CPH.UPD_NO), CPH.UPD_NO)  AS UPD_NM
-		           , DATE_FORMAT(CPH.UPD_DT, '%Y%m%d%H%i%S')         AS UPD_DT
-		           , DATE_FORMAT((
-		                          SELECT MAX(CP.EXP_BE_DT) AS EXP_BE_DT
-		                          FROM   TB_CUST_POINT CP
-		                          WHERE  CP.CUST_PNT_SQ = CPH.CUST_PNT_SQ
-			                      AND    CP.CUST_NO = CPH.CUST_NO
-		              ), '%Y%m%d%H%i%S') AS EXP_BE_DT
-		           , DATE_FORMAT((
-		                          SELECT MAX(CP.EXP_CMP_DT) AS EXP_CMP_DT
-		                          FROM   TB_CUST_POINT CP
-		                          WHERE  CP.CUST_PNT_SQ = CPH.CUST_PNT_SQ
-		                          AND    CP.CUST_NO = CPH.CUST_NO
-		              ), '%Y%m%d%H%i%S') AS EXP_CMP_DT
-		      FROM   TB_CUSTOMER C
-		      INNER JOIN
-		             TB_CUST_POINT_HST CPH
-		      ON     C.CUST_NO = CPH.CUST_NO
-		      WHERE  C.CUST_NO = #{custNo}
-		     ) CC
-		ORDER BY CC.DT DESC
+		SELECT  CPH.PNT_HST_SQ
+		      , C.CUST_ID
+		      , C.CUST_NO
+		      , C.SITE_CD
+		      , CPH.OCCUR_GB
+		      , CPH.OCCUR_DTL_DESC
+		      , CPH.PNT_AMT
+		      , CPH.ORD_DTL_NO
+		      , CPH.REVIEW_SQ
+		      , DATE_FORMAT(CPH.SWITCH_DUE_DT, '%Y%m%d%H%i%S')  AS SWITCH_DUE_DT
+		      , CPH.PNT_UPLOAD_STAT
+		      , DATE_FORMAT(CPH.PNT_UPLOAD_DT, '%Y%m%d%H%i%S')  AS PNT_UPLOAD_DT
+		      , IFNULL(FN_GET_USER_NM(CPH.REG_NO), CPH.REG_NO)  AS REG_NM
+		      , DATE_FORMAT(CPH.REG_DT, '%Y%m%d%H%i%S')         AS REG_DT
+		      , IFNULL(FN_GET_USER_NM(CPH.UPD_NO), CPH.UPD_NO)  AS UPD_NM
+		      , DATE_FORMAT(CPH.UPD_DT, '%Y%m%d%H%i%S')         AS UPD_DT
+		      , DATE_FORMAT((
+		                     SELECT MAX(CP.EXP_BE_DT) AS EXP_BE_DT
+		                     FROM   TB_CUST_POINT CP
+		                     WHERE  CP.CUST_PNT_SQ = CPH.CUST_PNT_SQ
+		                     AND    CP.CUST_NO = CPH.CUST_NO
+		         ), '%Y%m%d%H%i%S') AS EXP_BE_DT
+		      , DATE_FORMAT((
+		                     SELECT MAX(CP.EXP_CMP_DT) AS EXP_CMP_DT
+		                     FROM   TB_CUST_POINT CP
+		                     WHERE  CP.CUST_PNT_SQ = CPH.CUST_PNT_SQ
+		                     AND    CP.CUST_NO = CPH.CUST_NO
+		         ), '%Y%m%d%H%i%S') AS EXP_CMP_DT
+		FROM    TB_CUSTOMER C
+		INNER JOIN
+		        TB_CUST_POINT_HST CPH
+		ON      C.CUST_NO = CPH.CUST_NO
+		WHERE   C.CUST_NO = #{custNo}
+		ORDER BY CPH.REG_DT DESC
 	</select>
 
 	<!-- 회원 상품권이력 -->

+ 2 - 3
src/main/webapp/WEB-INF/views/customer/CellphoneChangePopupForm.html

@@ -18,7 +18,7 @@
 	<div class="panelStyle">
 		<!-- TITLE -->
 		<div class="panelTitle">
-			<strong >휴대전화번호변경팝업</strong>
+			<strong >휴대전화 번호 변경팝업</strong>
 			<button type="button" class="close" onclick="uifnPopupClose('popupCellphoneForm')"><em class="fa fa-times"></em></button>
 		</div>
 		<!-- //TITLE -->
@@ -59,7 +59,7 @@
 			<ul class="panelBar">
 				<li class="right">
 					<button type="button" id="btnSendCustCrtfdNo" class="btn btn-success btn-lg" >인증번호발송</button>
-					<button type="button" id="btnCustCertNo" class="btn btn-success btn-lg" style="display: none">인증번호확인</button>
+					<button type="button" id="btnCustCertNo" class="btn btn-success btn-lg" style="display: none">확인(번호변경)</button>
 				</li>
 			</ul>
 		</div>
@@ -71,7 +71,6 @@
 	const elementCellPhnno = [[${elementCellPhnno}]];
 	const elementCustNo = [[${elementCustNo}]];
 
-
 	// 인증번호 전송
 	$('#btnSendCustCrtfdNo').on('click', function () {
 		//휴대폰번호

+ 19 - 7
src/main/webapp/WEB-INF/views/customer/CustomerDetailForm.html

@@ -96,14 +96,14 @@
 										<td class="dashR">
 											<select id="custGb" name="custGb">
 												<option th:if="${custGbList}" th:each="oneData, status : ${custGbList}" th:value="${oneData.cd}"
-														th:text="|${oneData.cdNm}|"></option>
+														th:text="${'[' + oneData.cd + '] '+oneData.cdNm}"></option>
 											</select>
 										</td>
 										<th class="dashR">회원등급<em class="required" title="필수"></em></th>
 										<td class="dashR">
 											<select id="custGrade" name="custGrade">
 												<option th:if="${custGradeList}" th:each="oneData, status : ${custGradeList}" th:value="${oneData.cd}"
-														th:text="|${oneData.cdNm}|"></option>
+														th:text="${'[' + oneData.cd + '] '+oneData.cdNm}"></option>
 											</select>
 										</td>
 									</tr>
@@ -113,7 +113,7 @@
 											<select id="managedRsn" name="managedRsn">
 												<option value="">일반</option>
 												<option th:if="${managedRsnList}" th:each="oneData, status : ${managedRsnList}" th:value="${oneData.cd}"
-														th:text="|${oneData.cdNm}|"></option>
+														th:text="${'[' + oneData.cd + '] '+oneData.cdNm}"></option>
 											</select>
 											<span class="infoTxt cRed h5" id="managedRsnDp" name="managedRsnDp"></span>
 										</td>
@@ -644,7 +644,7 @@
 
 	//쿠폰내역 그리드
 	const columnCouponDefs = [
-		{width: 40, minWidth: 40, cellClass: 'text-center', pinned: 'left', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		// {width: 40, minWidth: 40, cellClass: 'text-center', pinned: 'left', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
 		{headerName: "회원쿠폰SQ", field: "custCpnSq", width: 100, cellClass: 'text-center', hide: true},
 		{headerName: "쿠폰ID", field: "cpnId", width: 100, cellClass: 'text-center'},
 		{headerName: "쿠폰명", field: "cpnNm", width: 300, cellClass: 'text-center'},
@@ -674,7 +674,8 @@
 			}
 		},
 		{headerName: "쿠폰발행 상세사유", field: "pubReasonDtl", width: 300, cellClass: 'text-center'},
-		{headerName: "등록자", field: "regNo", width: 100, cellClass: 'text-center'},
+		{headerName: "만료알림발송여부", field: "endAlimSendYn", width: 150, cellClass: 'text-center'},
+		{headerName: "등록자", field: "regNm", width: 100, cellClass: 'text-center'},
 		{
 			headerName: "등록일시", field: "regDt", width: 150, cellClass: 'text-center',
 			cellRenderer: function (params) {
@@ -892,7 +893,16 @@
 	let gridAddrOptions = gagaAgGrid.getGridOptions(columnAddrDefs);		//주소정보 그리드
 	let gridContactOptions = gagaAgGrid.getGridOptions(columnContactDefs);	//회원접촉이력 그리드
 
-	gridCouponOptions.rowSelection = 'multiple';
+	gridOrderOptions.suppressRowClickSelection = true;
+	gridCounselOptions.suppressRowClickSelection = true;
+	gridGoodsQnaOptions.suppressRowClickSelection = true;
+	gridCouponOptions.suppressRowClickSelection = true;
+	gridPointOptions.suppressRowClickSelection = true;
+	gridGiftCardOptions.suppressRowClickSelection = true;
+	gridReviewOptions.suppressRowClickSelection = true;
+	gridGradeOptions.suppressRowClickSelection = true;
+	gridAddrOptions.suppressRowClickSelection = true;
+	gridContactOptions.suppressRowClickSelection = true;
 
 	// 기본정보 - 비밀번호 초기화 버튼
 	$('#btnResetPassword').on('click', function () {
@@ -1098,7 +1108,9 @@
 
 	// 쿠폰발급 버튼
 	$('#btnCustCouponCreate').on('click', function () {
-		cfnCpnPubForCustPopup();
+		let elementCustNo ='#custInfoForm input[name=custNo]';
+		const actionUrl = '/marketing/coupon/issue/popup/form?elementCustNo=' + encodeURIComponent(elementCustNo);
+		cfnOpenModalPopup(actionUrl, 'popupCouponIssue');
 	});
 
 

+ 319 - 0
src/main/webapp/WEB-INF/views/marketing/CardInterestForm.html

@@ -0,0 +1,319 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : CardInterestForm.html
+ * @desc    : 카드무이자할부관리
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.01.29   eskim       최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<form id="cardInterestListForm" name="cardInterestListForm" action="#" th:action="@{'/marketing/card/interest/list'}">
+		<input type="hidden" id="prmtGb" name="prmtGb" value="B" /> <!-- 무이자 -->
+ 		<!-- 패널 영역1 -->
+		<div class="panelStyle" >
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col width="10%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>구분<em class="required" title="필수"></em></th>
+						<td>
+							<label class="rdoBtn"><input type="radio" name="sizeGb"  value="1"  checked/>프로모션ID</label>
+							<label class="rdoBtn"><input type="radio" name="sizeGb"  value="2"/>프로모션명</label>
+						</td>
+					</tr>
+					<tr>
+						<th>기간<em class="required" title="필수"></em></th>
+						<td id="sellTerms"></td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
+					</li>
+				</ul>	
+			</div>
+			<!-- //검색조건 영역 -->
+		</div>
+		<!-- 패널 영역1 -->
+		<div class="panelStyle">
+			<!-- 검색결과 영역 -->
+			<!-- 상단버튼 영역  -->
+			<ul class="panelBar">
+				<li>
+					<button type="button" class="btn btn-danger btn-lg" id="btnCardPromotionDispUpdate">선택비노출</button>
+					<button type="button" class="btn btn-danger btn-lg" id="btnCardPromotionDelete">선택삭제</button>
+				</li>
+				<li class="right">
+					<button type="button" class="btn btn-primary btn-lg" id="btnCardPromotionSave">등록</button>
+					검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+					
+					쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+					<select id="pageSize" name="pageSize">
+						<option value="50" selected="selected">50개씩 보기</option>
+						<option value="100">100개씩 보기</option>
+						<option value="500">500개씩 보기</option>
+						<option value="1000">1000개씩 보기</option>
+					</select>
+					<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+				</li>
+			</ul>
+			<!-- //상단버튼 영역  -->
+			<div id="gridList" style="width: 100%; height: 550px;" class="ag-theme-balham"></div>
+			<ul class="panelBar">
+				<li class="center">
+					<div class="tablePaging" id="cardListPagination"></div>
+				</li>
+			</ul>
+			<!-- 검색결과 영역 -->
+		</div>
+		</form>
+		<!-- //패널 영역2 -->
+	</div>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 60, cellClass: 'text-center',
+			valueGetter: function(params) { return cfnGridNumner('cardInterestListForm',params.node.rowIndex, 'A');}
+		},
+		{headerName: "프로모션ID", field: "cardPrmtSq", width: 130, cellClass: 'text-center'},
+		{headerName: "프로모션명", field: "prmtNm", width: 140, cellClass: 'text-center'
+			,cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}
+		},
+		{headerName: "노출여부", field: "dispYn", width: 180, cellClass: 'text-center'},
+		{headerName: "시작일", field: "prmtStd", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "종료일", field: "prmtEdd", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "수정자", field: "updNm" , width: 100, cellClass: 'text-center'},
+		{headerName: "수정일시", field: "updDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록자", field: "regNm", width: 100, cellClass: 'text-center'},
+		{headerName: "등록일시", field: "regDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		}
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var goodsCd = event.data.goodsCd;
+		if (event.colDef.field == "prmtNm"){
+			
+		}
+	}
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		fnInit();
+	});
+	
+	var fnInit = function(){
+		$('#cardInterestListForm')[0].reset();
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		$("#cardInterestListForm input[name=pageNo]").val('1');
+		fnCardPromotionListSearch();
+	});
+
+	// 조회
+	var fnCardPromotionListSearch = function() {
+		
+		if(!fnConditionCheck()) return;
+		
+		gagaPaging.init('cardInterestListForm', fnSearchCallBack, 'cardListPagination', $('#cardInterestListForm').find('#pageSize').val());
+		gagaPaging.load($("#cardInterestListForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#cardInterestListForm';
+		var form = document.cardInterestListForm;
+
+		var searchFlag = false;
+		var cnt = 0;
+		
+		for (i = 0; i < form.elements.length; i++ ) {
+			var el = form.elements[i];
+			if ($(el).prop("type") == "text" || $(el).prop("type") == "textarea" || ($(el).prop("type") == "select-one" && 
+					el.name != "search" && el.name != "pageSize" && el.name != "beforSkipFlag")) {
+				if (!(el.value == null || el.value == "")) {
+					cnt++;
+				}
+			}
+		}
+		
+		if(cnt > 0) searchFlag = true;
+		
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		
+		var fromDate = $('#cardInterestListForm input[name=stDate]').val();
+		var toDate = $('#cardInterestListForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#cardInterestListForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alert("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#cardInterestListForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		}
+
+		return true;
+	}
+	
+	var fnSearchCallBack = function(result){
+
+		$('#cardInterestListForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#cardInterestListForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#cardInterestListForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#cardInterestListForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.cardPromotionList);
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+	
+	//페이징 
+	$('#cardInterestListForm select[name=pageSize]').on('change', function() {
+		$("#cardInterestListForm input[name=pageNo]").val('1');
+		fnCardPromotionListSearch($("#cardInterestListForm input[name=searchGb]").val());
+	});
+	
+	//카드 무이자 팝업
+	$('#btnCardPromotionSave').click(function(e) {
+		var actionUrl = "/marketing/card/interest/popup/form";
+		cfnOpenModalPopup(actionUrl, 'popupCardInterest'); 
+	});
+	
+	//카드 프로모션 삭제
+	$('#btnCardPromotionDelete').click(function(e) {
+		//상품선택여부 확인처리 추가
+		var selectedData = gridOptions.api.getSelectedRows();
+
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return false;
+		}
+		
+		var arrGoodsCd = [];
+		var arrGoodsTnmResSq = [];
+		var chkFlag = false;
+		//selectedData = gagaAgGrid.getAllRowData(gridOptions);
+		$.each(selectedData, function(idx, item) {
+			
+			if (gagajf.isNull(item.goodsTnmResSq) || item.goodsTnmResSq == "0"){
+				chkFlag = true;
+				mcxDialog.alert(item.goodsCd +"상품은 상품타이틀이 예약된 상품이 아닙니다.");
+				return false;
+			}
+			
+			var toDateStr = new Date().format("YYYYMMDDHHmmss");
+			if (toDateStr > item.applyEddt){
+				chkFlag = true;
+				mcxDialog.alertC("종료된 예약 상품은 삭제할 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsRsvtTnmForm input[name=applyEdYMD]').focus();
+					}
+				});
+				return false;
+			}
+		
+			arrGoodsCd.push(item.goodsCd);
+			arrGoodsTnmResSq.push(item.goodsTnmResSq);
+		});
+
+		if (chkFlag){
+			return;
+		}
+		
+		mcxDialog.confirm('삭제하시겠습니까?',  {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {arrGoodsCd : arrGoodsCd
+						,arrGoodsTnmResSq : arrGoodsTnmResSq
+			};
+			
+			var jsonData = JSON.stringify(data);
+			gagajf.ajaxJsonSubmit('/goods/title/reserve/delete', jsonData, fnCardPromotionDeleteCollBack);
+			}
+		});
+	});
+	
+	var fnCardPromotionDeleteCollBack = function(){
+		//fnCardPromotionListSearch($();
+	}
+	
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '기간');
+		var chkBeforSkipFlag = '&nbsp;&nbsp;<label class="chkBox"><input type="checkbox" name="beforSkipFlag" value="Y" >이전데이터 제외</label>';
+		$("#cardInterestListForm").find('#sellTerms').append(chkBeforSkipFlag);
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+ 	
+</html>

+ 336 - 0
src/main/webapp/WEB-INF/views/marketing/CouponIssuePopupForm.html

@@ -0,0 +1,336 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : CouponIssuePopupForm.html
+ * @desc    : 쿠폰발급 팝업 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.01.28   jsshin     최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="960" data-height="900" >
+	<div id="panel" class="panelStyle">
+		<!-- TITLE -->
+		<div class="panelTitle">
+			<strong>쿠폰 발급</strong>
+			<button type="button" class="close" onclick="uifnPopupClose('popupCouponIssue');"><em class="fa fa-times"></em></button>
+		</div>
+		<!-- //TITLE -->
+
+		<!-- CONTENT -->
+		<div class="panelContent">
+			<form id="searchCouponForm" name="searchCouponForm" action="#" th:action="@{'/marketing/coupon/retrieve/list'}" th:method="post">
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:40%;"/>
+						<col style="width:10%;"/>
+						<col style="width:40%;"/>
+					</colgroup>
+					<tbody>
+						<tr>
+							<th>사이트<em class="required" title="필수"></em></th>
+							<td>
+								<select name="siteCd" required="required">
+									<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+								</select>
+							</td>
+							<th>쿠폰유형</th>
+							<td>
+								<select name="cpnType">
+									<option value="">[전체]</option>
+									<option th:if="${cpnTypeList}" th:each="oneData, status : ${cpnTypeList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+								</select>
+							</td>
+						</tr>
+						<tr>
+							<th>쿠폰ID</th>
+							<td>
+								<input type="text" name="cpnId" maxlength="20"/>
+							</td>
+							<th>쿠폰명</th>
+							<td>
+								<input type="text" name="cpnNm" maxlength="50"/>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearchCouponRetrieve">조회</button>
+					</li>
+				</ul>
+			</form>
+			<!-- 리스트 영역 -->
+			<div id="gridCouponList" style="width: 100%; height: 420px;" class="ag-theme-balham"></div>
+			<!-- //리스트 영역 -->
+			<form id="couponIssueForm" name="couponIssueForm">
+				<input type="hidden" name="cpnId"/>
+				<input type="hidden" name="pdGb"/>
+				<input type="hidden" name="custNo"/>
+				<table class="frmStyle" aria-describedby="발급내용">
+					<colgroup>
+						<col style="width: 10%"/>
+						<col style="width: 40%"/>
+						<col style="width: 10%"/>
+						<col style="width: 40%"/>
+					</colgroup>
+					<tr id="availTermsTr">
+						<th class="availTerm">유효기간시작일시<em class="required" title="필수"></em></th>
+						<td class="availTerm">
+							<input type="text" name="availStdt" class="schDate w100" data-valid-name="유효기간시작일시"/>
+							<select name="availStHH" data-valid-name="유효기간시작(시)"required="required">
+								<th:block th:each="num, index : ${#numbers.sequence(0, 23)}">
+									<option th:value="${#numbers.formatInteger(num, 2)}" th:text="|${#numbers.formatInteger(num, 2)}시|">시간</option>
+								</th:block>
+							</select>
+							<select name="availStMM" data-valid-name="유효기간시작(분)" required="required">
+								<th:block th:each="num, index : ${#numbers.sequence(0, 59)}">
+									<option th:value="${#numbers.formatInteger(num, 2)}" th:text="|${#numbers.formatInteger(num, 2)}분|">분</option>
+								</th:block>
+							</select>
+						</td>
+
+						<th class="availTerm">유효기간종료일시<em class="required" title="필수"></em></th>
+						<td class="availTerm">
+							<input type="text" name="availEddt" class="schDate w100" data-valid-name="유효기간종료일시"/>
+							<select name="availEdHH" data-valid-name="유효기간종료(시)">
+								<th:block th:each="num, index  : ${#numbers.sequence(0, 23)}">
+									<option th:value="${#numbers.formatInteger(num, 2)}" th:text="|${#numbers.formatInteger(num, 2)}시|">시간</option>
+								</th:block>
+							</select>
+							<select name="availEdMM" data-valid-name="유효기간종료(분)">
+								<th:block th:each="num: ${#numbers.sequence(0, 59)}">
+									<option th:value="${#numbers.formatInteger(num, 2)}" th:text="|${#numbers.formatInteger(num, 2)}분|">분</option>
+								</th:block>
+							</select>
+						</td>
+					</tr>
+					<tr id="availDaysTr" style="display:none;">
+						<th>유효기간(일)</th>
+						<td><input type="text" name="availDays" data-valid-type="integer"></td>
+					</tr>
+					<tr>
+						<th>발급사유</th>
+						<td>
+							<select name="pubReason" data-valid-name="발급사유" required>
+								<option th:if="${cpnPubReasonList}" th:each="oneData, status : ${cpnPubReasonList}" th:value="${oneData.cd}"
+										th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>만료알림발송여부<em class="required" title="필수"></em></th>
+						<td>
+							<select name="endAlimSendYn" id="endAlimSendYn" data-valid-name="만료알림발송여부" required="required">
+								<option value="Y">Y</option>
+								<option value="N" selected="selected">N</option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>상세사유</th>
+						<td colspan="3">
+							<textarea name="pubReasonDtl" class="textareaR3" style="resize: none;"  data-valid-name="상세사유" required="required"></textarea>
+						</td>
+					</tr>
+				</table>
+			</form>
+			<!-- 버튼 배치 영역 -->
+			<ul class="panelBar">
+				<li class="right">
+					<button type="button" class="btn btn-info btn-lg" id="btnIssueCoupon">발급</button>
+				</li>
+			</ul>
+			<!-- //버튼 배치 영역 -->
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	const START_END_TIME = '00';
+	const END_TIME = '59';
+
+	let elementCustNo = [[${elementCustNo}]];
+
+	let siteList = gagajf.convertToArray([[${siteList}]]);
+	let usableCustGbList = gagajf.convertToArray([[${usableCustGbList}]]);
+	let cpnTypeList = gagajf.convertToArray([[${cpnTypeList}]]);
+	let dcWayList = gagajf.convertToArray([[${dcWayList}]]);
+	
+	let columnDefsCouponList = [
+// 		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{
+			headerName: "사이트", field: "siteCd", width: 80, cellClass: "text-center", pinned: 'left',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(siteList, params.value); }
+		},
+		{headerName: "쿠폰ID", field: "cpnId", width: 90, cellClass: 'text-center', pinned: 'left'},
+		{headerName: "쿠폰명", field: "cpnNm", width: 150, pinned: 'left'},
+		{
+			headerName: "사용가능고객", field: "usableCustGb", width: 120, cellClass: "text-center",
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(usableCustGbList, params.value); }
+		},
+		{
+			headerName: "쿠폰유형", field: "cpnType", width: 100, cellClass: "text-center",
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(cpnTypeList, params.value); }
+		},
+		{
+			headerName: "할인방식", field: "dcWay", width: 100, cellClass: "text-center",
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(dcWayList, params.value); }
+		},
+		{
+			headerName: "할인값(PC)", field: "dcPval", width: 100, cellClass: "text-center",
+			cellRenderer: function(params) { return (!gagajf.isNull(params.value) ? gagaAgGrid.toAddComma(params.value) : '') + (params.data.dcWay == '10' ? '원' : '%'); }
+		},
+		{
+			headerName: "할인값(모바일)", field: "dcMval", width: 100, cellClass: "text-center",
+			cellRenderer: function(params) { return (!gagajf.isNull(params.value) ? gagaAgGrid.toAddComma(params.value) : '') + (params.data.dcWay == '10' ? '원' : '%'); }
+		},
+		{
+			headerName: "최고할인값", field: "maxDcAmt", width: 100, cellClass: "text-center",
+			cellRenderer: function(params) { return (!gagajf.isNull(params.value) ? gagaAgGrid.toAddComma(params.value) : '') + (params.data.dcWay == '10' ? '원' : '%'); }
+		},
+		{
+			headerName: "유효기간", field: "availPeriod", width: 300, cellClass: "text-center",
+			cellRenderer: function(params) {
+				return params.data.pdGb == 'P' ? gagaAgGrid.toDateTimeFormat(params.data.availStdt)
+					+ '~' + gagaAgGrid.toDateTimeFormat(params.data.availStdt) : gagaAgGrid.toAddComma(params.data.availDays) + '일';
+			}
+		},
+		{headerName: "발행제한여부", field: "pubLimitYn", width: 100, cellClass: "text-center"},
+		{
+			headerName: "고객당발행제한수량", field: "custPubLimitQty", width: 100, cellClass: "text-center",
+			cellRenderer: function(params) { return !gagajf.isNull(params.value) ? gagaAgGrid.toAddComma(params.value) : ''; }
+		},
+		{
+			headerName: "총발행제한수량", field: "totPubLimitQty", width: 100, cellClass: "text-center",
+			cellRenderer: function(params) { return !gagajf.isNull(params.value) ? gagaAgGrid.toAddComma(params.value) : ''; }
+		},
+		{
+			headerName: "1회발행수량", field: "onePubQty", width: 100, cellClass: "text-center",
+			cellRenderer: function(params) { return !gagajf.isNull(params.value) ? gagaAgGrid.toAddComma(params.value) : ''; }
+		},
+		{headerName: "다운로드구분", field: "dnGb", width: 100, cellClass: "text-center"},
+		{
+			headerName: "구매제한금액", field: "buyLimitAmt", width: 100, cellClass: "text-right",
+			cellRenderer: function(params) { return !gagajf.isNull(params.value) ? gagaAgGrid.toAddComma(params.value) : ''; }
+		}
+	];
+
+	let gridOptionsCouponList = gagaAgGrid.getGridOptions(columnDefsCouponList);
+	
+	gridOptionsCouponList.rowSelection = 'single';
+	gridOptionsCouponList.rowMultiSelectWithClick = true; // 클릭으로 선택 가능
+	//gridOptionsCouponList.suppressRowClickSelection = true;
+
+	// 셀 클릭 이벤트
+	gridOptionsCouponList.onCellClicked = function (event) {
+		fnBindCouponInfo(event.data);
+	};
+
+	// 조회
+	$('#btnSearchCouponRetrieve').on('click', function() {
+		// Fetch data
+		gagaAgGrid.fetch($('#searchCouponForm').prop('action'), gridOptionsCouponList, '#searchCouponForm');
+	});
+	
+
+	// 발생
+	$('#btnIssueCoupon').on('click', function() {
+		let selectedData = gagaAgGrid.selectedRowData(gridOptionsCouponList);
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 쿠폰이 없습니다.');
+			return false;
+		}
+
+		if (!gagajf.validation('#couponIssueForm'))
+			return ;
+
+		let availStHH = $("#couponIssueForm select[name=availStHH]").val();
+		let availStMM = $("#couponIssueForm select[name=availStMM]").val();
+		let availEdHH = $("#couponIssueForm select[name=availEdHH]").val();
+		let availEdMM = $("#couponIssueForm select[name=availEdMM]").val();
+
+		let custCoupon = $("#couponIssueForm").serializeObject();
+		if (custCoupon.pdGb === 'P') {
+			if (gagajf.isNull(custCoupon.availStdt) && gagajf.isNull(custCoupon.availEddt)) {
+				mcxDialog.alert("유효 시작일시 / 유효 종료일시를 입력해주세요");
+				return;
+			}
+			custCoupon.availStdt = custCoupon.availStdt+' '+availStHH +':'+ availStMM + ':' +START_END_TIME;
+			custCoupon.availEddt = custCoupon.availEddt+' '+availEdHH +':'+ availEdMM + ':' +END_TIME;
+		}
+
+		if (custCoupon.pdGb === 'D') {
+			if (gagajf.isNull(custCoupon.availDays)) {
+				mcxDialog.alert("유효기간(일)을 입력해주세요");
+				return;
+			}
+		}
+
+		mcxDialog.confirm("저장하시겠습니까?", {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function () {
+				let jsonData = JSON.stringify(custCoupon);
+				//console.log(jsonData);
+				gagajf.ajaxJsonSubmit('/marketing/coupon/issue/save', jsonData, fnIssueCouponCallBack);
+			}
+		});
+
+	});
+
+	var fnIssueCouponCallBack = function () {
+		uifnPopupClose('popupCouponIssue');
+		fnSearchCoupon();
+	}
+
+
+
+	// 선택 쿠폰정보 셋팅
+	var fnBindCouponInfo = function(params) {
+		$('#couponIssueForm input[name=cpnId]').val(params.cpnId);
+		$('#couponIssueForm input[name=pdGb]').val(params.pdGb);
+		$('#couponIssueForm input[name=availStdt]').val(gagaAgGrid.toDateFormat(params.availStdt));
+		$("#couponIssueForm select[name=availStHH]").val(params.availStdt.substring(8,10));
+		$("#couponIssueForm select[name=availStMM]").val(params.availStdt.substring(10,12));
+		$('#couponIssueForm input[name=availEddt]').val(gagaAgGrid.toDateFormat(params.availEddt));
+		$("#couponIssueForm select[name=availEdHH]").val(params.availEddt.substring(8,10));
+		$("#couponIssueForm select[name=availEdMM]").val(params.availEddt.substring(10,12));
+		$('#couponIssueForm input[name=availDays]').val(params.availDays);
+
+		//유효기간 숨김처리
+		if (params.pdGb === 'P') {
+			$("#availTermsTr").show();
+			$("#availDaysTr").hide();
+		} else if (params.pdGb === 'D') {
+			$("#availTermsTr").hide();
+			$("#availDaysTr").show();
+		}
+
+	}
+
+	var fnInitDataSet = function () {
+		let custNo = $(elementCustNo).val();
+		if(!gagajf.isNull(custNo)) {
+			$('#couponIssueForm input[name=custNo]').val(custNo);
+		}
+	};
+
+	$(document).ready(function() {
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridCouponList', gridOptionsCouponList);
+
+		fnInitDataSet();
+
+
+	});
+/*]]>*/
+</script>
+
+</html>

+ 19 - 8
src/main/webapp/WEB-INF/views/marketing/PointGrantPopupForm.html

@@ -38,31 +38,31 @@
 						<tr >
 							<th>사이트</th>
 							<td>
-								<select name="siteCd" data-valid-name="사이트" required>
-									<option th:if="${siteCdList}" th:each="oneData, status : ${siteCdList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}"></option>
+								<select name="siteCd" data-valid-name="사이트" required="required">
+									<option th:if="${siteCdList}" th:each="oneData, status : ${siteCdList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] '+ oneData.cdNm}"></option>
 								</select>
 							</td>
 						</tr>
 						<tr>
 							<th>포인트변경사유<em class="required" title="필수"></em></th>
 							<td>
-								<select name="occurGb" data-valid-name="포인트변경사유" required>
+								<select name="occurGb" data-valid-name="포인트변경사유" required="required">
 									<option value="">선택하세요</option>
-									<option th:if="${occurGbList}" th:each="oneData, status : ${occurGbList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}"></option>
+									<option th:if="${occurGbList}" th:each="oneData, status : ${occurGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] '+ oneData.cdNm}"></option>
 								</select>
 							</td>
 						</tr>
 						<tr>
 							<th>증감구분<em class="required" title="필수"></em></th>
 							<td>
-								<select name="signGb" data-valid-name="증감구분" required>
+								<select id="signGb" name="signGb" data-valid-name="증감구분" required="required">
 									<option value="">선택하세요</option>
 									<option value="+">증가</option>
 									<option value="-">감소</option>
 								</select>
 							</td>
 						</tr>
-						<tr class="expire">
+						<tr id="expire">
 							<th >만료일자</th>
 							<td>
 								<input type="text" name="expBeDt" th:value="${expBeDt}" class="schDate w100"/>
@@ -71,13 +71,13 @@
 						<tr>
 							<th>적립포인트</th>
 							<td>
-								<input type="text" name="pntAmt" min="1" data-valid-name="적립포인트" data-valid-type="integer" maxlength="6" required/>
+								<input type="text" name="pntAmt" min="1" data-valid-name="적립포인트" data-valid-type="integer" maxlength="6" required="required"/>
 							</td>
 						</tr>
 						<tr>
 							<th>상세사유</th>
 							<td colspan="3">
-								<textarea name="occurDtlDesc" class="textareaR4" style="resize: none;" data-valid-name="상세사유" required></textarea>
+								<textarea name="occurDtlDesc" class="textareaR4" style="resize: none;" data-valid-name="상세사유" required="required"></textarea>
 							</td>
 						</tr>
 						</tbody>
@@ -95,9 +95,19 @@
 </div>
 <script th:inline="javascript">
 	/*<![CDATA[*/
+	const END_TIME = '23:59:59';
 	const elementCustNo = [[${elementCustNo}]];
 	const pntAssignAmt = [[${pntAssignAmt}]];
 
+	$('#signGb').on('change',function () {
+		let signGb = $(this).val();
+		if (signGb === '+') {
+			$('#expire').show();
+		} else {
+			$('#expire').hide();
+		}
+	});
+
 	// 포인트 부여
 	$('#btnSavePoint').on('click', function () {
 		if(!gagajf.validation('#pointGrantForm'))
@@ -124,6 +134,7 @@
 		// (+ + 1) -> 1, (- + 1) -> -1
 		let pntAmt = grantPoint.pntAmt * (grantPoint.signGb + 1)
 		grantPoint.pntAmt = pntAmt;
+		grantPoint.expBeDt = grantPoint.expBeDt+' '+END_TIME;
 
 		mcxDialog.confirm("포인트를 부여하시겠습니까?", {
 			cancelBtnText: "취소",

+ 15 - 16
src/main/webapp/WEB-INF/views/order/ExchangeRequestForm.html

@@ -90,7 +90,7 @@
 							<th>회수지주소 <i class="star"></i></th>
 							<td colspan="3">
 								<input type="text" name ="chgerZipcode" class="w100" readonly="readonly"/>
-								<button type="button" class="btn btn-info" onclick="fnOpenDaumAddr('delvLoc');">우편번호찾기</button>
+								<button type="button" class="btn btn-info" onclick="fnOpenDaumAddr('withdraw');">우편번호찾기</button>
 								<input type="text" name ="chgerBaseAddr" class="w300"/>
 								<input type="text" name ="chgerDtlAddr" class="w300"/>
 							</td>
@@ -141,7 +141,7 @@
 						<th>교환지주소 <i class="star"></i></th>
 						<td colspan="3">
 							<input type="text" name ="recipZipcode" class="w100" readonly="readonly"/>
-							<button type="button" class="btn btn-info" onclick="fnOpenDaumAddr('delvLoc');">우편번호찾기</button>
+							<button type="button" class="btn btn-info" onclick="fnOpenDaumAddr('exchange');">우편번호찾기</button>
 							<input type="text" name ="recipBaseAddr" class="w300"/>
 							<input type="text" name ="recipDtlAddr" class="w300"/>
 						</td>
@@ -497,8 +497,8 @@ gridOptionsExchangeReqList.rowSelection = 'multiple';
 
 // 3. 배송정보(환불정보)
 var columnDelvCdList = [
-	{headerName: "업체"			, field: "supplyCompNm"		, width: 100	, cellClass: 'text-center', hide: temp2},
-	{headerName: "배송비코드"		, field: "delvFeeCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+	{headerName: "업체"			, field: "supplyCompNm"		, width: 100	, cellClass: 'text-center'},
+	{headerName: "배송비코드"		, field: "delvFeeCd"		, width: 100	, cellClass: 'text-center'},
 	{
 		headerName		: "추가배송비"
 		, field			: "addDelvFee"
@@ -507,13 +507,12 @@ var columnDelvCdList = [
 		, cellRenderer	: function (params) {
 			return params.value.addComma();
 		}
-		, hide			: temp2
 	},
-	{headerName: "반품지명"		, field: "rtnLocNm"			, width: 100	, cellClass: 'text-center', hide: temp2},
-	{headerName: "반품지전화번호"	, field: "rtnLocTelno"		, width: 100	, cellClass: 'text-center', hide: temp2},
-	{headerName: "반품지우편번호"	, field: "rtnLocZipcode"	, width: 100	, cellClass: 'text-center', hide: temp2},
-	{headerName: "반품지기본주소"	, field: "rtnLocBaseAddr"	, width: 300	, cellClass: 'text-center', hide: temp2},
-	{headerName: "반품지상세주소"	, field: "rtnLocDtlAddr"	, width: 300	, cellClass: 'text-center', hide: temp2},
+	{headerName: "반품지명"		, field: "rtnLocNm"			, width: 100	, cellClass: 'text-center'},
+	{headerName: "반품지전화번호"	, field: "rtnLocTelno"		, width: 100	, cellClass: 'text-center'},
+	{headerName: "반품지우편번호"	, field: "rtnLocZipcode"	, width: 100	, cellClass: 'text-center'},
+	{headerName: "반품지기본주소"	, field: "rtnLocBaseAddr"	, width: 300	, cellClass: 'text-center'},
+	{headerName: "반품지상세주소"	, field: "rtnLocDtlAddr"	, width: 300	, cellClass: 'text-center'},
 ];
 var gridOptionsDelvCdList = gagaAgGrid.getGridOptions(columnDelvCdList);
 </script>
@@ -620,8 +619,8 @@ var fnExchange = function () {
 			mcxDialog.alert("휴대전화를 입력하세요."); return;
 		}
 	
-		var chgerPhnno 		= chgerPhnno1 + chgerPhnno2 + chgerPhnno3;
-		var chgerTelno 		= chgerTelno1 + chgerTelno2 + chgerTelno3;
+		var chgerPhnno 		= chgerPhnno1 + '-' + chgerPhnno2 + '-' + chgerPhnno3;
+		var chgerTelno 		= chgerTelno1 + '-' + chgerTelno2 + '-' + chgerTelno3;
 		var chgerEmail 		= orderInfoList[0].ordEmail;
 	}
 
@@ -659,8 +658,8 @@ var fnExchange = function () {
 		mcxDialog.alert("휴대전화를 입력하세요."); return;
 	}
 	
-	var recipPhnno 		= recipPhnno1 + recipPhnno2 + recipPhnno3;
-	var recipTelno 		= recipTelno1 + recipTelno2 + recipTelno3;
+	var recipPhnno 		= recipPhnno1 + '-' + recipPhnno2 + '-' + recipPhnno3;
+	var recipTelno 		= recipTelno1 + '-' + recipTelno2 + '-' + recipTelno3;
 	var recipEmail 		= orderInfoList[0].ordEmail;
 	
 	var jsonObj = {
@@ -713,6 +712,7 @@ var fnExchange = function () {
 var fnOpenDaumAddr = function(loc) {
 	let daumZip = new daum.Postcode({
 		oncomplete: function(data) {
+			console.log(data);
 			// 우편번호와 주소 정보를 해당 필드에 넣는다.
 			if (loc == 'withdraw') {
 				$('#exchangeRequestFrm input[name=chgerZipcode]').val(data.zonecode);
@@ -873,8 +873,7 @@ var fnAddDelvFee = function (exchangeRequestTargetList) {
 $(document).ready(function() {
 	// 1. 그리드생성
 	gagaAgGrid.createGrid('gridOrderCancelRequestList'		, gridOptionsExchangeReqList);			// 주문정보
-	//gagaAgGrid.createGrid('gridOrderCancelRequestToBeList'	, gridOptionsExchangeReqToBeList);		// 취소정보
-	gagaAgGrid.createGrid('gridDelvCdList'					, gridOptionsDelvCdList);				// 배송비정보
+	gagaAgGrid.createGrid('gridDelvCdList'					, gridOptionsDelvCdList);				// 배송정보
 	gridOptionsExchangeReqList.api.setRowData(cancelRequestTargetList);
 	
 	// 2.1 TOTAL ROWS 없애기

+ 5 - 5
src/main/webapp/WEB-INF/views/order/OrderDetailForm.html

@@ -166,6 +166,8 @@ var orderChangeInfo 		= [[${orderChangeInfo}]];				// 취소/반품/교환요청
 var orderRefundInfo 		= [[${orderRefundInfo}]];				// 환불정보
 var orderCounselInfo 		= [[${orderCounselInfo}]];				// 상담내역
 var orderAdminMemoInfo 		= [[${orderAdminMemoInfo}]];			// 관리자메모
+
+var canChgDelvStat			= ['G013_10', 'G013_11', 'G013_17', 'G013_20', 'G013_30', 'G013_40'];
 </script>
 
 <!-- AgGrid 컬럼 세팅 -->
@@ -501,7 +503,6 @@ var gridOptionsOrderFreeGiftInfo = gagaAgGrid.getGridOptions(columnDefsOrderFree
 var columnDefsDeliveryInfo = [
 	{headerName: "배송지번호"		, field: "delvAddrSq"		, width: 80, cellClass: 'text-center'},
 	{headerName: "주문구분"		, field: "exchGbNm"			, width: 80, cellClass: 'text-center'},
-	{headerName: "수정여부"		, field: "delvAddrEditYn"	, width: 80, cellClass: 'text-center', hide: true},
 	{headerName: "받는분"			, field: "recipNm"			, width: 80, cellClass: 'text-left', editable: true},
 	{headerName: "핸드폰번호"		, field: "recipPhnno"		, width: 120, cellClass: 'text-left', editable: true},
 	{headerName: "전화번호"		, field: "recipTelno"		, width: 120, cellClass: 'text-left', editable: true},
@@ -512,10 +513,9 @@ var columnDefsDeliveryInfo = [
 		, cellClass		: 'text-center'
 		, cellRenderer	: function (params) {
 			var rtnStr = ""
-			
-			if (params.data.delvAddrEditYn < 1) {
+			if (canChgDelvStat.includes(params.data.ordDtlStat)) {
 				// 배송지 수정 (주문배송, 교환배송)
-				rtnStr += params.value;			
+				rtnStr += params.value;
 				rtnStr += "<button type=\"button\" style=\"margin-left:10px\" class=\"btn btn-info\" onclick=\"fnOpenDaumAddr('" + params.node.rowIndex + "', 'ADDR');\">POST</button>";
 				rtnStr += "<button type=\"button\" class=\"btn btn-info\" onclick=\"fnUpdateOrderAddr('" + params.node.rowIndex + "');\">저장</button>";
 			} else {
@@ -656,7 +656,7 @@ var columnDefsOrderChangeInfo = [
 			var rtnStr = ""
 			
 			// 회수지수정가능(교환요청, 반품요청)
-			if (params.data.chgStat == 'G685_30' || params.data.chgStat == 'G685_40' ) {
+			if (!params.data.wdGb != 'D' && (params.data.chgStat == 'G685_30' || params.data.chgStat == 'G685_40')) {
 				
 				rtnStr += params.value;			
 				rtnStr += "<button type=\"button\" style=\"margin-left:10px\" class=\"btn btn-info\" onclick=\"fnOpenDaumAddr('" + params.node.rowIndex + "', 'CLAIM');\">POST</button>";

+ 1 - 1
src/main/webapp/ux/css/admin.ui.css

@@ -599,7 +599,7 @@ hr {border:0; padding-bottom:10px;}/* 기본 여백 :10px */
 .w20 {width:20px !important;}
 .w50 {width:50px !important;}
 .w60 {width:60px !important;}
-.w70 {width:60px !important;}
+.w70 {width:70px !important;}
 .w80 {width:80px !important;}
 .w90 {width:80px !important;}
 .w100 {width:100px !important;}