rosewiper 2024-09-10
Merge branch 'master' into kakaoFT
@bda2447d475a64349faf2172b9635983907c65d3
src/main/java/itn/let/kakao/admin/kakaoAt/web/MjonKakaoATController.java
--- src/main/java/itn/let/kakao/admin/kakaoAt/web/MjonKakaoATController.java
+++ src/main/java/itn/let/kakao/admin/kakaoAt/web/MjonKakaoATController.java
@@ -768,7 +768,7 @@
 			channelIDVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
 			
 			if("".equals(channelIDVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-				channelIDVO.setSearchSortCnd("profileId");
+				channelIDVO.setSearchSortCnd("lastUpdtPnttm");
 				channelIDVO.setSearchSortOrd("desc");
 			}
 			
src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
--- src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
@@ -18,12 +18,22 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFDataFormat;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.ModelMap;
@@ -31,15 +41,20 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
 
 import egovframework.rte.fdl.idgnr.EgovIdGnrService;
 import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
 import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
 import itn.com.cmm.EgovMessageSource;
+import itn.com.cmm.JsonResult;
 import itn.com.cmm.LoginVO;
 import itn.com.cmm.service.EgovCmmUseService;
 import itn.com.cmm.util.MJUtil;
+import itn.com.cmm.util.StringUtil;
 import itn.com.utl.fcc.service.EgovStringUtil;
 import itn.let.kakao.kakaoComm.KakaoReturnVO;
 import itn.let.kakao.kakaoComm.KakaoSendUtil;
@@ -200,6 +215,569 @@
 		
 		return "web/kakao/msgdata/at/KakaoAlimtalkMsgDataView";
 	}
+	
+	
+	/*
+	 * 20240829 신규 추가 우영두
+	 * 기존 Script에서 처리하던 방식 변경
+	 * 카카오 알림톡 엑셀 불러오기 엑셀 처리
+	 * 
+	 * */
+	@RequestMapping(value = "/web/mjon/alimtalk/sendAlimtalkExelFilePhoneNumAjax.do")
+	@ResponseBody
+	public Object sendAlimtalkExelFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
+	
+		JsonResult jr = new JsonResult();
+		jr.setSuccess(false);
+		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
+		
+		try {
+		
+			//final Map<String, MultipartFile> files = multiRequest.getFileMap();
+			List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
+			
+			// 파일명에 .이 있을경우 오류 => Ex) 테스트6.20.xlsx 
+			int fileNameSplitCnt = 0;
+			
+			if(!files.isEmpty()) {
+				fileNameSplitCnt = files.get(0).getOriginalFilename().split("[.]").length;
+				
+				if (files.get(0).getSize() > 0 
+						&& (files.get(0).getContentType().indexOf("spreadsheetml") > -1) 
+						|| files.get(0).getContentType().indexOf("ms-excel") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xlsx") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xls") > -1) {
+					
+					// 엑셀 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
+					long fileSize = multiRequest.getFile("file0").getSize();
+					
+					String Ext = files.get(0).getOriginalFilename().split("[.]")[1];
+					String errMessage = "";
+			        String cellValue  = "";
+			        String errPhoneLine = "";
+			        int errPhoneCnt = 0;
+			        
+			        //수신번호 유효성 체크
+					String phoneRegExp = "^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
+					
+					if(Ext.equals("xls")) {
+						
+						HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
+					    HSSFSheet sheet = workbook.getSheetAt(0);
+					    
+					    if(sheet.getLastRowNum() > 501) { 
+			            	errMessage = "한번에 전송 가능한 최대 발송건은 500건 입니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }
+						
+					    List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+					    for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	HSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                HSSFCell cell = null;
+			                boolean errSts = true;
+			                for(int j = 0 ; j < 1; j++){ //행읽기(첫번째 컬럼만 필요)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
+			                		if(j == 1) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+			                		}
+			                    	
+			                    }
+			                	if(null != cell){
+			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+			                			case  Cell.CELL_TYPE_NUMERIC:
+			                			cell.setCellType(Cell.CELL_TYPE_STRING);
+			                		}
+			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+			                		
+			                		if(cellValue.matches(phoneRegExp) && errSts) {
+			                			jm.put("phone", cellValue);
+			                		}else {
+				    	            	errPhoneCnt++;
+				    	            	errPhoneLine += (i+1) + "행 ";
+				    	            	errSts = false;
+				    	            	break;
+			                		}
+			                    }
+			                	
+			                }
+			                
+			                if(null != jm.get("phone") && errSts) {
+			                	json.add(jm);
+			                }
+					    }
+					    
+					    int resultErrCnt = errPhoneCnt;
+			            
+			            jr.setData(json);
+						jr.setSuccess(true);
+						
+						if(resultErrCnt > 0) {
+							if (errPhoneCnt <= 10) {
+								if (StringUtils.isNotEmpty(errPhoneLine.trim())) {
+									errPhoneLine = "[" + errPhoneLine.trim() + "]";
+								}
+							}
+							else {
+								errPhoneLine = "";
+							}
+													
+							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건" + errPhoneLine.trim() + " 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
+						}else {
+							jr.setMessage("");
+						}
+					    
+					}else {//xlsx 확장자 처리
+						
+						OPCPackage opcPackage = OPCPackage.open(files.get(0).getInputStream());
+						XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
+			            XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
+			            opcPackage.close();
+			            
+			            int totRowDataCnt = 0;
+			            for(int r=1; r<sheet.getPhysicalNumberOfRows(); r++) {
+			            	
+			            	XSSFRow tmpRow = sheet.getRow(r);
+			            	//System.out.println("=================r:"+r);
+			            	XSSFCell cell = null;
+			            	if(tmpRow.getCell(0) != null) {
+			            		
+			            		cell = tmpRow.getCell(0); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+				            	if(cell != null && !cell.toString().trim().equals("")) {
+				            		//System.out.println("value-" + r + ":" +cell.getStringCellValue()); 
+				            		totRowDataCnt++;
+				            		//System.out.println("tmpRowCnt:"+totRowDataCnt);
+				            	}
+			            		
+			            	}
+			            	
+			            }
+			            
+			            if(totRowDataCnt > 501) { //
+			            	errMessage = "한번에 전송 가능한 최대 발송건은 500건 입니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }
+			            
+			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+			            
+			            for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	XSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                XSSFCell cell = null;
+			                boolean errSts = true;
+			                
+			                for(int j = 0 ; j < 1; j++){ //행읽기(첫번째 컬럼만 필요)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
+			                    	//System.out.println("Cell 데이터가 없습니다.");
+			                		if(j == 1) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+				                		
+			                		}
+			                    }
+			                	if(null != cell){
+			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+			                			case  Cell.CELL_TYPE_NUMERIC:
+			                			cell.setCellType(Cell.CELL_TYPE_STRING);
+			                		}
+			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+			                    }
+			                	
+			                	if(j == 0) {
+			                		
+			                		if(cellValue.matches(phoneRegExp) && errSts) {
+			                			jm.put("phone", cellValue);
+			                		}else {
+				    	            	errPhoneCnt++;
+				    	            	errPhoneLine += (i+1) + "행 ";
+				    	            	errSts = false;
+				    	            	break;
+			                		}
+			                		
+			                	}
+			                	
+			                }
+			                
+			                if(null != jm.get("phone") && errSts) {
+			                	json.add(jm);
+			                }
+			                
+			            }
+						
+			            int resultErrCnt = errPhoneCnt;
+			            
+			            jr.setData(json);
+						jr.setSuccess(true);
+						
+						if(resultErrCnt > 0) {
+							if (errPhoneCnt <= 10) {
+								if (StringUtils.isNotEmpty(errPhoneLine.trim())) {
+									errPhoneLine = "[" + errPhoneLine.trim() + "]";
+								}
+							}
+							else {
+								errPhoneLine = "";
+							}
+													
+							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건" + errPhoneLine.trim() + " 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
+						}else {
+							jr.setMessage("");
+						}
+			            
+					}
+					
+				}
+			}
+			
+		} catch (Exception e) {
+			// TODO: handle exception
+			System.out.println("+++++++++++++++++ sendAlimtalkExelFilePhoneNumAjax Controller Error !!! "+e);
+			jr.setSuccess(false);
+			jr.setMessage("엑셀 데이터에 오류가 있습니다. 엑셀 데이터를 확인해 주세요.");
+			return jr;
+		}
+		
+		return jr;
+	}
+	
+	
+	/*
+	 * 20240829 신규 추가 우영두
+	 * 기존 Script에서 처리하던 방식 변경
+	 * 카카오 알림톡 엑셀 불러오기 엑셀 처리
+	 * 
+	 * */
+	@RequestMapping(value = "/web/mjon/alimtalk/sendAlimtalkExelVarFilePhoneNumAjax.do")
+	@ResponseBody
+	public Object sendAlimtalkExelVarFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
+	
+		JsonResult jr = new JsonResult();
+		jr.setSuccess(false);
+		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
+		
+		
+		try {
+			
+			//final Map<String, MultipartFile> files = multiRequest.getFileMap();
+			List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
+			
+			// 파일명에 .이 있을경우 오류 => Ex) 테스트6.20.xlsx 
+			int fileNameSplitCnt = 0;
+			int excelVarCnt = Integer.parseInt(multiRequest.getParameter("excelVarCnt"));// 알림톡 템플릿 변수 갯수 데이터  
+			String [] excelVarArr = multiRequest.getParameter("excelVarList").split(",");
+			
+			
+			if(!files.isEmpty()) {
+				fileNameSplitCnt = files.get(0).getOriginalFilename().split("[.]").length;
+				
+				if (files.get(0).getSize() > 0 
+						&& (files.get(0).getContentType().indexOf("spreadsheetml") > -1) 
+						|| files.get(0).getContentType().indexOf("ms-excel") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xlsx") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xls") > -1) {
+					
+					// 엑셀 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
+					long fileSize = multiRequest.getFile("file0").getSize();
+					
+					String Ext = files.get(0).getOriginalFilename().split("[.]")[1];
+					String errMessage = "";
+			        String cellValue  = "";
+			        String errPhoneLine = "";
+			        int errPhoneCnt = 0;
+			        
+			        //수신번호 유효성 체크
+					String phoneRegExp = "^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
+					
+					if(Ext.equals("xls")) {
+						HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
+					    HSSFSheet sheet = workbook.getSheetAt(0);
+					    
+					    if(sheet.getLastRowNum() > 501) { 
+			            	errMessage = "한번에 전송 가능한 최대 발송건은 500건 입니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }
+						
+					    List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+					    for(int i=1; i< sheet.getLastRowNum() + 1; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	HSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                HSSFCell cell = null;
+			                boolean errSts = true;
+			                String rtnValueStr = "";
+			                for(int j = 0 ; j < excelVarCnt + 1; j++){ //행읽기(변수갯수 +1 개 만큼 컬럼을 읽음 수신번호 + 변수들)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //수신번호 , 변수들
+			                	if(null == cell || "".equals(cell.toString().trim())) { //수신번호 셀에 값이 없으면 
+			                		if(j == 0) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+			                		}
+			                    	
+			                    }
+			                	
+			                	if(j == 0) {
+			                		
+			                		if(null != cell){
+				                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+				                			case  Cell.CELL_TYPE_NUMERIC:
+				                			cell.setCellType(Cell.CELL_TYPE_STRING);
+				                		}
+				                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+				                		
+				                		if(cellValue.matches(phoneRegExp) && errSts) {
+				                			jm.put("phone", cellValue);
+				                		}else {
+					    	            	errPhoneCnt++;
+					    	            	errPhoneLine += (i+1) + "행 ";
+					    	            	errSts = false;
+					    	            	break;
+				                		}
+				                    }
+			                	}else {
+			                		
+			                		if(cell != null) {
+			                			
+			                			if(j <= excelVarCnt) {//등록 변수 갯수 까지만 입력
+				                			
+			                				switch(cell.getCellType()){ //숫자타임을 문자로 변환
+					                			case  Cell.CELL_TYPE_NUMERIC:
+					                			cell.setCellType(Cell.CELL_TYPE_STRING);
+					                		}
+				                			cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+					                		
+					                		if(cellValue != null && !cellValue.equals("")) {
+					                			rtnValueStr += cellValue + "§";
+					                		}else {//변ㅅ
+					                			rtnValueStr += "" + "§";
+					                		}
+				                			
+				                		}
+			                			
+			                		}else {
+			                			rtnValueStr += "" + "§";
+			                			
+			                		}
+			                		
+			                	}
+			                	
+			                }
+			                
+		                	jm.put("varVal", rtnValueStr.replaceFirst(".$", ""));//변수 데이터 추가
+			                if(null != jm.get("phone") && errSts) {
+			                	json.add(jm);
+			                }
+					    }
+					    
+					    int resultErrCnt = errPhoneCnt;
+			            
+			            jr.setData(json);
+						jr.setSuccess(true);
+						
+						if(resultErrCnt > 0) {
+							if (errPhoneCnt <= 10) {
+								if (StringUtils.isNotEmpty(errPhoneLine.trim())) {
+									errPhoneLine = "[" + errPhoneLine.trim() + "]";
+								}
+							}
+							else {
+								errPhoneLine = "";
+							}
+													
+							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건" + errPhoneLine.trim() + " 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
+						}else {
+							jr.setMessage("");
+						}
+					
+					}else {//xlsx 엑셀 자료 처리
+						
+						OPCPackage opcPackage = OPCPackage.open(files.get(0).getInputStream());
+						XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
+			            XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
+			            opcPackage.close();
+			            
+			            int totRowDataCnt = 0;
+			            for(int r=1; r<sheet.getPhysicalNumberOfRows(); r++) {
+			            	
+			            	XSSFRow tmpRow = sheet.getRow(r);
+			            	//System.out.println("=================r:"+r);
+			            	XSSFCell cell = null;
+			            	if(tmpRow.getCell(0) != null) {
+			            		
+			            		cell = tmpRow.getCell(0); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+				            	if(cell != null && !cell.toString().trim().equals("")) {
+				            		//System.out.println("value-" + r + ":" +cell.getStringCellValue()); 
+				            		totRowDataCnt++;
+				            		//System.out.println("tmpRowCnt:"+totRowDataCnt);
+				            	}
+			            		
+			            	}
+			            	
+			            }
+			            
+			            if(totRowDataCnt > 501) { //
+			            	errMessage = "한번에 전송 가능한 최대 발송건은 500건 입니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }
+			            
+			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+			            
+			            for(int i=1; i< sheet.getLastRowNum() + 1; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	XSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                XSSFCell cell = null;
+			                boolean errSts = true;
+			                String rtnValueStr = "";
+			                for(int j = 0 ; j < excelVarCnt + 1; j++){ //행읽기(변수갯수 +1 개 만큼 컬럼을 읽음 수신번호 + 변수들)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //수신번호 , 변수들
+			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
+			                    	//System.out.println("Cell 데이터가 없습니다.");
+			                		if(j == 1) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+				                		
+			                		}
+			                    }
+			                	if(null != cell){
+			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+			                			case  Cell.CELL_TYPE_NUMERIC:
+			                			cell.setCellType(Cell.CELL_TYPE_STRING);
+			                		}
+			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+			                    }
+			                	
+			                	if(j == 0) {//수신번호 추가
+			                		
+			                		if(cellValue.matches(phoneRegExp) && errSts) {
+			                			jm.put("phone", cellValue);
+			                		}else {
+				    	            	errPhoneCnt++;
+				    	            	errPhoneLine += (i+1) + "행 ";
+				    	            	errSts = false;
+				    	            	break;
+			                		}
+			                		
+			                	}else {//변수 데이터 추가
+			                		
+			                		if(cell != null) {
+			                			
+			                			if(j <= excelVarCnt) {//등록 변수 갯수 까지만 입력
+				                			
+			                				switch(cell.getCellType()){ //숫자타임을 문자로 변환
+					                			case  Cell.CELL_TYPE_NUMERIC:
+					                			cell.setCellType(Cell.CELL_TYPE_STRING);
+					                		}
+				                			cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+					                		
+					                		if(cellValue != null && !cellValue.equals("")) {
+					                			rtnValueStr += cellValue + "§";
+					                		}else {
+					                			rtnValueStr += "" + "§";
+					                		}
+				                			
+				                		}
+			                			
+			                		}else {
+			                			rtnValueStr += "" + "§";
+			                			
+			                		}
+			                		
+			                	}
+			                	
+			                }
+			                
+			                jm.put("varVal", rtnValueStr.replaceFirst(".$", ""));//변수 데이터 추가
+			                if(null != jm.get("phone") && errSts) {
+			                	json.add(jm);
+			                }
+			                
+			            }
+			            
+			            int resultErrCnt = errPhoneCnt;
+			            
+			            jr.setData(json);
+						jr.setSuccess(true);
+						
+						if(resultErrCnt > 0) {
+							if (errPhoneCnt <= 10) {
+								if (StringUtils.isNotEmpty(errPhoneLine.trim())) {
+									errPhoneLine = "[" + errPhoneLine.trim() + "]";
+								}
+							}
+							else {
+								errPhoneLine = "";
+							}
+													
+							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건" + errPhoneLine.trim() + " 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
+						}else {
+							jr.setMessage("");
+						}
+			            
+					}
+					
+				}
+			}
+			
+		} catch (Exception e) {
+			// TODO: handle exception
+			System.out.println("+++++++++++++++++ sendAlimtalkExelVarFilePhoneNumAjax Controller Error !!! "+e);
+			jr.setSuccess(false);
+			jr.setMessage("엑셀 데이터에 오류가 있습니다. 엑셀 데이터를 확인해 주세요.");
+			return jr;
+			
+		}
+	
+ 		return jr;
+	}
 
 
 	// 카카오 템플릿 목록 조회
