/***********************************************************************************
 * @@ Program Name : HttpReportModifyer.java Description : 보고자 보고자료 변경 Author : 강원중 Create Date : 2004-11-08 History :
 * @@
 ***********************************************************************************/

package kr.co.kihyun.beans.totsys.report;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.sql.ResultSet;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import kr.co.kihyun.beans.entity.AcceptanceCode;

//import kr.co.kihyun.beans.entity.AcceptanceCode;
import kr.co.kihyun.beans.entity.MDept;
import kr.co.kihyun.beans.entity.MUser;
//import kr.co.kihyun.beans.entity.TotDocType;
import kr.co.kihyun.beans.entity.TotReport;
import kr.co.kihyun.beans.entity.TotReportHistory;
import kr.co.kihyun.beans.entity.TotReportProcess;
import kr.co.kihyun.beans.entity.util.*;
import kr.co.kihyun.beans.totsys.doc.table.item.Item;
import kr.co.kihyun.beans.totsys.doc.table.item.ItemList;
import kr.co.kihyun.beans.totsys.menu.MenuBean;
import kr.co.kihyun.beans.user.HttpSSOLogin;
import kr.co.kihyun.db.CommonDBManager;
import kr.co.kihyun.io.FileUtil;
import kr.co.kihyun.io.MultipartRequest;
import kr.co.kihyun.lang.MInteger;
import kr.co.kihyun.lang.MLong;
import kr.co.kihyun.lang.MString;
import kr.co.kihyun.moumi.MoumiConfig;
import kr.co.kihyun.moumi.doc.table.InsertMTable;
import kr.co.kihyun.moumi.doc.table.item.MItem;
import kr.co.kihyun.moumi.report.MReportData;
import kr.co.kihyun.service.TotReportService;
import kr.co.kihyun.text.excel.Excel;
import kr.co.kihyun.text.html.HtmlUtil;
import kr.co.kihyun.text.html.ServletUtil;
import kr.co.kihyun.text.html.TagFilter;

import org.datanucleus.ObjectManager;
import org.datanucleus.jdo.JDOPersistenceManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@WebServlet("/servlet/kr.co.kihyun.beans.totsys.report.HttpReportModifyer")
public class HttpReportModifyer extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory.getLogger(HttpReportModifyer.class);

	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		doPost(req, res);
	}

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/html;charset=UTF-8");
		PrintWriter out = res.getWriter();
		HttpSession session = req.getSession(true);
		MenuBean tempboxMenu = new MenuBean(req, "/totsys/repoper/mydocbox/tempbox/report_list.jsp");

		/*********** User HttpLogin check ***********/
//		if (!HttpSSOLogin.isLogin(req)) {
//			String connURL = "location='/totsys/login/login.jsp';";
//			out.println(ServletUtil.getJavaScript(connURL));
//			return;
//		}
		/********** session내의 userId **********/
		String usID;
		if(HttpSSOLogin.getLoginID(req) != null){
			usID = HttpSSOLogin.getLoginID(req);
		}else{
			usID = (String) session.getAttribute("SSO_USER_ID");
		}
