Kaynağa Gözat

Merge remote-tracking branch 'origin/develop' into jsh77b

jsh77b 4 yıl önce
ebeveyn
işleme
d4934f4c58

+ 24 - 0
src/main/java/com/style24/admin/biz/dao/TsaStatisticsDao.java

@@ -65,4 +65,28 @@ public interface TsaStatisticsDao {
 	 */
 	Collection<Statistics> getBrandOrderList(Statistics statistics);
 
+	/**
+	 * 시간별 주문 조회
+	 * @return Collection<Statistics>
+	 * @author lmc
+	 * @since 2021. 9. 16.
+	 */
+	Collection<Statistics> getHourlyOrderList(Statistics statistics);
+
+	/**
+	 * 카테고리 주문 조회
+	 * author: 이명철
+	 * return: Collection<Statistics>
+	 * since: 2021. 9. 23.
+	 */
+	Collection<Statistics> getCategoryOrderList(Statistics statistics);
+
+	/**
+	 * 카테고리 주문 상세 조회
+	 * author: 이명철
+	 * return: Collection<Statistics>
+	 * since: 2021. 9. 23.
+	 */
+	Collection<Statistics> getCategoryOrderDetailList(Statistics statistics);
+
 }

+ 30 - 0
src/main/java/com/style24/admin/biz/service/TsaStatisticsService.java

@@ -86,4 +86,34 @@ public class TsaStatisticsService {
 		return statisticsDao.getBrandOrderList(statistics);
 	}
 
+	/**
+	 * 시작별 주문 조회
+	 * @return Collection<Statistics>
+	 * @author lmc
+	 * @since 2021. 9. 16.
+	 */
+	public Collection<Statistics> getHourlyOrderList(Statistics statistics) {
+		return statisticsDao.getHourlyOrderList(statistics);
+	}
+
+	/**
+	 * 카테고리 주문 조회
+	 * author: 이명철
+	 * return: Collection<Statistics>
+	 * since: 2021. 9. 23.
+	 */
+	public Collection<Statistics> getCategoryOrderList(Statistics statistics) {
+		return statisticsDao.getCategoryOrderList(statistics);
+	}
+
+	/**
+	 * 카테고리 주문 상세 조회
+	 * author: 이명철
+	 * return: Collection<Statistics>
+	 * since: 2021. 9. 23.
+	 */
+	public Collection<Statistics> getCategoryOrderDetailList(Statistics statistics) {
+		return statisticsDao.getCategoryOrderDetailList(statistics);
+	}
+
 }

+ 6 - 2
src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java

@@ -450,11 +450,13 @@ public class TsaOrderChangeController extends TsaBaseController {
 		String chgStat = "";
 
 		// 1. 반품가능 주문상세상탭값 설정
-		String[] ordDtlStatArr = new String[4];
+		// 2021.09.14 card007 구매확정 반품신청
+		String[] ordDtlStatArr = new String[5];
 		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();
+		ordDtlStatArr[4] = TscConstants.OrderDetailStat.PURCHASE_CONFIRM.value();
 		order.setOrdDtlStatArr(ordDtlStatArr);
 
 		// 2. 변경신청된 주문상세번호를 체크 후 있으면 해당 취소가능수량값 업데이트
@@ -806,10 +808,12 @@ public class TsaOrderChangeController extends TsaBaseController {
 
 		if (ordChgSq == null || ordChgSq == 0) {
 			// 교환가능 주문상세상탭값 설정
-			String[] ordDtlStatArr = new String[3];
+			// 2021.09.14 card007 구매확정 교환신청 처리
+			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.PURCHASE_CONFIRM.value();
 			order.setOrdDtlStatArr(ordDtlStatArr);
 		}
 		

+ 137 - 0
src/main/java/com/style24/admin/biz/web/TsaStatisticsController.java

@@ -343,6 +343,12 @@ public class TsaStatisticsController extends TsaBaseController {
 		return mav;
 	}
 
+	/**
+	 * 브랜드 주문 리스트 조회
+	 * @return Collection<Statistics>
+	 * @author lmc
+	 * @since 2021. 9. 16.
+	 */
 	@PostMapping("/brand/order/list")
 	@ResponseBody
 	public Collection<Statistics> getBrandOrderList(@RequestBody Statistics statistics) {
@@ -378,4 +384,135 @@ public class TsaStatisticsController extends TsaBaseController {
 		return statisticsService.getBrandOrderList(statistics);
 	}
 
+
+	/**
+	 * 시간별 주문 화면
+	 * @return ModelAndView
+	 * @author lmc
+	 * @since 2021. 9. 16.
+	 */
+	@GetMapping("/hourly/trading/form")
+	public ModelAndView hourlyTradingForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 정상이월구분
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+
+		mav.setViewName("statistics/HourlyTradingForm");
+		return mav;
+	}
+
+	/**
+	 * 시간별 주문 조회
+	 * @return Collection<Statistics>
+	 * @author lmc
+	 * @since 2021. 9. 16.
+	 */
+	@PostMapping("/hourly/order/list")
+	@ResponseBody
+	public Collection<Statistics> getHourlyOrderList(@RequestBody Statistics statistics) {
+
+		if (!StringUtils.isBlank(statistics.getExtmallIdList())) {
+			statistics.setMultiExtmallId(statistics.getExtmallIdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getSupplyCompCdList())) {
+			statistics.setMultiSupplyCompCd(statistics.getSupplyCompCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getAfLinkCdList())) {
+			statistics.setMultiAfLinkCd(statistics.getAfLinkCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getBrandCdList())) {
+			statistics.setMultiBrandCd(statistics.getBrandCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getItemkindCdList())) {
+			statistics.setMultiItemkindCd(statistics.getItemkindCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getGoodsCd())) {
+			statistics.setMultiGoodsCd(statistics.getGoodsCd().split(System.lineSeparator()));
+		}
+
+		if (!StringUtils.isBlank(statistics.getFormalGb())) {
+			statistics.setMultiFrontGb(statistics.getExtmallIdList().split(","));
+		}
+
+		return statisticsService.getHourlyOrderList(statistics);
+	}
+
+
+	/**
+	 * 카테고리별 매출현황 화면
+	 * author: 이명철
+	 * return: ModelAndView
+	 * since: 2021. 9. 21.
+	 */
+	@GetMapping("/category/trading/form")
+	public ModelAndView categoryTradingForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 정상이월구분
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+
+		mav.setViewName("statistics/CategoryTradingForm");
+		return mav;
+	}
+
+	/**
+	 * 카테고리별 매출현황 조회
+	 * author: 이명철
+	 * return: Collection<Statistics>
+	 * since: 2021. 9. 21.
+	 */
+	@PostMapping("/category/order/list")
+	@ResponseBody
+	public Collection<Statistics> getCategoryOrderList(@RequestBody Statistics statistics) {
+
+		if (!StringUtils.isBlank(statistics.getExtmallIdList())) {
+			statistics.setMultiExtmallId(statistics.getExtmallIdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getSupplyCompCdList())) {
+			statistics.setMultiSupplyCompCd(statistics.getSupplyCompCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getAfLinkCdList())) {
+			statistics.setMultiAfLinkCd(statistics.getAfLinkCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getBrandCdList())) {
+			statistics.setMultiBrandCd(statistics.getBrandCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getItemkindCdList())) {
+			statistics.setMultiItemkindCd(statistics.getItemkindCdList().split(","));
+		}
+
+		if (!StringUtils.isBlank(statistics.getGoodsCd())) {
+			statistics.setMultiGoodsCd(statistics.getGoodsCd().split(System.lineSeparator()));
+		}
+
+		if (!StringUtils.isBlank(statistics.getFormalGb())) {
+			statistics.setMultiFrontGb(statistics.getExtmallIdList().split(","));
+		}
+
+		return statisticsService.getCategoryOrderList(statistics);
+	}
+	
+	/**
+	 * 카테고리 주문 상세 조회
+	 * author: 이명철
+	 * return: Collection<Statistics>
+	 * since: 2021. 9. 23.
+	 */
+	@PostMapping("/category/order/detail/list")
+	@ResponseBody
+	public Collection<Statistics> getCategoryOrderDetailList(@RequestBody Statistics statistics) {
+		return statisticsService.getCategoryOrderDetailList(statistics);
+	}
+
+
 }

+ 17 - 0
src/main/java/com/style24/persistence/domain/Statistics.java