src/main/java/itn/let/kakao/user/sent/service/KakaoSentVO.java
--- src/main/java/itn/let/kakao/user/sent/service/KakaoSentVO.java
+++ src/main/java/itn/let/kakao/user/sent/service/KakaoSentVO.java
@@ -99,6 +99,10 @@
 	private String callToComma;
 	private String callFromComma;
 	
+	private String atDelayYn;				//알림톡 30분 지연 유무
+	private String atDelayCompleteYn;		//알림톡 30분 지연 승인/취소 처리 여부
+	private Date atDelayOrgTime;			//알림톡 30분 지연에 대한 원래 시간 (-30분 처리된 시간)
+	
 	public String getCallToComma() {
 		return callToComma;
 	}
@@ -545,6 +549,24 @@
 	public void setFailCount(int failCount) {
 		this.failCount = failCount;
 	}
+	public String getAtDelayYn() {
+		return atDelayYn;
+	}
+	public void setAtDelayYn(String atDelayYn) {
+		this.atDelayYn = atDelayYn;
+	}
+	public String getAtDelayCompleteYn() {
+		return atDelayCompleteYn;
+	}
+	public void setAtDelayCompleteYn(String atDelayCompleteYn) {
+		this.atDelayCompleteYn = atDelayCompleteYn;
+	}
+	public Date getAtDelayOrgTime() {
+		return atDelayOrgTime;
+	}
+	public void setAtDelayOrgTime(Date atDelayOrgTime) {
+		this.atDelayOrgTime = atDelayOrgTime;
+	}
 
 
 	
src/main/java/itn/let/mjo/msgsent/service/MjonMsgSentVO.java
--- src/main/java/itn/let/mjo/msgsent/service/MjonMsgSentVO.java
+++ src/main/java/itn/let/mjo/msgsent/service/MjonMsgSentVO.java
@@ -73,6 +73,7 @@
 	private String msgKind;	//문자종류(일반:N, 광고:A , 선거:C, 관리자:S, 이벤트:E)
 	private String delayYn; //지연 문자 유무
 	private String delayCompleteYn; //지연문자 처리 완료 여부
+	private Date delayOrgTime; 	//30분 딜레이된 발송시간에서 -30분 처리하여 원래 보내려던 발송시간 처리
 
 	private String msgId;		//문자아이디
 	private String atchFiles; 		// 그림문자 파일정보
@@ -83,6 +84,9 @@
 	private String callToComma;
 	private String msgSentType;
 	private String successCount;
+	
+	private String resultSValue;
+	private String resultWFValue;
 	
 	public String getSuccessCount() {
 		return successCount;
@@ -458,5 +462,23 @@
 	public void setSendKind(String sendKind) {
 		this.sendKind = sendKind;
 	}
+	public String getResultSValue() {
+		return resultSValue;
+	}
+	public void setResultSValue(String resultSValue) {
+		this.resultSValue = resultSValue;
+	}
+	public String getResultWFValue() {
+		return resultWFValue;
+	}
+	public void setResultWFValue(String resultWFValue) {
+		this.resultWFValue = resultWFValue;
+	}
+	public Date getDelayOrgTime() {
+		return delayOrgTime;
+	}
+	public void setDelayOrgTime(Date delayOrgTime) {
+		this.delayOrgTime = delayOrgTime;
+	}
 	
 }
src/main/java/itn/let/mjo/msgsent/web/MjonMsgSentController.java
--- src/main/java/itn/let/mjo/msgsent/web/MjonMsgSentController.java
+++ src/main/java/itn/let/mjo/msgsent/web/MjonMsgSentController.java
@@ -1280,7 +1280,7 @@
 					cell.setCellStyle(style);
 					
 					cell = row.createCell(10);
-					cell.setCellValue("실패");
+					cell.setCellValue("실패/대기");
 					cell.setCellStyle(style);
 					
 					cell = row.createCell(11);
@@ -1380,11 +1380,26 @@
 						
 						
 						double eachPrice = Float.parseFloat(resultAllSentList.get(i).getEachPrice());
+						int resultSValue = 0;
+						int resultWFValue = 0;
+						
+						if(resultAllSentList.get(i).getResultSValue() != null) {
+							resultSValue = Integer.parseInt(resultAllSentList.get(i).getResultSValue());
+						}else {
+							resultSValue = 1;
+						}
+						
+						if(resultAllSentList.get(i).getResultWFValue() != null) {
+							resultWFValue = Integer.parseInt(resultAllSentList.get(i).getResultWFValue());
+						}else {
+							resultWFValue = 1;
+						}
+						
 						
 						if("S".equals(resultAllSentList.get(i).getMsgResult())) {
-							resSucCnt = 1;
+							resSucCnt = resultSValue;
 						} else {
-							resFailCnt = 1;
+							resFailCnt = resultWFValue;
 						}
 							
 						resSucPrice = eachPrice * resSucCnt;
src/main/java/itn/let/mjo/pay/service/MjonPayVO.java
--- src/main/java/itn/let/mjo/pay/service/MjonPayVO.java
+++ src/main/java/itn/let/mjo/pay/service/MjonPayVO.java
@@ -207,6 +207,7 @@
 	private String amtCellSum; //휴대폰 결제 금액
 	private String amtBankSum; //즉시이체 결제 금액
 	private String amtVbankSum; //전용계좌 결제 금액
+	private String amtAfterPaySum; //전용계좌 결제 금액
 	private String amtRefundSum; //환불 금액
 	private String amtTotSum; //결제 금액 총액
 	
@@ -215,6 +216,7 @@
 	private String amtCellSumTot; //전체 휴대폰 결제 금액
 	private String amtBankSumTot; //전체 즉시이체 결제 금액
 	private String amtVbankSumTot; //전체 전용계좌 결제 금액
+	private String amtAfterPaySumTot; //전체 전용계좌 결제 금액
 	private String amtRefundSumTot;	//환불 금액
 	private String amtTotSumTot; //전체 결제 금액 총액
 	
@@ -223,6 +225,7 @@
 	private String amtCellCnt; //휴대폰 결제 수
 	private String amtBankCnt; //즉시이체 결제 수
 	private String amtVbankCnt; //전용계좌 결제 수
+	private String amtAfterPayCnt; //전용계좌 결제 수
 	private String amtRefundCnt; //환불 수
 	private String amtTotCnt; //결제 수 총수
 	
@@ -1708,6 +1711,30 @@
 	public void setTrdNo(String trdNo) {
 		this.trdNo = trdNo;
 	}
+
+	public String getAmtAfterPaySum() {
+		return amtAfterPaySum;
+	}
+
+	public void setAmtAfterPaySum(String amtAfterPaySum) {
+		this.amtAfterPaySum = amtAfterPaySum;
+	}
+
+	public String getAmtAfterPaySumTot() {
+		return amtAfterPaySumTot;
+	}
+
+	public void setAmtAfterPaySumTot(String amtAfterPaySumTot) {
+		this.amtAfterPaySumTot = amtAfterPaySumTot;
+	}
+
+	public String getAmtAfterPayCnt() {
+		return amtAfterPayCnt;
+	}
+
+	public void setAmtAfterPayCnt(String amtAfterPayCnt) {
+		this.amtAfterPayCnt = amtAfterPayCnt;
+	}
 	
 	
 }
src/main/java/itn/let/mjo/pay/web/MjonPayController.java
--- src/main/java/itn/let/mjo/pay/web/MjonPayController.java
+++ src/main/java/itn/let/mjo/pay/web/MjonPayController.java
@@ -5352,7 +5352,7 @@
 		
 		if("".equals(mjonPayVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
 			mjonPayVO.setSearchSortCnd("regDate");
-			mjonPayVO.setSearchSortOrd("desc");
+			mjonPayVO.setSearchSortOrd("asc");
 		}
 		
         List<MjonPayVO> resultList = mjonPayService.selectPayDayChart(mjonPayVO);   
@@ -5363,7 +5363,7 @@
 		mjonPayVO.setRecordCountPerPage(10000);
 		if("".equals(mjonPayVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
 			mjonPayVO.setSearchSortCnd("regDate");
-			mjonPayVO.setSearchSortOrd("desc");
+			mjonPayVO.setSearchSortOrd("asc");
 		}
 		
         List<MjonPayVO> resultList2 = mjonPayService.selectPayDayChart(mjonPayVO);           
@@ -5373,6 +5373,7 @@
     	long amtCellSumTot = 0; //전체 휴대폰 결제 금액
     	long amtBankSumTot = 0; //전체 즉시이체 결제 금액
     	long amtVbankSumTot = 0; //전체 전용계좌 결제 금액
+    	long amtAfterPaySumTot = 0; //전체 전용계좌 결제 금액
     	long amtRefundSumTot = 0; //전체 환불 금액
     	long amtTotSumTot = 0; //전체 결제 금액 총액
     	
@@ -5382,6 +5383,7 @@
         	amtCellSumTot += Long.parseLong(item.getAmtCellSum());
         	amtBankSumTot += Long.parseLong(item.getAmtBankSum());
         	amtVbankSumTot += Long.parseLong(item.getAmtVbankSum());
+        	amtAfterPaySumTot += Long.parseLong(item.getAmtAfterPaySum());
         	amtRefundSumTot += Long.parseLong(item.getAmtRefundSum());
         	amtTotSumTot += Long.parseLong(item.getAmtTotSum());
  	    }    	
@@ -5391,6 +5393,7 @@
     	mjonPayVO.setAmtCellSumTot(amtCellSumTot + "");
     	mjonPayVO.setAmtBankSumTot(amtBankSumTot + "");
     	mjonPayVO.setAmtVbankSumTot(amtVbankSumTot + "");
+    	mjonPayVO.setAmtAfterPaySumTot(amtAfterPaySumTot + "");
     	mjonPayVO.setAmtRefundSumTot(amtRefundSumTot + "");
     	mjonPayVO.setAmtTotSumTot(amtTotSumTot + "");
     	
@@ -5402,8 +5405,217 @@
 		
 		return "/uss/ion/pay/PayDayChart";
 	}