//		String dtID = HttpSSOLogin.getDeptID(req);

		/********** parameter value **********/
		String savePath = MoumiConfig.getRepoPerTmp().getPath(); // 업로드된 파일의 임시 저장 경로
		MultipartRequest multi = new MultipartRequest(req, savePath, 5 * 1024 * 1024);

		Long reportID = MLong.parseLong(multi.getParameter("reportID"));
		int acptNum = MInteger.parseInt(multi.getParameter("acptNum"), -1);
		LOG.debug("acptNum: {}", acptNum);
		String comment = multi.getParameter("comment");
		String tableRows = multi.getParameter("tableRows"); // 각 테이블당 입력칸이 몇줄 인지 데이터 예 : 2,3,2
		String inForm = URLDecoder.decode(MString.checkNull(multi.getParameter("inForm")), "UTF-8");
		String svrFilenames = multi.getParameter("svrFilenames");
		String usrFilenames = multi.getParameter("usrFilenames");
		int appro = MInteger.parseInt(multi.getParameter("appro")); // 자료공유 여부지정
		String memo = multi.getParameter("memo");
		String callbackFunc = MString.checkNull(multi.getParameter("callbackFunc"));

		// 승인자가 자료수정할때
		String deptID = null;
		String repUserID = null;
		String isRecog = MString.checkNull(multi.getParameter("isRecog"));

		if ("recog".equals(isRecog)) {
			deptID = multi.getParameter("deptID");
			repUserID = multi.getParameter("repUserID");
		}
        Long docId = MLong.parseLong(multi.getParameter("docId"));


		PersistenceManager pm = new MPersistenceManager(PMF.get().getPersistenceManager());
		Transaction tx = pm.currentTransaction();
		ObjectManager om = ((JDOPersistenceManager) tx.getPersistenceManager()).getObjectManager(); // jeus 6 proplem <- *sigh*
		CommonDBManager dbmanager = new CommonDBManager();
        ResultSet rset = null;



		try {
	        //미결함인지 확인
			/*
	        String query="SELECT "+
	        		" TRIM(DECODE(A.SANC_STTUS_CODE,'1','결재대기', '2', '결재', '3', '병렬결재', '4', '협조', '공람' ) ) AS r1 "+
	        		" , TRIM(DECODE(B.SANC_PRG_CODE ,'1','예결함','2','미결함','3','기결함','4','협조함','5','삭제함'))as r2 "+
	        		" , TRIM(DECODE(B.CONFM_SC_CODE, '1','결재대기','2','결재완료')) as r3 "+
	        		" FROM TN_BCMCFMRT001 A, TN_BCMCFMRT002 B "+
	        		" WHERE A.SANC_DOCT_IDNT_VALUE = B.SANC_DOCT_IDNT_VALUE "+
	        		" AND A.DOCT_KND_CODE = 'C21' "+
	        		" AND A.SANC_STTUS_CODE = '1' "+
	        		" AND B.SANC_PRG_CODE = '2' "+
	        		" AND B.CONFM_SC_CODE = '1' "+
	        		" AND A.SANC_DOCT_IDNT_VALUE  LIKE 'C21|' || ? || '%'";
	        boolean isMigulham=false;
			rset = dbmanager.execQuery(query, reportID);
			if(rset.next()){
	        	isMigulham=true;
	        }
			rset.close();
			dbmanager.pstmt.close();
			*/

			tx.begin();
			MUser mUser = pm.getObjectById(MUser.class, usID);
			String name = mUser.getName(pm).toString();
			String dtID = mUser.getDept().toString();

	        // 결재대기중(진행), 결재완료된 제출자료의 갯수를 조회한다.
	        // 1건이라도 있으면 서식을 수정해선 안된다.
	        TotReportService totReportService = new TotReportService(pm);
	        int unModifiableCount = totReportService.getUnModifiableCountByReportId(reportID);

	        //LOG.info("====> [At kr.co.kihyun.beans.totsys.report.HttpReportModifyer] reportID : {}, report count(prss = 5 or 6) : {}", new Object[] {reportID, unModifiableCount});

	        // 건수가 1개라도 있으면 집계자료의 서식을 수정하지 못하게 한다.
	        // 미결함일경우 스킵
	        if (unModifiableCount > 0/*&&!isMigulham*/) {
	            out.println(ServletUtil.alert("제출자료의 정보를 수정할 수 없습니다. 제출된 자료가 결재대기중 또는 결재완료된 상태에 있습니다."));
	            //out.println(ServletUtil.getJavaScript("history.back();"));
	            if( MString.isNull(callbackFunc) ) {
	                out.println(ServletUtil.redirect((String) session.getAttribute("modifySuccTargetURI")));
	            } else {
	                out.println(ServletUtil.getJavaScript(callbackFunc));
	            }
	            return;
	        }


			TotReport totReport = pm.getObjectById(TotReport.class, reportID);

			/********** regist **********/
			if ("recog".equals(isRecog)) {
				dynaReportModify(pm, totReport, multi, acptNum, inForm, deptID, repUserID, comment, usrFilenames, svrFilenames,
						appro, tableRows, TotReportProcess.APPROVE);
			} else {
				dynaReportModify(pm, totReport, multi, acptNum, inForm, dtID, usID, comment, usrFilenames, svrFilenames,
						appro, tableRows, TotReportProcess.TEMP);
				//재입력요청일시 제출진행으로 업데이트
				if(totReport.getProcess().ordinal()==3){
					totReport.setProcess(TotReportProcess.TEMP);
				}
			}

			String targetURI = (String) session.getAttribute("modifySuccTargetURI");
			if (targetURI.equals(tempboxMenu.getUrl().toString())) {
				//LOG.info(MoumiConfig.getMessageBundle().getString("moumi.message.tot_report")+ MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.modify")+ MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.success") + "  {}, {}, {}",
						//new Object[] { usID, req.getRemoteAddr(), reportID });
				out.println(ServletUtil.alert(MoumiConfig.getMessageBundle().getString("moumi.message.tot_report")
						+ MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.modify") + MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.complete") +" !\\n \\n" + MoumiConfig.getMessageBundle().getString("moumi.message.popup.reported") + tempboxMenu
						+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.inConfirm")));
			} else {
				//LOG.info(MoumiConfig.getMessageBundle().getString("moumi.message.tot_report") + MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.modify") + MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.success") +"  {}, {}, {}",
						//new Object[] { usID, req.getRemoteAddr(), reportID });
				out.println(ServletUtil.alert(MoumiConfig.getMessageBundle().getString("moumi.message.tot_report")
						+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.saved") + tempboxMenu + MoumiConfig.getMessageBundle().getString("moumi.message.popup.inConfirm")));
			}

			if (totReport.getSlaveTotDoc() != null) {
				TotReportHistory docHistory = new TotReportHistory(totReport, memo);
				pm.makePersistent(docHistory);

				//LOG.info(TotDocType.SUB_DOC + MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.modify") +" {}, {}, {}, {}", new Object[] { usID,
						//totReport.getSlaveTotDoc().getId(), dtID, memo });
			}
			if (totReport.getSlaveTotDoc() != null)
				om.postCommit(); // jeus 6 problem
			tx.commit();
			TotReport savedReport = pm.getObjectById(TotReport.class, reportID);
			//LOG.debug("totReport.data: {}", savedReport.getData());
            if( MString.isNull(callbackFunc) ) {
                out.println(ServletUtil.redirect((String) session.getAttribute("modifySuccTargetURI")));
            }else{
                out.println(ServletUtil.getJavaScript(callbackFunc));
            }
          //수정 이력 추가 시작

			String templateHtml=Excel.adjustFmlaToExcel(TagFilter.removeBlankPara(TotReportUtil.toHTML(totReport)));
			System.out.println("totReport \n" + totReport);
			System.out.println("templateHtml \n" + templateHtml);
			//INSERT시 TO_NUMBER추가 (REPORT.NUM과 VERSION.NUM 형식이 불일치) 2021.11.12이원석
			String sql="INSERT INTO MOUMI_TOT_REPORT_VERSION( "+
				  "ID "+
				  ",REPORT_ID "+
				  ",ACPT_CODE "+
				  ",APPRO "+
				  ",DOC_TYPE "+
				  ",ATTACHMENTS "+
				  ",CURRENT_REPOADM_ID "+
				  ",DATA "+
				  ",DEL_TYPE "+
				  ",DEPT_ID "+
				  ",USER_ID "+
				  ",NOTE "+
				  ",NUM "+
				  ",PRSS "+
				  ",RECOG "+
				  ",REG_DATE "+
				  ",REP_DOC_ID "+
				  ",DOWN_DOC_ID "+
				  ",SUBMIT_DATE "+
				  ",TABLE_NUM "+
				  ",TOT_DATA "+
				  ",DOC_ID "+
				  ",TYPE "+
				  ",MNG_CODE "+
				  ",OWNER_EMAIL "+
				  ",OWNER_NAME "+
				  ",OWNER_PHONE "+
				  ",ACPT_DOC_CODE "+
				  ",SECU_YN "+
				  ",MODIFIER_ID "+
				  ",MODIFIER_NAME "+
				  ",TEMPLATE_HTML "+
				  ",MODIFIER_DEPT_ID "+
				  ",MODIFIER_DEPT_NAME "+
				  ",ATTACHMENTS_PATH "+
					") select "+
				  " SQ_MOUMI.NEXTVAL "+
				  ",ID "+
				  ",ACPT_CODE "+
				  ",APPRO "+
				  ",DOC_TYPE "+
				  ",ATTACHMENTS "+
				  ",CURRENT_REPOADM_ID "+
				  ",DATA "+
				  ",DEL_TYPE "+
				  ",DEPT_ID "+
				  ",USER_ID "+
				  ",NOTE "+
				  ",DECODE(NUM,NULL,0,TO_NUMBER(NUM)) "+
				  ",PRSS "+
				  ",RECOG "+
				  ",SYSDATE "+
				  ",REP_DOC_ID "+
				  ",DOWN_DOC_ID "+
				  ",SUBMIT_DATE "+
				  ",TABLE_NUM "+
				  ",TOT_DATA "+
				  ",DOC_ID "+
				  ",TYPE "+
				  ",MNG_CODE "+
				  ",OWNER_EMAIL "+
				  ",OWNER_NAME "+
				  ",OWNER_PHONE "+
				  ",ACPT_DOC_CODE"+
				  ",SECU_YN "+
				  ",? "+ //로그인아이디
				  ",? "+ //유저이름
				  ",EMPTY_CLOB() "+ // 서식 html
				  ",(select dept_id from moumi_muser where id=?) "+ //로그인아이디
				  ",(select name from moumi_dept where id=(select dept_id from moumi_muser where id=?)) "+//로그인아이디
				  ",ATTACHMENTS_PATH "+
				  "FROM MOUMI_TOT_REPORT where id=?";// tot report id
			// loginid, username ,templatehtml,loginid,loginid,totreportid
			dbmanager.execUpdate(sql,usID,name,usID,usID,totReport.getId());


			String sql1 = " UPDATE MOUMI_TOT_REPORT_VERSION " +
						  " SET TEMPLATE_HTML = ? " +
						  " WHERE ID = (SELECT MAX(ID) FROM MOUMI_TOT_REPORT_VERSION WHERE REPORT_ID = ? )";
			dbmanager.execUpdate(sql1, templateHtml, totReport.getId());
			dbmanager.commit();
			dbmanager.pstmt.close();
			//System.out.println("수정 이력 인서트 "+rsltcnt);
			//수정 이력 추가 끝
		} catch (Exception ex) {
			//dbmanager.rollback();
			if (tx.isActive())
				tx.rollback();

			dbmanager.rollback();
			//LOG.error(MoumiConfig.getMessageBundle().getString("moumi.message.tot_report") + MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.modify") + MoumiConfig.getMessageBundle().getString("moumi.message.tot_doc.fail") +" {}, {}, {}",
					//new Object[] { usID, req.getRemoteAddr(), reportID });
                        //v2. 9.크로스사이트 스크립트 (PrintWrier) : Update by KWON,HAN
//			out.println(ServletUtil.alert(MoumiConfig.getMessageBundle().getString("moumi.message.tot_report")
//					+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.modifyFailAdmin")));

            // 수정 : 외부 입력값 필터링
            String callbackFunc2 = MoumiConfig.getMessageBundle().getString("moumi.message.tot_report")
		     + MoumiConfig.getMessageBundle().getString("moumi.message.popup.modifyFailAdmin");
            String filtered_callbackFunc2 = callbackFunc2.replaceAll("<","").replaceAll(">","").replaceAll("&","").replaceAll(",","");
            LOG.debug("v2 9.크로스사이트 스크립트 (PrintWrier) : HttpReportModifyer.doPost() catch filtered_callbackFunc2={}, Not Test", filtered_callbackFunc2);
            out.println(ServletUtil.alert(filtered_callbackFunc2));
            //========================================

			ex.printStackTrace();
		} finally {
//			try{rset.close();}catch(Exception e){}
			dbmanager.execClose();
			pm.close();

		}
	}

	/************
	 * 보고 등록 ************* return -1 => 실패 return =0 => 변경사항 없음 return >0 => 성공
	 ********************************/
	private void dynaReportModify(PersistenceManager pm, TotReport totReport, MultipartRequest multi, int acptNum, String inForm,
			String dtID, String usID, String comment, String upFileName, String saveFileName, int appro,
			String tableRows, TotReportProcess prss) throws Exception {
		Long formID = totReport.getTotDoc().getId();
		String tableTypes = totReport.getTotDoc().getTotTables().isEmpty() ? "" : totReport.getTotDoc().getTotTables()
				.iterator().next().getTypes();

		Item item = new Item();
		item.getStartInNum(formID);
		int[] itemTypeList = item.getType(formID);
		int[] itemInTypeList = item.getInTypeList(formID);

		String[] tableRowList = tableRows.split(",");
		String[] tableTypeList = tableTypes.split(",");
		int[] tableColNumList = new int[tableTypeList.length]; // 원본 폼의 각 테이블당 몇개의 입력칸이 존재 하는지 그 수 저장

		ItemList itemList = new ItemList();
		itemList.executeQuery(formID);
		String[] itemExprList = itemList.getExprList();
        for(int ii=0;ii<itemExprList.length;ii++) {
        	itemExprList[ii]=itemExprList[ii].replaceAll("=","");
        }
		String[] itemNameList = itemList.getNameList();
		int inItemCount = item.getInCount(formID); // 입력할 수 있는 item count

		int subFpos = 0;
		for (int i = 0; i < tableTypeList.length; i++) {
			String subForm = inForm.substring(subFpos, inForm.indexOf("</table>", subFpos) + 8);
			subFpos = inForm.indexOf("</table>", subFpos) + 8;
			InsertMTable inMTable = new InsertMTable();
			String inBodyForms = "";
			if (tableTypeList[i].equals("1")) {
				inMTable.getInputTitleForm(subForm);
				inBodyForms = inMTable.getInputBodyForm(subForm);
				// 몇개의 입력칸이 존재하는지 숫자 파악
				tableColNumList[i] = inBodyForms.split("<input type").length - 1;
				tableColNumList[i] = tableColNumList[i] + inBodyForms.split("<textarea ").length - 1;
				tableColNumList[i] = tableColNumList[i] + inBodyForms.split("<select ").length - 1;
			} else {
				inBodyForms = subForm.substring(0, subForm.indexOf("</table"));
				// 몇개의 입력칸이 존재하는지 숫자 파악
				tableColNumList[i] = inBodyForms.split("<input type").length - 1;
				tableColNumList[i] = tableColNumList[i] + inBodyForms.split("<textarea ").length - 1;
				tableColNumList[i] = tableColNumList[i] + inBodyForms.split("<select ").length - 1;
			}
			HtmlUtil.getTailForm(subForm);
		}

		int itemSize = 0;
		for (int a = 0; a < tableColNumList.length; a++){
			itemSize = itemSize + tableColNumList[a];
		}

		for (int a = 0; a < tableColNumList.length; a++)
        {
            try {
                tableColNumList[a] = tableColNumList[a] / Integer.parseInt(tableRowList[a]);
            //44.적절하지 않은 예외처리(광범위예외클래스)_CWE-754 Add by YOUNGJUN,CHO
            } catch(NumberFormatException nfex) {
                break;
            //++++++++++++++++++++++++++++++++++++++++++++++++
            } catch(Exception ex) {
                break;
            }
        }

		String[] stItemNameList = MItem.getStartNameList(inForm, itemSize);
		String[] stItemNumList = MItem.getStartNumList(inForm, itemSize);
		String[] inItemNameList = new String[itemSize];

		for (int a = 0; a < itemSize; a++){
			inItemNameList[a] = stItemNameList[a] + stItemNumList[a];
		}

		/*********** Report data values ***********/
		// 기본입력자료
		String[] dataList = MReportData.getDataList(multi, itemInTypeList, inItemNameList, tableColNumList,
				tableRowList);
		String datas = MReportData.getDatas(tableColNumList, tableRowList, dataList).replaceAll("'", "`");

		// 집계입력자료
		String[] totDataList = MReportData.getTotalDataList(itemSize, inItemCount, tableColNumList, tableRowList,
				itemTypeList, itemExprList, dataList, itemNameList);
		String totDatas = MReportData.getTotDatas(tableColNumList, totDataList);

		int tableNum = 1; // Table 별 입력 할 때 사용 예정
		MUser mUser = pm.getObjectById(MUser.class, usID);
		MDept mDept = pm.getObjectById(MDept.class, dtID);

                // 접수번호를 수정 가능하도록 수정함. 2014.12.01 by YOUNGJUN,CHO
                if (acptNum >= 0) {
                    totReport.setAcceptanceCode(new AcceptanceCode(mUser.getUpperDept(pm).getName(), acptNum));
                } else {
                    // 접수번호를 삭제할 경우.
                    totReport.setAcceptanceCode(null);
                }

		totReport.setTableNum(tableNum);
		//결제자 수정시 문서 상태 변경 안함
		//totReport.setUser(mUser);
		//totReport.setDept(mDept);
		//totReport.setProcess(prss);
		totReport.setData(datas);
		//LOG.debug("is report data null? {}", datas == null);
		totReport.setTotData(totDatas);
		totReport.setAppro(appro);
		totReport.setNote(comment);
//		FileUtil.putInFiles(saveFileName, totReport);
		pm.makePersistent(totReport);
//        FileUtil.delUpFiles(saveFileName, totReport);//물리 디렉토리에서 첨부파일 삭제
	}
}
