ソースを参照

Merge branch 'develop' of http://112.172.147.34:4936/style24/style24.admin.git into develop

eskim 4 年 前
コミット
0cbf42264e

+ 10 - 1
src/main/java/com/style24/admin/biz/dao/TsaWithdrawDao.java

@@ -181,8 +181,17 @@ public interface TsaWithdrawDao {
 	 */
 	Collection<Withdraw> getRefundDetailList(Withdraw withdraw);
 
+	/**
+	 * 환불관리 - 반품알림톡 정보 
+	 * 
+	 * @param withdraw - 주문변경번호
+	 * @return Withdraw
+	 * @author moon
+	 * @since 2021. 07. 15
+	 */
+	Withdraw getRefundInfo(Withdraw withdraw);
 
 
-
+	
 
 }

+ 86 - 94
src/main/java/com/style24/admin/biz/service/TsaShoplinkerService.java

@@ -285,19 +285,15 @@ public class TsaShoplinkerService {
 		if( "N".equals(goodsMap.getTobeFormYn())){
 			String descStr = goodsMap.getDetailDesc();
 			if( null != descStr) {
-				descStr = descStr.replace("http://www.istyle24.com/Upload/", "http://image.istyle24.com/Local/")
-						.replace("/Upload", "http://image.istyle24.com/Local")
-						.replace("http://www.istyle24.com/Images", "http://image.istyle24.com/Statics/design/Images");
-
 				htmlDesc = descStr;
 			}
 
 		}else {
 
 			String imgPath = env.getProperty("upload.goods.view");
-			imgPath = imgPath.replace("/Upload", "/Local")
-					.replace("http://www.istyle24.com/Upload/", "http://image.istyle24.com/Local/")
-					.replace("http://www.istyle24.com/Images", "http://image.istyle24.com/Statics/design/Images");
+			imgPath = imgPath.replace("http://www.istyle24.com/Upload/", "http://image.istyle24.com/Local/")
+					.replace("http://www.istyle24.com/Images", "http://image.istyle24.com/Statics/design/Images")
+					.replace("/Upload", "/Local");
 
 			Collection<ShoplinkerGoods> imgList = admShoplinkerDao.getGoodsImageList(shoplinkerGoods);
 
@@ -340,26 +336,22 @@ public class TsaShoplinkerService {
 			if( "".equals(dImgFront)) {
 				String descStr = goodsMap.getDetailDesc();
 				if( null != descStr) {
-					descStr = descStr.replace("http://www.istyle24.com/Upload/", "http://image.istyle24.com/Local/")
-							.replace("/Upload", "http://image.istyle24.com/Local")
-							.replace("http://www.istyle24.com/Images", "http://image.istyle24.com/Statics/design/Images");
-
 					htmlDesc = descStr;
 				}
 
 			}else {
 
 				// 1) 상세내용 - 상품설명
-				htmlDesc = "<div class='st_descrp_box' style='max-height:1100px; overflow:hidden;'>";
-				htmlDesc += "<div class='st_desc_simple' style='position:relative; margin-top:0px; margin-left:auto; margin-right:auto;'>";
-				htmlDesc += "<span class='st_tit_desc' style='display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;'>"+goodsMap.getDetailDescNew10()+"</span>";
-				htmlDesc += "<p class='st_ptxt01' style='font-size:16px;font-weight:200;line-height:1.5;word-break:keep-all;color:#666666;'>";
+				htmlDesc = "<div class=\"st_descrp_box\" style=\"max-height:1100px; overflow:hidden;\">";
+				htmlDesc += "<div class=\"st_desc_simple\" style=\"position:relative; margin-top:0px; margin-left:auto; margin-right:auto;\">";
+				htmlDesc += "<span class=\"st_tit_desc\" style=\"display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;\">"+goodsMap.getDetailDescNew10()+"</span>";
+				htmlDesc += "<p class=\"st_ptxt01\" style=\"font-size:16px;font-weight:200;line-height:1.5;word-break:keep-all;color:#666666;\">";
 				htmlDesc += goodsMap.getDetailDescNew20();
 				htmlDesc += "</p>";
 				htmlDesc += "</div>";
-				htmlDesc += "<div class='st_desc_character' style='position:relative; margin-top:40px; margin-left:auto; margin-right:auto;'>";
-				htmlDesc += "<span class='st_tit_desc' style='display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;'>상품특징</span>";
-				htmlDesc += "<p class='st_ptxt01' style='font-size:16px;font-weight:200;line-height:1.5;word-break:keep-all;color:#666666;'>";
+				htmlDesc += "<div class=\"st_desc_character\" style=\"position:relative; margin-top:40px; margin-left:auto; margin-right:auto;\">";
+				htmlDesc += "<span class=\"st_tit_desc\" style=\"display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;\">상품특징</span>";
+				htmlDesc += "<p class=\"st_ptxt01\" style=\"font-size:16px;font-weight:200;line-height:1.5;word-break:keep-all;color:#666666;\">";
 				htmlDesc += goodsMap.getDetailDescNew30();
 		        htmlDesc += "</p>";
         		htmlDesc += "</div>";
@@ -369,20 +361,20 @@ public class TsaShoplinkerService {
 				String colorDesc = "";
 				shoplinkerGoods.setColorListYn("Y"); // 상품이미지정보 색상별
 				Collection<ShoplinkerGoods> imgColorList = admShoplinkerDao.getGoodsImageList(shoplinkerGoods);
-				colorDesc = "<div class='st_view_option_box' style='margin-top: 100px;text-align: center;'>";
+				colorDesc = "<div class=\"st_view_option_box\" style=\"margin-top: 100px;text-align: center;\">";
 				String tmpColor = "";
 				for(ShoplinkerGoods ic : imgColorList ) {
 
 					if( !tmpColor.equals(ic.getColorCd())) {
-						colorDesc += "<span class='st_tit_desc' style='display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;'>컬러 : ";
+						colorDesc += "<span class=\"st_tit_desc\" style=\"display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;\">컬러 : ";
 						colorDesc += "<span>"+ ic.getColorKnm() +"</span></span>";
 					}
-					colorDesc += "<div class='st_view' style='margin-top: 40px;'>";
-					colorDesc += "<img src='"+ imgPath+"/"+ic.getSysImgNm()+"' alt='' style='max-width:100%;margin: 10px auto 0;margin-top: 0;display: block;'>";
-					colorDesc += "<img src='"+ imgPath+"/"+ic.getSysImgNm()+"' alt='' style='max-width:100%;display: block;margin: 10px auto 0;'>";
+					colorDesc += "<div class=\"st_view\" style=\"margin-top: 40px;\">";
+					colorDesc += "<img src=\""+ imgPath+"/"+ic.getSysImgNm()+"\" alt=\"\" style=\"max-width:100%;margin: 10px auto 0;margin-top: 0;display: block;\">";
+					colorDesc += "<img src=\""+ imgPath+"/"+ic.getSysImgNm()+"\" alt=\"\" style=\"max-width:100%;display: block;margin: 10px auto 0;\">";
 	                colorDesc += "</div>";
 		            if( !tmpColor.equals(ic.getColorCd())) {
-		            	colorDesc += "<div style='height:100px;'></div>";
+		            	colorDesc += "<div style=\"height:100px;\"></div>";
 		            	tmpColor = ic.getColorCd();
 					}
 				}
@@ -391,41 +383,41 @@ public class TsaShoplinkerService {
 
 				// 3) 상세내용 - 모델 착용컷
 				String dtlDesc = "";
-				dtlDesc += "<div class='st_view_outfit_box' style='margin-top: 100px;text-align: center;'>";
-				dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>OUTFIT VIEW</span>";
-				dtlDesc += "<span class='st_model_info' style='display: block;margin-top: 20px;color: #666;font-size: 16px;font-weight: 200;text-align: center;'>"+goodsMap.getModelInfo()+"</span>";
-				dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+				dtlDesc += "<div class=\"st_view_outfit_box\" style=\"margin-top: 100px;text-align: center;\">";
+				dtlDesc += "<span class=\"st_tit_view\" style=\"display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;\">OUTFIT VIEW</span>";
+				dtlDesc += "<span class=\"st_model_info\" style=\"display: block;margin-top: 20px;color: #666;font-size: 16px;font-weight: 200;text-align: center;\">"+goodsMap.getModelInfo()+"</span>";
+				dtlDesc += "<div class=\"st_view\" style=\"margin-top: 40px;\">";
 				for(String img : dImgModelList) {
-					dtlDesc += "<img src='"+ img +"' alt='' style='display: block;margin: 10px auto 0;'>";
+					dtlDesc += "<img src=\""+ img +"\" alt=\"\" style=\"display: block;margin: 10px auto 0;\">";
 				}
 				dtlDesc += "</div>";
 				dtlDesc += "</div>";
 
 				// 4) 상세내용 - 상품컷
-				dtlDesc += "<div class='st_view_detail_box' style='margin-top: 100px;text-align: center;'>";
-				dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>PRODUCT VIEW</span>";
-				dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+				dtlDesc += "<div class=\"st_view_detail_box\" style=\"margin-top: 100px;text-align: center;\">";
+				dtlDesc += "<span class=\"st_tit_view\" style=\"display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;\">PRODUCT VIEW</span>";
+				dtlDesc += "<div class=\"st_view\" style=\"margin-top: 40px;\">";
 				for(String img : dImgDetailList) {
-					dtlDesc += "<img src='"+ img +"' alt='' style='display: block;margin: 10px auto 0;'>";
+					dtlDesc += "<img src=\""+ img +"\" alt=\"\" style=\"display: block;margin: 10px auto 0;\">";
 				}
                 dtlDesc += "</div>";
         		dtlDesc += " </div>";
 
         		// 5) 상세내용 - 원단
-        		dtlDesc += "<div class='st_view_fabric_box' style='margin-top: 100px;text-align: center;'>";
-        		dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>FABRIC</span>";
-        		dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
-        		dtlDesc += "<img src='"+dMaterial +"' alt='' style='display: block;margin: 10px auto 0;margin-top: 0;'>";
+        		dtlDesc += "<div class=\"st_view_fabric_box\" style=\"margin-top: 100px;text-align: center;\">";
+        		dtlDesc += "<span class=\"st_tit_view\" style=\"display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;\">FABRIC</span>";
+        		dtlDesc += "<div class=\"st_view\" style=\"margin-top: 40px;\">";
+        		dtlDesc += "<img src=\""+dMaterial +"\" alt=\"\" style=\"display: block;margin: 10px auto 0;margin-top: 0;\">";
                 dtlDesc += "</div>";
                 dtlDesc += "</div>";
 
                 // 6) 상세내용 - 라벨
-                dtlDesc += "<div class='st_view_label_box' style='margin-top: 100px;text-align: center;'>";
-                dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>LABEL INFO</span>";
-                dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
-                dtlDesc += "<span style='display:inline-block;'>";
+                dtlDesc += "<div class=\"st_view_label_box\" style=\"margin-top: 100px;text-align: center;\">";
+                dtlDesc += "<span class=\"st_tit_view\" style=\"display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;\">LABEL INFO</span>";
+                dtlDesc += "<div class=\"st_view\" style=\"margin-top: 40px;\">";
+                dtlDesc += "<span style=\"display:inline-block;\">";
                 for(String img : dLabelList) {
-					dtlDesc += "<img src='"+ img +"' alt='' style='float:left; margin-top:0; margin-left:20px;'>";
+					dtlDesc += "<img src=\""+ img +"\" alt=\"\" style=\"float:left; margin-top:0; margin-left:20px;\">";
 				}
                 dtlDesc += "</span>";
                 dtlDesc += "</div>";
@@ -436,63 +428,63 @@ public class TsaShoplinkerService {
                 Collection<ShoplinkerGoods> sizeList = admShoplinkerDao.getGoodsSizeList(shoplinkerGoods);
                 if (sizeList == null || sizeList.isEmpty()) {
                 	//대표상품 실측정사이즈표 없을경우 > 브랜드 별 표준 이미지
-                	htmlDesc += "<div class='st_view_size_box' style='margin-top: 100px;text-align: center;'>";
-                	htmlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>사이즈정보</span>";
-                	htmlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+                	htmlDesc += "<div class=\"st_view_size_box\" style=\"margin-top: 100px;text-align: center;\">";
+                	htmlDesc += "<span class=\"st_tit_view\" style=\"display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;\">사이즈정보</span>";
+                	htmlDesc += "<div class=\"st_view\" style=\"margin-top: 40px;\">";
 
                 	String brandSizeImg = env.getProperty("upload.image.view") + "/Upload/brandSizeImg/";
                 	if( "Y".equals(goodsMap.getKidsYn())){
                 		brandSizeImg += "kids/"+goodsMap.getBrandEnm() +".jpg";
-                		htmlDesc += "<img src='"+ brandSizeImg +"' alt='ANDEW 표준 사이즈' style='display: block;margin: 10px auto 0;'>";
+                		htmlDesc += "<img src=\""+ brandSizeImg +"\" alt=\"ANDEW 표준 사이즈\" style=\"display: block;margin: 10px auto 0;\">";
                 	}else {
                 		brandSizeImg += "casuals/"+goodsMap.getBrandEnm() +".jpg";
-                		htmlDesc += "<img src='"+ brandSizeImg +"' alt='ANDEW 표준 사이즈' style='display: block;margin: 10px auto 0;'>";
+                		htmlDesc += "<img src=\""+ brandSizeImg +"\" alt=\"ANDEW 표준 사이즈\" style=\"display: block;margin: 10px auto 0;\">";
                 	}
                     htmlDesc += "</div>";
                     htmlDesc += "</div>";
 
                 }else {
 
-                	htmlDesc += "<div class='st_view_size_box' style='margin-top: 100px;text-align: center;'>";
-                	htmlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>사이즈정보</span>";
-                	htmlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+                	htmlDesc += "<div class=\"st_view_size_box\" style=\"margin-top: 100px;text-align: center;\">";
+                	htmlDesc += "<span class=\"st_tit_view\" style=\"display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;\">사이즈정보</span>";
+                	htmlDesc += "<div class=\"st_view\" style=\"margin-top: 40px;\">";
 
-                	htmlDesc += "<div class='st_tbl' style='padding:0; border-top:1px solid #000;'>";
-                	htmlDesc += "<table style='margin:0;padding:0;border-collapse:collapse;border-spacing:0;width:100%;border-top:1px solid #000;word-break:keep-all;'>";
-                	htmlDesc += "<thead style=''>";
-                	htmlDesc += "<tr style=''>";
+                	htmlDesc += "<div class=\"st_tbl\" style=\"padding:0; border-top:1px solid #000;\">";
+                	htmlDesc += "<table style=\"margin:0;padding:0;border-collapse:collapse;border-spacing:0;width:100%;border-top:1px solid #000;word-break:keep-all;\">";
+                	htmlDesc += "<thead style=\"\">";
+                	htmlDesc += "<tr style=\"\">";
 
                 	int cnt = 0;
                 	for(ShoplinkerGoods size : sizeList) {
 
                 		if( 0 == cnt ) {
                 			if( "하의".equals(size.getSizeTypecd())) {
-                				htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'></th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>허리둘레(cm)</th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>밑위(cm)</th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>엉덩이둘레(cm)</th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>허벅지둘레(cm)</th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>총길이(cm)</th>";
+                				htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\"></th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">허리둘레(cm)</th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">밑위(cm)</th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">엉덩이둘레(cm)</th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">허벅지둘레(cm)</th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">총길이(cm)</th>";
                 			}else {
-                				htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'></th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>가슴둘레(cm)</th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>어깨너비(cm)</th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>팔길이(cm)</th>";
-        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>총길이(cm)</th>";
+                				htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\"></th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">가슴둘레(cm)</th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">어깨너비(cm)</th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">팔길이(cm)</th>";
+        	                	htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">총길이(cm)</th>";
                 			}
                 			htmlDesc += "</tr>";
     	                	htmlDesc += "</thead>";
-    	                	htmlDesc += "<tbody style=''>";
+    	                	htmlDesc += "<tbody style=\"\">";
                 		}
 
-                		htmlDesc += "<tr style=''>";
-                		htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>"+ size.getOptCd2() +"</th>";
-        				htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue1() +"</td>";
-						htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue2() +"</td>";
-						htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue3() +"</td>";
-						htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue4() +"</td>";
+                		htmlDesc += "<tr style=\"\">";
+                		htmlDesc += "<th style=\"position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;\">"+ size.getOptCd2() +"</th>";
+        				htmlDesc += "<td style=\"position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;\">"+ size.getSizeValue1() +"</td>";
+						htmlDesc += "<td style=\"position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;\">"+ size.getSizeValue2() +"</td>";
+						htmlDesc += "<td style=\"position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;\">"+ size.getSizeValue3() +"</td>";
+						htmlDesc += "<td style=\"position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;\">"+ size.getSizeValue4() +"</td>";
 						if( "하의".equals(size.getSizeTypecd())) {
-							htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue5() +"</td>";
+							htmlDesc += "<td style=\"position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;\">"+ size.getSizeValue5() +"</td>";
 						}
                 		cnt ++;
                 	}
@@ -512,34 +504,34 @@ public class TsaShoplinkerService {
 
                 		if( "".equals(certInfo.getCertNum())) {
 
-                			htmlDesc += "<div class='st_required_box' style='margin-bottom:80px;'>";
-                			htmlDesc += "<div class='st_area_kcl' style='color:#222;display:block; position:relative; min-height:160px; margin-top:100px; padding:40px 40px 40px 160px; box-sizing:border-box; background:#f5f5f5;'>";
-                			htmlDesc += "<i class='st_ico_kcl' style='position:absolute;left:64px;top:50%;transform:translateY(-50%);z-index:2;background-image: url(/images/pc/ico_kcl.png);width: 32px;height: 50px;display: inline-block;vertical-align: middle;background-repeat: no-repeat;background-size: contain;background-position: 0% 0%;'></i>";
-                			htmlDesc += "<p class='st_tit' style='margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                			htmlDesc += "<div class=\"st_required_box\" style=\"margin-bottom:80px;\">";
+                			htmlDesc += "<div class=\"st_area_kcl\" style=\"color:#222;display:block; position:relative; min-height:160px; margin-top:100px; padding:40px 40px 40px 160px; box-sizing:border-box; background:#f5f5f5;\">";
+                			htmlDesc += "<i class=\"st_ico_kcl\" style=\"position:absolute;left:64px;top:50%;transform:translateY(-50%);z-index:2;background-image: url(/images/pc/ico_kcl.png);width: 32px;height: 50px;display: inline-block;vertical-align: middle;background-repeat: no-repeat;background-size: contain;background-position: 0% 0%;\"></i>";
+                			htmlDesc += "<p class=\"st_tit\" style=\"margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;\">";
                 			htmlDesc += certInfo.getCertTargetNm() +"/"+ certInfo.getCertOrganName();
                             htmlDesc += "</p>";
-                            htmlDesc += "<p style='margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;'>";
+                            htmlDesc += "<p style=\"margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;\">";
                         	htmlDesc += certInfo.getCertDiv();
                         	htmlDesc += "</p>";
-                            htmlDesc += "<p class='st_dot_info' style='color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
-                            htmlDesc += "<span style='color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;'></span>";
+                            htmlDesc += "<p class=\"st_dot_info\" style=\"color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;\">";
+                            htmlDesc += "<span style=\"color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;\"></span>";
                             htmlDesc += "해당 인증정보는 판매자가 등록한 것으로 등록정보에 대한 일체의 책임은 판매자에게 있습니다.";
                             htmlDesc += "</p>";
                             htmlDesc += "</div>";
                             htmlDesc += "</div>";
                 		}else {
-                			htmlDesc += "<div class='st_required_box' style='margin-bottom:80px;'>";
-                			htmlDesc += "<div class='st_area_kcl' style='display:block; position:relative; min-height:160px; margin-top:100px; padding:40px 40px 40px 160px; box-sizing:border-box; background:#f5f5f5;'>";
-                			htmlDesc += "<i class='st_ico_kcl' style='position:absolute;left:64px;top:50%;transform:translateY(-50%);z-index:2;background-image: url(/images/pc/ico_kcl.png);width: 32px;height: 50px;display: inline-block;vertical-align: middle;background-repeat: no-repeat;background-size: contain;background-position: 0% 0%;'></i>";
-                			htmlDesc += "<p class='st_tit' style='margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                			htmlDesc += "<div class=\"st_required_box\" style=\"margin-bottom:80px;\">";
+                			htmlDesc += "<div class=\"st_area_kcl\" style=\"display:block; position:relative; min-height:160px; margin-top:100px; padding:40px 40px 40px 160px; box-sizing:border-box; background:#f5f5f5;\">";
+                			htmlDesc += "<i class=\"st_ico_kcl\" style=\"position:absolute;left:64px;top:50%;transform:translateY(-50%);z-index:2;background-image: url(/images/pc/ico_kcl.png);width: 32px;height: 50px;display: inline-block;vertical-align: middle;background-repeat: no-repeat;background-size: contain;background-position: 0% 0%;\"></i>";
+                			htmlDesc += "<p class=\"st_tit\" style=\"margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;\">";
                 			htmlDesc += certInfo.getCertDiv() +"/"+ certInfo.getCertOrganName();
                             htmlDesc += "</p>";
-                            htmlDesc += "<p style='margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;'>";
+                            htmlDesc += "<p style=\"margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;\">";
                             htmlDesc += "인증번호: "+ certInfo.getCertNum();
-                            htmlDesc += "<a href='http://www.safetykorea.kr/search/searchPop?certNum=XX00000-0000' target='_blank' class='st_linktxt3' style='margin-left:20px; color:#888; font-weight:200; text-decoration:none !important;'>상세보기</a>";
+                            htmlDesc += "<a href=\"http://www.safetykorea.kr/search/searchPop?certNum=XX00000-0000\" target=\"_blank\" class=\"st_linktxt3\" style=\"margin-left:20px; color:#888; font-weight:200; text-decoration:none !important;\">상세보기</a>";
                             htmlDesc += "</p>";
-                            htmlDesc += "<p class='st_dot_info' style='color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
-                            htmlDesc += "<span style='color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;'></span>";
+                            htmlDesc += "<p class=\"st_dot_info\" style=\"color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;\">";
+                            htmlDesc += "<span style=\"color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;\"></span>";
                             htmlDesc += "해당 인증정보는 판매자가 등록한 것으로 등록정보에 대한 일체의 책임은 판매자에게 있습니다.";
                             htmlDesc += "</p>";
                             htmlDesc += "</div>";
@@ -547,16 +539,16 @@ public class TsaShoplinkerService {
                 		}
 
                 	}else if( "G083_3".equals(certInfo.getCertTargetGb())) {	// 상세설명별도표기
-                		htmlDesc += "<div class='st_required_box' style='margin-bottom:80px;'>";
-                		htmlDesc += "<div class='st_area_kcl st_no-mark' style='display:block;position:relative;min-height:160px;margin-top:100px;padding:40px 40px 40px 160px;box-sizing:border-box;background:#f5f5f5;padding-left:65px;'>";
-                		htmlDesc += "<p class='st_tit' style='margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                		htmlDesc += "<div class=\"st_required_box\" style=\"margin-bottom:80px;\">";
+                		htmlDesc += "<div class=\"st_area_kcl st_no-mark\" style=\"display:block;position:relative;min-height:160px;margin-top:100px;padding:40px 40px 40px 160px;box-sizing:border-box;background:#f5f5f5;padding-left:65px;\">";
+                		htmlDesc += "<p class=\"st_tit\" style=\"margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;\">";
                 		htmlDesc += certInfo.getCertTargetNm();
                         htmlDesc += "</p>";
-                        htmlDesc += "<p style='margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;'>";
+                        htmlDesc += "<p style=\"margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;\">";
                         htmlDesc += "제품 상세정보 내 표기되어 있습니다. 상품 정보를 확인해주세요.";
                         htmlDesc += "</p>";
-                        htmlDesc += "<p class='st_dot_info' style='color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
-                        htmlDesc += "<span style='color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;'></span>";
+                        htmlDesc += "<p class=\"st_dot_info\" style=\"color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;\">";
+                        htmlDesc += "<span style=\"color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;\"></span>";
                         htmlDesc += "해당 인증정보는 판매자가 등록한 것으로 등록정보에 대한 일체의 책임은 판매자에게 있습니다.";
                         htmlDesc += "</p>";
                         htmlDesc += "</div>";

+ 25 - 1
src/main/java/com/style24/admin/biz/service/TsaWithdrawService.java

@@ -21,6 +21,7 @@ import com.style24.core.support.env.TscConstants.OrderChangeGb;
 import com.style24.core.support.env.TscConstants.OrderChangeStat;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.core.support.util.CryptoUtils;
+import com.style24.core.biz.service.TscKakaotalkService;
 import com.style24.persistence.domain.Order;
 import com.style24.persistence.domain.OrderChange;
 import com.style24.persistence.domain.Withdraw;
@@ -66,6 +67,11 @@ public class TsaWithdrawService {
 	@Autowired
 	private TscNaverPayService coreNaverPayService;
 
+	@Autowired
+	private TscKakaotalkService kakaotalkService;
+
+	
+	
 
 	/**
 	 * 환불관리 목록 건수
@@ -354,7 +360,7 @@ public class TsaWithdrawService {
 
 
 	/**
-	 * 회수관리 - 회수처리
+	 * 회수관리 > 환불컨펌 > 환불처리 
 	 *
 	 * @param params
 	 * @return
@@ -434,6 +440,24 @@ public class TsaWithdrawService {
 				orderChangeService.partialRefund(info, userNo);
 			}
 
+			// 반품완료 알림톡
+			
+			Withdraw refundOrdchgSq = new Withdraw();
+			refundOrdchgSq.setOrdChgSq(params.getInt("ordChgSq"));
+			Withdraw info = withdrawDao.getRefundInfo(refundOrdchgSq);
+			
+			Order order = new Order();
+			order.setOrdNo(info.getOrdNo());
+			order.setCustNo(info.getCustNo());
+			order.setOrdNm(info.getOrdNm());
+			order.setOrdPhnno(info.getOrdPhnno());
+			order.setRefundAmt(info.getRefundAmt());
+			order.setGoodsCnt(info.getGoodsCnt()+"");
+			order.setGoodsNm(info.getGoodsNm());
+			
+			kakaotalkService.sendRefundComplete(order, userNo);
+			
+			
 			// 네이버페이 환불컨펌
 			if(TscConstants.PgGb.NAVER_ORDER.value().equals(change.getPgGb())) {
 				// PG 미전송이 아닐 경우 (Y면 미전송, N이면 전송)

+ 1 - 0
src/main/java/com/style24/persistence/domain/Withdraw.java

@@ -104,6 +104,7 @@ public class Withdraw extends TscBaseDomain {
 	private int totalOrdQty;    // 주문총수량 
 	private int addDeliveryFee;
 	private int refundAmt; 
+	private int goodsCnt;
 	
 	private String stDate;					// 조회 시작 기간
 	private String edDate;					// 조회 종료 기간

+ 1 - 1
src/main/java/com/style24/persistence/mybatis/shop/TsaShoplinker.xml

@@ -118,7 +118,7 @@
         	AND (B.DEFAULT_IMG_YN = 'Y' OR B.EXTMALL_IMG_YN = 'Y')
         </if>
         <if test='colorListYn != null and colorListYn == "Y"'>
-
+			AND (B.SYS_IMG_NM LIKE '%_01.jpg' or B.SYS_IMG_NM LIKE '%_02.jpg' )
         </if>
 		ORDER BY B.COLOR_CD, B.DISP_ORD
 	</select>

+ 24 - 1
src/main/java/com/style24/persistence/mybatis/shop/TsaWithdraw.xml

@@ -180,7 +180,7 @@
 	        , ROW_NUMBER() OVER T AS ROWSPAN_RANK
 	        , ROW_NUMBER() OVER S AS ROWSPAN_DT_CNT 
 	        , ROW_NUMBER() OVER C AS ROWSPAN_DT_RANK
-	        , (SELECT E.EXTMALL_NM FROM TB_EXTMALL E WHERE E.EXTMALL_ID = Z.EXTMALL_ID) AS SITE_CD
+	        , (SELECT E.EXTMALL_NM FROM TB_EXTMALL E WHERE E.VENDOR_ID = Z.VENDOR_ID AND E.EXTMALL_ID = Z.EXTMALL_ID) AS SITE_CD
 	        , CASE WHEN Z.CHG_GB = 'G680_30' THEN FN_GET_CODE_NM('G688', Z.CHG_REASON)
 			       WHEN Z.CHG_GB = 'G680_40' THEN FN_GET_CODE_NM('G689', Z.CHG_REASON)   ELSE '' END AS CHG_REASON_NM  
 			, CASE WHEN Z.CHG_GB = 'EXC' THEN '출고예외'  ELSE IFNULL(FN_GET_CODE_NM('G680', Z.CHG_GB),'회수예외') END  AS CHG_GB_NM
@@ -189,6 +189,7 @@
 		FROM (
 		    SELECT A.*, ROW_NUMBER() OVER(ORDER BY  A.ORDER_NO, A.RECALL_EXCEPTION_NO, A.RECALL_EXCEPTION_ITEM_NO)  RNUM 
 		          , CASE WHEN A.MALL_GB = 'G011_20' THEN (SELECT MAX(BB.EXTMALL_ID) FROM TB_ORDER_DETAIL BB WHERE BB.ORD_NO = A.ORDER_NO) ELSE 'APISHOP_0054' END AS EXTMALL_ID
+		          , CASE WHEN A.MALL_GB = 'G011_20' THEN (SELECT MAX(BB.VENDOR_ID) FROM TB_ORDER_DETAIL BB WHERE BB.ORD_NO = A.ORDER_NO) ELSE 'G003_V001' END AS VENDOR_ID
 		    FROM (   
 				SELECT A.*
 				  FROM (
@@ -636,4 +637,26 @@
 		  AND DEL_YN     = 'N'
 	</select>	
 		
+	<!-- 반품알림톡 정보 조회  -->
+	<select id="getRefundInfo" parameterType="Withdraw" resultType="Withdraw">
+		/* TsaWithdraw.getRefundInfo */
+		SELECT
+			  D.ORD_NO 
+			, D.CUST_NO 
+			, D.ORD_PHNNO 
+			, D.ORD_NM 
+			, (SELECT GOODS_NM FROM TB_GOODS WHERE GOODS_CD= MAX(C.GOODS_CD))  AS GOODS_NM
+			, COUNT(C.GOODS_CD) -1 AS GOODS_CNT
+			, E.REFUND_AMT 
+		  FROM TB_ORDER_CHANGE A
+		  JOIN TB_ORDER_CHANGE_DETAIL B ON A.ORD_CHG_SQ = B.ORD_CHG_SQ 
+		  JOIN TB_ORDER_DETAIL C        ON B.ORD_DTL_NO = C.ORD_DTL_NO 
+		  JOIN TB_ORDER        D        ON C.ORD_NO     = D.ORD_NO 
+		  JOIN TB_REFUND       E        ON E.ORD_NO     = D.ORD_NO AND E.ORD_CHG_SQ = A.ORD_CHG_SQ 
+		 WHERE A.ORD_CHG_SQ = #{ordChgSq}
+		   AND B.DEL_YN ='N'
+		 GROUP BY D.ORD_NO, D.CUST_NO, D.ORD_PHNNO, D.ORD_NM, E.REFUND_AMT  
+		 
+ 
+	</select>			
 </mapper>

+ 5 - 1
src/main/webapp/WEB-INF/views/display/MainMultiContentsPopupForm.html

@@ -709,6 +709,7 @@ console.log('brandGroupNo:'+brandGroupNo);
 	// 전시 일시 체크
 	function dateValidation(){
 		var dateBool = true;
+		let dupCnt = 0;
 		$(".tableTest").each(function(i){
 			var dispStdt = $(this).find("[name=dispStdt]").val().replace(/[^0-9]/g, '') + "" +$(this).find("[name=stTimeHour]").val().replace('시', '') + "" +$(this).find("[name=stTimeMin]").val().replace('분', '') + "00";
 			var dispEddt = $(this).find("[name=dispEddt]").val().replace(/[^0-9]/g, '') + "" +$(this).find("[name=edTimeHour]").val().replace('시', '') + "" +$(this).find("[name=edTimeMin]").val().replace('분', '') + "59";
@@ -719,6 +720,7 @@ console.log('brandGroupNo:'+brandGroupNo);
 				mcxDialog.alert("시작일자는 종료일자 보다 클 수 없습니다.");
 				$(this).find('input[name=dispStdt]').focus();
 				// dateBool = false;
+				dupCnt++;
 				return false;
 			}
 		});
@@ -727,7 +729,9 @@ console.log('brandGroupNo:'+brandGroupNo);
 		// }else{
 		// 	return true;
 		// }
-		return true;
+		if(dupCnt==0){
+			return true;
+		}
 	}
 
 	// 몰메인 신상품 : 상품데이터 체크

+ 1243 - 1242
src/main/webapp/ux/plugins/gaga/gaga.validation.js

@@ -1,1242 +1,1243 @@
-/*
- * Form Validation Java Script written by gagamel
- *
- * Copyright (c) 2017 gagamel
- * Dual licensed under GPL (GPL-LICENSE.txt) licenses.
- *
- * $Date: 2017-09-20 $
- * $Modify: 2019-03-07 $
- *
- * Using)
- * 		1. Add "data-valid-type" and "data-valid-name" attribute to Elements of form
- * 			ex) <input type="text" name="userNm" data-valid-type="alpahNumeric" data-valid-name="User Name"/>
- *
- * 		2. data-valid-type
- * 			numeric, alphaNumeric, email, cellPhone, ipAddress
- *
- * 		3. When submit a form, call "validation()" function.
- * 			ex)
- * 				if (!$('#aForm').validation())
- * 					return;
- */
-(function($) {
-	/**
-	 * Spring Security를 사용하는 경우 Default로 CSRF(Cross Site Request Forgery)가 활성화 되어 있다.
-	 * 이 때문에 $.ajax 함수를 호출 시 404 에러가 발생한다. 이는 다음과 같이 해결한다.
-	 *
-	 * 		1. SecurityConfig에 csrf().disable() 설정. <= CSRF(Cross Site Request Forgery) 해제
-	 * 		또는
-	 * 		2. Thymeleaf에서는 csrf 토큰이 hidden input에 자동으로 추가되어 있음으로 아래와 같이 ajax 호출 시 토큰을 Header에 설정한다.
-	 */
-	/*var token = $("meta[name='_csrf']").attr("content");
-	var header = $("meta[name='_csrf_header']").attr("content");
-	$.ajaxSend(function(e, xhr, options) {
-		xhr.setRequestHeader(header, token);
-	});*/
-});
-
-var gagajf = {
-	/**
-	 * @type   : function
-	 * @access : public
-	 * @desc   : 값이 null 이거나 white space 문자로만 이루어진 경우 true를 리턴한다.
-	 * <pre>
-	 *     gagajf.isNull("  ");
-	 * </pre>
-	 * 위와같이 사용했을 경우 true를 리턴한다.
-	 * @param  : value - 필수 입력 값
-	 * @return : boolean. null(혹은 white space) 여부
-	 * @author : gagamel
-	 */
-	isNull : function(value) {
-		if (value == null || (typeof(value) == "string" && value.trim() == ""))
-			return true;
-
-		return false;
-	},
-
-	/**
-	 * @type   : function
-	 * @access : public
-	 * @desc   : 값이 null str로 true를 리턴한다.
-	 * <pre>
-	 *     gagajf.convNull(item.value, '');
-	 * </pre>
-	 * 위와같이 사용했을 경우 item.value 가 null일경우 ''을 리턴한다.
-	 * @param  : value - 필수 입력 값
-	 * @param  : str - 필수 입력 값
-	 * @return : value or str
-	 * @author : gagamel
-	 */
-	convNull : function(value, str) {
-		if (value == null)
-			return str;
-
-		return value;
-	},
-
-	/**
-	 * 유효한 이벤트 키코드인지 체크
-	 * @return : 유효한 이벤트 키코드이면 키코드 값, 아니면 -1
-	 * @since  : 2017/09/20
-	 * @author : gagamel
-	 */
-	getKeyCode : function() {
-		// 이벤트 객체와 문자 코드를 호환 가능한 방식으로 얻는다.
-		var e = event || window.event; // 키 이벤트 객체
-		var keyCode = e.charCode || e.keyCode; // 어떤 키가 눌러졌는가?
-//		console.log('keyCode: ' + keyCode);
-
-		// Ctrl 키나 Alt 키, ASCII 제어문자, 화살표 등 skip
-		if (e.ctrlKey || e.altkey || keyCode < 47) {
-			return -1;
-		}
-
-		return keyCode;
-	},
-
-	/**
-	 * 값이 정규표현식에 부합하는지는 체크한다.
-	 * @param  : el - 엘리먼트
-	 * @param  : regexp - 정규표현식
-	 * @param  : type - 엘리먼트 type
-	 * @return : 부합하는 경우 true, 그 외 false
-	 * @since  : 2017/09/21
-	 * @author : gagamel
-	 */
-	testRegexp : function(el, regexp, type) {
-		var val = $(el).val();
-
-		if (type == 'integer' || type == 'real') {
-			// 콤마(,) 제거
-			val = val.removeComma();
-		}
-
-		if (!regexp.test(val)) {
-			mcxDialog.alertC($(el).data('validName') + '의 형식이 잘못되었습니다.', {
-				sureBtnText: "확인",
-				sureBtnClick: function() {
-					$(el).select();
-					$(el).focus();
-				}
-			});
-			return false;
-		}
-
-		return true;
-	},
-
-	/**
-	 * alert 메시지
-	 * @param  : el - 엘리먼트
-	 *           mgsType - 메시지유형(input, select)
-	 * @since  : 2017/09/21
-	 * @author : gagamel
-	 */
-	alertMessage : function(el, mgsType) {
-		var validNm = $(el).data('validName');
-
-		if (mgsType == 'input') {
-			mcxDialog.alertC(validNm + '을(를) 입력해 주세요.', {
-				sureBtnText: "확인",
-				sureBtnClick: function() {
-					$(el).focus();
-				}
-			});
-		} else if (mgsType == 'select') {
-			mcxDialog.alertC(validNm + '을(를) 선택해 주세요.', {
-				sureBtnText: "확인",
-				sureBtnClick: function() {
-					$(el).focus();
-				}
-			});
-		}
-	},
-
-	/**
-	 * 체크박스와 라디오버튼을 선택한 것이 있는지 체크한다.
-	 * @param  : el - 엘리먼트
-	 *           mgsType - 메시지유형(input, select)
-	 * @since  : 2017/09/21
-	 * @author : gagamel
-	 */
-	isCheckedCheckbox : function(el) {
-		$(el).each(function(idx) {
-			if ($(el).eq(idx).is(':checked')) {
-				return true;
-			} else {
-				return false;
-			}
-		});
-	},
-
-	/**
-	 * 비밀번호 체크
-	 * 		1.영문대문자, 영문소문자, 특수문자, 숫자로만 구성
-	 * 		2.이 중에 3가지 이상으로 구성 시 8자 이상, 2가지 이상으로 구성 시 10자 이상
-	 * @param  : el - 엘리먼트
-	 * @since  : 2017/09/21
-	 * @author : gagamel
-	 */
-	checkPassword : function(el) {
-		var passwd = $(el).val();
-		var cnt = 0;
-		if (/[a-z]{1,}/.test(passwd)) cnt++;
-		if (/[A-Z]{1,}/.test(passwd)) cnt++;
-		if (/[0-9]{1,}/.test(passwd)) cnt++;
-		if (/[\~,\!,\@,\#,\$,\%,\^,\&,\*,\(,\),\_,\?,\{,\},\[,\]]{1,}/.test(passwd)) cnt++;
-
-		if (cnt >= 3) {
-			if (passwd.length < 8) {
-				mcxDialog.alertC('3가지 이상으로 구성 시 8 자리 이상으로 입력해 주세요.', {
-					sureBtnText: "확인",
-					sureBtnClick: function() {
-						$(el).select();
-						$(el).focus();
-					}
-				});
-				return false;
-			}
-		} else if (cnt >= 2) {
-			if (passwd.length < 10) {
-				mcxDialog.alertC('2가지 이상으로 구성 시 10 자리 이상으로 입력해 주세요.', {
-					sureBtnText: "확인",
-					sureBtnClick: function() {
-						$(el).select();
-						$(el).focus();
-					}
-				});
-				return false;
-			}
-		} else {
-			mcxDialog.alertC('대/소문자, 특수문자, 숫자로 구성해 주세요.', {
-				sureBtnText: "확인",
-				sureBtnClick: function() {
-					$(el).select();
-					$(el).focus();
-				}
-			});
-			return false;
-		}
-
-		return true;
-	},
-
-	/**
-	 * 필수입력항목 엘리먼트를 체크해서 alert를 표시한다.
-	 */
-	checkRequired : function(oForm) {
-		var isInvalid = true;
-
-		$(oForm).find(':input').each(function(idx, el) {
-			if ($(el).attr('required') != 'required')
-				return true;
-
-			var type = $(el).attr('type');
-			if (!type) type = 'select';
-//			var msg = $(el).data('validName');
-
-			switch (type) {
-				case 'text':
-				case 'password':
-				case 'textarea':
-//				case 'select-one':
-					var value = $(el).val();
-					if (!gagajf.isNull(value))
-						return true;
-
-					gagajf.alertMessage($(el), 'input');
-					isInvalid = false;
-					return false;
-				case 'select':
-					var value = $(el).val();
-					if (!gagajf.isNull(value))
-						return true;
-
-					gagajf.alertMessage($(el), 'select');
-					isInvalid = false;
-					return false;
-				case 'checkbox':
-				case 'radio':
-					if (gagajf.isCheckedCheckbox($(el)))
-						return true;
-
-					gagajf.alertMessage($(el), 'select');
-					isInvalid = false;
-					return false;
-				case 'file':
-					var value = $(el).val();
-					if (!gagajf.isNull(value))
-						return true;
-
-					gagajf.alertMessage($(el), 'select');
-					isInvalid = false;
-					return false;
-			}
-		});
-
-		return isInvalid;
-	},
-
-	/**
-	 * 값이 형식에 맞는지 패턴을 체크한다.
-	 */
-	checkPattern : function(oForm) {
-		var isInvalid = true;
-
-		$(oForm).find('input').each(function(idx, el) {
-			if (gagajf.isNull($(el).val()))
-				return true;
-
-			var validType = $(el).data('validType');
-
-			// data-valid-type이 지정되지 않은 엘리먼트는 skip
-			if (!validType) return true;
-
-			// 값이 없으면 skip
-			if (gagajf.isNull($(el).val())) return true;
-
-			switch (validType) {
-				case 'numeric': // 숫자
-					if (gagajf.testRegexp($(el), /^[0-9]+$/))
-						return true;
-
-					isInvalid = false;
-					return false;
-				case 'integer': // 정수
-					if (gagajf.testRegexp($(el), /(^-?[0-9]+\d*$)|(^-$)/, 'integer'))
-						return true;
-
-					isInvalid = false;
-					return false;
-				case 'real': // 실수
-					if (gagajf.testRegexp($(el), /^-?(([0-9]+\.?)|(\.?))\d*$/, 'real'))
-						return true;
-
-					isInvalid = false;
-					return false;
-				case 'alphaNumeric': // 알파벳+숫자
-					if (gagajf.testRegexp($(el), /^[a-zA-Z0-9]+$/))
-						return true;
-
-					isInvalid = false;
-					return false;
-				case 'email': // 이메일
-					if (gagajf.testRegexp($(el), /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/))
-						return true;
-					isInvalid = false;
-					return false;
-				case 'password': // 이메일
-					if (gagajf.checkPassword($(el)))
-						return true;
-					isInvalid = false;
-					return false;
-				case 'cellPhone': // 휴대전화번호
-					if (gagajf.testRegexp($(el), /^(01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4})$/))
-						return true;
-
-					isInvalid = false;
-					return false;
-				case 'phone': // 일반전화번호
-					if (gagajf.testRegexp($(el), /^\d{2,3}-\d{3,4}-\d{4}$/))
-						return true;
-
-					isInvalid = false;
-					return false;
-				case 'ipAddress': // IP주소
-					if (gagajf.testRegexp($(el), /^(([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}))$/))
-						return true;
-
-					isInvalid = false;
-					return false;
-			}
-		});
-
-		return isInvalid;
-	},
-
-	checkValue : function(oForm){
-		var isInvalid = true;
-
-		$(oForm).find('input').each(function(idx, el) {
-
-			var validType = $(el).data('validType');
-
-			// data-valid-type이 지정되지 않은 엘리먼트는 skip
-			if (!validType) return true;
-
-			// 값이 없으면 skip
-			if (gagajf.isNull($(el).val())) return true;
-
-			switch (validType) {
-				case 'numeric': // 숫자
-					//최대값
-					if ($(el).attr("max")) {
-						if ($(el).val() > $(el).attr("max")) {
-							mcxDialog.alertC($(el).data('validName') + '은(는) 최대 ' + $(el).attr("max") + '보다 작아야 합니다.', {
-								sureBtnText: "확인",
-								sureBtnClick: function() {
-									$(el).focus();
-								}
-							});
-							isInvalid = false;
-							return false;
-						}
-					}
-					//최소값
-					if ($(el).attr("min")) {
-						if ($(el).val() < $(el).attr("min")) {
-							mcxDialog.alertC($(el).data('validName') + '은(는) 최소 ' + $(el).attr("min") + '보다 커야 합니다.', {
-								sureBtnText: "확인",
-								sureBtnClick: function() {
-									$(el).focus();
-								}
-							});
-							isInvalid = false;
-							return false;
-						}
-					}
-
-				case 'integer': // 정수
-					//최대값
-					if ($(el).attr("max")) {
-						if ($(el).val() > $(el).attr("max")) {
-							mcxDialog.alertC($(el).data('validName') + '은(는) 최대 ' + $(el).attr("max") + '보다 작아야 합니다.', {
-								sureBtnText: "확인",
-								sureBtnClick: function() {
-									$(el).focus();
-								}
-							});
-							isInvalid = false;
-							return false;
-						}
-					}
-					//최소값
-					if ($(el).attr("min")) {
-						if ($(el).val() < $(el).attr("min")) {
-							mcxDialog.alertC($(el).data('validName') + '은(는) 최소 ' + $(el).attr("min") + '보다 커야 합니다.', {
-								sureBtnText: "확인",
-								sureBtnClick: function() {
-									$(el).focus();
-								}
-							});
-							isInvalid = false;
-							return false;
-						}
-					}
-				case 'real': // 실수
-					//최대값
-					if ($(el).attr("max")) {
-						if ($(el).val() > $(el).attr("max")) {
-							mcxDialog.alertC($(el).data('validName') + '은(는) 최대 ' + $(el).attr("max") + '보다 작아야 합니다.', {
-								sureBtnText: "확인",
-								sureBtnClick: function() {
-									$(el).focus();
-								}
-							});
-							isInvalid = false;
-							return false;
-						}
-					}
-					//최소값
-					if ($(el).attr("min")) {
-						if ($(el).val() < $(el).attr("min")) {
-							mcxDialog.alertC($(el).data('validName') + '은(는) 최소 ' + $(el).attr("min") + '보다 커야 합니다.', {
-								sureBtnText: "확인",
-								sureBtnClick: function() {
-									$(el).focus();
-								}
-							});
-							isInvalid = false;
-							return false;
-						}
-					}
-			}
-		});
-		
-		return isInvalid;
-	},
-
-	/**
-	 * form을 validation 한다.
-	 * 예)
-	 * 		if (gagajf.validation('#registerForm');
-	 */
-	validation : function(formId) {
-		var $form = $(formId);
-
-		if (!this.checkRequired($form))
-			return false;
-
-		if (!this.checkPattern($form))
-			return false;
-
-		if(!this.checkValue($form))
-			return false;
-
-		return true;
-	},
-
-	/**
-	 * formId의 input의 data-valid-type이 integer, real인 경우에 값에 comma(,)를 자동으로 붙여 표시한다.
-	 * 사용) gagajf.addCommaAtNumberFormattedInput('#registerForm');
-	 */
-	addCommaAtNumberFormattedInput : function(formId) {
-		$(formId).find('input').each(function(idx, el) {
-			if ($(el).data('validType') == 'integer' || $(el).data('validType') == 'real') {
-				$(el).val($(el).val().removeComma().addComma());
-			}
-		});
-	},
-
-	/**
-	 * formId의 input의 data-valid-type이 integer, real, numeric 인 경우에 값에 comma(,)를 자동으로 제거한다.
-	 * 사용) gagajf.removeCommaAtNumberFormattedInput('#registerForm');
-	 */
-	removeCommaAtNumberFormattedInput : function(formId) {
-		$(formId).find('input').each(function(idx, el) {
-			if ($(el).data('validType') == 'integer' || $(el).data('validType') == 'real' || $(el).data('validType') == 'numeric') {
-				$(el).val($(el).val().removeComma());
-			}
-		});
-	},
-	
-	/**
-	 * formId의 input의 값에 ?가 여러 개인 경우 ? 한 개로 대체한다.
-	 * 사용) gagajf.replaceOneQuestionMark('#registerForm');
-	 */
-	replaceOneQuestionMark : function(formId) {
-		$(formId).find('input[type=text]').each(function(idx, el) {
-			$(el).val($(el).val().replace(/\?+/gi, "?"));
-		});
-		
-		$(formId).find('textarea').each(function(idx, el) {
-			$(el).val($(el).val().replace(/\?+/gi, "?"));
-		});
-	},
-
-	/**
-	 * Progress bar
-	 */
-	showProgressbar : function(isLoading) {
-		if (isLoading) {
-			// Button disabled & progressBar creation
-			//$('.btn').each(function(idx) { $(this).attr('disabled', true); });
-			var load_AjaxSubmit = '<div id="load_AjaxSubmit" style="'
-				+ 'background: url(/ux/plugins/gaga/loader.gif); border-style: none; background-repeat: no-repeat; '
-				+ 'position: absolute; top: 45%; left: 50%; width: auto; '
-				+ 'z-index: 101; padding: 16px; margin: 5px;'
-				+ '"></div>';
-			$('#content').append(load_AjaxSubmit);
-		} else {
-			// Button activated & progressBar remove
-			//$('.btn').each(function(idx) { $(this).attr('disabled', false); });
-			$('#load_AjaxSubmit').remove();
-		}
-	},
-
-	/**
-	 * form의 데이터를 json으로 변환 후 ajax 방식으로 submit 한다.
-	 * 모든 form의 ajax 처리는 이것으로 진행한다.
-	 * <pre>
-	 *     ajaxFormSubmit('/rest/commoncode/create', '#registerForm', jfRegisterSaveCallback);
-	 * </pre>
-	 * @param actionUrl - Request URL
-	 * @param formId - form ID
-	 * @param callbackFn - Callback function
-	 * @author gagamel
-	 * @since 2019. 4. 8
-	 */
-	ajaxFormSubmit : function(actionUrl, formId, callbackFn) {
-		// comma(,) 제거
-		gagajf.removeCommaAtNumberFormattedInput(formId);
-		
-		// 물음표(?) 여러 개를 1개로 대체
-		gagajf.replaceOneQuestionMark(formId);
-
-		var jsonData = JSON.stringify($(formId).serializeObject());
-		
-		$.ajax({
-			type : 'POST',
-			url : actionUrl,
-			data : jsonData,
-			dataType : 'json',
-			beforeSend : function(xhr, settings) {
-				// AJAX call
-				xhr.setRequestHeader("AJAX", "true");
-
-				// dataType: "json"일 때
-				xhr.setRequestHeader('Accept', 'application/json');
-				xhr.setRequestHeader('Content-Type', 'application/json');
-
-				// Button disabled & progressBar creation
-				gagajf.showProgressbar(true);
-			},
-			complete : function(xhr) {
-				// Button abled & progressBar remove
-				gagajf.showProgressbar(false);
-
-				// 세션이 없다. 로그인 페이지로 이동
-				if (xhr.status == 901) {
-					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
-						sureBtnText: "확인",
-						sureBtnClick: function() {
-							document.location.href = "/error/noSession";
-						}
-					});
-				}
-			},
-			success : function(result) {
-				if (typeof(result.status) == 'undefined' || result.status == 200) { // 성공
-					if (!gagajf.isNull(result.message)) {
-						mcxDialog.alertC(result.message, {
-							sureBtnText: "확인",
-							sureBtnClick: function() {
-								if (typeof(callbackFn) == "function") {
-									callbackFn.call(this, result);
-								}
-							}
-						});
-					} else {
-						if (typeof(callbackFn) == "function") {
-							callbackFn.call(this, result);
-						}
-					}
-				} else { // 실패
-					if (!gagajf.isNull(result.error.message)) {
-						mcxDialog.alert(result.error.message);
-					}
-
-					return;
-				}
-			},
-			error : function(result) {
-				console.log(result);
-				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
-			}
-		});
-	},
-
-	/**
-	 * json 데이터를 가지고 ajax 방식으로 submit 한다.
-	 * 모든 ajax 처리는 이것으로 진행한다.
-	 * <pre>
-	 *     gagajf.removeCommaAtNumberFormattedInput('#registerForm'); // comma(,) 제거
-	 *     gagajf.replaceOneQuestionMark('#registerForm'); // 물음표(?) 여러개를 1개로 대체
-	 *     var jsonData = JSON.stringify($('#registerForm').serializeObject());
-	 *     gagajf.ajaxJsonSubmit('/rest/commoncode/create', jsonData, jfRegisterSaveCallback);
-	 * </pre>
-	 * @param actionUrl - Request URL
-	 * @param jsonData - Data of json format
-	 * @param callbackFn - Callback function
-	 * @author gagamel
-	 * @since 2019. 4. 8
-	 */
-	ajaxJsonSubmit : function(actionUrl, jsonData, callbackFn) {
-		$.ajax({
-			type : 'POST',
-			url : actionUrl,
-			data : jsonData,
-			dataType : 'json',
-			beforeSend : function(xhr, settings) {
-				// AJAX call
-				xhr.setRequestHeader("AJAX", "true");
-
-				// dataType: "json"일 때
-				xhr.setRequestHeader('Accept', 'application/json');
-				xhr.setRequestHeader('Content-Type', 'application/json');
-
-				// Button disabled & progressBar creation
-				gagajf.showProgressbar(true);
-			},
-			complete : function(xhr) {
-				// Button abled & progressBar remove
-				gagajf.showProgressbar(false);
-
-				// 세션이 없다. 로그인 페이지로 이동
-				if (xhr.status == 901) {
-					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
-						sureBtnText: "확인",
-						sureBtnClick: function() {
-							document.location.href = "/error/noSession";
-						}
-					});
-				}
-			},
-			success : function(result) {
-				if (typeof(result.status) == 'undefined' || result.status == 200) { // 성공
-					if (!gagajf.isNull(result.message)) {
-						mcxDialog.alertC(result.message, {
-							sureBtnText: "확인",
-							sureBtnClick: function() {
-								if (typeof(callbackFn) == "function") {
-									callbackFn.call(this, result);
-								}
-							}
-						});
-					} else {
-						if (typeof(callbackFn) == "function") {
-							callbackFn.call(this, result);
-						}
-					}
-				} else { // 실패
-					if (!gagajf.isNull(result.error.message)) {
-						mcxDialog.alert(result.error.message);
-					}
-
-					return;
-				}
-			},
-			error : function(result) {
-				console.log(result);
-				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
-			}
-		});
-	},
-
-	/**
-	 * ajax 방식으로 파일을 업로드 한다.
-	 * <pre>
-	 *     gagajf.ajaxFileUpload('/common/file/upload?subDir=notice', this.files[0], jfCallback);
-	 * </pre>
-	 * @param actionUrl - Request URL
-	 * @param file - A file to upload
-	 * @param callbackFn - Callback function
-	 * @param policy - Upload policy
-	 * @author gagamel
-	 * @since 2019. 7. 9
-	 */
-	ajaxFileUpload : function(actionUrl, file, callbackFn, policy) {
-		var formData = new FormData();
-		formData.append("file", file);
-
-		if (typeof policy != 'undefined') {
-			formData.append("policy", policy);
-		}
-
-		$.ajax({
-			type : 'POST',
-			url : actionUrl,
-			data : formData,
-			dataType: 'json',
-			processData : false, // true: data의 파일 형태가 query String으로 전송. false : non-processed data
-			contentType : false, // multipart/form-data 형태로 전송되기 위한 옵션 값
-			beforeSend : function(xhr, settings) {
-				// AJAX call
-				xhr.setRequestHeader("AJAX", "true");
-
-				// Button disabled & progressBar creation
-				gagajf.showProgressbar(true);
-			},
-			complete : function(xhr) {
-				// Button abled & progressBar remove
-				gagajf.showProgressbar(false);
-
-				// 세션이 없다. 로그인 페이지로 이동
-				if (xhr.status == 901) {
-					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
-						sureBtnText: "확인",
-						sureBtnClick: function() {
-							document.location.href = "/error/noSession";
-						}
-					});
-				}
-			},
-			success : function(result) {
-				if (typeof(result.status) == 'undefined' || result.status == 200) { // 성공
-					if (!gagajf.isNull(result.message)) {
-						mcxDialog.alertC(result.message, {
-							sureBtnText: "확인",
-							sureBtnClick: function() {
-								if (typeof(callbackFn) == "function") {
-									callbackFn.call(this, result);
-								}
-							}
-						});
-					} else {
-						if (typeof(callbackFn) == "function") {
-							callbackFn.call(this, result);
-						}
-					}
-				} else { // 실패
-					if (!gagajf.isNull(result.error.message)) {
-						mcxDialog.alert(result.error.message);
-					}
-
-					return;
-				}
-			},
-			error: function(result) {
-				console.log(result);
-				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
-			}
-		});
-	},
-
-	/**
-	 * 대용량 json 데이터를 가지고 ajax 방식으로 submit 한다.
-	 * <pre>
-	 *     gagajf.removeCommaAtNumberFormattedInput('#registerForm'); // comma(,) 제거
-	 *     gagajf.replaceOneQuestionMark('#registerForm'); // 물음표(?) 여러개를 1개로 대체
-	 *     var jsonData = JSON.stringify($('#registerForm').serializeObject());
-	 *     gagajf.ajaxJsonBatchSubmit('/rest/commoncode/create', jsonData, 1, 3, jfRegisterSaveCallback);
-	 * </pre>
-	 * @param actionUrl - Request URL
-	 * @param jsonData - Data of json format
-	 * @param callIdx - 호출인덱스(실제 호출한 횟수)
-	 * @param callCnt - 호출해야할횟수(몇 번 호출해야 하는지)
-	 * @param callbackFn - Callback function
-	 * @author gagamel
-	 * @since 2019. 4. 8
-	 */
-	ajaxJsonBatchSubmit : function(actionUrl, jsonData, callIdx, callCnt, callbackFn) {
-		$.ajax({
-			type : 'POST',
-			url : actionUrl,
-			data : jsonData,
-			dataType : 'json',
-			beforeSend : function(xhr, settings) {
-				// AJAX call
-				xhr.setRequestHeader("AJAX", "true");
-
-				// dataType: "json"일 때
-				xhr.setRequestHeader('Accept', 'application/json');
-				xhr.setRequestHeader('Content-Type', 'application/json');
-
-				// Button disabled & progressBar creation
-				if (callIdx == 1) { // 첫번째 호출이면
-					gagajf.showProgressbar(true);
-				}
-			},
-			complete : function(xhr) {
-				// Button abled & progressBar remove
-				if (callIdx == callCnt) { // 마지막 호출이면
-					gagajf.showProgressbar(false);
-				}
-
-				// 세션이 없다. 로그인 페이지로 이동
-				if (xhr.status == 901) {
-					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
-						sureBtnText: "확인",
-						sureBtnClick: function() {
-							document.location.href = "/error/noSession";
-						}
-					});
-				}
-			},
-			success : function(result) {
-				if (callIdx == callCnt) { // 마지막 호출이면
-					mcxDialog.alertC('성공적으로 처리되었습니다.', {
-						sureBtnText: "확인",
-						sureBtnClick: function() {
-							if (typeof(callbackFn) == "function") {
-								callbackFn.call(this, result);
-							}
-						}
-					});
-				} else {
-					if (typeof(callbackFn) == "function") {
-						callbackFn.call(this, result);
-					}
-				}
-			},
-			error : function(result) {
-				console.log(result);
-				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
-			}
-		});
-	},
-
-	/**
-	 * JQuery를 이용한 비동기 submit 처리
-	 * 파라미터의 명칭은 쿼리문과 동일하게 작성해야 한다.
-	 * <pre>
-	 *     var params = new Object();
-	 *     params.cdGb = "G900";
-	 *     params.cd = "0202";
-	 *
-	 *     gagajf.ajaxSubmit("/rest/commoncode/create", "json", jfCallback, params);
-	 *
-	 *     or
-	 *
-	 *     gagajf.ajaxSubmit("/rest/commoncode/create", "json", jfCallback);
-	 * </pre>
-	 * @param  : actionUrl - action url. 필수
-	 *           type - 처리결과 형식(text, html, xml, json). 필수
-	 *           callback - type이 text, xml, json 일 때는 콜백함수명
-	 *                      type이 html일 때는 target명. 필수
-	 *           params - 파라미터 오브젝트. 옵션
-	 * @author gagamel
-	 * @since 2019. 4. 8
-	 */
-	ajaxSubmit : function(actionUrl, type, callback, params) {
-		$.ajaxSetup({
-			beforeSend: function(xhr, settings) {
-				// AJAX call
-				xhr.setRequestHeader("AJAX", "true");
-
-				// type: "json"일 때
-				if (type == "json") {
-					xhr.setRequestHeader('Accept', 'application/json');
-					xhr.setRequestHeader('Content-Type', 'application/json');
-				}
-			},
-			complete: function(xhr) {
-				// 세션이 없다. 로그인 페이지로 이동
-				if (xhr.status == 901) {
-					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
-						sureBtnText: "확인",
-						sureBtnClick: function() {
-							document.location.href = "/error/noSession";
-						}
-					});
-				}
-			}
-		});
-
-		if (!params) params = new Object();
-
-		var paramData = $.param(params);
-
-		// dataType: "json"일 때
-		if (type == "json") {
-			paramData = JSON.stringify(params);
-		}
-
-		$.post(actionUrl
-			, paramData
-			, function(result) {
-				if (type == "html") {
-					if (!gagajf.isNull(callback))
-						$(document.getElementById(callback)).html(result);
-				} else {
-					// Callback 함수 호출
-					if (typeof(callback) == "function")
-						callback.call(this, result);
-				}
-			}
-			, type);
-	},
-
-	/**
-	 * @type   : function
-	 * @access : public
-	 * @desc   : 기간의 시작일자와 종료일자를 설정한다.
-	 * <pre>
-	 *     gagajf.setDate($('#sellStdt'), $('#sellEddt'), 't');
-	 * </pre>
-	 * @param  : fromObj - 시작일자 오브젝트
-	 * @param  : toObj - 종료일자 오브젝트
-	 * @param  : type - 유형(오늘: t, 어제: y, 최근한주: 7d, 이번주: tw, 지난주: pw, 최근한달: 1m, 이번달: tm, 지난달: pm, 최근3개월: 3m
-	 * @since  : 2019/08/09
-	 * @author : gagamel
-	 */
-	setDate : function(tgtId, fromObj, toObj, type) {
-		var date = new Date();
-
-		if (type == '') { // 기간 X
-			$(tgtId +' #' + fromObj).val('');
-			$(tgtId +' #' + toObj).val('');
-		} else if (type == 't') { // 오늘
-			$(tgtId +' #' + fromObj).val(date.format("YYYY-MM-DD"));
-			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
-		} else if (type == 'y') { // 어제
-			$(tgtId +' #' + fromObj).val(date.before(0, 0, 1).format("YYYY-MM-DD"));
-			$(tgtId +' #' + toObj).val(date.before(0, 0, 1).format("YYYY-MM-DD"));
-		} else if (type == '7d') { // 최근한주
-			$(tgtId +' #' + fromObj).val(date.before(0, 0, 6).format("YYYY-MM-DD"));
-			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
-		} else if (type == 'tw') { // 이번주
-			var wdays = date.getDate() - date.getDay();
-			$(tgtId +' #' + fromObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays).format("YYYY-MM-DD"));
-			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays + 6).format("YYYY-MM-DD"));
-		} else if (type == 'pw') { // 지난주
-			var wdays = date.getDate() - date.getDay();
-			$(tgtId +' #' + fromObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays - 7).format("YYYY-MM-DD"));
-			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays - 1).format("YYYY-MM-DD"));
-		} else if (type == '1m') { // 최근한달
-			$(tgtId +' #' + fromObj).val(date.before(0, 1, 0).after(0, 0, 1).format("YYYY-MM-DD"));
-			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
-		} else if (type == 'tm') { // 이번달
-			$(tgtId +' #' + fromObj).val(date.format("YYYY-MM-") + '01');
-			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 1, 0).before(0, 0, 1).format("YYYY-MM-DD"));
-		} else if (type == 'pm') { // 지난달
-			//$(tgtId +' #' + fromObj).val(date.before(0, 1, 0).format("YYYY-MM-")  + '01');
-			$(tgtId +' #' + fromObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').before(0, 1, 0).format("YYYY-MM-")  + '01');
-			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').before(0, 0, 1).format("YYYY-MM-DD"));
-		} else if (type == '3m') { // 최근3개월
-			$(tgtId +' #' + fromObj).val(date.before(0, 3, 0).after(0, 0, 1).format("YYYY-MM-DD"));
-			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
-		}
-	},
-
-	/**
-	 * @type   : function
-	 * @access : public
-	 * @desc   : Set Cookie
-	 * <pre>
-	 *     gagajf.setCookie("COOKIE_TODAY_PROD", "HUE00C105GE", 1);
-	 * </pre>
-	 * @param  : name - 쿠키명
-	 * @param  : value - 쿠키 값
-	 * @param  : expiredays - 만료기간
-	 * @return : None
-	 * @since  : 2019/07/01
-	 * @author : gagamel
-	 */
-	setCookie : function(name, value, expiredays) {
-		var todayDate = new Date();
-		todayDate.setDate(todayDate.getDate() + expiredays);
-		document.cookie = name + "=" + escape(value) + "; path=/; expires=" + todayDate.toGMTString() + ";";
-	},
-
-	/**
-	 * @type   : function
-	 * @access : public
-	 * @desc   : Get Cookie
-	 * <pre>
-	 *     gagajf.getCookie("COOKIE_TODAY_PROD");
-	 * </pre>
-	 * @param  : name - 쿠키명
-	 * @return : None
-	 * @since  : 2019/07/01
-	 * @author : gagamel
-	 */
-	getCookie : function(name) {
-		var nameOfCookie = name + "=";
-		var x = 0;
-		while (x <= document.cookie.length) {
-			var y = (x+nameOfCookie.length);
-			if (document.cookie.substring(x, y) == nameOfCookie) {
-				if ((endOfCookie=document.cookie.indexOf(";", y)) == -1) endOfCookie = document.cookie.length;
-				return unescape(document.cookie.substring(y, endOfCookie));
-			}
-			x = document.cookie.indexOf(" ", x) + 1;
-			if (x == 0) break;
-		}
-
-		return "";
-	},
-	
-	/**
-	 * 데이터를 배열로 변환
-	 * 예)
-	 * 		convertToArray({cd: "KNE", cdNm: "KNE"});
-	 * @param  : data - 데이터
-	 * @param  : isCodeDisplay - 코드표시여부(true/false). default false
-	 * @author : gagamel
-	 * @since  : 2019. 6. 7
-	 */
-	convertToArray : function(data, isCodeDisplay) {
-		if (data.length == 0)
-			return [];
-
-		if (typeof(isCodeDisplay) == 'undefined')
-			isCodeDisplay = false;
-
-		var arrValue = {};
-
-		$.each(data, function(idx, item) {
-			arrValue[item.cd] = (isCodeDisplay ? '[' + item.cd + '] ' : '') + item.cdNm;
-		});
-
-		return arrValue;
-	} ,
-	checkFileSize : function (data){
-		var isInvalid = true;
-
-		var fileSize = data.size;
-		var maxSize = 1024 * 1024 * 10;
-		if(fileSize > maxSize){
-			alert("파일용량이 10MB을 초과했습니다.");
-			isInvalid = false;
-			return false;
-		}else{
-			isInvalid = true
-			return true;
-		}
-
-		return isInvalid;
-	}
-};
-
-/**
- * @type   : function
- * @access : document
- * @desc   : <input> 태그에 대한 키눌림에 대해 validation을 체크한다.
- *           data-valid-type="numeric" : 숫자. 속성 지정시 숫자만 입력 가능
- *           data-valid-type="integer" : 정수. 속성 지정시 숫자와 +, - 만 입력 가능
- *           data-valid-type="real" : 실수. 속성 지정시 숫자와 +, -, . 만 입력 가능
- *           data-valid-type="alphaNumeric" : 알파벳과 숫자. 속성 지정 시 영문과 숫자만 형식에 맞게 입력 가능
- *           data-valid-type="date" : 숫자와 / 만 입력 가능
- *           data-valid-type="korean" : 한글. 속성 지정 시 한글만 형식에 맞게 입력 가능
- *           data-valid-type="email" : 이메일
- *           data-valid-type="password" : 비밀번호
- *           data-valid-type="cellPhone" : 휴대전화번호
- *           data-valid-type="phone" : 일반전화번호
- *           data-valid-type="ipAddress" : IP주소
- *           data-valid-type="bizRegNo" : 사업자등록번호
- * <pre>
- *     <input type="text" data-valid-type="numeric" />
- *     <input type="text" data-valid-type="integer" />
- *     <input type="text" data-valid-type="real" />
- *     <input type="text" data-valid-type="alphaNumeric" />
- *     <input type="text" data-valid-type="date" />
- *     <input type="text" data-valid-type="korean" />
- *     <input type="text" data-valid-type="email" />
- *     <input type="text" data-valid-type="password" />
- *     <input type="text" data-valid-type="cellPhone" />
- *     <input type="text" data-valid-type="phone" />
- *     <input type="text" data-valid-type="ipAddress" />
- *     <input type="text" data-valid-type="bizRegNo" />
- * </pre>
- * @author : gagamel
- * @since  : 2017/09/20
- */
-$(document).on("keyup", "[data-valid-type=numeric]", function() { $(this).val($(this).val().replace(/[^0-9]/gi,"")); });
-$(document).on("keydown", "[data-valid-type=numeric]", function() {
-	var value = $(this).val();
-
-	var keyCode = gagajf.getKeyCode();
-	if (keyCode == -1)
-		return true;
-
-	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
-		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
-		)) {
-		$(this).val(value);
-		event.returnValue = false;
-	}
-});
-$(document).on("blur", "[data-valid-type=integer]", function() { $(this).val($(this).val().removeComma().addComma()); });
-$(document).on("click", "[data-valid-type=integer]", function() { $(this).val($(this).val().removeComma()); });
-$(document).on("keyup", "[data-valid-type=integer]", function() { $(this).val($(this).val().replace(/[^0-9-\+]/gi,"")); });
-$(document).on("keydown", "[data-valid-type=integer]", function() {
-	var value = $(this).val();
-
-	var keyCode = gagajf.getKeyCode();
-	if (keyCode == -1)
-		return true;
-
-	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
-		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
-		|| (keyCode == 187 && event.shiftKey) // Shift 하고 +
-		|| (keyCode == 107) // + (Num Lock)
-		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
-		|| (keyCode == 109) // - (Num Lock)
-		)) {
-		$(this).val(value);
-		event.returnValue = false;
-	}
-});
-$(document).on("blur", "[data-valid-type=real]", function() { $(this).val($(this).val().removeComma().addComma()); });
-$(document).on("click", "[data-valid-type=real]", function() { $(this).val($(this).val().removeComma()); });
-$(document).on("keyup", "[data-valid-type=real]", function() { $(this).val($(this).val().replace(/[^0-9-\+\.]/gi,"")); });
-$(document).on("keydown", "[data-valid-type=real]", function() {
-	var value = $(this).val();
-
-	var keyCode = gagajf.getKeyCode();
-	if (keyCode == -1)
-		return true;
-
-	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
-		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
-		|| (keyCode == 187 && event.shiftKey) // Shift 하고 +
-		|| (keyCode == 107) // + (Num Lock)
-		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
-		|| (keyCode == 109) // - (Num Lock)
-		|| (keyCode == 190 && !event.shiftKey) // .
-		)) {
-		$(this).val(value);
-		event.returnValue = false;
-	}
-});
-$(document).on("keyup", "[data-valid-type=alphaNumeric]", function() { $(this).val($(this).val().replace(/[^a-zA-Z0-9]/gi, "")); });
-$(document).on("keyup", "[data-valid-type=date]", function() { $(this).val($(this).val().replace(/[^0-9\/]/gi,"")); });
-$(document).on("keyup", "[data-valid-type=calendar]", function() { $(this).val($(this).val().replace(/[^0-9\/]/gi,"")); });
-$(document).on("blur", "[data-valid-type=calendar]", function() {
-	var val = $(this).val();
-	if(val==''){
-		return;
-	}
-	val = val.replace(/-/gi, "");
-	var temp = val.substring(0, 4)+" ";
-	if(Number(val.substring(4, 6))>12){
-		temp += "12";
-	}else if(Number(val.substring(4, 6))==0){
-		temp += "1";
-	}else{
-		temp += Number(val.substring(4, 6));
-	}
-	temp += " ";
-	if(Number(val.substring(6, 8))>31){
-		temp += "31";
-	}else if(Number(val.substring(6, 8))==0){
-		temp += "1";
-	}else{
-		temp += Number(val.substring(6, 8));
-	}
-	
-	var date = new Date(temp);
-	var yyyy = date.getFullYear().toString();
-	var mm = (date.getMonth() + 1).toString();
-	var dd = date.getDate().toString();
-	$(this).val(yyyy + '-' + (mm[1] ? mm : '0'+mm[0])+ '-'  + (dd[1] ? dd : '0'+dd[0]));
-});
-$(document).on("keyup", "[data-valid-type=korean]", function() { $(this).val($(this).val().replace(/[^가-힣]/gi, "")); });
-$(document).on("keyup", "[data-valid-type=email]", function() { $(this).val($(this).val().replace(/[^a-zA-Z0-9\@\+\_\.\@\-]/gi, "")); });
-$(document).on("keyup", "[data-valid-type=password]", function() { $(this).val($(this).val().replace(/[^a-zA-Z0-9\~\!\@\#\$\%\^\&\*\?\(\)\_\+\{\}\[\]]/gi, "")); });
-$(document).on("keyup", "[data-valid-type=cellPhone]", function() { $(this).val($(this).val().replace(/[^\d-]/gi, "")); });
-$(document).on("keydown", "[data-valid-type=cellPhone]", function() {
-	var value = $(this).val();
-
-	var keyCode = gagajf.getKeyCode();
-	if (keyCode == -1)
-		return true;
-
-	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
-		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
-		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
-		|| (keyCode == 109) // - (Num Lock)
-		)) {
-		$(this).val(value);
-		event.returnValue = false;
-	}
-});
-$(document).on("keyup keydown paste change", "[data-valid-type=cellPhone]", function() {
-	$(this).val($(this).val().replace(/[^0-9]/g, "").replace(/(^02|^050[0-9]{1}|^1[0-9]{3}|^0[0-9]{2})([0-9]+)?([0-9]{4})$/,"$1-$2-$3").replace("--", "-"));
-});
-$(document).on("keyup", "[data-valid-type=phone]", function() { $(this).val($(this).val().replace(/[^\d-]/gi, "")); });
-$(document).on("keydown", "[data-valid-type=phone]", function() {
-	var value = $(this).val();
-
-	var keyCode = gagajf.getKeyCode();
-	if (keyCode == -1)
-		return true;
-
-	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
-		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
-		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
-		|| (keyCode == 109) // - (Num Lock)
-		)) {
-		$(this).val(value);
-		event.returnValue = false;
-	}
-});
-$(document).on("keyup", "[data-valid-type=ipAddress]", function() { $(this).val($(this).val().replace(/[^\d\.]/gi, "")); });
-$(document).on("keydown", "[data-valid-type=ipAddress]", function() {
-	var value = $(this).val();
-
-	var keyCode = gagajf.getKeyCode();
-	if (keyCode == -1)
-		return true;
-
-	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
-		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
-		|| (keyCode == 190 && !event.shiftKey) // .
-		)) {
-		$(this).val(value);
-		event.returnValue = false;
-	}
-});
-$(document).on("keyup", "[data-valid-type=bizRegNo]", function() { $(this).val($(this).val().replace(/[^0-9\-]/gi,"")); });
+/*
+ * Form Validation Java Script written by gagamel
+ *
+ * Copyright (c) 2017 gagamel
+ * Dual licensed under GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2017-09-20 $
+ * $Modify: 2019-03-07 $
+ *
+ * Using)
+ * 		1. Add "data-valid-type" and "data-valid-name" attribute to Elements of form
+ * 			ex) <input type="text" name="userNm" data-valid-type="alpahNumeric" data-valid-name="User Name"/>
+ *
+ * 		2. data-valid-type
+ * 			numeric, alphaNumeric, email, cellPhone, ipAddress
+ *
+ * 		3. When submit a form, call "validation()" function.
+ * 			ex)
+ * 				if (!$('#aForm').validation())
+ * 					return;
+ */
+(function($) {
+	/**
+	 * Spring Security를 사용하는 경우 Default로 CSRF(Cross Site Request Forgery)가 활성화 되어 있다.
+	 * 이 때문에 $.ajax 함수를 호출 시 404 에러가 발생한다. 이는 다음과 같이 해결한다.
+	 *
+	 * 		1. SecurityConfig에 csrf().disable() 설정. <= CSRF(Cross Site Request Forgery) 해제
+	 * 		또는
+	 * 		2. Thymeleaf에서는 csrf 토큰이 hidden input에 자동으로 추가되어 있음으로 아래와 같이 ajax 호출 시 토큰을 Header에 설정한다.
+	 */
+	/*var token = $("meta[name='_csrf']").attr("content");
+	var header = $("meta[name='_csrf_header']").attr("content");
+	$.ajaxSend(function(e, xhr, options) {
+		xhr.setRequestHeader(header, token);
+	});*/
+});
+
+var gagajf = {
+	/**
+	 * @type   : function
+	 * @access : public
+	 * @desc   : 값이 null 이거나 white space 문자로만 이루어진 경우 true를 리턴한다.
+	 * <pre>
+	 *     gagajf.isNull("  ");
+	 * </pre>
+	 * 위와같이 사용했을 경우 true를 리턴한다.
+	 * @param  : value - 필수 입력 값
+	 * @return : boolean. null(혹은 white space) 여부
+	 * @author : gagamel
+	 */
+	isNull : function(value) {
+		if (value == null || (typeof(value) == "string" && value.trim() == ""))
+			return true;
+
+		return false;
+	},
+
+	/**
+	 * @type   : function
+	 * @access : public
+	 * @desc   : 값이 null str로 true를 리턴한다.
+	 * <pre>
+	 *     gagajf.convNull(item.value, '');
+	 * </pre>
+	 * 위와같이 사용했을 경우 item.value 가 null일경우 ''을 리턴한다.
+	 * @param  : value - 필수 입력 값
+	 * @param  : str - 필수 입력 값
+	 * @return : value or str
+	 * @author : gagamel
+	 */
+	convNull : function(value, str) {
+		if (value == null)
+			return str;
+
+		return value;
+	},
+
+	/**
+	 * 유효한 이벤트 키코드인지 체크
+	 * @return : 유효한 이벤트 키코드이면 키코드 값, 아니면 -1
+	 * @since  : 2017/09/20
+	 * @author : gagamel
+	 */
+	getKeyCode : function() {
+		// 이벤트 객체와 문자 코드를 호환 가능한 방식으로 얻는다.
+		var e = event || window.event; // 키 이벤트 객체
+		var keyCode = e.charCode || e.keyCode; // 어떤 키가 눌러졌는가?
+//		console.log('keyCode: ' + keyCode);
+
+		// Ctrl 키나 Alt 키, ASCII 제어문자, 화살표 등 skip
+		if (e.ctrlKey || e.altkey || keyCode < 47) {
+			return -1;
+		}
+
+		return keyCode;
+	},
+
+	/**
+	 * 값이 정규표현식에 부합하는지는 체크한다.
+	 * @param  : el - 엘리먼트
+	 * @param  : regexp - 정규표현식
+	 * @param  : type - 엘리먼트 type
+	 * @return : 부합하는 경우 true, 그 외 false
+	 * @since  : 2017/09/21
+	 * @author : gagamel
+	 */
+	testRegexp : function(el, regexp, type) {
+		var val = $(el).val();
+
+		if (type == 'integer' || type == 'real') {
+			// 콤마(,) 제거
+			val = val.removeComma();
+		}
+
+		if (!regexp.test(val)) {
+			mcxDialog.alertC($(el).data('validName') + '의 형식이 잘못되었습니다.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$(el).select();
+					$(el).focus();
+				}
+			});
+			return false;
+		}
+
+		return true;
+	},
+
+	/**
+	 * alert 메시지
+	 * @param  : el - 엘리먼트
+	 *           mgsType - 메시지유형(input, select)
+	 * @since  : 2017/09/21
+	 * @author : gagamel
+	 */
+	alertMessage : function(el, mgsType) {
+		var validNm = $(el).data('validName');
+
+		if (mgsType == 'input') {
+			mcxDialog.alertC(validNm + '을(를) 입력해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$(el).focus();
+				}
+			});
+		} else if (mgsType == 'select') {
+			mcxDialog.alertC(validNm + '을(를) 선택해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$(el).focus();
+				}
+			});
+		}
+	},
+
+	/**
+	 * 체크박스와 라디오버튼을 선택한 것이 있는지 체크한다.
+	 * @param  : el - 엘리먼트
+	 *           mgsType - 메시지유형(input, select)
+	 * @since  : 2017/09/21
+	 * @author : gagamel
+	 */
+	isCheckedCheckbox : function(el) {
+		$(el).each(function(idx) {
+			if ($(el).eq(idx).is(':checked')) {
+				return true;
+			} else {
+				return false;
+			}
+		});
+	},
+
+	/**
+	 * 비밀번호 체크
+	 * 		1.영문대문자, 영문소문자, 특수문자, 숫자로만 구성
+	 * 		2.이 중에 3가지 이상으로 구성 시 8자 이상, 2가지 이상으로 구성 시 10자 이상
+	 * @param  : el - 엘리먼트
+	 * @since  : 2017/09/21
+	 * @author : gagamel
+	 */
+	checkPassword : function(el) {
+		var passwd = $(el).val();
+		var cnt = 0;
+		if (/[a-z]{1,}/.test(passwd)) cnt++;
+		if (/[A-Z]{1,}/.test(passwd)) cnt++;
+		if (/[0-9]{1,}/.test(passwd)) cnt++;
+		if (/[\~,\!,\@,\#,\$,\%,\^,\&,\*,\(,\),\_,\?,\{,\},\[,\]]{1,}/.test(passwd)) cnt++;
+
+		if (cnt >= 3) {
+			if (passwd.length < 8) {
+				mcxDialog.alertC('3가지 이상으로 구성 시 8 자리 이상으로 입력해 주세요.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$(el).select();
+						$(el).focus();
+					}
+				});
+				return false;
+			}
+		} else if (cnt >= 2) {
+			if (passwd.length < 10) {
+				mcxDialog.alertC('2가지 이상으로 구성 시 10 자리 이상으로 입력해 주세요.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$(el).select();
+						$(el).focus();
+					}
+				});
+				return false;
+			}
+		} else {
+			mcxDialog.alertC('대/소문자, 특수문자, 숫자로 구성해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$(el).select();
+					$(el).focus();
+				}
+			});
+			return false;
+		}
+
+		return true;
+	},
+
+	/**
+	 * 필수입력항목 엘리먼트를 체크해서 alert를 표시한다.
+	 */
+	checkRequired : function(oForm) {
+		var isInvalid = true;
+
+		$(oForm).find(':input').each(function(idx, el) {
+			if ($(el).attr('required') != 'required')
+				return true;
+
+			var type = $(el).attr('type');
+			if (!type) type = 'select';
+//			var msg = $(el).data('validName');
+
+			switch (type) {
+				case 'text':
+				case 'password':
+				case 'textarea':
+//				case 'select-one':
+					var value = $(el).val();
+					if (!gagajf.isNull(value))
+						return true;
+
+					gagajf.alertMessage($(el), 'input');
+					isInvalid = false;
+					return false;
+				case 'select':
+					var value = $(el).val();
+					if (!gagajf.isNull(value))
+						return true;
+
+					gagajf.alertMessage($(el), 'select');
+					isInvalid = false;
+					return false;
+				case 'checkbox':
+				case 'radio':
+					if (gagajf.isCheckedCheckbox($(el)))
+						return true;
+
+					gagajf.alertMessage($(el), 'select');
+					isInvalid = false;
+					return false;
+				case 'file':
+					var value = $(el).val();
+					if (!gagajf.isNull(value))
+						return true;
+
+					gagajf.alertMessage($(el), 'select');
+					isInvalid = false;
+					return false;
+			}
+		});
+
+		return isInvalid;
+	},
+
+	/**
+	 * 값이 형식에 맞는지 패턴을 체크한다.
+	 */
+	checkPattern : function(oForm) {
+		var isInvalid = true;
+
+		$(oForm).find('input').each(function(idx, el) {
+			if (gagajf.isNull($(el).val()))
+				return true;
+
+			var validType = $(el).data('validType');
+
+			// data-valid-type이 지정되지 않은 엘리먼트는 skip
+			if (!validType) return true;
+
+			// 값이 없으면 skip
+			if (gagajf.isNull($(el).val())) return true;
+
+			switch (validType) {
+				case 'numeric': // 숫자
+					if (gagajf.testRegexp($(el), /^[0-9]+$/))
+						return true;
+
+					isInvalid = false;
+					return false;
+				case 'integer': // 정수
+					if (gagajf.testRegexp($(el), /(^-?[0-9]+\d*$)|(^-$)/, 'integer'))
+						return true;
+
+					isInvalid = false;
+					return false;
+				case 'real': // 실수
+					if (gagajf.testRegexp($(el), /^-?(([0-9]+\.?)|(\.?))\d*$/, 'real'))
+						return true;
+
+					isInvalid = false;
+					return false;
+				case 'alphaNumeric': // 알파벳+숫자
+					if (gagajf.testRegexp($(el), /^[a-zA-Z0-9]+$/))
+						return true;
+
+					isInvalid = false;
+					return false;
+				case 'email': // 이메일
+					if (gagajf.testRegexp($(el), /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/))
+						return true;
+					isInvalid = false;
+					return false;
+				case 'password': // 이메일
+					if (gagajf.checkPassword($(el)))
+						return true;
+					isInvalid = false;
+					return false;
+				case 'cellPhone': // 휴대전화번호
+					if (gagajf.testRegexp($(el), /^(01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4})$/))
+						return true;
+
+					isInvalid = false;
+					return false;
+				case 'phone': // 일반전화번호
+					if (gagajf.testRegexp($(el), /^\d{2,3}-\d{3,4}-\d{4}$/))
+						return true;
+
+					isInvalid = false;
+					return false;
+				case 'ipAddress': // IP주소
+					if (gagajf.testRegexp($(el), /^(([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}))$/))
+						return true;
+
+					isInvalid = false;
+					return false;
+			}
+		});
+
+		return isInvalid;
+	},
+
+	checkValue : function(oForm){
+		var isInvalid = true;
+
+		$(oForm).find('input').each(function(idx, el) {
+
+			var validType = $(el).data('validType');
+
+			// data-valid-type이 지정되지 않은 엘리먼트는 skip
+			if (!validType) return true;
+
+			// 값이 없으면 skip
+			if (gagajf.isNull($(el).val())) return true;
+
+			switch (validType) {
+				case 'numeric': // 숫자
+					//최대값
+					if ($(el).attr("max")) {
+						if ($(el).val() > $(el).attr("max")) {
+							mcxDialog.alertC($(el).data('validName') + '은(는) 최대 ' + $(el).attr("max") + '보다 작아야 합니다.', {
+								sureBtnText: "확인",
+								sureBtnClick: function() {
+									$(el).focus();
+								}
+							});
+							isInvalid = false;
+							return false;
+						}
+					}
+					//최소값
+					if ($(el).attr("min")) {
+						if ($(el).val() < $(el).attr("min")) {
+							mcxDialog.alertC($(el).data('validName') + '은(는) 최소 ' + $(el).attr("min") + '보다 커야 합니다.', {
+								sureBtnText: "확인",
+								sureBtnClick: function() {
+									$(el).focus();
+								}
+							});
+							isInvalid = false;
+							return false;
+						}
+					}
+
+				case 'integer': // 정수
+					//최대값
+					if ($(el).attr("max")) {
+						if ($(el).val() > $(el).attr("max")) {
+							mcxDialog.alertC($(el).data('validName') + '은(는) 최대 ' + $(el).attr("max") + '보다 작아야 합니다.', {
+								sureBtnText: "확인",
+								sureBtnClick: function() {
+									$(el).focus();
+								}
+							});
+							isInvalid = false;
+							return false;
+						}
+					}
+					//최소값
+					if ($(el).attr("min")) {
+						if ($(el).val() < $(el).attr("min")) {
+							mcxDialog.alertC($(el).data('validName') + '은(는) 최소 ' + $(el).attr("min") + '보다 커야 합니다.', {
+								sureBtnText: "확인",
+								sureBtnClick: function() {
+									$(el).focus();
+								}
+							});
+							isInvalid = false;
+							return false;
+						}
+					}
+				case 'real': // 실수
+					//최대값
+					if ($(el).attr("max")) {
+						if ($(el).val() > $(el).attr("max")) {
+							mcxDialog.alertC($(el).data('validName') + '은(는) 최대 ' + $(el).attr("max") + '보다 작아야 합니다.', {
+								sureBtnText: "확인",
+								sureBtnClick: function() {
+									$(el).focus();
+								}
+							});
+							isInvalid = false;
+							return false;
+						}
+					}
+					//최소값
+					if ($(el).attr("min")) {
+						if ($(el).val() < $(el).attr("min")) {
+							mcxDialog.alertC($(el).data('validName') + '은(는) 최소 ' + $(el).attr("min") + '보다 커야 합니다.', {
+								sureBtnText: "확인",
+								sureBtnClick: function() {
+									$(el).focus();
+								}
+							});
+							isInvalid = false;
+							return false;
+						}
+					}
+			}
+		});
+		
+		return isInvalid;
+	},
+
+	/**
+	 * form을 validation 한다.
+	 * 예)
+	 * 		if (gagajf.validation('#registerForm');
+	 */
+	validation : function(formId) {
+		var $form = $(formId);
+
+		if (!this.checkRequired($form))
+			return false;
+
+		if (!this.checkPattern($form))
+			return false;
+
+		if(!this.checkValue($form))
+			return false;
+
+		return true;
+	},
+
+	/**
+	 * formId의 input의 data-valid-type이 integer, real인 경우에 값에 comma(,)를 자동으로 붙여 표시한다.
+	 * 사용) gagajf.addCommaAtNumberFormattedInput('#registerForm');
+	 */
+	addCommaAtNumberFormattedInput : function(formId) {
+		$(formId).find('input').each(function(idx, el) {
+			if ($(el).data('validType') == 'integer' || $(el).data('validType') == 'real') {
+				$(el).val($(el).val().removeComma().addComma());
+			}
+		});
+	},
+
+	/**
+	 * formId의 input의 data-valid-type이 integer, real, numeric 인 경우에 값에 comma(,)를 자동으로 제거한다.
+	 * 사용) gagajf.removeCommaAtNumberFormattedInput('#registerForm');
+	 */
+	removeCommaAtNumberFormattedInput : function(formId) {
+		$(formId).find('input').each(function(idx, el) {
+			if ($(el).data('validType') == 'integer' || $(el).data('validType') == 'real' || $(el).data('validType') == 'numeric') {
+				$(el).val($(el).val().removeComma());
+			}
+		});
+	},
+	
+	/**
+	 * formId의 input의 값에 ?가 여러 개인 경우 ? 한 개로 대체한다.
+	 * 사용) gagajf.replaceOneQuestionMark('#registerForm');
+	 */
+	replaceOneQuestionMark : function(formId) {
+		$(formId).find('input[type=text]').each(function(idx, el) {
+			$(el).val($(el).val().replace(/\?+/gi, "?"));
+		});
+		
+		$(formId).find('textarea').each(function(idx, el) {
+			$(el).val($(el).val().replace(/\?+/gi, "?"));
+		});
+	},
+
+	/**
+	 * Progress bar
+	 */
+	showProgressbar : function(isLoading) {
+		if (isLoading) {
+			// Button disabled & progressBar creation
+			//$('.btn').each(function(idx) { $(this).attr('disabled', true); });
+			var load_AjaxSubmit = '<div id="load_AjaxSubmit" style="'
+				+ 'background: url(/ux/plugins/gaga/loader.gif); border-style: none; background-repeat: no-repeat; '
+				+ 'position: absolute; top: 45%; left: 50%; width: auto; '
+				+ 'z-index: 101; padding: 16px; margin: 5px;'
+				+ '"></div>';
+			$('#content').append(load_AjaxSubmit);
+		} else {
+			// Button activated & progressBar remove
+			//$('.btn').each(function(idx) { $(this).attr('disabled', false); });
+			$('#load_AjaxSubmit').remove();
+		}
+	},
+
+	/**
+	 * form의 데이터를 json으로 변환 후 ajax 방식으로 submit 한다.
+	 * 모든 form의 ajax 처리는 이것으로 진행한다.
+	 * <pre>
+	 *     ajaxFormSubmit('/rest/commoncode/create', '#registerForm', jfRegisterSaveCallback);
+	 * </pre>
+	 * @param actionUrl - Request URL
+	 * @param formId - form ID
+	 * @param callbackFn - Callback function
+	 * @author gagamel
+	 * @since 2019. 4. 8
+	 */
+	ajaxFormSubmit : function(actionUrl, formId, callbackFn) {
+		// comma(,) 제거
+		gagajf.removeCommaAtNumberFormattedInput(formId);
+		
+		// 물음표(?) 여러 개를 1개로 대체
+//		gagajf.replaceOneQuestionMark(formId);
+
+		var jsonData = JSON.stringify($(formId).serializeObject());
+		
+		$.ajax({
+			type : 'POST',
+			url : actionUrl,
+			data : jsonData,
+			dataType : 'json',
+			jsonp : false, // 물음표(?) 여러 개가 jQuery~로 변경되는 현상 방지
+			beforeSend : function(xhr, settings) {
+				// AJAX call
+				xhr.setRequestHeader("AJAX", "true");
+
+				// dataType: "json"일 때
+				xhr.setRequestHeader('Accept', 'application/json');
+				xhr.setRequestHeader('Content-Type', 'application/json');
+
+				// Button disabled & progressBar creation
+				gagajf.showProgressbar(true);
+			},
+			complete : function(xhr) {
+				// Button abled & progressBar remove
+				gagajf.showProgressbar(false);
+
+				// 세션이 없다. 로그인 페이지로 이동
+				if (xhr.status == 901) {
+					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							document.location.href = "/error/noSession";
+						}
+					});
+				}
+			},
+			success : function(result) {
+				if (typeof(result.status) == 'undefined' || result.status == 200) { // 성공
+					if (!gagajf.isNull(result.message)) {
+						mcxDialog.alertC(result.message, {
+							sureBtnText: "확인",
+							sureBtnClick: function() {
+								if (typeof(callbackFn) == "function") {
+									callbackFn.call(this, result);
+								}
+							}
+						});
+					} else {
+						if (typeof(callbackFn) == "function") {
+							callbackFn.call(this, result);
+						}
+					}
+				} else { // 실패
+					if (!gagajf.isNull(result.error.message)) {
+						mcxDialog.alert(result.error.message);
+					}
+
+					return;
+				}
+			},
+			error : function(result) {
+				console.log(result);
+				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
+			}
+		});
+	},
+
+	/**
+	 * json 데이터를 가지고 ajax 방식으로 submit 한다.
+	 * 모든 ajax 처리는 이것으로 진행한다.
+	 * <pre>
+	 *     gagajf.removeCommaAtNumberFormattedInput('#registerForm'); // comma(,) 제거
+	 *     var jsonData = JSON.stringify($('#registerForm').serializeObject());
+	 *     gagajf.ajaxJsonSubmit('/rest/commoncode/create', jsonData, jfRegisterSaveCallback);
+	 * </pre>
+	 * @param actionUrl - Request URL
+	 * @param jsonData - Data of json format
+	 * @param callbackFn - Callback function
+	 * @author gagamel
+	 * @since 2019. 4. 8
+	 */
+	ajaxJsonSubmit : function(actionUrl, jsonData, callbackFn) {
+		$.ajax({
+			type : 'POST',
+			url : actionUrl,
+			data : jsonData,
+			dataType : 'json',
+			jsonp : false, // 물음표(?) 여러 개가 jQuery~로 변경되는 현상 방지
+			beforeSend : function(xhr, settings) {
+				// AJAX call
+				xhr.setRequestHeader("AJAX", "true");
+
+				// dataType: "json"일 때
+				xhr.setRequestHeader('Accept', 'application/json');
+				xhr.setRequestHeader('Content-Type', 'application/json');
+				
+				// Button disabled & progressBar creation
+				gagajf.showProgressbar(true);
+			},
+			complete : function(xhr) {
+				// Button abled & progressBar remove
+				gagajf.showProgressbar(false);
+
+				// 세션이 없다. 로그인 페이지로 이동
+				if (xhr.status == 901) {
+					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							document.location.href = "/error/noSession";
+						}
+					});
+				}
+			},
+			success : function(result) {
+				if (typeof(result.status) == 'undefined' || result.status == 200) { // 성공
+					if (!gagajf.isNull(result.message)) {
+						mcxDialog.alertC(result.message, {
+							sureBtnText: "확인",
+							sureBtnClick: function() {
+								if (typeof(callbackFn) == "function") {
+									callbackFn.call(this, result);
+								}
+							}
+						});
+					} else {
+						if (typeof(callbackFn) == "function") {
+							callbackFn.call(this, result);
+						}
+					}
+				} else { // 실패
+					if (!gagajf.isNull(result.error.message)) {
+						mcxDialog.alert(result.error.message);
+					}
+
+					return;
+				}
+			},
+			error : function(result) {
+				console.log(result);
+				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
+			}
+		});
+	},
+
+	/**
+	 * ajax 방식으로 파일을 업로드 한다.
+	 * <pre>
+	 *     gagajf.ajaxFileUpload('/common/file/upload?subDir=notice', this.files[0], jfCallback);
+	 * </pre>
+	 * @param actionUrl - Request URL
+	 * @param file - A file to upload
+	 * @param callbackFn - Callback function
+	 * @param policy - Upload policy
+	 * @author gagamel
+	 * @since 2019. 7. 9
+	 */
+	ajaxFileUpload : function(actionUrl, file, callbackFn, policy) {
+		var formData = new FormData();
+		formData.append("file", file);
+
+		if (typeof policy != 'undefined') {
+			formData.append("policy", policy);
+		}
+
+		$.ajax({
+			type : 'POST',
+			url : actionUrl,
+			data : formData,
+			dataType: 'json',
+			processData : false, // true: data의 파일 형태가 query String으로 전송. false : non-processed data
+			contentType : false, // multipart/form-data 형태로 전송되기 위한 옵션 값
+			beforeSend : function(xhr, settings) {
+				// AJAX call
+				xhr.setRequestHeader("AJAX", "true");
+
+				// Button disabled & progressBar creation
+				gagajf.showProgressbar(true);
+			},
+			complete : function(xhr) {
+				// Button abled & progressBar remove
+				gagajf.showProgressbar(false);
+
+				// 세션이 없다. 로그인 페이지로 이동
+				if (xhr.status == 901) {
+					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							document.location.href = "/error/noSession";
+						}
+					});
+				}
+			},
+			success : function(result) {
+				if (typeof(result.status) == 'undefined' || result.status == 200) { // 성공
+					if (!gagajf.isNull(result.message)) {
+						mcxDialog.alertC(result.message, {
+							sureBtnText: "확인",
+							sureBtnClick: function() {
+								if (typeof(callbackFn) == "function") {
+									callbackFn.call(this, result);
+								}
+							}
+						});
+					} else {
+						if (typeof(callbackFn) == "function") {
+							callbackFn.call(this, result);
+						}
+					}
+				} else { // 실패
+					if (!gagajf.isNull(result.error.message)) {
+						mcxDialog.alert(result.error.message);
+					}
+
+					return;
+				}
+			},
+			error: function(result) {
+				console.log(result);
+				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
+			}
+		});
+	},
+
+	/**
+	 * 대용량 json 데이터를 가지고 ajax 방식으로 submit 한다.
+	 * <pre>
+	 *     gagajf.removeCommaAtNumberFormattedInput('#registerForm'); // comma(,) 제거
+	 *     gagajf.replaceOneQuestionMark('#registerForm'); // 물음표(?) 여러개를 1개로 대체
+	 *     var jsonData = JSON.stringify($('#registerForm').serializeObject());
+	 *     gagajf.ajaxJsonBatchSubmit('/rest/commoncode/create', jsonData, 1, 3, jfRegisterSaveCallback);
+	 * </pre>
+	 * @param actionUrl - Request URL
+	 * @param jsonData - Data of json format
+	 * @param callIdx - 호출인덱스(실제 호출한 횟수)
+	 * @param callCnt - 호출해야할횟수(몇 번 호출해야 하는지)
+	 * @param callbackFn - Callback function
+	 * @author gagamel
+	 * @since 2019. 4. 8
+	 */
+	ajaxJsonBatchSubmit : function(actionUrl, jsonData, callIdx, callCnt, callbackFn) {
+		$.ajax({
+			type : 'POST',
+			url : actionUrl,
+			data : jsonData,
+			dataType : 'json',
+			beforeSend : function(xhr, settings) {
+				// AJAX call
+				xhr.setRequestHeader("AJAX", "true");
+
+				// dataType: "json"일 때
+				xhr.setRequestHeader('Accept', 'application/json');
+				xhr.setRequestHeader('Content-Type', 'application/json');
+
+				// Button disabled & progressBar creation
+				if (callIdx == 1) { // 첫번째 호출이면
+					gagajf.showProgressbar(true);
+				}
+			},
+			complete : function(xhr) {
+				// Button abled & progressBar remove
+				if (callIdx == callCnt) { // 마지막 호출이면
+					gagajf.showProgressbar(false);
+				}
+
+				// 세션이 없다. 로그인 페이지로 이동
+				if (xhr.status == 901) {
+					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							document.location.href = "/error/noSession";
+						}
+					});
+				}
+			},
+			success : function(result) {
+				if (callIdx == callCnt) { // 마지막 호출이면
+					mcxDialog.alertC('성공적으로 처리되었습니다.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							if (typeof(callbackFn) == "function") {
+								callbackFn.call(this, result);
+							}
+						}
+					});
+				} else {
+					if (typeof(callbackFn) == "function") {
+						callbackFn.call(this, result);
+					}
+				}
+			},
+			error : function(result) {
+				console.log(result);
+				mcxDialog.alert('오류로 인해 처리되지 않았습니다.');
+			}
+		});
+	},
+
+	/**
+	 * JQuery를 이용한 비동기 submit 처리
+	 * 파라미터의 명칭은 쿼리문과 동일하게 작성해야 한다.
+	 * <pre>
+	 *     var params = new Object();
+	 *     params.cdGb = "G900";
+	 *     params.cd = "0202";
+	 *
+	 *     gagajf.ajaxSubmit("/rest/commoncode/create", "json", jfCallback, params);
+	 *
+	 *     or
+	 *
+	 *     gagajf.ajaxSubmit("/rest/commoncode/create", "json", jfCallback);
+	 * </pre>
+	 * @param  : actionUrl - action url. 필수
+	 *           type - 처리결과 형식(text, html, xml, json). 필수
+	 *           callback - type이 text, xml, json 일 때는 콜백함수명
+	 *                      type이 html일 때는 target명. 필수
+	 *           params - 파라미터 오브젝트. 옵션
+	 * @author gagamel
+	 * @since 2019. 4. 8
+	 */
+	ajaxSubmit : function(actionUrl, type, callback, params) {
+		$.ajaxSetup({
+			beforeSend: function(xhr, settings) {
+				// AJAX call
+				xhr.setRequestHeader("AJAX", "true");
+
+				// type: "json"일 때
+				if (type == "json") {
+					xhr.setRequestHeader('Accept', 'application/json');
+					xhr.setRequestHeader('Content-Type', 'application/json');
+				}
+			},
+			complete: function(xhr) {
+				// 세션이 없다. 로그인 페이지로 이동
+				if (xhr.status == 901) {
+					mcxDialog.alertC('세션이 없습니다. 로그인 페이지로 이동합니다.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							document.location.href = "/error/noSession";
+						}
+					});
+				}
+			}
+		});
+
+		if (!params) params = new Object();
+
+		var paramData = $.param(params);
+
+		// dataType: "json"일 때
+		if (type == "json") {
+			paramData = JSON.stringify(params);
+		}
+
+		$.post(actionUrl
+			, paramData
+			, function(result) {
+				if (type == "html") {
+					if (!gagajf.isNull(callback))
+						$(document.getElementById(callback)).html(result);
+				} else {
+					// Callback 함수 호출
+					if (typeof(callback) == "function")
+						callback.call(this, result);
+				}
+			}
+			, type);
+	},
+
+	/**
+	 * @type   : function
+	 * @access : public
+	 * @desc   : 기간의 시작일자와 종료일자를 설정한다.
+	 * <pre>
+	 *     gagajf.setDate($('#sellStdt'), $('#sellEddt'), 't');
+	 * </pre>
+	 * @param  : fromObj - 시작일자 오브젝트
+	 * @param  : toObj - 종료일자 오브젝트
+	 * @param  : type - 유형(오늘: t, 어제: y, 최근한주: 7d, 이번주: tw, 지난주: pw, 최근한달: 1m, 이번달: tm, 지난달: pm, 최근3개월: 3m
+	 * @since  : 2019/08/09
+	 * @author : gagamel
+	 */
+	setDate : function(tgtId, fromObj, toObj, type) {
+		var date = new Date();
+
+		if (type == '') { // 기간 X
+			$(tgtId +' #' + fromObj).val('');
+			$(tgtId +' #' + toObj).val('');
+		} else if (type == 't') { // 오늘
+			$(tgtId +' #' + fromObj).val(date.format("YYYY-MM-DD"));
+			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
+		} else if (type == 'y') { // 어제
+			$(tgtId +' #' + fromObj).val(date.before(0, 0, 1).format("YYYY-MM-DD"));
+			$(tgtId +' #' + toObj).val(date.before(0, 0, 1).format("YYYY-MM-DD"));
+		} else if (type == '7d') { // 최근한주
+			$(tgtId +' #' + fromObj).val(date.before(0, 0, 6).format("YYYY-MM-DD"));
+			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
+		} else if (type == 'tw') { // 이번주
+			var wdays = date.getDate() - date.getDay();
+			$(tgtId +' #' + fromObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays).format("YYYY-MM-DD"));
+			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays + 6).format("YYYY-MM-DD"));
+		} else if (type == 'pw') { // 지난주
+			var wdays = date.getDate() - date.getDay();
+			$(tgtId +' #' + fromObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays - 7).format("YYYY-MM-DD"));
+			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 0, wdays - 1).format("YYYY-MM-DD"));
+		} else if (type == '1m') { // 최근한달
+			$(tgtId +' #' + fromObj).val(date.before(0, 1, 0).after(0, 0, 1).format("YYYY-MM-DD"));
+			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
+		} else if (type == 'tm') { // 이번달
+			$(tgtId +' #' + fromObj).val(date.format("YYYY-MM-") + '01');
+			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').after(0, 1, 0).before(0, 0, 1).format("YYYY-MM-DD"));
+		} else if (type == 'pm') { // 지난달
+			//$(tgtId +' #' + fromObj).val(date.before(0, 1, 0).format("YYYY-MM-")  + '01');
+			$(tgtId +' #' + fromObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').before(0, 1, 0).format("YYYY-MM-")  + '01');
+			$(tgtId +' #' + toObj).val((date.format('YYYY-MM-') + '01').toDate('YYYY-MM-DD').before(0, 0, 1).format("YYYY-MM-DD"));
+		} else if (type == '3m') { // 최근3개월
+			$(tgtId +' #' + fromObj).val(date.before(0, 3, 0).after(0, 0, 1).format("YYYY-MM-DD"));
+			$(tgtId +' #' + toObj).val(date.format("YYYY-MM-DD"));
+		}
+	},
+
+	/**
+	 * @type   : function
+	 * @access : public
+	 * @desc   : Set Cookie
+	 * <pre>
+	 *     gagajf.setCookie("COOKIE_TODAY_PROD", "HUE00C105GE", 1);
+	 * </pre>
+	 * @param  : name - 쿠키명
+	 * @param  : value - 쿠키 값
+	 * @param  : expiredays - 만료기간
+	 * @return : None
+	 * @since  : 2019/07/01
+	 * @author : gagamel
+	 */
+	setCookie : function(name, value, expiredays) {
+		var todayDate = new Date();
+		todayDate.setDate(todayDate.getDate() + expiredays);
+		document.cookie = name + "=" + escape(value) + "; path=/; expires=" + todayDate.toGMTString() + ";";
+	},
+
+	/**
+	 * @type   : function
+	 * @access : public
+	 * @desc   : Get Cookie
+	 * <pre>
+	 *     gagajf.getCookie("COOKIE_TODAY_PROD");
+	 * </pre>
+	 * @param  : name - 쿠키명
+	 * @return : None
+	 * @since  : 2019/07/01
+	 * @author : gagamel
+	 */
+	getCookie : function(name) {
+		var nameOfCookie = name + "=";
+		var x = 0;
+		while (x <= document.cookie.length) {
+			var y = (x+nameOfCookie.length);
+			if (document.cookie.substring(x, y) == nameOfCookie) {
+				if ((endOfCookie=document.cookie.indexOf(";", y)) == -1) endOfCookie = document.cookie.length;
+				return unescape(document.cookie.substring(y, endOfCookie));
+			}
+			x = document.cookie.indexOf(" ", x) + 1;
+			if (x == 0) break;
+		}
+
+		return "";
+	},
+	
+	/**
+	 * 데이터를 배열로 변환
+	 * 예)
+	 * 		convertToArray({cd: "KNE", cdNm: "KNE"});
+	 * @param  : data - 데이터
+	 * @param  : isCodeDisplay - 코드표시여부(true/false). default false
+	 * @author : gagamel
+	 * @since  : 2019. 6. 7
+	 */
+	convertToArray : function(data, isCodeDisplay) {
+		if (data.length == 0)
+			return [];
+
+		if (typeof(isCodeDisplay) == 'undefined')
+			isCodeDisplay = false;
+
+		var arrValue = {};
+
+		$.each(data, function(idx, item) {
+			arrValue[item.cd] = (isCodeDisplay ? '[' + item.cd + '] ' : '') + item.cdNm;
+		});
+
+		return arrValue;
+	} ,
+	checkFileSize : function (data){
+		var isInvalid = true;
+
+		var fileSize = data.size;
+		var maxSize = 1024 * 1024 * 10;
+		if(fileSize > maxSize){
+			alert("파일용량이 10MB을 초과했습니다.");
+			isInvalid = false;
+			return false;
+		}else{
+			isInvalid = true
+			return true;
+		}
+
+		return isInvalid;
+	}
+};
+
+/**
+ * @type   : function
+ * @access : document
+ * @desc   : <input> 태그에 대한 키눌림에 대해 validation을 체크한다.
+ *           data-valid-type="numeric" : 숫자. 속성 지정시 숫자만 입력 가능
+ *           data-valid-type="integer" : 정수. 속성 지정시 숫자와 +, - 만 입력 가능
+ *           data-valid-type="real" : 실수. 속성 지정시 숫자와 +, -, . 만 입력 가능
+ *           data-valid-type="alphaNumeric" : 알파벳과 숫자. 속성 지정 시 영문과 숫자만 형식에 맞게 입력 가능
+ *           data-valid-type="date" : 숫자와 / 만 입력 가능
+ *           data-valid-type="korean" : 한글. 속성 지정 시 한글만 형식에 맞게 입력 가능
+ *           data-valid-type="email" : 이메일
+ *           data-valid-type="password" : 비밀번호
+ *           data-valid-type="cellPhone" : 휴대전화번호
+ *           data-valid-type="phone" : 일반전화번호
+ *           data-valid-type="ipAddress" : IP주소
+ *           data-valid-type="bizRegNo" : 사업자등록번호
+ * <pre>
+ *     <input type="text" data-valid-type="numeric" />
+ *     <input type="text" data-valid-type="integer" />
+ *     <input type="text" data-valid-type="real" />
+ *     <input type="text" data-valid-type="alphaNumeric" />
+ *     <input type="text" data-valid-type="date" />
+ *     <input type="text" data-valid-type="korean" />
+ *     <input type="text" data-valid-type="email" />
+ *     <input type="text" data-valid-type="password" />
+ *     <input type="text" data-valid-type="cellPhone" />
+ *     <input type="text" data-valid-type="phone" />
+ *     <input type="text" data-valid-type="ipAddress" />
+ *     <input type="text" data-valid-type="bizRegNo" />
+ * </pre>
+ * @author : gagamel
+ * @since  : 2017/09/20
+ */
+$(document).on("keyup", "[data-valid-type=numeric]", function() { $(this).val($(this).val().replace(/[^0-9]/gi,"")); });
+$(document).on("keydown", "[data-valid-type=numeric]", function() {
+	var value = $(this).val();
+
+	var keyCode = gagajf.getKeyCode();
+	if (keyCode == -1)
+		return true;
+
+	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
+		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
+		)) {
+		$(this).val(value);
+		event.returnValue = false;
+	}
+});
+$(document).on("blur", "[data-valid-type=integer]", function() { $(this).val($(this).val().removeComma().addComma()); });
+$(document).on("click", "[data-valid-type=integer]", function() { $(this).val($(this).val().removeComma()); });
+$(document).on("keyup", "[data-valid-type=integer]", function() { $(this).val($(this).val().replace(/[^0-9-\+]/gi,"")); });
+$(document).on("keydown", "[data-valid-type=integer]", function() {
+	var value = $(this).val();
+
+	var keyCode = gagajf.getKeyCode();
+	if (keyCode == -1)
+		return true;
+
+	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
+		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
+		|| (keyCode == 187 && event.shiftKey) // Shift 하고 +
+		|| (keyCode == 107) // + (Num Lock)
+		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
+		|| (keyCode == 109) // - (Num Lock)
+		)) {
+		$(this).val(value);
+		event.returnValue = false;
+	}
+});
+$(document).on("blur", "[data-valid-type=real]", function() { $(this).val($(this).val().removeComma().addComma()); });
+$(document).on("click", "[data-valid-type=real]", function() { $(this).val($(this).val().removeComma()); });
+$(document).on("keyup", "[data-valid-type=real]", function() { $(this).val($(this).val().replace(/[^0-9-\+\.]/gi,"")); });
+$(document).on("keydown", "[data-valid-type=real]", function() {
+	var value = $(this).val();
+
+	var keyCode = gagajf.getKeyCode();
+	if (keyCode == -1)
+		return true;
+
+	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
+		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
+		|| (keyCode == 187 && event.shiftKey) // Shift 하고 +
+		|| (keyCode == 107) // + (Num Lock)
+		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
+		|| (keyCode == 109) // - (Num Lock)
+		|| (keyCode == 190 && !event.shiftKey) // .
+		)) {
+		$(this).val(value);
+		event.returnValue = false;
+	}
+});
+$(document).on("keyup", "[data-valid-type=alphaNumeric]", function() { $(this).val($(this).val().replace(/[^a-zA-Z0-9]/gi, "")); });
+$(document).on("keyup", "[data-valid-type=date]", function() { $(this).val($(this).val().replace(/[^0-9\/]/gi,"")); });
+$(document).on("keyup", "[data-valid-type=calendar]", function() { $(this).val($(this).val().replace(/[^0-9\/]/gi,"")); });
+$(document).on("blur", "[data-valid-type=calendar]", function() {
+	var val = $(this).val();
+	if(val==''){
+		return;
+	}
+	val = val.replace(/-/gi, "");
+	var temp = val.substring(0, 4)+" ";
+	if(Number(val.substring(4, 6))>12){
+		temp += "12";
+	}else if(Number(val.substring(4, 6))==0){
+		temp += "1";
+	}else{
+		temp += Number(val.substring(4, 6));
+	}
+	temp += " ";
+	if(Number(val.substring(6, 8))>31){
+		temp += "31";
+	}else if(Number(val.substring(6, 8))==0){
+		temp += "1";
+	}else{
+		temp += Number(val.substring(6, 8));
+	}
+	
+	var date = new Date(temp);
+	var yyyy = date.getFullYear().toString();
+	var mm = (date.getMonth() + 1).toString();
+	var dd = date.getDate().toString();
+	$(this).val(yyyy + '-' + (mm[1] ? mm : '0'+mm[0])+ '-'  + (dd[1] ? dd : '0'+dd[0]));
+});
+$(document).on("keyup", "[data-valid-type=korean]", function() { $(this).val($(this).val().replace(/[^가-힣]/gi, "")); });
+$(document).on("keyup", "[data-valid-type=email]", function() { $(this).val($(this).val().replace(/[^a-zA-Z0-9\@\+\_\.\@\-]/gi, "")); });
+$(document).on("keyup", "[data-valid-type=password]", function() { $(this).val($(this).val().replace(/[^a-zA-Z0-9\~\!\@\#\$\%\^\&\*\?\(\)\_\+\{\}\[\]]/gi, "")); });
+$(document).on("keyup", "[data-valid-type=cellPhone]", function() { $(this).val($(this).val().replace(/[^\d-]/gi, "")); });
+$(document).on("keydown", "[data-valid-type=cellPhone]", function() {
+	var value = $(this).val();
+
+	var keyCode = gagajf.getKeyCode();
+	if (keyCode == -1)
+		return true;
+
+	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
+		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
+		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
+		|| (keyCode == 109) // - (Num Lock)
+		)) {
+		$(this).val(value);
+		event.returnValue = false;
+	}
+});
+$(document).on("keyup keydown paste change", "[data-valid-type=cellPhone]", function() {
+	$(this).val($(this).val().replace(/[^0-9]/g, "").replace(/(^02|^050[0-9]{1}|^1[0-9]{3}|^0[0-9]{2})([0-9]+)?([0-9]{4})$/,"$1-$2-$3").replace("--", "-"));
+});
+$(document).on("keyup", "[data-valid-type=phone]", function() { $(this).val($(this).val().replace(/[^\d-]/gi, "")); });
+$(document).on("keydown", "[data-valid-type=phone]", function() {
+	var value = $(this).val();
+
+	var keyCode = gagajf.getKeyCode();
+	if (keyCode == -1)
+		return true;
+
+	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
+		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
+		|| (keyCode == 189 && !event.shiftKey) // Shift 없이 -
+		|| (keyCode == 109) // - (Num Lock)
+		)) {
+		$(this).val(value);
+		event.returnValue = false;
+	}
+});
+$(document).on("keyup", "[data-valid-type=ipAddress]", function() { $(this).val($(this).val().replace(/[^\d\.]/gi, "")); });
+$(document).on("keydown", "[data-valid-type=ipAddress]", function() {
+	var value = $(this).val();
+
+	var keyCode = gagajf.getKeyCode();
+	if (keyCode == -1)
+		return true;
+
+	if (!((keyCode >= 48 && keyCode <= 57 && !event.shiftKey) // 0 ~ 9
+		|| (keyCode >= 96 && keyCode <= 105) // 0 ~ 9 (Num Lock)
+		|| (keyCode == 190 && !event.shiftKey) // .
+		)) {
+		$(this).val(value);
+		event.returnValue = false;
+	}
+});
+$(document).on("keyup", "[data-valid-type=bizRegNo]", function() { $(this).val($(this).val().replace(/[^0-9\-]/gi,"")); });