+    
+    /*
+     * 일별 매출 통계 엑셀 다운로드
+     * 
+     * */
+  	@RequestMapping(value= {"/uss/ion/pay/payDayChartExcelDownload.do"})
+  	public void payDayChartExcelDownload( MjonPayVO mjonPayVO, 
+  			HttpServletRequest request, 
+  			HttpServletResponse response , 
+  			ModelMap model) throws Exception {
+  		
+  		mjonPayVO.setRecordCountPerPage(mjonPayVO.getPageUnit());
+  		mjonPayVO.setFirstIndex(0);
+  		LoginVO loginVO = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();
+		if(null != loginVO && !"super".equals(loginVO.getSiteId())){
+			mjonPayVO.setSiteId(loginVO.getSiteId());
+		}
+  		// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
+  		SXSSFWorkbook wb = new SXSSFWorkbook(100);
+  		CellStyle style = wb.createCellStyle();
+  		style.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게 
+   		style.setBorderLeft(CellStyle.BORDER_THIN);
+   		style.setBorderRight(CellStyle.BORDER_THIN);
+   		style.setBorderTop(CellStyle.BORDER_THIN);
+   		Font font = wb.createFont();
+   		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
+   		
+  		Cell cell = null;
+  		Row row = null;
+  		
+  		String fileName ="일별 매출 통계";
+  		
+  		String sheetTitle = ""; 
+  		try{
+  			List<MjonPayVO> resultList = mjonPayService.selectPayDayChart(mjonPayVO);
+  			{ //화면 리스트
+  				sheetTitle = "일별 매출 통계" ; //제목
+  				Sheet sheet = wb.createSheet(sheetTitle);
+  				row = sheet.createRow(0);
+  		        
+  				cell = row.createCell(0);
+				cell.setCellValue("결제일");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(1);
+				cell.setCellValue("신용카드");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(2);
+				cell.setCellValue("휴대폰");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(3);
+				cell.setCellValue("즉시이체");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(4);
+				cell.setCellValue("전용계좌");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(5);
+				cell.setCellValue("간편결제");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(6);
+				cell.setCellValue("후불결제");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(7);
+				cell.setCellValue("환불");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(8);
+				cell.setCellValue("합계(VAT포함)");
+				cell.setCellStyle(style);
+				
+				long amtCardSumTot = 0; //전체 신용카드 결제 금액
+		      	long amtCellSumTot = 0; //전체 휴대폰 결제 금액
+		      	long amtBankSumTot = 0; //전체 즉시이체 결제 금액
+		      	long amtVbankSumTot = 0; //전체 전용계좌 결제 금액
+		      	long amtSpaySumTot = 0; //전체 간편결제 결제 금액
+		      	long amtAfterPaySumTot = 0; //전체 후불결제 금액
+		      	long amtRefundSumTot = 0; //전체 환불 금액
+		      	long amtTotSumTot = 0; //전체 결제 금액 총액
+  			    
+  		        for(int i=0; i <  resultList.size(); i++){
+  			    	row = sheet.createRow(i+1);
+  			    	for(int j=0 ; j < 9 ; j++) {
+  			        	cell = row.createCell(j);
+  			        	cell.setCellStyle(style);
+  			        	
+  			        	String regDate = (resultList.get(i)).getRegDate();
+  			        	String amtCardSum = (resultList.get(i)).getAmtCardSum();
+  			        	String amtCellSum = (resultList.get(i)).getAmtCellSum();
+  			        	String amtBankSum = (resultList.get(i)).getAmtBankSum();
+  			        	String amtVbankSum = (resultList.get(i)).getAmtVbankSum();
+  			        	String amtSpaySum = (resultList.get(i)).getAmtSpaySum();
+  			        	String amtAfterPaySum = (resultList.get(i)).getAmtAfterPaySum();
+  			        	String amtRefundSum = (resultList.get(i)).getAmtRefundSum();
+  			        	String amtTotSum = (resultList.get(i)).getAmtTotSum();
+  			        	
+  			        	if(j==0) cell.setCellValue(regDate); //결제월
+  			        	if(j==1) {
+  			        		cell.setCellValue(amtCardSum); //신용카드
+  			        		amtCardSumTot += Long.parseLong(amtCardSum);
+  			        	}
+  			        	if(j==2) {
+  			        		cell.setCellValue(amtCellSum); //휴대폰
+  			        		amtCellSumTot += Long.parseLong(amtCellSum);
+  			        	}
+  			        	if(j==3) {
+  			        		cell.setCellValue(amtBankSum); //즉시이체
+  			        		amtBankSumTot += Long.parseLong(amtBankSum);
+  			        	}
+  			        	if(j==4) {
+  			        		cell.setCellValue(amtVbankSum); //전용계좌
+  			        		amtVbankSumTot += Long.parseLong(amtVbankSum);
+  			        	}
+  			        	if(j==5) {
+  			        		cell.setCellValue(amtSpaySum); //간편결제
+  			        		amtSpaySumTot += Long.parseLong(amtSpaySum);
+  			        	}
+  			        	if(j==6) {
+  			        		cell.setCellValue(amtAfterPaySum); //후불결제
+  			        		amtAfterPaySumTot += Long.parseLong(amtAfterPaySum);
+  			        	}
+  			        	if(j==7) {
+  			        		cell.setCellValue(amtRefundSum); //환불
+  			        		amtRefundSumTot += Long.parseLong(amtRefundSum);
+  			        	}
+  			        	if(j==8) {
+  			        		cell.setCellValue(amtTotSum); //합계(VAT포함)
+  			        		amtTotSumTot += Long.parseLong(amtTotSum);
+  			        	}
+  			        	
+  				 	}
+  		        }
+	  		    
+  		        //전체 합계 행 추가
+  		        row = sheet.createRow(resultList.size()+1);
+	  		    cell = row.createCell(0);
+	  		    cell.setCellStyle(style);
+		  		cell.setCellValue("합계"); //결제월
+		  		
+		  		cell = row.createCell(1);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtCardSumTot); //신용카드
+		        
+		        cell = row.createCell(2);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtCellSumTot); //휴대폰
+		        
+		        cell = row.createCell(3);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtBankSumTot); //즉시이체
+		        
+		        cell = row.createCell(4);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtVbankSumTot); //전용계좌
+		        
+		        cell = row.createCell(5);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtSpaySumTot); //간편결제
+		        
+		        cell = row.createCell(6);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtAfterPaySumTot); //후불결제
+		        
+		        cell = row.createCell(7);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtRefundSumTot); //환불
+		        
+		        cell = row.createCell(8);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtTotSumTot); //합계(VAT포함)
+  		        
+  			}
+  	    response.setHeader("Set-Cookie", "fileDownload=true; path=/");
+  		SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyy_MM_dd_HH_mm_ss", Locale.KOREA );
+  		Date currentTime = new Date ();
+  		String mTime = mSimpleDateFormat.format ( currentTime );
+  		fileName = fileName+"("+mTime+")";
+  		
+  		response.setHeader("Content-Disposition", String.format("attachment; filename=\""+new String((fileName).getBytes("KSC5601"),"8859_1")+".xlsx"));
+  		wb.write(response.getOutputStream());
+  	    
+  		}catch(Exception e) {
+  			response.setHeader("Set-Cookie", "fileDownload=false; path=/");
+  			response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+  			response.setHeader("Content-Type","text/html; charset=utf-8");
+  			OutputStream out = null;
+  			try {
+  				out = response.getOutputStream();
+  				byte[] data = new String("fail..").getBytes();
+  				out.write(data, 0, data.length);
+  			} catch(Exception ignore) {
+  				ignore.printStackTrace();
+  			} finally {
+  				if(out != null) try { out.close(); } catch(Exception ignore) {}
+  				if(wb != null) try { wb.dispose(); wb.close(); } catch(Exception ignore) {}
+  			}
+  		}finally {
+  			// 디스크 적었던 임시파일을 제거합니다.
+  			wb.dispose();
+  			try { wb.close(); } catch(Exception ignore) {}
+  		}
+  	}
+    
+    
     /**
-     * 월별 결제 통계
+     * 월별 매출 통계
      * @param searchVO
      * @param model
      * @return	"/uss/ion/pay/payDayChart"
@@ -5434,7 +5646,7 @@
     	}
     	if("".equals(mjonPayVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
     		mjonPayVO.setSearchSortCnd("regDate");
-    		mjonPayVO.setSearchSortOrd("desc");
+    		mjonPayVO.setSearchSortOrd("asc");
     	}
     	
 		mjonPayVO.setFirstIndex(0);
@@ -5447,6 +5659,7 @@
     	long amtCellSumTot = 0; //전체 휴대폰 결제 금액
     	long amtBankSumTot = 0; //전체 즉시이체 결제 금액
     	long amtVbankSumTot = 0; //전체 전용계좌 결제 금액
+    	long amtAfterPaySumTot = 0; //전체 후불결제 금액
     	long amtRefundSumTot = 0; //전체 환불 금액
     	long amtTotSumTot = 0; //전체 결제 금액 총액
     	
@@ -5456,6 +5669,7 @@
         	amtCellSumTot += Long.parseLong(item.getAmtCellSum());
         	amtBankSumTot += Long.parseLong(item.getAmtBankSum());
         	amtVbankSumTot += Long.parseLong(item.getAmtVbankSum());
+        	amtAfterPaySumTot += Long.parseLong(item.getAmtAfterPaySum());
         	amtRefundSumTot += Long.parseLong(item.getAmtRefundSum());
         	amtTotSumTot += Long.parseLong(item.getAmtTotSum());
  	    }    	
@@ -5465,6 +5679,7 @@
     	mjonPayVO.setAmtCellSumTot(amtCellSumTot + "");
     	mjonPayVO.setAmtBankSumTot(amtBankSumTot + "");
     	mjonPayVO.setAmtVbankSumTot(amtVbankSumTot + "");
+    	mjonPayVO.setAmtAfterPaySumTot(amtAfterPaySumTot + "");
     	mjonPayVO.setAmtRefundSumTot(amtRefundSumTot + "");
     	mjonPayVO.setAmtTotSumTot(amtTotSumTot + "");
     	
@@ -5478,6 +5693,214 @@
     	return "/uss/ion/pay/PayMonthChart";
     }
     
+    
+    /*
+     * 월별 매출 통계 엑셀 다운로드
+     * 
+     * */
+  	@RequestMapping(value= {"/uss/ion/pay/payMonthChartExcelDownload.do"})
+  	public void payMonthChartExcelDownload( MjonPayVO mjonPayVO, 
+  			HttpServletRequest request, 
+  			HttpServletResponse response , 
+  			ModelMap model) throws Exception {
+  		
+  		mjonPayVO.setRecordCountPerPage(mjonPayVO.getPageUnit());
+  		mjonPayVO.setFirstIndex(0);
+  		LoginVO loginVO = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();
+		if(null != loginVO && !"super".equals(loginVO.getSiteId())){
+			mjonPayVO.setSiteId(loginVO.getSiteId());
+		}
+  		// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
+  		SXSSFWorkbook wb = new SXSSFWorkbook(100);
+  		CellStyle style = wb.createCellStyle();
+  		style.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게 
+   		style.setBorderLeft(CellStyle.BORDER_THIN);
+   		style.setBorderRight(CellStyle.BORDER_THIN);
+   		style.setBorderTop(CellStyle.BORDER_THIN);
+   		Font font = wb.createFont();
+   		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
+   		
+  		Cell cell = null;
+  		Row row = null;
+  		
+  		String fileName ="월별 매출 통계";
+  		
+  		String sheetTitle = ""; 
+  		try{
+  			List<MjonPayVO> resultList = mjonPayService.selectPayMonthChart(mjonPayVO);   
+  			{ //화면 리스트
+  				sheetTitle = "월별 매출 통계" ; //제목
+  				Sheet sheet = wb.createSheet(sheetTitle);
+  				row = sheet.createRow(0);
+  		        
+  				cell = row.createCell(0);
+				cell.setCellValue("결제월");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(1);
+				cell.setCellValue("신용카드");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(2);
+				cell.setCellValue("휴대폰");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(3);
+				cell.setCellValue("즉시이체");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(4);
+				cell.setCellValue("전용계좌");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(5);
+				cell.setCellValue("간편결제");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(6);
+				cell.setCellValue("후불결제");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(7);
+				cell.setCellValue("환불");
+				cell.setCellStyle(style);
+				
+				cell = row.createCell(8);
+				cell.setCellValue("합계(VAT포함)");
+				cell.setCellStyle(style);
+				
+				long amtCardSumTot = 0; //전체 신용카드 결제 금액
+		      	long amtCellSumTot = 0; //전체 휴대폰 결제 금액
+		      	long amtBankSumTot = 0; //전체 즉시이체 결제 금액
+		      	long amtVbankSumTot = 0; //전체 전용계좌 결제 금액
+		      	long amtSpaySumTot = 0; //전체 간편결제 결제 금액
+		      	long amtAfterPaySumTot = 0; //전체 후불결제 금액
+		      	long amtRefundSumTot = 0; //전체 환불 금액
+		      	long amtTotSumTot = 0; //전체 결제 금액 총액
+  			    
+  		        for(int i=0; i <  resultList.size(); i++){
+  			    	row = sheet.createRow(i+1);
+  			    	for(int j=0 ; j < 9 ; j++) {
+  			        	cell = row.createCell(j);
+  			        	cell.setCellStyle(style);
+  			        	
+  			        	String regDate = (resultList.get(i)).getRegDate();
+  			        	String amtCardSum = (resultList.get(i)).getAmtCardSum();
+  			        	String amtCellSum = (resultList.get(i)).getAmtCellSum();
+  			        	String amtBankSum = (resultList.get(i)).getAmtBankSum();
+  			        	String amtVbankSum = (resultList.get(i)).getAmtVbankSum();
+  			        	String amtSpaySum = (resultList.get(i)).getAmtSpaySum();
+  			        	String amtAfterPaySum = (resultList.get(i)).getAmtAfterPaySum();
+  			        	String amtRefundSum = (resultList.get(i)).getAmtRefundSum();
+  			        	String amtTotSum = (resultList.get(i)).getAmtTotSum();
+  			        	
+  			        	if(j==0) cell.setCellValue(regDate); //결제월
+  			        	if(j==1) {
+  			        		cell.setCellValue(amtCardSum); //신용카드
+  			        		amtCardSumTot += Long.parseLong(amtCardSum);
+  			        	}
+  			        	if(j==2) {
+  			        		cell.setCellValue(amtCellSum); //휴대폰
+  			        		amtCellSumTot += Long.parseLong(amtCellSum);
+  			        	}
+  			        	if(j==3) {
+  			        		cell.setCellValue(amtBankSum); //즉시이체
+  			        		amtBankSumTot += Long.parseLong(amtBankSum);
+  			        	}
+  			        	if(j==4) {
+  			        		cell.setCellValue(amtVbankSum); //전용계좌
+  			        		amtVbankSumTot += Long.parseLong(amtVbankSum);
+  			        	}
+  			        	if(j==5) {
+  			        		cell.setCellValue(amtSpaySum); //간편결제
+  			        		amtSpaySumTot += Long.parseLong(amtSpaySum);
+  			        	}
+  			        	if(j==6) {
+  			        		cell.setCellValue(amtAfterPaySum); //후불결제
+  			        		amtAfterPaySumTot += Long.parseLong(amtAfterPaySum);
+  			        	}
+  			        	if(j==7) {
+  			        		cell.setCellValue(amtRefundSum); //환불
+  			        		amtRefundSumTot += Long.parseLong(amtRefundSum);
+  			        	}
+  			        	if(j==8) {
+  			        		cell.setCellValue(amtTotSum); //합계(VAT포함)
+  			        		amtTotSumTot += Long.parseLong(amtTotSum);
+  			        	}
+  			        	
+  				 	}
+  		        }
+	  		    
+  		        //총합계 행 추가
+  		        row = sheet.createRow(resultList.size()+1);
+	  		    cell = row.createCell(0);
+	  		    cell.setCellStyle(style);
+		  		cell.setCellValue("합계"); //결제월
+		  		
+		  		cell = row.createCell(1);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtCardSumTot); //신용카드
+		        
+		        cell = row.createCell(2);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtCellSumTot); //휴대폰
+		        
+		        cell = row.createCell(3);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtBankSumTot); //즉시이체
+		        
+		        cell = row.createCell(4);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtVbankSumTot); //전용계좌
+		        
+		        cell = row.createCell(5);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtSpaySumTot); //간편결제
+		        
+		        cell = row.createCell(6);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtAfterPaySumTot); //후불결제
+		        
+		        cell = row.createCell(7);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtRefundSumTot); //환불
+		        
+		        cell = row.createCell(8);
+	  		    cell.setCellStyle(style);
+		        cell.setCellValue(amtTotSumTot); //합계(VAT포함)
+  		        
+  			}
+  	    response.setHeader("Set-Cookie", "fileDownload=true; path=/");
+  		SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyy_MM_dd_HH_mm_ss", Locale.KOREA );
+  		Date currentTime = new Date ();
+  		String mTime = mSimpleDateFormat.format ( currentTime );
+  		fileName = fileName+"("+mTime+")";
+  		
+  		response.setHeader("Content-Disposition", String.format("attachment; filename=\""+new String((fileName).getBytes("KSC5601"),"8859_1")+".xlsx"));
+  		wb.write(response.getOutputStream());
+  	    
+  		}catch(Exception e) {
+  			response.setHeader("Set-Cookie", "fileDownload=false; path=/");
+  			response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+  			response.setHeader("Content-Type","text/html; charset=utf-8");
+  			OutputStream out = null;
+  			try {
+  				out = response.getOutputStream();
+  				byte[] data = new String("fail..").getBytes();
+  				out.write(data, 0, data.length);
+  			} catch(Exception ignore) {
+  				ignore.printStackTrace();
+  			} finally {
+  				if(out != null) try { out.close(); } catch(Exception ignore) {}
+  				if(wb != null) try { wb.dispose(); wb.close(); } catch(Exception ignore) {}
+  			}
+  		}finally {
+  			// 디스크 적었던 임시파일을 제거합니다.
+  			wb.dispose();
+  			try { wb.close(); } catch(Exception ignore) {}
+  		}
+  	}
+    
 /*    @RequestMapping(value= {"/web/main/vacTest.do"})
     public void vacTest() throws Exception {
     	
src/main/java/itn/let/mjo/reservmsg/service/MjonResvMsgVO.java
--- src/main/java/itn/let/mjo/reservmsg/service/MjonResvMsgVO.java
+++ src/main/java/itn/let/mjo/reservmsg/service/MjonResvMsgVO.java
@@ -61,6 +61,11 @@
 	private String callFromComma;
 	private String callToComma;
 	
+	private String delayYn;			//30분 딜레이 유무
+	private String delayCompleteYn;	//30분 딜레이 문자 처리 완료 유무
+	
+	private Date delayOrgTime; 	//30분 딜레이된 발송시간에서 -30분 처리하여 원래 보내려던 발송시간 처리
+	
 	public String getCallFromComma() {
 		return callFromComma;
 	}
@@ -319,6 +324,25 @@
 	public void setSendKind(String sendKind) {
 		this.sendKind = sendKind;
 	}
+	public String getDelayYn() {
+		return delayYn;
+	}
+	public void setDelayYn(String delayYn) {
+		this.delayYn = delayYn;
+	}
+	public String getDelayCompleteYn() {
+		return delayCompleteYn;
+	}
+	public void setDelayCompleteYn(String delayCompleteYn) {
+		this.delayCompleteYn = delayCompleteYn;
+	}
+	public Date getDelayOrgTime() {
+		return delayOrgTime;
+	}
+	public void setDelayOrgTime(Date delayOrgTime) {
+		this.delayOrgTime = delayOrgTime;
+	}
+
 	
 	
 	
src/main/java/itn/let/uat/uia/web/EgovMypageController.java
--- src/main/java/itn/let/uat/uia/web/EgovMypageController.java
+++ src/main/java/itn/let/uat/uia/web/EgovMypageController.java
@@ -1532,12 +1532,30 @@
 	public String sendNumberManageRegister(
 		@ModelAttribute MberManageVO mberManageVO
 		, HttpServletRequest request
+		, RedirectAttributes redirectAttributes
 		, ModelMap model) throws Exception {
 		/*LoginVO	loginVO = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();*/
 		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
 		if(loginVO == null) {
 			return "redirect:/web/user/login/login.do";
+		}else {
+			
+			/**
+    		 * 회원 정지된 상태이면 문자 발송이 안되도록 처리함
+    		 * 현재 로그인 세션도 만료 처리함
+    		 * */
+    		boolean mberSttus = userManageService.selectUserStatusInfo(userId);
+    		
+    		if(!mberSttus) {
+    			
+    			request.getSession().invalidate();
+    			redirectAttributes.addFlashAttribute("message", "현재 고객님께서는 문자온 서비스 이용이 정지된 상태로 발신번호 등록을 할 수 없습니다. 이용정지 해제를 원하시면 고객센터로 연락주시기 바랍니다.");
+    			
+    			RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/web/main/mainPage.do");
+    			return redirectUrlMaker.getRedirectUrl();
+    		}
+			
 		}
 		model.addAttribute("loginVO", loginVO);
 		model.addAttribute("pageTab", "sendNumberManage");