@@ -36,10 +36,16 @@ public class Statistics extends TscBaseDomain {
 	private long exUsacAmt;		// 예상 정산액C*(1-D)
 	private long realOrdAmt;	// 실결제금액
 
+	private String cateNm1;     // 대분류
+	private String cateNm2;     // 중분류
+	private String cateNm3;     // 소분류
+
 	// 검색조건
 	private String dayGb;		// 날짜구분(D:일별, W:주별, M:월별)
 	private String startDt;		// 시작일
 	private String endDt;		// 종료일
+	private String compStDt;	// 비교시작일
+	private String compEdDt;	// 비교종료일
 	private String frontGb;	    // 프론트구분
 	private String frontGbP;	// 프론트구분(=디바이스구분)PC웹
 	private String frontGbM;	// 프론트구분(=디바이스구분)모바일웹
@@ -82,6 +88,9 @@ public class Statistics extends TscBaseDomain {
 	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 	private String[] multiFrontGb;	// 화면구분
 
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] dtGb;	// 날짜구분
+
 	// 일일거래내역
 	private Integer ordNo;				// 주문번호
 	private Integer ordDtlNo;			// 주문상세번호
@@ -140,4 +149,12 @@ public class Statistics extends TscBaseDomain {
 	private String formalGb;			// 이월구분
 	private double yoyRate;             // 전년대비 증감율
 
+	private String hour;                //시간
+	private int ordAmt;                 //주문금액
+	private int ordCust;                //주문자수
+	private int cplRate;                //달성율
+	private long custPrice;             //고객단가
+	private long compOrdAmt;            //비교
+
+
 }

+ 332 - 88
src/main/java/com/style24/persistence/mybatis/shop/TsaStatistics.xml

@@ -420,6 +420,45 @@
 	<!-- 제휴몰 주문 목록 조회 -->
 	<select id="getExtmallOrderList" parameterType="Statistics" resultType="Statistics">
 		/* TsaStatistics.getExtmallOrderList */
+		WITH YOY AS (
+			SELECT X.EXTMALL_ID
+			     , SUM(X.EXTMALL_AMT - X.CNCL_AMT - X.RTN_AMT) AS YOY_TOT_ORD_AMT
+               FROM   TB_STAT_ORD_DAY X
+               WHERE  1 = 1
+				 <![CDATA[
+			     AND X.DAY >= DATE_ADD(STR_TO_DATE(#{startDt},'%Y-%m-%d'), INTERVAL -1 YEAR)
+			     AND X.DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL -1 YEAR)
+				 ]]>
+				<if test="multiBrandCd != null">
+					/* 브랜드 */
+					<foreach collection="multiBrandCd" item="item" index="index"  open="AND X.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiFormalGb != null">
+					/* 정상/이월구분 */
+					<foreach collection="multiFormalGb" item="item" index="index"  open="AND X.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiSupplyCompCd != null">
+					/* 공급처 */
+					<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND X.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiAfLinkCd != null">
+					/* 채널 */
+					<foreach collection="multiAfLinkCd" item="item" index="index"  open="AND X.AF_LINK_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiItemkindCd != null">
+					/* 품목 */
+					<foreach collection="multiItemkindCd" item="item" index="index"  open="AND X.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiFrontGb != null">
+					/* 디바이스 */
+					<foreach collection="multiFrontGb" item="item" index="index"  open="AND X.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiDistributionGb != null">
+					/* 물류구분 */
+					<foreach collection="multiDistributionGb" item="item" index="index"  open="AND X.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+			GROUP BY X.EXTMALL_ID
+		)
 		SELECT EXTMALL_NM
 		     , TOT_AMT
 		     , SELL_QTY
@@ -435,12 +474,12 @@
 				SELECT
 				    (SELECT EXTMALL_NM FROM TB_EXTMALL X WHERE X.EXTMALL_ID = A.EXTMALL_ID LIMIT 1) AS EXTMALL_NM
 				    , SUM(A.EXTMALL_AMT - A.CNCL_AMT - A.RTN_AMT) AS TOT_AMT /* 총매출 */
-				    , SUM(A.SELL_QTY) AS SELL_QTY /* 판매수량 */
+				    , SUM(A.SELL_QTY) AS SELL_QTY             /* 판매수량 */
 				    , SUM(A.EXTMALL_AMT) AS EXTMALL_AMT
-				    , SUM(A.CNCL_QTY + A.RTN_QTY) AS CNCL_QTY -- 취/반품수량
-				    , SUM(A.CNCL_AMT + A.RTN_AMT) AS CNCL_AMT -- 취/반품액
-				    , SUM(A.REAL_ORD_AMT) AS REAL_ORD_AMT /* 실결제액 */
-				    , (SELECT SELL_FEE_RATE FROM TB_EXTMALL X WHERE X.EXTMALL_ID = A.EXTMALL_ID LIMIT 1) AS SELL_FEE_RATE -- 수수료율
+				    , SUM(A.CNCL_QTY + A.RTN_QTY) AS CNCL_QTY /*취/반품수량*/
+				    , SUM(A.CNCL_AMT + A.RTN_AMT) AS CNCL_AMT /*취/반품액*/
+				    , SUM(A.REAL_ORD_AMT) AS REAL_ORD_AMT     /*실결제액 */
+				    , (SELECT SELL_FEE_RATE FROM TB_EXTMALL X WHERE X.EXTMALL_ID = A.EXTMALL_ID LIMIT 1) AS SELL_FEE_RATE /*수수료율*/
 				    , (SUM(A.REAL_ORD_AMT) * (1 - (SELECT SELL_FEE_RATE FROM TB_EXTMALL X WHERE X.EXTMALL_ID = A.EXTMALL_ID LIMIT 1) / 100)) AS EX_USAC_AMT
 					, IFNULL((SELECT SUM(X.EXTMALL_AMT - X.CNCL_AMT - X.RTN_AMT)
 				               FROM   TB_STAT_ORD_DAY X
@@ -480,6 +519,7 @@
 								</if>
 				              ),0)                                           AS YOY_TOT_ORD_AMT /*전년동기대비매출액*/
 				FROM TB_STAT_ORD_DAY A
+				LEFT OUTER JOIN YOY AS B ON A.EXTMALL_ID = B.EXTMALL_ID
 				WHERE 1=1
 				    AND A.EXTMALL_ID IS NOT NULL
 				<![CDATA[
@@ -522,6 +562,37 @@
 	<!-- 채널 주문목록 조회 -->
 	<select id="getChannelOrderList" parameterType="Statistics" resultType="Statistics">
 		/* TsaStatistics.getChannelOrderList */
+		WITH YOY AS (
+		  SELECT X.AF_LINK_CD
+		       , SUM(X.CHANNEL_AMT - X.CNCL_AMT - X.RTN_AMT) AS YOY_TOT_ORD_AMT
+		    FROM TB_STAT_ORD_DAY X
+		   WHERE 1=1
+			<![CDATA[
+			     AND X.DAY >= DATE_ADD(STR_TO_DATE(#{startDt},'%Y-%m-%d'), INTERVAL -1 YEAR)
+			     AND X.DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL -1 YEAR)
+			]]>
+			<if test="multiFrontGb != null">
+				/* 디바이스 */
+				<foreach collection="multiFrontGb" item="item" index="index"  open="AND X.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiFormalGb != null">
+				/* 정상/이월구분 */
+				<foreach collection="multiFormalGb" item="item" index="index"  open="AND X.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiDistributionGb != null">
+				/* 물류구분 */
+				<foreach collection="multiDistributionGb" item="item" index="index"  open="AND X.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiSupplyCompCd != null">
+				/* 공급처 */
+				<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND X.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiItemkindCd != null">
+				/* 품목 */
+				<foreach collection="multiItemkindCd" item="item" index="index"  open="AND X.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+		  GROUP BY X.AF_LINK_CD
+		)
 		SELECT AF_LINK_CD
 		     , AF_LINK_NM
 		     , CHANNEL_AMT
@@ -536,8 +607,8 @@
 		     , ROUND(TOT_AMT / YOY_TOT_ORD_AMT * 100 - 100,1) AS YOY_RATE
 		  FROM (
 				SELECT
-				    AF_LINK_CD
-				    , (SELECT AF_LINK_NM FROM TB_AF_LINK X WHERE X.AF_LINK_CD = A.AF_LINK_CD) AS AF_LINK_NM
+				    A.AF_LINK_CD
+				    , B.AF_LINK_NM
 				    , SUM(A.CHANNEL_AMT) AS CHANNEL_AMT
 				    , SUM(A.CHANNEL_AMT - A.CNCL_AMT - A.RTN_AMT) AS TOT_AMT /* 총매출 */
 				    , SUM(A.SELL_QTY) AS SELL_QTY  /* 판매수량 */
@@ -546,47 +617,15 @@
 				    , SUM(A.REAL_ORD_AMT) AS REAL_ORD_AMT /* 실결제금액 */
 				    , (SELECT FEE_RATE FROM TB_AF_LINK X WHERE X.AF_LINK_CD = A.AF_LINK_CD) AS SELL_FEE_RATE
 				    , (SUM(A.REAL_ORD_AMT) * (1 - (SELECT FEE_RATE FROM TB_AF_LINK X WHERE X.AF_LINK_CD = A.AF_LINK_CD) / 100)) AS EX_USAC_AMT
-					, IFNULL((SELECT SUM(X.CHANNEL_AMT - X.CNCL_AMT - X.RTN_AMT)
-				                FROM TB_STAT_ORD_DAY X
-				               WHERE 1=1
-				                 AND X.AF_LINK_CD = A.AF_LINK_CD
-							<![CDATA[
-							     AND X.DAY >= DATE_ADD(STR_TO_DATE(#{startDt},'%Y-%m-%d'), INTERVAL -1 YEAR)
-							     AND X.DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL 1 DAY)
-							]]>
-							<if test="multiFrontGb != null">
-								/* 디바이스 */
-								<foreach collection="multiFrontGb" item="item" index="index"  open="AND X.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiFormalGb != null">
-								/* 정상/이월구분 */
-								<foreach collection="multiFormalGb" item="item" index="index"  open="AND X.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiDistributionGb != null">
-								/* 물류구분 */
-								<foreach collection="multiDistributionGb" item="item" index="index"  open="AND X.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiSupplyCompCd != null">
-								/* 공급처 */
-								<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND X.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiItemkindCd != null">
-								/* 품목 */
-								<foreach collection="multiItemkindCd" item="item" index="index"  open="AND X.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-				              ),0)                                           AS YOY_TOT_ORD_AMT /*전년동기대비매출액*/
+				    , SUM(IFNULL(C.YOY_TOT_ORD_AMT,0)) AS YOY_TOT_ORD_AMT
 				FROM TB_STAT_ORD_DAY A
-				WHERE 1=1
+				INNER JOIN TB_AF_LINK B ON A.AF_LINK_CD = B.AF_LINK_CD
+				LEFT OUTER JOIN YOY   C ON A.AF_LINK_CD = C.AF_LINK_CD
+				WHERE B.AF_CHANNEL != 'G053_01'
 				<![CDATA[
-				    AND DAY >= STR_TO_DATE(#{startDt},'%Y-%m-%d')
-				    AND DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL 1 DAY)
+				    AND A.DAY >= STR_TO_DATE(#{startDt},'%Y-%m-%d')
+				    AND A.DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL 1 DAY)
 				]]>
-				    AND EXISTS(
-				          SELECT 1
-				          FROM TB_AF_LINK X
-				          WHERE X.AF_LINK_CD = A.AF_LINK_CD
-				            AND X.AF_CHANNEL != 'G053_01'
-				      )
 				<if test="multiFrontGb != null">
 					/* 디바이스 */
 					<foreach collection="multiFrontGb" item="item" index="index"  open="AND A.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
@@ -608,7 +647,6 @@
 					<foreach collection="multiItemkindCd" item="item" index="index"  open="AND A.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
 				</if>
 				GROUP BY AF_LINK_CD
-
 	) TAB
 	ORDER BY AF_LINK_NM
 	</select>
@@ -616,6 +654,48 @@
 	<!-- 브랜드 주문목록 조회 -->
 	<select id="getBrandOrderList" parameterType="Statistics" resultType="Statistics">
 		/* TsaStatistics.getBrandOrderList */
+		WITH YOY AS (
+		  SELECT X.BRAND_CD, SUM(X.SELF_AMT + X.CHANNEL_AMT + X.EXTMALL_AMT - X.CNCL_AMT - X.RTN_AMT) AS YOY_TOT_ORD_AMT
+		    FROM TB_STAT_ORD_DAY X
+		   WHERE 1=1
+			<![CDATA[
+		     AND X.DAY >= STR_TO_DATE(#{startDt},'%Y-%m-%d')
+		     AND X.DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL 1 DAY)
+			]]>
+			<if test="multiFrontGb != null">
+				/* 디바이스 */
+				<foreach collection="multiFrontGb" item="item" index="index"  open="AND X.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiFormalGb != null">
+				/* 정상/이월구분 */
+				<foreach collection="multiFormalGb" item="item" index="index"  open="AND X.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiDistributionGb != null">
+				/* 물류구분 */
+				<foreach collection="multiDistributionGb" item="item" index="index"  open="AND X.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiSupplyCompCd != null">
+				/* 공급처 */
+				<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND X.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiItemkindCd != null">
+				/* 품목 */
+				<foreach collection="multiItemkindCd" item="item" index="index"  open="AND X.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiExtmallId != null">
+				/* 제휴몰 */
+				<foreach collection="multiExtmallId" item="item" index="index"  open="AND X.EXTMALL_ID IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiAfLinkCd != null">
+				/* 채널 */
+				<foreach collection="multiAfLinkCd" item="item" index="index"  open="AND X.AF_LINK_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiBrandCd != null">
+				/* 브랜드 */
+				<foreach collection="multiBrandCd" item="item" index="index"  open="AND Y.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+		  GROUP BY X.BRAND_CD
+		)
 		SELECT
 		    BRAND_CD /*브랜드코드*/
 		    , BRAND_ENM /*브랜드명*/
@@ -641,7 +721,7 @@
 		        , SUM(CNCL_AMT) AS CNCL_AMT
 		        , SUM(CASE WHEN FORMAL_GB = 'G009_10' THEN TOT_AMT ELSE 0 END) AS TOT_AMT_10 /*정상매출*/
 		        , SUM(CASE WHEN FORMAL_GB = 'G009_20' THEN TOT_AMT ELSE 0 END) AS TOT_AMT_20 /*이월매출*/
-		        , X.YOY_TOT_ORD_AMT
+		        , YOY_TOT_ORD_AMT
 		    FROM (
 		        SELECT
 		            A.BRAND_CD -- 브랜드코드
@@ -653,48 +733,10 @@
 		            , SUM(A.SELF_AMT + A.CHANNEL_AMT) AS SELFMALL_AMT -- 자사몰매출
 		            , SUM(A.EXTMALL_AMT) AS EXTMALL_AMT -- 제휴몰매출
 		            , SUM(A.CNCL_AMT + A.RTN_AMT) AS CNCL_AMT -- 취/반품액
-					, IFNULL((SELECT SUM(X.SELF_AMT + X.CHANNEL_AMT + X.EXTMALL_AMT - X.CNCL_AMT - X.RTN_AMT)
-				                FROM TB_STAT_ORD_DAY X
-				               WHERE A.BRAND_CD = X.BRAND_CD
-							<![CDATA[
-							     AND X.DAY >= DATE_ADD(STR_TO_DATE(#{startDt},'%Y-%m-%d'), INTERVAL -1 YEAR)
-							     AND X.DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL -1 YEAR)
-							]]>
-							<if test="multiFrontGb != null">
-								/* 디바이스 */
-								<foreach collection="multiFrontGb" item="item" index="index"  open="AND X.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiFormalGb != null">
-								/* 정상/이월구분 */
-								<foreach collection="multiFormalGb" item="item" index="index"  open="AND X.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiDistributionGb != null">
-								/* 물류구분 */
-								<foreach collection="multiDistributionGb" item="item" index="index"  open="AND X.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiSupplyCompCd != null">
-								/* 공급처 */
-								<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND X.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiItemkindCd != null">
-								/* 품목 */
-								<foreach collection="multiItemkindCd" item="item" index="index"  open="AND X.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiExtmallId != null">
-								/* 제휴몰 */
-								<foreach collection="multiExtmallId" item="item" index="index"  open="AND X.EXTMALL_ID IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiAfLinkCd != null">
-								/* 채널 */
-								<foreach collection="multiAfLinkCd" item="item" index="index"  open="AND X.AF_LINK_CD IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-							<if test="multiBrandCd != null">
-								/* 브랜드 */
-								<foreach collection="multiBrandCd" item="item" index="index"  open="AND Y.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
-							</if>
-				              ),0)                                           AS YOY_TOT_ORD_AMT /*전년동기대비매출액*/
-		        FROM TB_STAT_ORD_DAY A, TB_BRAND B
+		            , C.YOY_TOT_ORD_AMT
+		        FROM TB_STAT_ORD_DAY A, TB_BRAND B, YOY C
 		        WHERE A.BRAND_CD = B.BRAND_CD
+		          AND A.BRAND_CD = C.BRAND_CD
 				<![CDATA[
 			      AND DAY >= STR_TO_DATE(#{startDt},'%Y-%m-%d')
 			      AND DAY <= DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'), INTERVAL 1 DAY)
@@ -738,4 +780,206 @@
 		ORDER BY SELF_YN DESC, BRAND_ENM
 	</select>
 
+	<!-- 시간별 주문 조회 -->
+	<select id="getHourlyOrderList" parameterType="Statistics" resultType="Statistics">
+		/* TsaStatistics.getHourlyOrderList */
+		WITH TAB AS (
+		    SELECT
+		        DATE_FORMAT(DAY_TIME, '%H') AS HOUR
+		        , SUM(ORD_AMT) AS ORD_AMT /*매출*/
+		        , SUM(ORD_CUST) AS ORD_CUST /*주문자수*/
+		        , SUM(ORD_CNT) AS ORD_CNT /*주문수*/
+		        , SUM(SELL_QTY) AS SELL_QTY /*판매수*/
+		        , FLOOR(AVG(CUST_PRICE)) AS CUST_PRICE /*객단가*/
+		        , SUM(CNCL_QTY) AS CNCL_QTY /*취반품개수*/
+		        , SUM(CNCL_AMT) AS CNCL_AMT /*취반품액*/
+		    FROM TB_STAT_ORD_TIME A
+		    WHERE 1=1
+		    	<if test="dtGb != null">
+					<foreach collection="dtGb" item="item" index="index">
+						<if test="item == 'COMPARE_TERMS'">
+					        <![CDATA[
+					        /* 직전동기간 */
+					        AND A.DAY_TIME >= DATE_ADD(DATE_FORMAT(#{compStDt},'%Y-%m-%d'), INTERVAL (DATE_FORMAT(#{compStDt}, '%Y%m%d') - DATE_FORMAT(#{compEdDt}, '%Y%m%d')) -1  DAY)
+					        AND A.DAY_TIME < DATE_ADD(DATE_FORMAT(#{compEdDt}, '%Y%m%d'), INTERVAL (DATE_FORMAT(#{compStDt}, '%Y%m%d') - DATE_ADD(DATE_FORMAT(#{compEdDt}, '%Y%m%d'), INTERVAL 1 DAY)) * -1 DAY)
+					        ]]>
+						</if>
+						<if test="item == 'YOY'">
+					        <![CDATA[
+					        /* 전년비교 */
+					        AND A.DAY_TIME >= DATE_ADD(DATE_FORMAT(#{startDt}, '%Y%m%d'), INTERVAL -1 YEAR )
+					        AND A.DAY_TIME < DATE_ADD(DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY), INTERVAL -1 YEAR )
+					        ]]>
+						</if>
+					</foreach>
+				</if>
+				<if test="dtGb == null">
+				        <![CDATA[
+				        /* 직접선택 */
+				        AND A.DAY_TIME >= DATE_FORMAT(#{compStDt}, '%Y%m%d')
+				        AND A.DAY_TIME <  DATE_ADD(DATE_FORMAT(#{compEdDt}, '%Y%m%d'), INTERVAL 1 DAY)
+				        ]]>
+				</if>
+				<if test="multiFrontGb != null">
+					/* 디바이스 */
+					<foreach collection="multiFrontGb" item="item" index="index"  open="AND A.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiFormalGb != null">
+					/* 정상/이월구분 */
+					<foreach collection="multiFormalGb" item="item" index="index"  open="AND A.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiDistributionGb != null">
+					/* 물류구분 */
+					<foreach collection="multiDistributionGb" item="item" index="index"  open="AND A.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiSupplyCompCd != null">
+					/* 공급처 */
+					<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND A.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiItemkindCd != null">
+					/* 품목 */
+					<foreach collection="multiItemkindCd" item="item" index="index"  open="AND A.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiExtmallId != null">
+					/* 제휴몰 */
+					<foreach collection="multiExtmallId" item="item" index="index"  open="AND A.EXTMALL_ID IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiAfLinkCd != null">
+					/* 채널 */
+					<foreach collection="multiAfLinkCd" item="item" index="index"  open="AND A.AF_LINK_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiBrandCd != null">
+					/* 브랜드 */
+					<foreach collection="multiBrandCd" item="item" index="index"  open="AND A.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+		        AND A.SHOT_DELV_YN = 'Y' /*총알배송*/
+		    GROUP BY HOUR
+		)
+		SELECT
+		    A.HOUR
+		    , A.ORD_AMT /*매출*/
+		    , B.ORD_AMT AS COMP_ORD_AMT /*비교*/
+		    , ROUND(FLOOR(A.ORD_AMT / B.ORD_AMT * 100 * 100) / 100, 2) AS CPL_RATE /*달성율*/
+		    , A.ORD_CUST /*주문자수*/
+		    , A.ORD_CNT /*주문수*/
+		    , A.SELL_QTY /*판매수*/
+		    , A.CUST_PRICE /*객단가*/
+		    , A.CNCL_QTY /*취반품개수*/
+		    , A.CNCL_AMT /*취반품액*/
+		FROM (
+		    SELECT
+		        DATE_FORMAT(DAY_TIME, '%H') AS HOUR
+		        , SUM(ORD_AMT) AS ORD_AMT /*매출*/
+		        , SUM(ORD_CUST) AS ORD_CUST /*주문자수*/
+		        , SUM(ORD_CNT) AS ORD_CNT /*주문수*/
+		        , SUM(SELL_QTY) AS SELL_QTY /*판매수*/
+		        , FLOOR(AVG(CUST_PRICE)) AS CUST_PRICE /*객단가*/
+		        , SUM(CNCL_QTY) AS CNCL_QTY /*취반품개수*/
+		        , SUM(CNCL_AMT) AS CNCL_AMT /*취반품액*/
+		    FROM TB_STAT_ORD_TIME A
+		    WHERE 1=1
+		    <![CDATA[
+		    AND A.DAY_TIME >= DATE_FORMAT(#{startDt}, '%Y%m%d')
+		    AND A.DAY_TIME < DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY)
+		    ]]>
+			<if test="multiFrontGb != null">
+				/* 디바이스 */
+				<foreach collection="multiFrontGb" item="item" index="index"  open="AND A.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiFormalGb != null">
+				/* 정상/이월구분 */
+				<foreach collection="multiFormalGb" item="item" index="index"  open="AND A.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiDistributionGb != null">
+				/* 물류구분 */
+				<foreach collection="multiDistributionGb" item="item" index="index"  open="AND A.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiSupplyCompCd != null">
+				/* 공급처 */
+				<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND A.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiItemkindCd != null">
+				/* 품목 */
+				<foreach collection="multiItemkindCd" item="item" index="index"  open="AND A.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiExtmallId != null">
+				/* 제휴몰 */
+				<foreach collection="multiExtmallId" item="item" index="index"  open="AND A.EXTMALL_ID IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiAfLinkCd != null">
+				/* 채널 */
+				<foreach collection="multiAfLinkCd" item="item" index="index"  open="AND A.AF_LINK_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiBrandCd != null">
+				/* 브랜드 */
+				<foreach collection="multiBrandCd" item="item" index="index"  open="AND A.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+
+		    GROUP BY HOUR
+		) A
+		LEFT OUTER JOIN TAB B ON A.HOUR = B.HOUR
+		ORDER BY A.HOUR
+	</select>
+
+	<!-- 카테고리별 주문 조회 -->
+	<select id="getCategoryOrderList" parameterType="Statistics" resultType="Statistics">
+		/* TsaStatistics.getCategoryOrderList */
+		SELECT A.ITEMKIND_CD
+		    , SUBSTRING_INDEX(T4.FULL_CATE_NM, ' > ', 1) AS CATE_NM1 /* 대분류 */
+		    , SUBSTRING_INDEX(SUBSTRING(T4.FULL_CATE_NM, INSTR(SUBSTRING_INDEX(T4.FULL_CATE_NM, ' > ', 2), ' > ') + 3), ' > ', 1) AS CATE_NM2 /* 중분류 */
+		    , SUBSTRING_INDEX(T4.FULL_CATE_NM, ' > ', -1) AS CATE_NM3 -- 소분류
+		    , SUM(A.SELF_AMT + A.CHANNEL_AMT + A.EXTMALL_AMT - A.CNCL_AMT - A.RTN_AMT) AS TOT_AMT /*총매출*/
+		    , SUM(A.SELF_AMT + A.CHANNEL_AMT) AS SELFMALL_AMT /*자사몰매출*/
+		    , SUM(A.EXTMALL_AMT) AS EXTMALL_AMT /*제휴몰매출*/
+		FROM TB_STAT_ORD_DAY A, TB_ITEMKIND_CATE TC, TB_CATE_4SRCH T4
+		WHERE A.ITEMKIND_CD = TC.ITEMKIND_CD
+		    AND TC.CATE_NO = T4.LEAF_CATE_NO
+		    AND (A.SELF_AMT + A.CHANNEL_AMT + A.EXTMALL_AMT - A.CNCL_AMT - A.RTN_AMT) > 0
+	        <![CDATA[
+	        /* 직접선택 */
+	        AND A.DAY >= DATE_FORMAT(#{startDt}, '%Y%m%d')
+	        AND A.DAY <  DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY)
+	        ]]>
+			<if test="multiFrontGb != null">
+				/* 디바이스 */
+				<foreach collection="multiFrontGb" item="item" index="index"  open="AND A.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiExtmallId != null">
+				/* 제휴몰 */
+				<foreach collection="multiExtmallId" item="item" index="index"  open="AND A.EXTMALL_ID IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiSupplyCompCd != null">
+				/* 공급처 */
+				<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND A.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiBrandCd != null">
+				/* 브랜드 */
+				<foreach collection="multiBrandCd" item="item" index="index"  open="AND A.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+		GROUP BY A.ITEMKIND_CD, T4.FULL_CATE_NM
+	</select>
+
+	<!-- 카테고리 상세 조회 -->
+	<select id="getCategoryOrderDetailList" parameterType="Statistics" resultType="Statistics">
+		/* TsaStatistics.getCategoryOrderDetailList */
+		SELECT
+		    C.BRAND_ENM
+		    , A.GOODS_CD
+		    , B.GOODS_NM
+		    , SUM(A.SELF_AMT + A.CHANNEL_AMT + A.EXTMALL_AMT - A.CNCL_AMT - A.RTN_AMT) AS TOT_AMT /*총매출*/
+		    , SUM(A.SELL_QTY) AS SELL_QTY /*판매수량*/
+		    , SUM(A.ORD_CUST) AS ORD_CUST /*구매자수*/
+		FROM TB_STAT_ORD_DAY A, TB_GOODS B, TB_BRAND C
+		WHERE A.GOODS_CD = B.GOODS_CD
+		    AND A.BRAND_CD = C.BRAND_CD
+		    AND (A.SELF_AMT + A.CHANNEL_AMT + A.EXTMALL_AMT - A.CNCL_AMT - A.RTN_AMT) > 0
+		    AND A.ITEMKIND_CD = #{itemkindCd}
+	        <![CDATA[
+	        /* 직접선택 */
+	        AND A.DAY >= DATE_FORMAT(#{startDt}, '%Y%m%d')
+	        AND A.DAY <  DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY)
+	        ]]>
+		GROUP BY C.BRAND_ENM, A.GOODS_CD, B.GOODS_NM
+	</select>
+
 </mapper>

+ 1 - 0
src/main/resources/config/application.yml

@@ -40,6 +40,7 @@ naverPay:
     approvePaymentUrl: /naverpay/payments/v2/apply/payment
     paymentOrderUrl: /naverpay/payments/v2/list/history
     cancelPaymentUrl: /naverpay/payments/v1/cancel
+    decideOrderUrl: /naverpay/payments/v1/purchase-confirm
   
 # CJ대한통운
 cj:

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

@@ -381,7 +381,7 @@ var columnDefsGoodsInfo = [
 					}
 					
 					// 배송중, 배송완료 (교환신청, 반품신청) 
-					if (params.value == 'G013_50' || params.value == 'G013_60') {
+					if (params.value == 'G013_50' || params.value == 'G013_60' || params.value == 'G013_70') {
 						if (params.data.ordQty > (params.data.cnclRtnQty + params.data.ordReqChgQty)) {
 							var paramData 	= params.data.ordNo;
 							paramData 		+= '@' + params.data.ordDtlNo;

+ 8 - 4
src/main/webapp/WEB-INF/views/statistics/BrandTradingForm.html

@@ -129,19 +129,19 @@
 	let columnDefs = [
 		{ headerName: "브랜드번호", field: "brandCd", width: 100, cellClass: 'text-center' },
 		{ headerName: "브랜드명", field: "brandEnm", width: 180, cellClass: 'text-center'},
-		{ headerName: "브랜드 매출액", field: "", width: 120, cellClass: 'text-center',
+		{ headerName: "브랜드 매출액", field: "", width: 120, cellClass: 'text-right',
 			children: [
 				{headerName: "총매출액(A+B+C)", field: "totAmt", width: 120, cellClass: 'text-center',
 					cellRenderer: function(params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "판매 개수", field: "sellQty", width: 120, cellClass: 'text-left',
+				{headerName: "판매 개수", field: "sellQty", width: 120, cellClass: 'text-right',
 					cellRenderer: function(params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "YOY(%)", field: "yoyRate", width: 100, cellClass: 'text-left',
+				{headerName: "YOY(%)", field: "yoyRate", width: 100, cellClass: 'text-right',
 					cellRenderer: function(params) {
 						return params.value +'%';
 					}
@@ -399,7 +399,11 @@
 			}
 		});
 
-		totInfo.yoyRate = (totInfo.totAmt / totInfo.yoyTotOrdAmt * 100 - 100).toFixed(1);
+		if(totInfo.totAmt > 0 && totInfo.yoyTotOrdAmt > 0){
+			totInfo.yoyRate = (totInfo.totAmt / totInfo.yoyTotOrdAmt * 100 - 100).toFixed(1);
+		}else{
+			totInfo.yoyRate = 0;
+		}
 
 		gagaAgGrid.setPinnedRowData(gridOptions, totInfo, 'top');
 	}

+ 465 - 0
src/main/webapp/WEB-INF/views/statistics/CategoryTradingForm.html

@@ -0,0 +1,465 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : CategoryTradingForm.html
+ * @desc    : 카테고리별주문 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021-09-22 수   lmc        최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title"></div>
+		<!-- //메인타이틀 영역 -->
+
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc"></div>
+		<!-- //메뉴 설명 -->
+
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<form id="searchForm" name="searchForm" action="#" th:action="@{'/statistics/category/order/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+				<input type="hidden" name="dayGb" value="D"/>
+
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:25%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>기간<i class="required" title="필수" aria-hidden="true"></i></th>
+						<td colspan="5" id="terms">
+						</td>
+					</tr>
+					<tr>
+						<th>디바이스</th>
+						<td>
+							<label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="P" checked="checked"/>PC웹</label>
+							<label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="M" checked="checked"/>모바일웹</label>
+							<label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="A" checked="checked"/>APP</label>
+						</td>
+						<th>제휴몰</th>
+						<td>
+							<input type="text" class="w100" name="extmallIdSearchTxt" id="extmallIdSearchTxt" maxlength="20"/>
+							<button type="button" class="btn icn" onclick="cfnOpenExtmallListPopup('fnSetExtmallInfo', 'M');"><i class="fa fa-search"></i></button>
+							<span id="extmallIdTxt"></span>
+							<input type="hidden" name="extmallIdList"/>
+						</td>
+					</tr>
+					<tr>
+						<th>공급업체</th>
+						<td>
+							<input type="text" class="w100" name="supplyCompCdSearchTxt" id="supplyCompCdSearchTxt" maxlength="20"/>
+							<button type="button" class="btn icn" onclick="cfnOpenCompanyListPopup('fnSetSupplyCompInfo', 'M');"><i class="fa fa-search"></i></button>
+							<span id="supplyCompCdTxt"></span>
+							<input type="hidden" name="supplyCompCdList"/>
+						</td>
+						<th>브랜드</th>
+						<td>
+							<input type="text" class="w100" name="brandCdSearchTxt" id="brandCdSearchTxt" maxlength="20" />
+							<button type="button" class="btn icn" onclick="cfnOpenBrandListPopup('fnSetBrandInfo', 'M');"><i class="fa fa-search"></i></button>
+							<span id="brandCdTxt"></span>
+							<input type="hidden" name="brandCdList"/>
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit">초기화</button>
+					</li>
+				</ul>
+			</form>
+			<form id="detailSearchForm" action="/statistics/category/order/detail/list" style="display:none;">
+				<input name="itemkindCd">
+				<input name="startDt">
+				<input name="endDt">
+			</form>
+		</div>
+		<!-- 검색조건 영역 -->
+
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<ul class="panelBar">
+				<li>
+					<button type="button" class="btn btn-default btn-lg" onclick="fnExcelDownLoad();">엑셀다운로드</button>
+				</li>
+			</ul>
+			<div id="gridList" style="width: 100%; height: 470px" class="ag-theme-balham"></div>
+		</div>
+		<div class="panelStyle">
+			<ul class="panelBar">
+				<li>
+					<button type="button" class="btn btn-default btn-lg" onclick="fnDetailExcelDownLoad();">엑셀다운로드</button>
+				</li>
+			</ul>
+			<div id="detailGridList" style="width: 100%; height: 470px" class="ag-theme-balham"></div>
+		</div>
+		<!-- //리스트 영역 -->
+	</div>
+
+<style>
+.ag-header-group-text{
+	margin-left: calc(50% - 25px);
+}
+</style>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	let columnDefs = [
+		{ headerName: "대분류", field: "cateNm1", width: 150, cellClass: 'text-center' },
+		{ headerName: "중분류", field: "cateNm2", width: 150, cellClass: 'text-center' },
+		{ headerName: "소분류", field: "cateNm3", width: 150, cellClass: 'text-center' },
+		{ headerName: "매출 현황", field: "", width: 100, cellClass: 'text-center',
+			children: [
+				{headerName: "총 매출액(A+B)", field: "totAmt", width: 120, cellClass: 'text-right',
+					cellRenderer: function(params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "자사몰(A)", field: "selfmallAmt", width: 120, cellClass: 'text-right',
+					cellRenderer: function(params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "제휴몰(B)", field: "extmallAmt", width: 120, cellClass: 'text-right',
+					cellRenderer: function(params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+			]
+		},
+		{ headerName: "판매현황보기", field: "sellStatus", width: 100, cellClass: 'text-center',
+			cellRenderer: function (params) {
+				return '<a href="javascript:void(0);">판매현황보기</a>';
+			}
+		},
+	];
+
+	let detailColumnDefs = [
+		{ headerName: "브랜드", field: "brandEnm", width: 150, cellClass: 'text-center' },
+		{ headerName: "상품번호", field: "goodsCd", width: 150, cellClass: 'text-center',
+			cellRenderer: function (params) {
+				return '<a href="javascript:void(0);">'+params.value+'</a>';
+			}
+		},
+		{ headerName: "상품명", field: "goodsNm", width: 300, cellClass: 'text-left',
+			cellRenderer: function (params) {
+				return '<a href="javascript:void(0);">'+params.value+'</a>';
+			}
+		},
+		{ headerName: "상품매출액", field: "totAmt", width: 150, cellClass: 'text-right',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+			}
+		},
+		{ headerName: "판매수량", field: "sellQty", width: 150, cellClass: 'text-right',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+			}
+		},
+		{ headerName: "구매자수", field: "ordCust", width: 150, cellClass: 'text-right',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+			}
+		},
+	];
+
+	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+	let detailGridOptions = gagaAgGrid.getGridOptions(detailColumnDefs);
+
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var params = event.data;
+		if (event.colDef.field == "goodsCd"){
+			cfnOpenGoodsDetailPopup('U', params.goodsCd);
+		}
+		else if (event.colDef.field == "goodsNm"){
+			cfnOpenGoodsDetailPopup('U', params.goodsCd);
+		}
+		else if (event.colDef.field == "sellStatus"){
+			$("#detailSearchForm input[name=itemkindCd]").val(params.itemkindCd);
+			$("#detailSearchForm input[name=startDt]").val($("#searchForm input[name=startDt]").val());
+			$("#detailSearchForm input[name=endDt]").val($("#searchForm input[name=endDt]").val());
+			gagaAgGrid.fetch($('#detailSearchForm').prop('action'), detailGridOptions, '#detailSearchForm', fnDetailCreateTotal);
+		}
+	}
+
+	// Row Click
+	detailGridOptions.onCellClicked = function(event) {
+		var params = event.data;
+		if (event.colDef.field == "goodsCd"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}
+		else if (event.colDef.field == "goodsNm"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}
+	}
+
+    gridOptions.excelStyles = [
+        {
+            id: 'text-center',
+            dataType: 'string',
+			font: {size : 10, bold: false}
+        },
+        {
+            id: 'text-left',
+            dataType: 'string',
+			font: {size : 10, bold: false}
+        },
+        {
+            id: 'text-right',
+            dataType: 'number',
+			font: {size : 10, bold: false}
+        }
+    ];
+
+    detailGridOptions.excelStyles = gridOptions.excelStyles;
+
+    var fnExcelDownLoad = function(){
+
+    	var totalRows = gridOptions.api.getDisplayedRowCount();
+		if(totalRows==0){
+			mcxDialog.alert('조회된 내역이 없습니다.');
+			return;
+		}
+
+    	var date = new Date().format("YYYYMMDDHHmmss");
+		var params = {
+						fileName : "카테고리별 주문목록_"+ date,
+						sheetName: "DATA"
+					 };
+		gridOptions.api.exportDataAsExcel(params);
+    }
+    var fnDetailExcelDownLoad = function(){
+
+    	var totalRows = detailGridOptions.api.getDisplayedRowCount();
+		if(totalRows==0){
+			mcxDialog.alert('조회된 내역이 없습니다.');
+			return;
+		}
+
+    	var date = new Date().format("YYYYMMDDHHmmss");
+		var params = {
+						fileName : "카테고리별 주문상세목록_"+ date,
+						sheetName: "DATA"
+					 };
+		detailGridOptions.api.exportDataAsExcel(params);
+    }
+
+	// 제휴몰 조회 팝업에서 호출
+	var fnSetExtmallInfo = function(result) {
+		var arrExtmallId = [];
+		var extmallIdTxt = "";
+		var sIndex = 0;
+		$('#extmallIdTxt').html('');
+		$('#searchForm input[name=extmallIdSearchTxt]').val('');
+
+		result.forEach(function(extmall) {
+			sIndex++;
+			arrExtmallId.push(extmall.extmallId);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (sIndex == 1) {
+			$('#searchForm input[name=extmallIdSearchTxt]').val(arrExtmallId[0]);
+		} else {
+			extmallIdTxt = sIndex + " 개";
+			$('#extmallIdTxt').html(extmallIdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrExtmallId);
+		$("#searchForm input[name=extmallIdList]").val(arrExtmallId.join(','));
+	}
+
+	// 업체 조회 팝업에서 호출
+	var fnSetSupplyCompInfo = function(result) {
+		var arrSupplyCompCd = [];
+		var supplyCompCdTxt = "";
+		var sIndex = 0;
+		$('#supplyCompCdTxt').html('');
+		$('#searchForm input[name=supplyCompCdSearchTxt]').val('');
+
+		result.forEach(function(supplyComp) {
+			sIndex++;
+			arrSupplyCompCd.push(supplyComp.supplyCompCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (sIndex == 1) {
+			$('#searchForm input[name=supplyCompCdSearchTxt]').val(arrSupplyCompCd[0]);
+		} else {
+			supplyCompCdTxt = sIndex + " 개";
+			$('#supplyCompCdTxt').html(supplyCompCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrSupplyCompCd);
+		$("#searchForm input[name=supplyCompCdList]").val(arrSupplyCompCd.join(','));
+	}
+
+	// 제휴채널 조회 팝업에서 호출
+	var fnSetAfLinkInfo = function(result) {
+		var arrAfLinkCd = [];
+		var afLinkCdTxt = "";
+		var sIndex = 0;
+		$('#afLinkCdTxt').html('');
+		$('#searchForm input[name=afLinkCdSearchTxt]').val('');
+
+		result.forEach(function(afLink) {
+			sIndex++;
+			arrAfLinkCd.push(afLink.afLinkCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (sIndex == 1) {
+			$('#searchForm input[name=afLinkCdSearchTxt]').val(arrAfLinkCd[0]);
+		} else {
+			afLinkCdTxt = sIndex + " 개";
+			$('#afLinkCdTxt').html(afLinkCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrAfLinkCd);
+		$("#searchForm input[name=afLinkCdList]").val(arrAfLinkCd.join(","));
+	}
+
+	// 브랜드 조회 팝업에서 호출
+	var fnSetBrandInfo = function(result) {
+		var arrBrandCd = [];
+		var brandCdTxt = "";
+		var bIndex = 0;
+		$('#brandCdTxt').html('');
+		$('#searchForm input[name=brandCdSearchTxt]').val('');
+
+		result.forEach(function(brand){
+			bIndex++;
+			arrBrandCd.push(brand.brandCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (bIndex == 1) {
+			$('#searchForm input[name=brandCdSearchTxt]').val(arrBrandCd[0]);
+		} else {
+			brandCdTxt = bIndex + " 개";
+			$('#brandCdTxt').html(brandCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrBrandCd);
+		$("#searchForm input[name=brandCdList]").val(arrBrandCd.join(","));
+	}
+
+	// 품목 조회 팝업에서 호출
+	var fnSetItemkindInfo = function(result) {
+		var arrItemkindCd = [];
+		var itemkindCdTxt = "";
+		var bIndex = 0;
+		$('#itemkindCdTxt').html('');
+		$('#searchForm input[name=itemkindCdSearchTxt]').val('');
+
+		result.forEach(function(itemkind){
+			bIndex++;
+			arrItemkindCd.push(itemkind.itemkindCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (bIndex == 1) {
+			$('#searchForm input[name=itemkindCdSearchTxt]').val(arrItemkindCd[0]);
+		} else {
+			itemkindCdTxt = bIndex + " 개";
+			$('#itemkindCdTxt').html(itemkindCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrItemkindCd);
+		$("#searchForm input[name=itemkindCdList]").val(arrItemkindCd.join(','));
+	}
+
+	// 검색
+	$('#btnSearch').on('click', function() {
+		// 입력 값 체크
+		if (!gagajf.validation($('#searchForm')))
+			return false;
+
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm', fnCreateTotal);
+	});
+
+	// 합계 생성
+	let fnCreateTotal = function() {
+
+		let totInfo = {};
+		totInfo.itemkindCd  = "TOTAL";
+		totInfo.totAmt      = 0;
+		totInfo.selfmallAmt = 0;
+		totInfo.extmallAmt  = 0;
+
+		gridOptions.api.forEachNode(function(rowNode, index) {
+			if (!rowNode.group) {
+				if( typeof rowNode.data.totAmt         == 'number') { totInfo.totAmt          += rowNode.data.totAmt         ; }
+				if( typeof rowNode.data.selfmallAmt    == 'number') { totInfo.selfmallAmt     += rowNode.data.selfmallAmt    ; }
+				if( typeof rowNode.data.extmallAmt     == 'number') { totInfo.extmallAmt      += rowNode.data.extmallAmt     ; }
+			}
+		});
+
+		gagaAgGrid.setPinnedRowData(gridOptions, totInfo, 'top');
+	}
+
+	// 합계 생성
+	let fnDetailCreateTotal = function() {
+
+		let totInfo = {};
+		totInfo.brandEnm= 'TOTAL';
+		totInfo.goodsCd = '';
+		totInfo.goodsNm	= '';
+		totInfo.totAmt  = 0;
+		totInfo.sellQty = 0;
+		totInfo.ordCust = 0;
+
+		detailGridOptions.api.forEachNode(function(rowNode, index) {
+			if (!rowNode.group) {
+				if( typeof rowNode.data.totAmt     == 'number') { totInfo.totAmt      += rowNode.data.totAmt     ; }
+				if( typeof rowNode.data.sellQty    == 'number') { totInfo.sellQty     += rowNode.data.sellQty    ; }
+				if( typeof rowNode.data.ordCust    == 'number') { totInfo.ordCust     += rowNode.data.ordCust    ; }
+			}
+		});
+
+		gagaAgGrid.setPinnedRowData(detailGridOptions, totInfo, 'top');
+	}
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		$('#searchForm')[0].reset();
+
+		$('#extmallIdTxt').html('');
+		$('#searchForm input[name=extmallIdList]').val('');
+		$('#supplyCompCdTxt').html('');
+		$('#searchForm input[name=supplyCompCdList]').val('');
+		$('#afLinkCdTxt').html('');
+		$('#searchForm input[name=afLinkCdList]').val('');
+		$('#brandCdTxt').html('');
+		$('#searchForm input[name=brandCdList]').val('');
+		$('#itemkindCdTxt').html('');
+		$('#searchForm input[name=itemkindCdList]').val('');
+	});
+
+	$(document).ready(function() {
+		cfnCreateCalendar('#terms', 'startDt', 'endDt', true, '주문', undefined, ['btnToday']);
+		$('.btnYesterday').trigger('click');
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+		// Create a agGrid
+		gagaAgGrid.createGrid('detailGridList', detailGridOptions);
+
+		//조회
+		$('#btnSearch').click();
+	});
+/*]]>*/
+</script>
+
+</html>

+ 6 - 2
src/main/webapp/WEB-INF/views/statistics/ChannelTradingForm.html

@@ -373,11 +373,15 @@
 				if( typeof rowNode.data.realOrdAmt   == 'number') { totInfo.realOrdAmt   += rowNode.data.realOrdAmt   ; }
 				if( typeof rowNode.data.sellFeeRate  == 'number') { totInfo.sellFeeRate  += rowNode.data.sellFeeRate  ; }
 				if( typeof rowNode.data.exUsacAmt    == 'number') { totInfo.exUsacAmt    += rowNode.data.exUsacAmt    ; }
-				if( typeof rowNode.data.yoyTotOrdAmt == 'number') { totInfo.yoyTotOrdAmt +=  rowNode.data.yoyTotOrdAmt; }
+				if( typeof rowNode.data.yoyTotOrdAmt == 'number') { totInfo.yoyTotOrdAmt += rowNode.data.yoyTotOrdAmt ; }
 			}
 		});
 
-		totInfo.yoyRate = (totInfo.totAmt / totInfo.yoyTotOrdAmt * 100 - 100).toFixed(1);
+		if(totInfo.totAmt > 0 && totInfo.yoyTotOrdAmt > 0 ){
+			totInfo.yoyRate = (totInfo.totAmt / totInfo.yoyTotOrdAmt * 100 - 100).toFixed(1);
+		}else{
+			totInfo.yoyRate = 0;
+		}
 
 		gagaAgGrid.setPinnedRowData(gridOptions, totInfo, 'top');
 	}

+ 5 - 1
src/main/webapp/WEB-INF/views/statistics/ExtmallTradingForm.html

@@ -316,7 +316,11 @@
 			}
 		});
 
-		totInfo.yoyRate = (totInfo.totAmt / totInfo.yoyTotOrdAmt * 100 - 100).toFixed(1);
+		if(totInfo.totAmt > 0 && totInfo.yoyTotOrdAmt > 0 ){
+			totInfo.yoyRate = (totInfo.totAmt / totInfo.yoyTotOrdAmt * 100 - 100).toFixed(1);
+		}else{
+			totInfo.yoyRate = 0;
+		}
 
 		gagaAgGrid.setPinnedRowData(gridOptions, totInfo, 'top');
 	}

+ 486 - 0
src/main/webapp/WEB-INF/views/statistics/HourlyTradingForm.html

@@ -0,0 +1,486 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : HourlyTradingForm.html
+ * @desc    : 시간별 주문 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021-09-16 목   lmc        최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title"></div>
+		<!-- //메인타이틀 영역 -->
+
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc"></div>
+		<!-- //메뉴 설명 -->
+
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<form id="searchForm" name="searchForm" action="#" th:action="@{'/statistics/hourly/order/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+				<input type="hidden" name="dayGb" value="D"/>
+
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:25%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>기간<i class="required" title="필수" aria-hidden="true"></i></th>
+						<td colspan="3" id="terms"></td>
+					</tr>
+					<tr>
+						<th>비교기간<i class="required" title="필수" aria-hidden="true"></i></th>
+						<td colspan="3">
+							<label class="chkBox checked"><input type="checkbox" name="dtGb" value="COMPARE_TERMS"/>직전 동일 기간 비교</label>
+							<label class="chkBox checked"><input type="checkbox" name="dtGb" value="YOY"/>전년 비교</label>
+							<span id="compTerms"></span>
+						</td>
+					</tr>
+					<tr>
+						<th>디바이스</th>
+						<td>
+							<label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="P" checked="checked"/>PC웹</label>
+							<label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="M" checked="checked"/>모바일웹</label>
+							<label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="A" checked="checked"/>APP</label>
+						</td>
+						<th>제휴몰</th>
+						<td>
+							<input type="text" class="w100" name="extmallIdSearchTxt" id="extmallIdSearchTxt" maxlength="20"/>
+							<button type="button" class="btn icn" onclick="cfnOpenExtmallListPopup('fnSetExtmallInfo', 'M');"><i class="fa fa-search"></i></button>
+							<span id="extmallIdTxt"></span>
+							<input type="hidden" name="extmallIdList"/>
+						</td>
+					</tr>
+					<tr>
+						<th>브랜드</th>
+						<td>
+							<input type="text" class="w100" name="brandCdSearchTxt" id="brandCdSearchTxt" maxlength="20" />
+							<button type="button" class="btn icn" onclick="cfnOpenBrandListPopup('fnSetBrandInfo', 'M');"><i class="fa fa-search"></i></button>
+							<span id="brandCdTxt"></span>
+							<input type="hidden" name="brandCdList"/>
+						</td>
+						<th>품목</th>
+						<td>
+							<input type="text" class="w100" name="itemkindCdSearchTxt" id="itemkindCdSearchTxt" maxlength="20" />
+							<button type="button" class="btn icn" onclick="cfnOpenItemkindListPopup('fnSetItemkindInfo', 'M');"><i class="fa fa-search"></i></button>
+							<span id="itemkindTxt"></span>
+							<input type="hidden" name="itemkindCdList"/>
+						</td>
+					</tr>
+				</table>
+
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit">초기화</button>
+					</li>
+				</ul>
+			</form>
+		</div>
+		<!-- 검색조건 영역 -->
+
+		<!-- 차트영역 -->
+		<div class="panelStyle" id="chartDiv" style="display:none;">
+			<div id="chart" class="chartUnit"></div>
+		</div>
+		<!-- //차트영역 -->
+
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<ul class="panelBar">
+				<li>
+					<button type="button" class="btn btn-default btn-lg" onclick="fnExcelDownLoad();">엑셀다운로드</button>
+				</li>
+			</ul>
+			<div id="gridList" style="width: 100%; height: 470px" class="ag-theme-balham"></div>
+		</div>
+		<!-- //리스트 영역 -->
+	</div>
+
+<style>
+.ag-header-group-text{
+	margin-left: calc(50% - 25px);
+}
+</style>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	let columnDefs = [
+		{ headerName: "시간", field: "hour", width: 100, cellClass: 'text-center'},
+		{ headerName: "매출현황", field: "", width: 100, cellClass: 'text-center',
+			children: [
+				{headerName: "시간 별 매출액", field: "ordAmt", width: 120, cellClass: 'text-right',
+					cellRenderer: function(params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "비교(A)", field: "compOrdAmt", width: 120, cellClass: 'text-right',
+					cellRenderer: function(params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "달성율(%)", field: "cplRate", width: 120, cellClass: 'text-right',
+					cellRenderer: function(params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+			]
+		},
+		{ headerName: "주문 현황", field: "", width: 100, cellClass: 'text-center',
+			children: [
+				{headerName: "주문자수", field: "ordCust", width: 150, cellClass: 'text-right',
+					cellRenderer: function (params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "주문 수", field: "ordCnt", width: 150, cellClass: 'text-right',
+					cellRenderer: function (params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "판매수", field: "sellQty", width: 150, cellClass: 'text-right',
+					cellRenderer: function (params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "객단가", field: "custPrice", width: 150, cellClass: 'text-right',
+					cellRenderer: function (params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "취/반품갯수", field: "cnclQty", width: 150, cellClass: 'text-right',
+					cellRenderer: function (params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+				{headerName: "취/반품액", field: "cnclAmt", width: 150, cellClass: 'text-right',
+					cellRenderer: function (params) {
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
+					}
+				},
+			]
+		},
+	];
+
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var goodsCd = event.data.goodsCd;
+		if (event.colDef.field == "goodsCd"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}
+		if (event.colDef.field == "goodsNm"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}
+	}
+
+    gridOptions.excelStyles = [
+        {
+            id: 'text-center',
+            dataType: 'string',
+			font: {size : 10, bold: false}
+        },
+        {
+            id: 'text-left',
+            dataType: 'string',
+			font: {size : 10, bold: false}
+        },
+        {
+            id: 'text-right',
+            dataType: 'number',
+			font: {size : 10, bold: false}
+        }
+    ];
+
+    var fnExcelDownLoad = function(){
+
+    	var totalRows = gridOptions.api.getDisplayedRowCount();
+		if(totalRows==0){
+			mcxDialog.alert('조회된 내역이 없습니다.');
+			return;
+		}
+
+    	var date = new Date().format("YYYYMMDDHHmmss");
+		var params = {
+						fileName : "시간별 주문목록_"+ date,
+						sheetName: "DATA"
+					 };
+		gridOptions.api.exportDataAsExcel(params);
+    }
+
+	// 제휴몰 조회 팝업에서 호출
+	var fnSetExtmallInfo = function(result) {
+		var arrExtmallId = [];
+		var extmallIdTxt = "";
+		var sIndex = 0;
+		$('#extmallIdTxt').html('');
+		$('#searchForm input[name=extmallIdSearchTxt]').val('');
+
+		result.forEach(function(extmall) {
+			sIndex++;
+			arrExtmallId.push(extmall.extmallId);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (sIndex == 1) {
+			$('#searchForm input[name=extmallIdSearchTxt]').val(arrExtmallId[0]);
+		} else {
+			extmallIdTxt = sIndex + " 개";
+			$('#extmallIdTxt').html(extmallIdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrExtmallId);
+		$("#searchForm input[name=extmallIdList]").val(arrExtmallId.join(','));
+	}
+
+	// 업체 조회 팝업에서 호출
+	var fnSetSupplyCompInfo = function(result) {
+		var arrSupplyCompCd = [];
+		var supplyCompCdTxt = "";
+		var sIndex = 0;
+		$('#supplyCompCdTxt').html('');
+		$('#searchForm input[name=supplyCompCdSearchTxt]').val('');
+
+		result.forEach(function(supplyComp) {
+			sIndex++;
+			arrSupplyCompCd.push(supplyComp.supplyCompCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (sIndex == 1) {
+			$('#searchForm input[name=supplyCompCdSearchTxt]').val(arrSupplyCompCd[0]);
+		} else {
+			supplyCompCdTxt = sIndex + " 개";
+			$('#supplyCompCdTxt').html(supplyCompCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrSupplyCompCd);
+		$("#searchForm input[name=supplyCompCdList]").val(arrSupplyCompCd.join(','));
+	}
+
+	// 제휴채널 조회 팝업에서 호출
+	var fnSetAfLinkInfo = function(result) {
+		var arrAfLinkCd = [];
+		var afLinkCdTxt = "";
+		var sIndex = 0;
+		$('#afLinkCdTxt').html('');
+		$('#searchForm input[name=afLinkCdSearchTxt]').val('');
+
+		result.forEach(function(afLink) {
+			sIndex++;
+			arrAfLinkCd.push(afLink.afLinkCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (sIndex == 1) {
+			$('#searchForm input[name=afLinkCdSearchTxt]').val(arrAfLinkCd[0]);
+		} else {
+			afLinkCdTxt = sIndex + " 개";
+			$('#afLinkCdTxt').html(afLinkCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrAfLinkCd);
+		$("#searchForm input[name=afLinkCdList]").val(arrAfLinkCd.join(","));
+	}
+
+	// 브랜드 조회 팝업에서 호출
+	var fnSetBrandInfo = function(result) {
+		var arrBrandCd = [];
+		var brandCdTxt = "";
+		var bIndex = 0;
+		$('#brandCdTxt').html('');
+		$('#searchForm input[name=brandCdSearchTxt]').val('');
+
+		result.forEach(function(brand){
+			bIndex++;
+			arrBrandCd.push(brand.brandCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (bIndex == 1) {
+			$('#searchForm input[name=brandCdSearchTxt]').val(arrBrandCd[0]);
+		} else {
+			brandCdTxt = bIndex + " 개";
+			$('#brandCdTxt').html(brandCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrBrandCd);
+		$("#searchForm input[name=brandCdList]").val(arrBrandCd.join(","));
+	}
+
+	// 품목 조회 팝업에서 호출
+	var fnSetItemkindInfo = function(result) {
+		var arrItemkindCd = [];
+		var itemkindCdTxt = "";
+		var bIndex = 0;
+		$('#itemkindCdTxt').html('');
+		$('#searchForm input[name=itemkindCdSearchTxt]').val('');
+
+		result.forEach(function(itemkind){
+			bIndex++;
+			arrItemkindCd.push(itemkind.itemkindCd);
+		});
+
+		// 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
+		if (bIndex == 1) {
+			$('#searchForm input[name=itemkindCdSearchTxt]').val(arrItemkindCd[0]);
+		} else {
+			itemkindCdTxt = bIndex + " 개";
+			$('#itemkindCdTxt').html(itemkindCdTxt);
+		}
+
+		var jsonData = JSON.stringify(arrItemkindCd);
+		$("#searchForm input[name=itemkindCdList]").val(arrItemkindCd.join(','));
+	}
+
+	// 검색
+	$('#btnSearch').on('click', function() {
+		// 입력 값 체크
+		if (!gagajf.validation($('#searchForm')))
+			return false;
+
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm', fnCreateTotal);
+	});
+
+	// 합계 생성
+	let fnCreateTotal = function() {
+
+		// Draw chart
+		fnDrawChart(gagaAgGrid.getAllRowData(gridOptions));
+		$("#chartDiv").show();
+
+		let totInfo = {};
+		totInfo.hour       = 'TOTAL';
+		totInfo.ordAmt     = 0;
+		totInfo.compOrdAmt = 0;
+		totInfo.cplRate    = 0;
+		totInfo.ordCust    = 0;
+		totInfo.ordCnt     = 0;
+		totInfo.sellQty    = 0;
+		totInfo.custPrice  = 0;
+		totInfo.cnclQty    = 0;
+		totInfo.cnclAmt	   = 0;
+
+
+		gridOptions.api.forEachNode(function(rowNode, index) {
+			if (!rowNode.group) {
+				if( typeof rowNode.data.ordAmt     == 'number') { totInfo.ordAmt      += rowNode.data.ordAmt     ; }
+				if( typeof rowNode.data.compOrdAmt == 'number') { totInfo.compOrdAmt  += rowNode.data.compOrdAmt ; }
+				if( typeof rowNode.data.cplRate    == 'number') { totInfo.cplRate     += rowNode.data.cplRate    ; }
+				if( typeof rowNode.data.ordCust    == 'number') { totInfo.ordCust     += rowNode.data.ordCust    ; }
+				if( typeof rowNode.data.ordCnt     == 'number') { totInfo.ordCnt      += rowNode.data.ordCnt     ; }
+				if( typeof rowNode.data.sellQty    == 'number') { totInfo.sellQty     += rowNode.data.sellQty    ; }
+				if( typeof rowNode.data.custPrice  == 'number') { totInfo.custPrice   += rowNode.data.custPrice  ; }
+				if( typeof rowNode.data.cnclQty    == 'number') { totInfo.cnclQty     += rowNode.data.cnclQty    ; }
+				if( typeof rowNode.data.cnclAmt	   == 'number') { totInfo.cnclAmt	  += rowNode.data.cnclAmt	 ; }
+			}
+		});
+
+		gagaAgGrid.setPinnedRowData(gridOptions, totInfo, 'top');
+	}
+
+	// 그래프 그리기
+	var chart1;
+	var fnDrawChart = function(data) {
+		let xList = [];
+		let totOrdAmtList = [];
+		let compOrdAmtList = [];
+
+		for(var i in data){
+			xList.push(data[i].hour);
+			totOrdAmtList.push(data[i].ordAmt);
+			compOrdAmtList.push(data[i].compOrdAmt);
+		}
+
+		chart1 = c3.generate({
+			bindto: "#chart",
+			padding: {
+				bottom: 20 //adjust chart padding bottom
+			},
+			data: {
+				x: 'x',
+				json: {
+					x: xList,
+					결제액: totOrdAmtList,
+					비교기간결제액: compOrdAmtList
+				},
+				types: {
+					결제액: 'bar',
+					비교기간결제액: 'line'
+				}
+			},
+		    axis : {
+				x: {
+					type: 'category',
+					padding: { left: 0.5, right: 0.5 }
+				},
+		        y : {
+		            tick: {
+		                format: d3.format(",")
+		            }
+		        }
+		    },
+			color: {
+				pattern: ['#48C9B0', '#FF7043']
+			},
+			legend: { padding: 15 }, //범례 item 우측 간격
+			tooltip: {
+				format: {
+					title: function (d) {
+						return '시간별 주문 통계 Chart';
+					},
+				}
+			}
+		});
+	}
+
+	// LNB 또는 GNB 클릭시 차트 넓이 변경
+	var chartResize = function() {
+		setTimeout(function () {
+			// 모든 차트 ID객체에 적용
+			chart1.resize();
+		}, 300);
+	}
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		$('#searchForm')[0].reset();
+
+		$('#extmallIdTxt').html('');
+		$('#searchForm input[name=extmallIdList]').val('');
+		$('#supplyCompCdTxt').html('');
+		$('#searchForm input[name=supplyCompCdList]').val('');
+		$('#afLinkCdTxt').html('');
+		$('#searchForm input[name=afLinkCdList]').val('');
+		$('#brandCdTxt').html('');
+		$('#searchForm input[name=brandCdList]').val('');
+		$('#itemkindCdTxt').html('');
+		$('#searchForm input[name=itemkindCdList]').val('');
+	});
+
+	$(document).ready(function() {
+		cfnCreateCalendar('#terms', 'startDt', 'endDt', true, '주문', undefined, ['btnToday']);
+		$('.btnYesterday').trigger('click');
+		cfnCreateCalendar('#compTerms', 'compStDt', 'compEdDt', true, '주문', undefined, ['btnToday']);
+		$('.btnYesterday').trigger('click');
+
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+/*]]>*/
+</script>
+
+</html>

+ 19 - 26
src/main/webapp/WEB-INF/views/withdraw/RefundDetailForm.html

@@ -405,7 +405,9 @@
 		
 		if (data.pgGb == 'KCP') {
 			pgGbNm	= data.payMeansNm;
-			cardGbNm	= "(" + data.cardNm + ")";
+			if(!gagajf.isNull(data.cardNm)) {
+				cardGbNm = "(" + data.cardNm + ")";
+			}
 		} else if (data.pgGb == 'NAVER') {
 			pgGbNm	= "네이버페이";
 		} else if (data.pgGb == 'NAVER_ORDER') {
@@ -504,16 +506,11 @@
 		let refundAmt;
 		
 		// 2021.09.07 card007 전체반품 원배송비 무료 해택 차감 처리
-		console.log('delvCanYn : ' + reFundInfo.delvCanYn);
-		console.log('delvFeeCdCanList : ' + reFundInfo.delvCanYn.delvFeeCdCanList);
-		console.log('allDelvCanYnList : ' + reFundInfo.delvCanYn.allDelvCanYnList);
 		let delvFeeCdCanList = reFundInfo.delvCanYn.delvFeeCdCanList;
 		let allDelvCanYnList = reFundInfo.delvCanYn.allDelvCanYnList;
 		
 		let index = -1;
 		$.each(delvFeeCdCanList, function(idx, item) {
-			console.log('delvFeeCd : ' + reFundInfo.delvFeeCd);
-			console.log('item : ' + item);
 			if (reFundInfo.delvFeeCd == item) {
 				index = idx;
 			}
@@ -524,22 +521,15 @@
 			allDelvCanYn = allDelvCanYnList[index]
 		}
 		
-		console.log('allDelvCanYn : ' + allDelvCanYn);
 		let orgDelvFee = 0;
-		console.log('returnOrderInfo : ' + returnOrderInfo);
-		console.log('delvGfcdUseAmt : ' + returnOrderInfo[0].delvGfcdUseAmt);
-		console.log('realDelvAmt : ' + returnOrderInfo[0].realDelvAmt);
-		console.log('orgDelvFee : ' + returnOrderInfo[0].orgDelvFee);
 		if (allDelvCanYn == 'Y' && returnOrderInfo != null && returnOrderInfo[0].delvGfcdUseAmt + returnOrderInfo[0].realDelvAmt == 0) {
 			orgDelvFee = returnOrderInfo[0].orgDelvFee;
 		}
 
-		console.log('orgDelvFee : ' + orgDelvFee);
-		
 		// 출고예외(확정후 품절,불량)일 경우
 		if (delvExpnYn == "Y") {
 			// 총 주문수량  =  반품수량 배송비가 있을시 환불해줌
-			if (toTalOrdQty == ordChgQty) {
+			if (allDelvCanYn == 'Y') {
 				if (spanSumDeliveryFee > 0) {
 					addDeliveryFee = spanSumDeliveryFee - spanDelvCpnDcAmt;
 					addDeliveryFeeYn = "Y";
@@ -640,9 +630,6 @@
 						// 2021.07.02 환불컨펌 환불금액계산
 						// 환불금액  = (취소상품실결제금액 + 동봉비 + 추가결제비) - (추가배송비 + 반품배송비 + 착불비)
 						//reFundInfo.spanRefundAmt = (reFundInfo.spanRealCnclRtnAmt + Number(enCloseFee) + Number(addPaycost)) - (spanTotDeliveryFee + spanTotRtnDelvFee);
-						console.log('spanTotDeliveryFee : ' + spanTotDeliveryFee);
-						console.log('spanTotRtnDelvFee : ' + spanTotRtnDelvFee);
-						console.log('orgDelvFee : ' + orgDelvFee);
 						leftRefundAmt = (spanRealCnclRtnAmt + Number(enCloseFee) + Number(addPaycost));
 						leftDelvFee = spanTotDeliveryFee + spanTotRtnDelvFee + Number(codFee) + orgDelvFee;
 						delvFee = 0 - spanTotDeliveryFee - spanTotRtnDelvFee - orgDelvFee;
@@ -686,7 +673,13 @@
 				else {
 					// 2021.07.02 환불컨펌 환불금액계산
 					// 환불금액  = (취소상품실결제금액)
-					refundAmt = spanRealCnclRtnAmt;
+					if (allDelvCanYn == 'Y') {
+						refundAmt = spanRealCnclRtnAmt + spanSumDeliveryFee - spanDelvCpnDcAmt - spanDelvGfcdUseAmt;
+						delvFee = spanSumDeliveryFee - spanDelvCpnDcAmt;
+						delvGfcdUseAmt	= spanDelvGfcdUseAmt;
+					} else {
+						refundAmt = spanRealCnclRtnAmt;
+					}
 				}
 			}
 		}
@@ -703,21 +696,21 @@
 		
 		// 할인금액차감
 		$(".spanCpnDcAmt").text(spanCpnDcAmt.addComma()+"원");						// 쿠폰할인차감 > 합계
-		$(".spanCpn1DcAmt").text(spanCpn1DcAmt.addComma()+"원");						// 쿠폰할인차감 > 즉시할인쿠폰
-		$(".spanGoodsCpnDcAmt").text(spanGoodsCpnDcAmt.addComma()+"원");				// 쿠폰할인차감 > 주문서상품쿠폰
+		$(".spanCpn1DcAmt").text(spanCpn1DcAmt.addComma()+"원");					// 쿠폰할인차감 > 즉시할인쿠폰
+		$(".spanGoodsCpnDcAmt").text(spanGoodsCpnDcAmt.addComma()+"원");			// 쿠폰할인차감 > 주문서상품쿠폰
 		$(".spanCartCpnDcAmt").text(spanCartCpnDcAmt.addComma()+"원");				// 쿠폰할인차감 > 장바구니쿠폰
-		$(".goodsDcSumAmt").text(goodsDcSumAmt.addComma()+"원");						// 상품할인차감 > 합계
-		$(".spanPrePntDcAmt").text(spanPrePntDcAmt.addComma()+"원");					// 상품할인차감 > 선포인트할인
-		$(".spanTmtbDcAmt").text(spanTmtbDcAmt.addComma()+"원");						// 상품할인차감 > 다다익선할인
+		$(".goodsDcSumAmt").text(goodsDcSumAmt.addComma()+"원");					// 상품할인차감 > 합계
+		$(".spanPrePntDcAmt").text(spanPrePntDcAmt.addComma()+"원");				// 상품할인차감 > 선포인트할인
+		$(".spanTmtbDcAmt").text(spanTmtbDcAmt.addComma()+"원");					// 상품할인차감 > 다다익선할인
 		
 		// 배송비
-		$(".spanRealDelvAmt").text(delvFee.addComma()+"원");							// 환불배송비 > 합계
+		$(".spanRealDelvAmt").text(delvFee.addComma()+"원");						// 환불배송비 > 합계
 		$(".addDelvFee").text(addDelvFee.addComma()+"원");							// 환불배송비 > 추가금결제
-		$(".delvCpnAmt").text(spanDelvCpnDcAmt.addComma()+"원");						// 환불배송비 > 배송비쿠폰
+		$(".delvCpnAmt").text(spanDelvCpnDcAmt.addComma()+"원");					// 환불배송비 > 배송비쿠폰
 		
 		// 환불금액
 		$(".totalRefundAmt").text(totalRefundAmt.addComma()+"원");					// 총환불금액
-		$(".spanRefundAmt").text(refundAmt.addComma()+"원");							// 결제수단환불
+		$(".spanRefundAmt").text(refundAmt.addComma()+"원");						// 결제수단환불
 		$(".pgGbNm").text(pgGbNm);													// 결제수단환불 > 결제수단
 		$(".cardNm").text(cardGbNm);												// 결제수단환불 > 카드명
 		$(".spanGfcdUseAmt").text(totalGfcdUseAmt.addComma()+"원");					// 상품권환불