src/main/resources/egovframework/sqlmap/let/mjo/kakao/KakaoSent_SQL_Mysql.xml
--- src/main/resources/egovframework/sqlmap/let/mjo/kakao/KakaoSent_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/mjo/kakao/KakaoSent_SQL_Mysql.xml
@@ -211,6 +211,7 @@
 			M2.subject ,
 			M2.regDate ,
 			M2.reqDate ,
+			IF(atDelayYn = 'Y' and atDelayCompleteYn = 'N', DATE_ADD(M2.reqdate, INTERVAL -30 MINUTE), M2.reqdate) AS atDelayOrgTime ,
 			M2.rsltDate ,
 			M2.callFrom ,
 			M2.callTo ,
@@ -222,6 +223,8 @@
 			M2.curState ,
 			M2.rsltCode ,
 			M2.rsltCode2 ,
+			M2.atDelayYn ,
+			M2.atDelayCompleteYn ,
 			M2.orderByrsltCode ,
 			M2.delFlag ,
 			M2.msgType ,
@@ -306,6 +309,8 @@
 				CUR_STATE                             AS curState ,
 				RSLT_CODE                             AS rsltCode ,
 				RSLT_CODE2                            AS rsltCode2 ,
+				AT_DELAY_YN							  AS atDelayYn ,
+				AT_DELAY_COMPLETE_YN				  AS atDelayCompleteYn ,
 				IF((RSLT_CODE != '7000'),'1','0')     AS orderByrsltCode ,
 				DEL_FLAG                              AS delFlag ,
 				M.MSG_TYPE                            AS msgType ,
@@ -344,6 +349,8 @@
 					MD.CUR_STATE ,
 					MD.RSLT_CODE ,
 					MD.RSLT_CODE2 ,
+					MG.AT_DELAY_YN,
+					MG.AT_DELAY_COMPLETE_YN,
 					CASE
 						 WHEN MG.MSG_TYPE = '8'
 						 THEN '알림톡'
@@ -1080,6 +1087,7 @@
 			M2.subject ,
 			M2.regDate ,
 			M2.reqDate ,
+			IF(atDelayYn = 'Y' and atDelayCompleteYn = 'N', DATE_ADD(M2.reqdate, INTERVAL -30 MINUTE), M2.reqdate) AS atDelayOrgTime ,
 			M2.rsltDate ,
 			M2.diffMin,
 			M2.callFrom ,
@@ -1092,6 +1100,8 @@
 			M2.curState ,
 			M2.rsltCode ,
 			M2.rsltCode2 ,
+			M2.atDelayYn ,
+			M2.atDelayCompleteYn ,
 			M2.orderByrsltCode ,
 			M2.delFlag ,
 			M2.msgType ,
@@ -1177,6 +1187,8 @@
 				CUR_STATE                             AS curState ,
 				RSLT_CODE                             AS rsltCode ,
 				RSLT_CODE2                            AS rsltCode2 ,
+				AT_DELAY_YN 						  AS atDelayYn , 
+				AT_DELAY_COMPLETE_YN 				  AS atDelayCompleteYn ,
 				IF((RSLT_CODE != '7000'),'1','0')     AS orderByrsltCode ,
 				DEL_FLAG                              AS delFlag ,
 				M.MSG_TYPE                            AS msgType ,
@@ -1215,6 +1227,8 @@
 					MD.CUR_STATE ,
 					MD.RSLT_CODE ,
 					MD.RSLT_CODE2 ,
+					MG.AT_DELAY_YN , 
+					MG.AT_DELAY_COMPLETE_YN ,
 					CASE
 						 WHEN MG.MSG_TYPE = '8'
 						 THEN '알림톡'
src/main/resources/egovframework/sqlmap/let/msg/MjonMsgResv_SQL_mysql.xml
--- src/main/resources/egovframework/sqlmap/let/msg/MjonMsgResv_SQL_mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/msg/MjonMsgResv_SQL_mysql.xml
@@ -202,6 +202,7 @@
 		         M2.subject,
 		         M2.regdate,
 		         M2.reqdate,
+		         IF(delayYn = 'Y' and delayCompleteYn = 'N', DATE_ADD(M2.reqdate, INTERVAL -30 MINUTE), M2.reqdate) AS delayOrgTime,
 		         M2.diffMin,
 		         M2.callFrom,
 				 FN_GETHYPHEN(M2.callFrom)	AS callFromComma,		         
@@ -218,6 +219,8 @@
 		         M2.cancelDate,
 		         M2.sendKind,
 				 M2.shipmentStatus,
+				 M2.delayYn,
+				 M2.delayCompleteYn,
 				 M2.orderByCode										
 		FROM (		
 			SELECT   COUNT(USER_ID) OVER() AS totMsgCnt,
@@ -241,7 +244,9 @@
 			         AGENT_CODE AS agentCode,
 			         RESERVE_C_YN AS reserveCYn,
 			         CANCELDATE AS cancelDate,
-			         SEND_KIND as sendKind,
+			         SEND_KIND AS sendKind,
+			         DELAY_YN AS delayYn,
+			         DELAY_COMPLETE_YN AS delayCompleteYn,
 					CASE
 						WHEN RESERVE_C_YN = 'Y'
 						THEN '예약취소'
@@ -282,6 +287,8 @@
 			                 MD.CUR_STATE,
 			                 MD.RSLT_CODE,
 			                 MD.RSLT_CODE2,
+			                 MGD.DELAY_YN,
+			                 MGD.DELAY_COMPLETE_YN,
 							 MGD.SEND_KIND
 			         FROM    mj_msg_data MD
 			                 INNER JOIN MJ_MSG_GROUP_DATA MGD
src/main/resources/egovframework/sqlmap/let/msg/MjonMsgSent_SQL_mysql.xml
--- src/main/resources/egovframework/sqlmap/let/msg/MjonMsgSent_SQL_mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/msg/MjonMsgSent_SQL_mysql.xml
@@ -233,6 +233,7 @@
 			, M2.subject
 			, M2.regdate
 			, M2.reqdate
+			, IF(delayYn = 'Y' and delayCompleteYn = 'N', DATE_ADD(M2.reqdate, INTERVAL -30 MINUTE), M2.reqdate) AS delayOrgTime
 			, M2.callFrom
 			, M2.callTo
 			, FN_GETHYPHEN(M2.callFrom)	AS callFromComma
@@ -256,6 +257,10 @@
 			, M2.msgResult
 			, M2.sendKind
 			, M2.msgKind
+			, M2.resultSValue
+			, M2.resultWFValue
+			, M2.delayYn
+			, M2.delayCompleteYn
 		FROM
 			(		
 			SELECT
@@ -297,8 +302,12 @@
 				, msgTypeName					 AS msgTypeName
 				, orderByCode					 AS orderByCode
 				, RESULT						 AS msgResult
+				, SUM(IF(RESULT = 'S', 1, 0 ))	 AS resultSValue
+                , SUM(IF(RESULT = 'W' OR RESULT = 'F', 1, 0 ))	AS resultWFValue
 				, sendKind						 AS sendKind
 				, MSG_KIND						 AS msgKind
+				, DELAY_YN						 AS delayYn
+				, DELAY_COMPLETE_YN				 AS delayCompleteYn
 			FROM
 				( SELECT
 					B.USER_ID
@@ -324,6 +333,8 @@
 					, A.RSLT_CODE2
 					, B.SEND_KIND as sendKind
 					, B.MSG_KIND
+					, B.DELAY_YN
+					, B.DELAY_COMPLETE_YN
 					, CASE
 						WHEN B.MSG_TYPE = '6'
 							AND B.FILE_CNT > 0
@@ -618,6 +629,7 @@
 			, M2.subject
 			, M2.regdate
 			, M2.reqdate
+			, IF(delayYn = 'Y' and delayCompleteYn = 'N', DATE_ADD(M2.reqdate, INTERVAL -30 MINUTE), M2.reqdate) AS delayOrgTime
 			, M2.callFrom
 			, M2.callTo
 			, FN_GETHYPHEN(M2.callFrom)	AS callFromComma
@@ -637,6 +649,8 @@
 			, M2.msgId
 			, M2.msgResult
 			, M2.sendKind
+			, M2.delayYn
+			, M2.delayCompleteYn
 		FROM
 			(		
 			SELECT
@@ -657,6 +671,8 @@
 				, CUR_STATE								 AS curState
 				, RSLT_CODE								 AS rsltCode
 				, RSLT_CODE2							 AS rsltCode2
+				, DELAY_YN						 		 AS delayYn
+				, DELAY_COMPLETE_YN				 		 AS delayCompleteYn
 				, IF( (RSLT_CODE != '0'
 						AND RSLT_CODE != '100'
 						AND RSLT_CODE != '101'
@@ -703,6 +719,8 @@
 					, MD.CUR_STATE
 					, MD.RSLT_CODE
 					, MD.RSLT_CODE2
+					, MGD.DELAY_YN
+					, MGD.DELAY_COMPLETE_YN
 					, MGD.SEND_KIND AS sendKind
 					,(<include refid="MjonMsgSentDAO.selectAgentResultQuery_MD"/>) AS RESULT
 				FROM
src/main/resources/egovframework/sqlmap/let/pay/MjonPay_SQL_mysql.xml
--- src/main/resources/egovframework/sqlmap/let/pay/MjonPay_SQL_mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/pay/MjonPay_SQL_mysql.xml
@@ -1651,7 +1651,9 @@
 		       ROUND(IFNULL(S6.AMT, 0)) AS amtRefundSum,
 		       IFNULL(S6.CNT, 0) AS amtRefundCnt,
 		       ROUND(IFNULL(S7.AMT, 0)) AS amtSpaySum,
-		       IFNULL(S7.CNT, 0) AS amtSpayCnt
+		       IFNULL(S7.CNT, 0) AS amtSpayCnt,
+		       ROUND(IFNULL(S8.AMT, 0)) AS amtAfterPaySum,
+		       IFNULL(S8.CNT, 0) AS amtAfterPayCnt
 		FROM   (SELECT  DATE_FORMAT(t1.REG_DATE, '%Y-%m-%d') AS REG_DATE ,
 		                SUM(t1.AMT)                          AS AMT,
 		                COUNT(0)                           	AS CNT,
@@ -1768,6 +1770,23 @@
 		              )
 		              S7
 		       ON     S7.REG_DATE = S1.REG_DATE
+		       LEFT JOIN
+		              ( SELECT  DATE_FORMAT(t8.REG_DATE, '%Y-%m-%d') AS REG_DATE ,
+		                       SUM(t8.AMT)                           AS AMT,
+				               COUNT(0)                           	AS CNT
+		              FROM     MJ_PG t8
+		              WHERE    t8.PG_STATUS  = 1
+		              AND      t8.pay_method ='AFTERPAY'
+		              <isNotEmpty property="ntceBgnde">
+		     	       AND <![CDATA[ DATE_FORMAT(t8.REG_DATE, '%Y-%m-%d')  >=   #ntceBgnde# ]]>
+		              </isNotEmpty>
+		              <isNotEmpty property="ntceEndde">
+		               AND <![CDATA[ DATE_FORMAT(t8.REG_DATE, '%Y-%m-%d')  <=   #ntceEndde# ]]>
+		              </isNotEmpty>
+		              GROUP BY DATE_FORMAT(t8.REG_DATE, '%Y-%m-%d')
+		              )
+		              S8
+		       ON     S8.REG_DATE = S1.REG_DATE
 		ORDER BY 1=1
 		<isNotEmpty property="searchSortCnd">
 			,$searchSortCnd$
@@ -1790,7 +1809,8 @@
 		       ROUND(IFNULL(S4.AMT, 0)) AS amtBankSum,
 		       ROUND(IFNULL(S5.AMT, 0)) AS amtVbankSum,
 		       ROUND(IFNULL(S6.AMT, 0)) AS amtRefundSum,
-		       ROUND(IFNULL(S7.AMT, 0)) AS amtSpaySum
+		       ROUND(IFNULL(S7.AMT, 0)) AS amtSpaySum,
+		       ROUND(IFNULL(S8.AMT, 0)) AS amtAfterPaySum
 		FROM   (SELECT  DATE_FORMAT(t1.REG_DATE, '%Y-%m') AS REG_DATE ,
 		                SUM(t1.AMT)                          AS AMT,
 		                t1.moid								AS MOID
@@ -1879,6 +1899,19 @@
 		              )
 		              S7
 		       ON     S7.REG_DATE = S1.REG_DATE
+		       LEFT JOIN
+		              ( SELECT  DATE_FORMAT(t8.REG_DATE, '%Y-%m') AS REG_DATE ,
+		                       SUM(t8.AMT)                           AS AMT
+		              FROM     MJ_PG t8
+		              WHERE    t8.PG_STATUS  = 1
+		              AND      t8.pay_method ='AFTERPAY'
+		              <isNotEmpty property="ntceBgnde">
+		     	       AND <![CDATA[ DATE_FORMAT(t8.REG_DATE, '%Y')  =   #ntceBgnde# ]]>
+		              </isNotEmpty>
+		              GROUP BY DATE_FORMAT(t8.REG_DATE, '%Y-%m')
+		              )
+		              S8
+		       ON     S8.REG_DATE = S1.REG_DATE
 		ORDER BY 1=1
 		<isNotEmpty property="searchSortCnd">
 			,$searchSortCnd$
src/main/webapp/WEB-INF/jsp/cmm/uss/umt/EgovGnrlUserSelectUpdt.jsp
--- src/main/webapp/WEB-INF/jsp/cmm/uss/umt/EgovGnrlUserSelectUpdt.jsp
+++ src/main/webapp/WEB-INF/jsp/cmm/uss/umt/EgovGnrlUserSelectUpdt.jsp
@@ -1535,7 +1535,7 @@
 	var mberSttus = $('#mberSttus').val();
 	mberSttus = "B";	//이용자 정지 처리
 	var smiMemo = $('#smiContents').val();
-	smiMemo = "관리자가 최근 문자 지연 내역에서 스미싱의심으로 판단하여 발송취소를 한 후 이용자 정지 처리함";
+	smiMemo = "시스템 스팸 필터링에 의한 이용정지";
 	
 	fn_SpamMberUpdt(mberSttus, smiMemo, "이용자 정지를 진행하시겠습니까?");
 	/*
src/main/webapp/WEB-INF/jsp/uss/ion/kakaoat/KakaoATChannelIDList.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/kakaoat/KakaoATChannelIDList.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/kakaoat/KakaoATChannelIDList.jsp
@@ -205,7 +205,7 @@
 							<th>채널명<input type="button" class="sort sortBtn" id="sort_yellowId"></th>
 							<th>등록상태</th>
 							<th>채널생성일</th>
-							<th>채널등록일</th>
+							<th>채널등록일<input type="button" class="sort sortBtn" id="sort_lastUpdtPnttm"></th>
 							<th>삭제여부<input type="button" class="sort sortBtn" id="sort_deleteYn"></th>
 						</tr>
 					</thead>
src/main/webapp/WEB-INF/jsp/uss/ion/kakaoat/SendKakaoATList.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/kakaoat/SendKakaoATList.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/kakaoat/SendKakaoATList.jsp
@@ -476,7 +476,7 @@
 function fn_MsgDelayCancel_after(userId){
 	var mberSttus = $('#mberSttus').val();
 	mberSttus = "B";	//이용자 정지 처리
-	var smiMemo = "관리자가 최근 문자 지연 내역에서 스미싱의심으로 판단하여 발송취소를 한 후 이용자 정지 처리함";
+	var smiMemo = "시스템 스팸 필터링에 의한 이용정지";
 	
 	fn_SpamMberUpdt(userId, mberSttus, smiMemo, "이용자 정지를 진행하시겠습니까?");
 }
src/main/webapp/WEB-INF/jsp/uss/ion/msg/SendMsgList.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/msg/SendMsgList.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/msg/SendMsgList.jsp
@@ -499,11 +499,11 @@
 function fn_MsgDelayCancel_after(userId){
 	var mberSttus = $('#mberSttus').val();
 	mberSttus = "B";	//이용자 정지 처리
-	var smiMemo = "관리자가 최근 문자 지연 내역에서 스미싱의심으로 판단하여 발송취소를 한 후 이용자 정지 처리함";
+	var smiMemo = "시스템 스팸 필터링에 의한 이용정지";
 	
 	fn_SpamMberUpdt(userId, mberSttus, smiMemo, "이용자 정지를 진행하시겠습니까?");
 }
-
+ 
 //회원 이용정지 처리
 function fn_SpamMberUpdt(userId, p_mberSttus, p_smiMemo, p_confirm_msg) {
 	url = "/uss/umt/user/EgovGnrlUpdateUserMsttusAjax.do";
@@ -781,9 +781,9 @@
 												
 												<c:if test="${result.reserveCYn eq 'N' && result.delayYn eq 'Y' && result.delayCompleteYn eq 'N'}">
 													<br />
-													<fmt:formatDate value="${now}" pattern="yyyyMMddhhmm" var="nowDate" />
+													<fmt:formatDate value="${now}" pattern="yyyyMMddHHmm" var="nowDate" />
 													<fmt:parseDate value="${result.reqFullDate}" pattern="yyyy-MM-dd HH:mm" var="checkValue" />
-													<fmt:formatDate value="${checkValue}" pattern="yyyyMMddhhmm" var="checkDate"/>																								
+													<fmt:formatDate value="${checkValue}" pattern="yyyyMMddHHmm" var="checkDate"/>		
 													<c:if test="${nowDate < checkDate}">
 														<button type="button" class="fillBlue" onclick="fnMsgDelaySendArray('<c:out value="${result.msgGroupId}"/>','<c:out value="${result.userId}"/>'); return false;">발송승인</button>
 														<button type="button" class="fillRed" onclick="fnMsgDelayCancelArray('<c:out value="${result.msgGroupId}"/>','<c:out value="${result.userId}"/>'); return false;">발송취소</button>
src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayDayChart.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayDayChart.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayDayChart.jsp
@@ -105,6 +105,44 @@
 	form.ntceEnddeYYYMMDD.value = year + "-" + month + "-" + date;
 	
 }
+
+function fnGoPayList(payType, payDate){
+	
+	var form = document.payParamForm;
+	form.searchCondition2.value = payType;
+	form.searchStartDate.value= payDate;
+	form.searchEndDate.value= payDate;
+	
+	form.action="<c:url value='/uss/ion/pay/PayList.do'/>";
+	form.submit();
+	
+}
+
+function fnGoPayRefundList(refundType, refundDate){
+	
+	var form = document.payRefParamForm;
+	
+	form.searchCondition2.value = refundType;
+	form.searchStartDate.value= refundDate;
+	form.searchEndDate.value= refundDate;
+	
+	form.action="<c:url value='/uss/ion/pay/RefundList.do'/>";
+	form.submit();
+	
+}
+
+function payDayExcelDownload(){
+	
+	var form = document.payExcelDwnForm;
+	
+	$('#excelNtceBgnde').val($('#ntceBgndeYYYMMDD').val()) ;
+	$('#excelNtceEndde').val($('#ntceEnddeYYYMMDD').val()) ;
+	
+	form.action="<c:url value='/uss/ion/pay/payDayChartExcelDownload.do'/>";
+    form.submit();
+    
+}
+
 </script>
 <style>
 .calBtn {
@@ -169,34 +207,28 @@
 			</div>
 			<div class="listTop">
 				<p class="tType5">총  <span class="tType4 c_456ded fwBold"><fmt:formatNumber value="${paginationInfo.totalRecordCount}" pattern="#,###" /></span>건</p>
-				<div style="float: right;">
-					카드 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCardSumTot}" pattern="#,###" /></span>원,
-					휴대폰 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCellSumTot}" pattern="#,###" /></span>원,
-					이체 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtBankSumTot}" pattern="#,###" /></span>원,
-					전용 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtVbankSumTot}" pattern="#,###" /></span>원,
-					간편 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtSpaySumTot}" pattern="#,###" /></span>원,
-					환불 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtRefundSumTot}" pattern="#,###" /></span>원,
-					합계 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtTotSumTot}" pattern="#,###" /></span>원
-					<%-- 
-					&nbsp; 
-					<select name="pageUnit" id="pageUnit" class="select" title="검색조건선택" onchange="linkPage(1);" style="height: 30px !important; min-width: 40px !important;">
+				
+				<div class="rightWrap">
+					<p style="vertical-align: bottom; margin-right:10px; margin-bottom:4px;">&nbsp;(단위 : 원)</p>
+					<input type="button" class="excelBtn" onclick="javascript:payDayExcelDownload();" style="cursor: pointer;" />
+					<select name="pageUnit" id="pageUnit" class="select" title="검색조건선택" onchange="linkPage(1);">
 						<option value='10' <c:if test="${searchVO.pageUnit == '10' or searchVO.pageUnit == ''}">selected</c:if>>10줄</option>
-						<option value='20' <c:if test="${searchVO.pageUnit == '20'}">selected</c:if>>20줄</option>
-						<option value='30' <c:if test="${searchVO.pageUnit == '30'}">selected</c:if>>30줄</option>
+						<option value='50' <c:if test="${searchVO.pageUnit == '50'}">selected</c:if>>50줄</option>
+						<option value='100' <c:if test="${searchVO.pageUnit == '100'}">selected</c:if>>100줄</option>
 					</select>
-					--%>
 				</div>
 			</div>
 			<div class="tableWrap">
 				<table class="tbType1">
 					<colgroup>
 						<col style="width: auto;">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
 						<col style="width: 13%">
 					</colgroup>
 					<thead>
@@ -207,6 +239,7 @@
 							<th>즉시이체<input type="button" class="sort sortBtn" id="sort_amtBankSum"></th>
 							<th>전용계좌<input type="button" class="sort sortBtn" id="sort_amtVbankSum"></th>
 							<th>간편결제<input type="button" class="sort sortBtn" id="sort_amtSpaySum"></th>
+							<th>후불결제<input type="button" class="sort sortBtn" id="sort_amtAfterPaySum"></th>
 							<th>환불<input type="button" class="sort sortBtn" id="sort_amtRefundSum"></th>
 							<th>합계(VAT 포함)<input type="button" class="sort sortBtn" id="sort_amtTotSum"></th>
 						</tr>
@@ -215,7 +248,7 @@
 						<c:forEach var="result" items="${resultList}" varStatus="status">
 						<tr>
 							<td><c:out value="${result.regDate}"/></td>
-							<td>
+							<td <c:if test="${result.amtCardCnt > 0}"> onclick="fnGoPayList('CARD', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
 								<fmt:formatNumber value="${result.amtCardSum}" pattern="#,###" />
 								<c:choose>
 									<c:when test="${result.amtCardCnt > 0}">
@@ -223,7 +256,7 @@
 									</c:when>
 								</c:choose>															
 							</td>
-							<td>
+							<td <c:if test="${result.amtCellCnt > 0}"> onclick="fnGoPayList('CELLPHONE', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
 								<fmt:formatNumber value="${result.amtCellSum}" pattern="#,###" />
 								<c:choose>
 									<c:when test="${result.amtCellCnt > 0}">
@@ -231,7 +264,7 @@
 									</c:when>
 								</c:choose>																							
 							</td>
-							<td>
+							<td <c:if test="${result.amtBankCnt > 0}"> onclick="fnGoPayList('BANK', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
 								<fmt:formatNumber value="${result.amtBankSum}" pattern="#,###" />
 								<c:choose>
 									<c:when test="${result.amtBankCnt > 0}">
@@ -239,7 +272,7 @@
 									</c:when>
 								</c:choose>																							
 							</td>
-							<td>
+							<td <c:if test="${result.amtVbankCnt > 0}"> onclick="fnGoPayList('VBANK', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
 								<fmt:formatNumber value="${result.amtVbankSum}" pattern="#,###" />
 								<c:choose>
 									<c:when test="${result.amtVbankCnt > 0}">
@@ -247,7 +280,7 @@
 									</c:when>
 								</c:choose>																							
 							</td>
-							<td>
+							<td <c:if test="${result.amtSpayCnt > 0}"> onclick="fnGoPayList('SPAY', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
 								<fmt:formatNumber value="${result.amtSpaySum}" pattern="#,###" />
 								<c:choose>
 									<c:when test="${result.amtSpayCnt > 0}">
@@ -255,7 +288,15 @@
 									</c:when>
 								</c:choose>																							
 							</td>							
-							<td>
+							<td <c:if test="${result.amtAfterPayCnt > 0}"> onclick="fnGoPayList('AFTERPAY', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtAfterPaySum}" pattern="#,###" />
+								<c:choose>
+									<c:when test="${result.amtAfterPayCnt > 0}">
+										(<fmt:formatNumber value="${result.amtAfterPayCnt}" pattern="#,###" />)
+									</c:when>
+								</c:choose>																							
+							</td>
+							<td <c:if test="${result.amtRefundCnt > 0}"> onclick="fnGoPayRefundList('1', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
 								<fmt:formatNumber value="${result.amtRefundSum}" pattern="#,###" />
 								<c:choose>
 									<c:when test="${result.amtRefundCnt > 0}">
@@ -273,8 +314,38 @@
 							</td>
 						</tr>
 						</c:forEach>
+						<tr>
+							<td>
+								합&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;계
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCardSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCellSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtBankSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtVbankSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtSpaySumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtAfterPaySumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtRefundSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtTotSumTot}" pattern="#,###" /></span>
+							</td>
+							
+						</tr>
 						<c:if test="${empty resultList}">
-		         			<tr><td colspan="8"><spring:message code="common.nodata.msg" /></td></tr>
+		         			<tr><td colspan="9"><spring:message code="common.nodata.msg" /></td></tr>
 		         		</c:if>    
 					</tbody>
 				</table>
@@ -294,5 +365,27 @@
 	</div>
 </form>
 </compress:html>
+
+<form id="payParamForm" name="payParamForm" method="post">
+	<input type="hidden" id="searchCondition2" name="searchCondition2" value=""/><!-- 결제방식 -->
+	<input type="hidden" id="searchCondition3" name="searchCondition3" value="1"/><!-- 결제상태 : 결제완료 -->
+	<input type="hidden" id="searchStartDate" name="searchStartDate" value=""/><!-- 결제검색 시작일자 -->
+	<input type="hidden" id="searchEndDate" name="searchEndDate" value=""/><!-- 결제검색 종료일자 -->
+	<input type="hidden" id="baseMenuNo" name="baseMenuNo" value="4520000"/><!-- 결제상세 메뉴 번호 -->
+</form>
+
+<form id="payRefParamForm" name="payRefParamForm" method="post">
+	<input type="hidden" id="searchCondition2" name="searchCondition2" value=""/><!-- 구분방식 -->
+	<input type="hidden" id="searchRefundStatus" name="searchRefundStatus" value="3"/><!-- 처리상태 : 처리완료 -->
+	<input type="hidden" id="searchStartDate" name="searchStartDate" value=""/><!-- 환불검색 시작일자 -->
+	<input type="hidden" id="searchEndDate" name="searchEndDate" value=""/><!-- 환불검색 종료일자 -->
+	<input type="hidden" id="baseMenuNo" name="baseMenuNo" value="4550000"/><!-- 결제상세 메뉴 번호 -->
+</form>
+
+<form id="payExcelDwnForm" name="payExcelDwnForm" method="post">
+	<input type="hidden" name="ntceBgnde" id="excelNtceBgnde"  value="<c:out value="${searchVO.ntceBgnde}" />">
+	<input type="hidden" name="ntceEndde" id="excelNtceEndde"  value="<c:out value="${searchVO.ntceEndde}" />">
+</form>
+
 </body>
 </html>
src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayList.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayList.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayList.jsp
@@ -311,8 +311,8 @@
 					<input type="button" class="excelBtn" onclick="javascript:sendMsgExcelDownload();" style="cursor: pointer;" />
 					<select name="pageUnit" id="pageUnit" class="select" title="검색조건선택" onchange="linkPage(1);">
 						<option value='10' <c:if test="${searchVO.pageUnit == '10' or searchVO.pageUnit == ''}">selected</c:if>>10줄</option>
-						<option value='20' <c:if test="${searchVO.pageUnit == '20'}">selected</c:if>>20줄</option>
-						<option value='30' <c:if test="${searchVO.pageUnit == '30'}">selected</c:if>>30줄</option>
+						<option value='50' <c:if test="${searchVO.pageUnit == '50'}">selected</c:if>>50줄</option>
+						<option value='100' <c:if test="${searchVO.pageUnit == '100'}">selected</c:if>>100줄</option>
 					</select>
 				</div>
 			</div>
src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayMonthChart.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayMonthChart.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/pay/PayMonthChart.jsp
@@ -58,6 +58,80 @@
 	$('#ntceBgnde').val($('#searchYear option:selected').val());
 	listForm.submit();
 }
+	
+function fnGoPayList(payType, payDate){
+	var form = document.payParamForm;
+
+	//월의 시작/마지막일 받아오기
+	var FLDate = getFLDate(payDate);
+	
+	form.searchCondition2.value = payType;
+	form.searchStartDate.value= FLDate[0];
+	form.searchEndDate.value= FLDate[1];
+	
+	console.log(form.searchCondition2.value);
+	
+	form.action="<c:url value='/uss/ion/pay/PayList.do'/>";
+	form.submit();
+	
+}
+
+function fnGoPayRefundList(refundType, refundDate){
+	
+	var form = document.payRefParamForm;
+	
+	//월의 시작/마지막일 받아오기
+	var FLDate = getFLDate(refundDate);
+	
+	form.searchCondition2.value = refundType;
+	form.searchStartDate.value= FLDate[0];
+	form.searchEndDate.value= FLDate[1];
+	
+	form.action="<c:url value='/uss/ion/pay/RefundList.do'/>";
+	form.submit();
+	
+}
+
+
+function payMonthExcelDownload(){
+	
+	var frm = document.payExcelDwnForm;
+	$('#excelNtceBgnde').val($('#searchYear option:selected').val());
+	frm.action = "<c:url value='/uss/ion/pay/payMonthChartExcelDownload.do'/>";
+	frm.submit(); 
+	
+}
+
+
+//날짜 월의 첫번째 날짜와 마지막 날짜 생성하기
+function getFLDate(date){
+	
+	var splitDate = [];
+	splitDate = date.split("-");
+	
+	var year = splitDate[0];
+	var month = Number(splitDate[1]-1);
+	
+	//해당월의 첫째날 구하기
+	var firstDate = new Date(year, Number(month), 1);
+	
+	//해당 월의 마지막날 구하기
+	var lastDate = new Date(year, Number(month)+1, 0);
+	
+	//날짜 포맷 변환하기
+	var fDate = firstDate.getFullYear() + 
+	"-" +  ((firstDate.getMonth() + 1) > 9 ? (firstDate.getMonth() + 1).toString() : "0" + (firstDate.getMonth() + 1)) + 
+	"-" + (firstDate.getDate() > 9 ? firstDate.getDate().toString() : "0" + firstDate.getDate().toString());
+	var lDate = lastDate.getFullYear() + 
+	"-" +  ((lastDate.getMonth() + 1) > 9 ? (lastDate.getMonth() + 1).toString() : "0" + (lastDate.getMonth() + 1)) + 
+	"-" + (lastDate.getDate() > 9 ? lastDate.getDate().toString() : "0" + lastDate.getDate().toString());
+	
+	var rtnDate = [];
+	rtnDate[0] = fDate;
+	rtnDate[1] = lDate;
+	return rtnDate;
+	
+}
 
 </script>
 <style>
@@ -117,14 +191,14 @@
 			<div class="listTop">
 				<p class="tType5">총  <span class="tType4 c_456ded fwBold"><fmt:formatNumber value="${paginationInfo.totalRecordCount}" pattern="#,###" /></span>건</p>
 
-				<div style="float: right;">
-					카드 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCardSumTot}" pattern="#,###" /></span>원,
-					휴대폰 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCellSumTot}" pattern="#,###" /></span>원,
-					이체 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtBankSumTot}" pattern="#,###" /></span>원,
-					전용 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtVbankSumTot}" pattern="#,###" /></span>원,
-					간편 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtSpaySumTot}" pattern="#,###" /></span>원,
-					환불 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtRefundSumTot}" pattern="#,###" /></span>원,
-					합계 : <span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtTotSumTot}" pattern="#,###" /></span>원
+				<div class="rightWrap">
+					<p style="vertical-align: bottom; margin-right:10px; margin-bottom:4px;">&nbsp;(단위 : 원)</p>
+					<input type="button" class="excelBtn" onclick="javascript:payMonthExcelDownload();" style="cursor: pointer;" />
+					<%-- <select name="pageUnit" id="pageUnit" class="select" title="검색조건선택" onchange="linkPage(1);">
+						<option value='10' <c:if test="${searchVO.pageUnit == '10' or searchVO.pageUnit == ''}">selected</c:if>>10줄</option>
+						<option value='50' <c:if test="${searchVO.pageUnit == '50'}">selected</c:if>>50줄</option>
+						<option value='100' <c:if test="${searchVO.pageUnit == '100'}">selected</c:if>>100줄</option>
+					</select> --%>
 				</div>
 			</div>			
 			
@@ -133,12 +207,13 @@
 				<table class="tbType1">
 					<colgroup>
 						<col style="width: auto;">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
-						<col style="width: 12.5%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
+						<col style="width: 11%">
 						<col style="width: 13%">
 					</colgroup>
 					<thead>
@@ -149,6 +224,7 @@
 							<th>즉시이체<input type="button" class="sort sortBtn" id="sort_amtBankSum"></th>
 							<th>전용계좌<input type="button" class="sort sortBtn" id="sort_amtVbankSum"></th>
 							<th>간편결제<input type="button" class="sort sortBtn" id="sort_amtSpaySum"></th>
+							<th>후불결제<input type="button" class="sort sortBtn" id="sort_amtAfterPaySum"></th>
 							<th>환불<input type="button" class="sort sortBtn" id="sort_amtRefundSum"></th>
 							<th>합계(VAT 포함)<input type="button" class="sort sortBtn" id="sort_amtTotSum"></th>
 						</tr>
@@ -156,13 +232,30 @@
 					<tbody>
 						<c:forEach var="result" items="${resultList}" varStatus="status">
 						<tr>
-							<td><c:out value="${result.regDate}"/></td>
-							<td><fmt:formatNumber value="${result.amtCardSum}" pattern="#,###" /></td>
-							<td><fmt:formatNumber value="${result.amtCellSum}" pattern="#,###" /></td>
-							<td><fmt:formatNumber value="${result.amtBankSum}" pattern="#,###" /></td>
-							<td><fmt:formatNumber value="${result.amtVbankSum}" pattern="#,###" /></td>
-							<td><fmt:formatNumber value="${result.amtSpaySum}" pattern="#,###" /></td>
-							<td><fmt:formatNumber value="${result.amtRefundSum}" pattern="#,###" /></td>
+							<td>
+								<c:out value="${result.regDate}"/>
+							</td>
+							<td <c:if test="${result.amtCardSum > 0}"> onclick="fnGoPayList('CARD', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtCardSum}" pattern="#,###" />
+							</td>
+							<td <c:if test="${result.amtCellSum > 0}"> onclick="fnGoPayList('CELLPHONE', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtCellSum}" pattern="#,###" />
+							</td>
+							<td <c:if test="${result.amtBankSum > 0}"> onclick="fnGoPayList('BANK', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtBankSum}" pattern="#,###" />
+							</td>
+							<td <c:if test="${result.amtVbankSum > 0}"> onclick="fnGoPayList('VBANK', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtVbankSum}" pattern="#,###" />
+							</td>
+							<td <c:if test="${result.amtSpaySum > 0}"> onclick="fnGoPayList('SPAY', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtSpaySum}" pattern="#,###" />
+							</td>
+							<td <c:if test="${result.amtAfterPaySum > 0}"> onclick="fnGoPayList('AFTERPAY', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtAfterPaySum}" pattern="#,###" />
+							</td>
+							<td <c:if test="${result.amtRefundSum >= 0}"> onclick="fnGoPayRefundList('1', '<c:out value="${result.regDate}"/>');" style="cursor:pointer;" </c:if> >
+								<fmt:formatNumber value="${result.amtRefundSum}" pattern="#,###" />
+							</td>
 							<td>
 								<c:choose>
 									<c:when test="${result.amtTotSum > 0}">
@@ -175,8 +268,37 @@
 							</td>
 						</tr>
 						</c:forEach>
+						<tr>
+							<td>
+								합&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;계
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCardSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtCellSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtBankSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtVbankSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtSpaySumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtAfterPaySumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtRefundSumTot}" pattern="#,###" /></span>
+							</td>
+							<td>
+								<span class="tType5 c_456ded"><fmt:formatNumber value="${mjonPayVO.amtTotSumTot}" pattern="#,###" /></span>
+							</td>
+						</tr>
 						<c:if test="${empty resultList}">
-		         			<tr><td colspan="8"><spring:message code="common.nodata.msg" /></td></tr>
+		         			<tr><td colspan="9"><spring:message code="common.nodata.msg" /></td></tr>
 		         		</c:if>    
 					</tbody>
 				</table>
@@ -185,5 +307,25 @@
 	</div>
 </form>
 </compress:html>
+<form id="payParamForm" name="payParamForm" method="post">
+	<input type="hidden" id="searchCondition2" name="searchCondition2" value=""/><!-- 결제방식 -->
+	<input type="hidden" id="searchCondition3" name="searchCondition3" value="1"/><!-- 결제상태 : 결제완료 -->
+	<input type="hidden" id="searchStartDate" name="searchStartDate" value=""/><!-- 결제검색 시작일자 -->
+	<input type="hidden" id="searchEndDate" name="searchEndDate" value=""/><!-- 결제검색 종료일자 -->
+	<input type="hidden" id="baseMenuNo" name="baseMenuNo" value="4520000"/><!-- 결제상세 메뉴 번호 -->
+</form>
+
+<form id="payRefParamForm" name="payRefParamForm" method="post">
+	<input type="hidden" id="searchCondition2" name="searchCondition2" value=""/><!-- 구분방식 -->
+	<input type="hidden" id="searchRefundStatus" name="searchRefundStatus" value="3"/><!-- 처리상태 : 처리완료 -->
+	<input type="hidden" id="searchStartDate" name="searchStartDate" value=""/><!-- 환불검색 시작일자 -->
+	<input type="hidden" id="searchEndDate" name="searchEndDate" value=""/><!-- 환불검색 종료일자 -->
+	<input type="hidden" id="baseMenuNo" name="baseMenuNo" value="4550000"/><!-- 결제상세 메뉴 번호 -->
+</form>
+
+<form id="payExcelDwnForm" name="payExcelDwnForm" method="post">
+	<input type="hidden" name="ntceBgnde" id="excelNtceBgnde"  value="<c:out value="${searchVO.ntceBgnde}" />">
+</form>
+
 </body>
 </html>
src/main/webapp/WEB-INF/jsp/uss/ion/pay/RefundList.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/pay/RefundList.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/pay/RefundList.jsp
@@ -163,12 +163,12 @@
 					</select>
 					<input type="hidden" name="cal_url" id="cal_url" value="/sym/cmm/EgovNormalCalPopup.do">
 					<div class="calendar_box" onclick="javascript:fn_egov_NormalCalendar(document.forms.listForm, document.forms.listForm.searchStartDate);">
-						<input style="width:auto;min-width: 83px;" type="text" class="date_format" name="searchStartDate" id="searchStartDate" size="4" maxlength="4" readonly="" value="<c:out value='${searchVO.searchStartDate}'/>">
+						<input style="width:auto;min-width: 83px;" type="text" class="date_format" name="searchStartDate" id="searchStartDate" size="4" maxlength="4" readonly="" value="<c:out value='${RefundVO.searchStartDate}'/>">
 						<input type="button" class="calBtn">
 					</div>
 					<span class="line">~</span>
 					<div class="calendar_box" onclick="javascript:fn_egov_NormalCalendar(document.forms.listForm, document.forms.listForm.searchEndDate);">
-						<input style="width:auto;min-width: 83px;" type="text" class="date_format" name="searchEndDate" id="searchEndDate" size="4" maxlength="4" readonly="" value="<c:out value='${searchVO.searchEndDate}'/>">
+						<input style="width:auto;min-width: 83px;" type="text" class="date_format" name="searchEndDate" id="searchEndDate" size="4" maxlength="4" readonly="" value="<c:out value='${RefundVO.searchEndDate}'/>">
 						<input type="button" class="calBtn">
 					</div>
 				</div>
src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
--- src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
@@ -284,11 +284,14 @@
 /**
  * 먼저 불러온 DATA가 있으면 삭제
  * !! 화면에 보이는 data만 삭제 !!
+ * 총건수, 중복건수 데이터 0으로 초기화
  * 엑셀 불러오기 데이터 
  */
 function fn_viewDataInit02(){
 	$('.excelBody').remove();
 	$('#excelHead').empty();
+	$('#rowTotCnt').text("0");
+	$('#rowDupCnt').text("0");
 }
 
 /*
@@ -1352,7 +1355,8 @@
 												<div class="receipt_num_top">
 													<input type="text" placeholder="선택된 파일이 없습니다." onfocus="this.placeholder=''" onblur="this.placeholder='번호를 입력하세요'" style="width:340px;">
 													<button type="button" class="btnType btnType6" id="fileClick"/>파일선택</button>
-													<input type="file" id="excelFile" accept=".xls, .xlsx" onchange="excelExport02(event); return false;" style="display:none"/>
+													<input type="file" id="excelFile" accept=".xls, .xlsx" onchange="excelExportVarAjax(event); return false;" style="display:none"/>
+													<!-- <input type="file" id="excelFile" accept=".xls, .xlsx" onchange="excelExport02(event); return false;" style="display:none"/> -->
 												</div>
 												<div class="receipt_num_midde">
 													<div class="listType list01" id="wrap02">
@@ -1735,21 +1739,27 @@
 					<div class="attachedFile">
 						<label for="excelNm01" class="attachedFile_label">첨부파일</label>
 						<input type="text" id="excelNm01" value="" readonly>
-						<input type="file" id="excelFile01" accept=".xls, .xlsx" onchange="excelExport01(event); return false;" style="display:none"/>
+						<input type="file" id="excelFile01" accept=".xls, .xlsx" onchange="excelExportAjax(event); return false;" style="display:none"/>
+						<!-- <input type="file" id="excelFile01" accept=".xls, .xlsx" onchange="excelExport01(event); return false;" style="display:none"/> -->
 						<button type="button" class="btnType btnType6 c1">찾아보기</button>
 <!-- 						<p><span class="vMiddle">*</span> 첨부된 파일은 <span class="c_e40000">[추가]버튼을 클릭</span>하셔야 받는 사람에 등록됩니다.</p> -->
 						<p><span class="vMiddle">*</span> 첨부된 파일은 <span class="c_e40000">[추가]버튼을 클릭</span>하셔야 받는 사람에 등록됩니다.</p>
 					</div>
 				</div><!--// 엑셀파일 불러오기 -->
 				<div class="popup_btn_wrap2">
-					<button type="button" class="tooltip-close" data-focus="popup02-close"  data-focus-next="popup02" onclick="excelAdd()">추가</button>
+					<button type="button" class="tooltip-close" data-focus="popup02-close"  data-focus-next="popup02" onclick="excelAddAjax()">추가</button>
+					<!-- <button type="button" class="tooltip-close" data-focus="popup02-close"  data-focus-next="popup02" onclick="excelAdd()">추가</button> -->
 					<button type="button" class="tooltip-close" data-focus="popup02-close"  data-focus-next="popup02">닫기</button>                      
 				</div>
 			</div>
 		</div>
 	</div><!--// 엑셀 불러오기 -->
 </form>
-
+<form id="excelVarFileForm" name="excelVarFileForm" method="post">
+	<input type="hidden" id="excelVarCnt" name="excelVarCnt" value="0"/>
+	<input type="hidden" id="excelVarList" name="excelVarList" value=""/>
+	
+</form>
 
 <form id="msgResendForm" name="msgResendForm" method="post">
 	<input name="msgResendFlag" type="hidden" value="N"/>
src/main/webapp/WEB-INF/jsp/web/kakao/sent/KakaoSentAllListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/kakao/sent/KakaoSentAllListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/kakao/sent/KakaoSentAllListAjax.jsp
@@ -143,7 +143,28 @@
 								<input type="checkbox" id="msgSentDel${status.count}" name="msgSentDel" 
 									value="${resultAllSentList.msgGroupId}" <c:if test="${resultAllSentList.curState eq '0'}">disabled</c:if>> 
 							</td>
-							<td rowspan="2"><p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p></td>
+							<td rowspan="2">
+								<c:choose>
+									<c:when test="${resultAllSentList.atDelayYn eq 'Y' && resultAllSentList.atDelayCompleteYn eq 'N'}">
+										<c:choose>
+											<c:when test="${resultAllSentList.curState eq '0'}">
+												<%-- 
+													20240906 추가
+													발송 대기 상태일 때만 원래 발송시간을 보여주고, 발송이 완료되면 발송 처리 완료 시간(reqDate)을 보여준다.
+													30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+												 --%>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.atDelayOrgTime}" /></p>
+											</c:when>
+											<c:otherwise>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
+											</c:otherwise>
+										</c:choose>
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>									
+									</c:otherwise>
+								</c:choose>
+							</td>
 							<td rowspan="2">
 								<p class="c_222 fwRg">
 									<c:if test="${resultAllSentList.msgType eq '8'}">알림톡</c:if>
src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentAllListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentAllListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentAllListAjax.jsp
@@ -173,7 +173,28 @@
 								
 							</td>
 							<td name="listTd">
-								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
+								<c:choose>
+									<c:when test="${resultAllSentList.delayYn eq 'Y' && resultAllSentList.delayCompleteYn eq 'N'}">
+									
+										<c:choose>
+											<c:when test="${resultAllSentList.curState eq '0'}">
+												<%-- 
+													20240906 추가
+													발송 대기 상태일 때만 원래 발송시간을 보여주고, 발송이 완료되면 발송 처리 완료 시간(reqDate)을 보여준다.
+													30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+												 --%>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.delayOrgTime}" /></p>	
+											</c:when>
+											<c:otherwise>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
+											</c:otherwise>
+										</c:choose>
+										
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
+									</c:otherwise>
+								</c:choose>
 							</td>
 							<td name="listTd">
 								<p>
src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentCompleteListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentCompleteListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentCompleteListAjax.jsp
@@ -152,6 +152,16 @@
 								
 							</td>
 							<td>
+								<%-- <c:choose>
+									<c:when test="${resultAllSentList.delayYn eq 'Y' && resultAllSentList.delayCompleteYn eq 'N'}">
+										20240906 추가
+										30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.delayOrgTime}" /></p>
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
+									</c:otherwise>
+								</c:choose> --%>
 								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
 							</td>
 							<td>
src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentFailListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentFailListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentFailListAjax.jsp
@@ -140,6 +140,16 @@
 								
 							</td>
 							<td>
+								<%-- <c:choose>
+									<c:when test="${resultAllSentList.delayYn eq 'Y' && resultAllSentList.delayCompleteYn eq 'N'}">
+										20240906 추가
+										30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.delayOrgTime}" /></p>
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
+									</c:otherwise>
+								</c:choose> --%>
 								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.reqdate}" /></p>
 							</td>
 							<td>
src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentReadyListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentReadyListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentReadyListAjax.jsp
@@ -152,7 +152,27 @@
 								
 							</td>
 							<td>
-								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.regdate}" /></p>
+								<c:choose>
+									<c:when test="${resultAllSentList.delayYn eq 'Y' && resultAllSentList.delayCompleteYn eq 'N'}">
+										<c:choose>
+											<c:when test="${resultAllSentList.curState eq '0'}">
+												<%-- 
+													20240906 추가
+													발송 대기 상태일 때만 원래 발송시간을 보여주고, 발송이 완료되면 발송 처리 완료 시간(reqDate)을 보여준다.
+													30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+												 --%>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.delayOrgTime}" /></p>	
+											</c:when>
+											<c:otherwise>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.regdate}" /></p>
+											</c:otherwise>
+										</c:choose>
+										
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllSentList.regdate}" /></p>
+									</c:otherwise>
+								</c:choose>
 							</td>
 							<td>
 								<p>
src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedKakaoAllListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedKakaoAllListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedKakaoAllListAjax.jsp
@@ -198,7 +198,26 @@
 								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.regdate}" /></p>
 							</td>
 							<td>
-								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>
+								<c:choose>
+									<c:when test="${resultAllResList.atDelayYn eq 'Y' && resultAllResList.atDelayCompleteYn eq 'N'}">
+										<c:choose>
+											<c:when test="${resultAllResList.curState eq '0'}">
+												<%-- 
+													20240906 추가
+													발송 대기 상태일 때만 원래 발송시간을 보여주고, 발송이 완료되면 발송 처리 완료 시간(reqDate)을 보여준다.
+													30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+												 --%>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.atDelayOrgTime}" /></p>
+											</c:when>
+											<c:otherwise>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>	
+											</c:otherwise>
+										</c:choose>
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>
+									</c:otherwise>
+								</c:choose>
 							</td>
 							<td>
 								<p>
src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedKakaoReadyListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedKakaoReadyListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedKakaoReadyListAjax.jsp
@@ -169,7 +169,26 @@
 								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.regdate}" /></p>
 							</td>
 							<td>
-								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>
+								<c:choose>
+									<c:when test="${resultAllResList.atDelayYn eq 'Y' && resultAllResList.atDelayCompleteYn eq 'N'}">
+										<c:choose>
+											<c:when test="${resultAllResList.curState eq '0'}">
+												<%-- 
+													20240906 추가
+													발송 대기 상태일 때만 원래 발송시간을 보여주고, 발송이 완료되면 발송 처리 완료 시간(reqDate)을 보여준다.
+													30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+												 --%>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.atDelayOrgTime}" /></p>
+											</c:when>
+											<c:otherwise>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>	
+											</c:otherwise>
+										</c:choose>
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>
+									</c:otherwise>
+								</c:choose>
 							</td>
 							<td>
 								<p>
src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedMsgAllListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedMsgAllListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedMsgAllListAjax.jsp
@@ -202,7 +202,27 @@
 								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.regdate}" /></p>
 							</td>
 							<td>
-								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>
+								<c:choose>
+									<c:when test="${resultAllResList.delayYn eq 'Y' && resultAllResList.delayCompleteYn eq 'N'}">
+										<c:choose>
+											<c:when test="${resultAllResList.curState eq '0'}">
+												<%-- 
+													20240906 추가
+													발송 대기 상태일 때만 원래 발송시간을 보여주고, 발송이 완료되면 발송 처리 완료 시간(reqDate)을 보여준다.
+													30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+												 --%>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.delayOrgTime}" /></p>	
+											</c:when>
+											<c:otherwise>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>	
+											</c:otherwise>
+										</c:choose>
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>	
+									</c:otherwise>
+								</c:choose>
+								
 							</td>
 							<td>
 								<p>
src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedMsgReadyListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedMsgReadyListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/reservedmsg/ReservedMsgReadyListAjax.jsp
@@ -175,7 +175,26 @@
 								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.regdate}" /></p>
 							</td>
 							<td>
-								<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>
+								<c:choose>
+									<c:when test="${resultAllResList.delayYn eq 'Y' && resultAllResList.delayCompleteYn eq 'N'}">
+										<c:choose>
+											<c:when test="${resultAllResList.curState eq '0'}">
+												<%-- 
+													20240906 추가
+													발송 대기 상태일 때만 원래 발송시간을 보여주고, 발송이 완료되면 발송 처리 완료 시간(reqDate)을 보여준다.
+													30분 딜레이 된 건으로 관리자 승인/취소 처리가 완료 되지 않은 건에 대해서 -30분 처리하여 원래 사용자가 보내려던 시간을 표시해줌
+												 --%>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.delayOrgTime}" /></p>	
+											</c:when>
+											<c:otherwise>
+												<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>	
+											</c:otherwise>
+										</c:choose>
+									</c:when>
+									<c:otherwise>
+										<p><fmt:formatDate pattern = "yyyy-MM-dd HH:mm" value = "${resultAllResList.reqdate}" /></p>	
+									</c:otherwise>
+								</c:choose>
 							</td>
 							<td>
 								<p>
src/main/webapp/js/kakao/at/alimtalkExcel.js
--- src/main/webapp/js/kakao/at/alimtalkExcel.js
+++ src/main/webapp/js/kakao/at/alimtalkExcel.js
@@ -48,6 +48,352 @@
 	}
 }
 
+/*
+ * 신규 엑셀 파일 불러오기
+ * 기존 json 처리가 아닌 POI 방식으로 처리하기 위함
+ * 
+ * */
+function excelExportAjax(){
+	
+	var data = new FormData(document.excelToolTipForm);
+	
+	var fileValue = $("#excelFile01").val().split("\\");
+	var fileName = fileValue[fileValue.length-1];
+	
+	var fileExt = fileName.split('.').pop().toLowerCase();
+	
+	if(fileExt.length > 0){
+		if($.inArray(fileExt, ['xls','xlsx']) == -1) {
+
+			alert('xls, xlsx 파일만 업로드 할수 있습니다.');
+			return false;
+
+	   	}
+		
+	}
+	fn_viewDataInit02();
+	$('#excelNm01').val(fileName);
+	
+}
+
+function excelAddAjax(){
+	
+	var data = new FormData(document.excelToolTipForm);
+	data.append("file0", $('#excelFile01').prop('files')[0]);
+	
+	var url = "/web/mjon/alimtalk/sendAlimtalkExelFilePhoneNumAjax.do";
+	
+	$.ajax({
+        type: "POST",
+        enctype: 'multipart/form-data',
+        url: url,
+        data: data,
+        dataType:'json',
+        async: true,
+        processData: false,
+        contentType: false,
+        cache: false,
+        //timeout: 600000,
+        success: function (returnData, status) {
+			if(status == 'success'){ // status 확인 필요한가. 석세스 안뜨면 에러 가지 않나
+				
+				if(returnData.success){
+					
+					var data = returnData.data;
+					var message = returnData.message;
+					
+					if(message != '' ){
+						alert(returnData.message);
+					}
+					
+					if(data != null){
+						
+						//수신목록 Html 태그
+						var addHtml = 	'<div class="list_table list_body excelBody">'
+							+'\t<div class="cb_wrap">'
+							+'\t\t<label for="" class="label"></label>'
+							+'\t\t<input type="checkbox" class="wrap01C">'
+							+'\t</div>'
+							+'\t<div class="list_table_num phoneArea">'
+							+'\t\t<p>$PHONE$</p>'
+							+'\t</div>'
+							/*23.04.06  이름제거 요청으로인한 화면 이름 제거*/
+							/*+'\t<div class="list_table_name">'
+							+'\t\t<p>$NAME$</p>'
+							+'\t</div>'*/
+							+'</div>';
+						
+						var totalDuplCnt = $('#rowDupCnt').text();//중복 건수 정보
+						var $excelBody = $('#wrap01_body');
+						var phoneNum;
+
+						$.each(data, function(i, item){
+							
+							if(checkHpNum(item.phone)){
+							
+								phoneNum = removeDash(item.phone);
+								
+								if(!phoneDupl(phoneNum))
+									/*23.04.06  이름제거 요청으로인한 화면 이름 제거*/
+//									$excelBody.append(addHtml.replace('$PHONE$', phoneNum).replace('$NAME$', jsonData[bodyIndex]['이름'] ??= ''));
+									$excelBody.append(addHtml.replace('$PHONE$', phoneNum));
+								else
+									totalDuplCnt++;
+								
+							} else{
+								
+								alert("엑셀 파일 데이터의 형식이 맞지 않는 부분이 있습니다.");
+				        		excelAddr = []; //엑셀 데이터 저장 변수 초기화
+				        		$("#excelFile").val(""); //첨부파일 input 초기화
+				        	    $("#excelNm").val("");  // 첨부파일 명 초기화
+				        	    fileName = "";
+				        		return;
+								
+							} 
+						 
+						});
+						
+						$('#rowDupCnt').text(totalDuplCnt);
+						$("#excelFile01").val(""); //첨부파일 input 초기화
+		        	    $("#excelNm01").val("");  // 첨부파일 명 초기화
+						updateTotCnt();
+
+					}
+					
+				}else{
+					alert(returnData.message);
+//						alert("첨부파일 불러오는 중 오류가 발생하였습니다.");
+					excelAddr = []; //엑셀 데이터 저장 변수 초기화
+	        		$("#excelFile01").val(""); //첨부파일 input 초기화
+	        	    $("#excelNm01").val("");  // 첨부파일 명 초기화
+	        	    fileName = "";
+					return;
+					
+				}
+			} else if(status== 'fail'){
+				alert("첨부파일 불러오는 중 오류가 발생하였습니다.1");
+				console.log("status : fail ~");
+			}
+		},
+		error: function (e) { 
+        	alert("첨부파일 불러오는 중 오류가 발생하였습니다2."); 
+        	console.log("ERROR : ", e); 
+        },
+		beforeSend : function(xmlHttpRequest) {
+        	//로딩창 show
+        	$('.loading_layer').addClass('active');				
+		},	        	        
+        complete : function(xhr, textStatus) {
+        	//로딩창 hide
+        	$('.loading_layer').removeClass('active');
+		}
+    });
+	
+}
+
+
+/*
+ * 신규 변수명 설정 엑셀 파일 불러오기
+ * 기존 json 처리가 아닌 POI 방식으로 처리하기 위함
+ * 
+ * */
+function excelExportVarAjax(){
+	
+	var data = document.getElementById('excelFile').files;
+	
+	var fileValue = $("#excelFile").val().split("\\");
+	var fileName = fileValue[fileValue.length-1];
+	
+	var fileExt = fileName.split('.').pop().toLowerCase();
+	
+	if(fileExt.length > 0){
+		if($.inArray(fileExt, ['xls','xlsx']) == -1) {
+
+			alert('xls, xlsx 파일만 업로드 할수 있습니다.');
+			return false;
+
+	   	}
+		
+	}
+	fn_viewDataInit01();
+	excelAddVarAjax();
+}
+
+function excelAddVarAjax(){
+	
+	var varList = $("#excelTemplateContent").val().match(/#\{([^}]+)\}/g);
+	
+	var form = document.excelVarFileForm;
+	form.excelVarCnt.value = varList.length;
+	form.excelVarList.value = varList;
+	
+	var data =  new FormData(form);
+	data.append("file0", $('#excelFile').prop('files')[0]);
+	
+	var url = "/web/mjon/alimtalk/sendAlimtalkExelVarFilePhoneNumAjax.do";
+	
+	$.ajax({
+        type: "POST",
+        enctype: 'multipart/form-data',
+        url: url,
+        data: data,
+        dataType:'json',
+        async: true,
+        processData: false,
+        contentType: false,
+        cache: false,
+        //timeout: 600000,
+        success: function (returnData, status) {
+			if(status == 'success'){ // status 확인 필요한가. 석세스 안뜨면 에러 가지 않나
+				
+				if(returnData.success){
+					
+					var data = returnData.data;
+					var message = returnData.message;
+					
+					if(message != '' ){
+						alert(returnData.message);
+					}
+					
+					if(data != null){
+						
+						//수신목록 Html 태그
+						// 엑셀 헤더
+						var excelTitleHeadText ='<div class="list_table_name">'
+										+'\t<p>$HEADTITLE$</p>'
+										+'</div>';
+
+						// 바디 row 수신자 tag
+						var excelBodyRowTextIndex00 ='<div class="list_table_name phoneArea">'
+												+'\t\t<p>$ROWTEXT$</p>'
+												+'\t</div>';
+												
+						// 바디 row tag
+						var excelBodyRowTextIndex01 ='<div class="list_table_name transData">'
+												+'\t\t<p>$ROWTEXT$</p>'
+												+'\t</div>';
+						
+						//맨 앞에 수신번호 배열 추가
+						varList.unshift('수신번호'); 
+						//변수 문자열 중복 제거
+						var newList = Array.from(new Set(varList));
+						
+						//엑셀헤더 selector
+						var $excelHead = $('#excelHead');
+						//엑셀바디 selector
+						var $excelBody = $('#excelBody02');
+
+						// 엑셀 헤더 부분
+						$.each(newList, function(headerIndex, value) {
+							$excelHead.append(excelTitleHeadText.replace('$HEADTITLE$', value));
+						});
+						
+						var totalDuplCnt = $('#rowDupCnt').text();//중복 건수 정보
+						var $excelBody = $('#excelBody02');
+						var bodyData;
+						var addDiv = "";
+						var phoneNum;
+
+						//입력데이터를 역정렬해준다.
+						data.reverse();
+
+						//변수명 추출해주기
+						var varListArr = [];
+						varListArr = form.excelVarList.value.split(",");
+						
+						$.each(data, function(i, item){
+							
+							if(checkHpNum(item.phone)){
+							
+								phoneNum = removeDash(item.phone);
+								
+								if(!phoneDupl(phoneNum)){
+									var varVal = item.varVal;
+									var lengthCheck =true;
+									/*23.04.06  이름제거 요청으로인한 화면 이름 제거*/
+									var excelBody = '<div class="list_table list_body excelBody">';
+									
+									//수신번호 화면 태그 생성
+									excelBody += excelBodyRowTextIndex00.replace('$ROWTEXT$', removeDash(phoneNum));
+									
+									//변수 데이터 태그 생성
+									var varValArr = []
+									varValArr = varVal.split("§");
+									for(var i=0; i < varValArr.length; i++){
+										
+										var bodyData = varValArr[i];
+										
+										// 기타변수는 50자리 까지 입력
+										if(bodyData.length > 100 || bodyData.length == 0){
+											alert("등록 변수[ "+varListArr[i]+" ] \n기타변수의 입력 값이 없거나 100자리를 초과하는 내용이 포함되어 해당 내용 제외되었습니다.");
+											lengthCheck = false;
+											break;
+										}
+										excelBody += excelBodyRowTextIndex01.replace('$ROWTEXT$', bodyData);
+										
+									}
+									
+									excelBody += '</div>';
+									
+									if(lengthCheck){
+										addDiv += excelBody;
+									}
+									
+								}
+									
+								else
+									totalDuplCnt++;
+								
+							} else{
+								
+								alert("엑셀 파일 데이터의 형식이 맞지 않는 부분이 있습니다.");
+				        		excelAddr = []; //엑셀 데이터 저장 변수 초기화
+				        		$("#excelFile").val(""); //첨부파일 input 초기화
+				        	    $("#excelNm").val("");  // 첨부파일 명 초기화
+				        	    fileName = "";
+				        		return;
+								
+							} 
+						 
+						});
+						
+						//화면에 수신번호 및 변수 데이터 추가해 주기
+						$excelBody.append(addDiv);
+
+					}
+					
+				}else{
+					alert(returnData.message);
+//						alert("첨부파일 불러오는 중 오류가 발생하였습니다.");
+					excelAddr = []; //엑셀 데이터 저장 변수 초기화
+	        		$("#excelFile01").val(""); //첨부파일 input 초기화
+	        	    $("#excelNm01").val("");  // 첨부파일 명 초기화
+	        	    fileName = "";
+					return;
+					
+				}
+			} else if(status== 'fail'){
+				alert("첨부파일 불러오는 중 오류가 발생하였습니다.");
+				console.log("status : fail ~");
+			}
+		},
+		error: function (e) { 
+        	alert("첨부파일 불러오는 중 오류가 발생하였습니다."); 
+        	console.log("ERROR : ", e); 
+        },
+		beforeSend : function(xmlHttpRequest) {
+        	//로딩창 show
+        	$('.loading_layer').addClass('active');				
+		},	        	        
+        complete : function(xhr, textStatus) {
+        	//로딩창 hide
+        	$('.loading_layer').removeClass('active');
+		}
+    });
+	
+}
+
+
 /**
  * 엑셀 파일 불러오기
  */
@@ -337,7 +683,6 @@
 	var resultBoo = true;
 
 	data = removeDash(data);
-
 	/*
 	* 중복체크
 	* 기존 데이터 배열화
Add a comment
List