
package nccloud.impl.pub.ace;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONArray;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.impl.pubapp.pattern.data.bill.BillLazyQuery;
import nc.impl.pubapp.pattern.data.bill.tool.BillTransferTool;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.ui.querytemplate.querytree.IQueryScheme;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.hi.psndoc.Glbdef3VO;
import nc.vo.hrkq.monthottime.AggMonthOtTimeVO;
import nc.vo.hrkq.monthottime.MonthOtTimeBVO;
import nc.vo.hrkq.monthottime.MonthOtTimeVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pub.pf.BillStatusEnum;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nccloud.bs.hrkq.hrkq.aggbusi.ace.bp.AceMonthOtTimeVOApproveBP;
import nccloud.bs.hrkq.hrkq.aggbusi.ace.bp.AceMonthOtTimeVODeleteBP;
import nccloud.bs.hrkq.hrkq.aggbusi.ace.bp.AceMonthOtTimeVOInsertBP;
import nccloud.bs.hrkq.hrkq.aggbusi.ace.bp.AceMonthOtTimeVOSendApproveBP;
import nccloud.bs.hrkq.hrkq.aggbusi.ace.bp.AceMonthOtTimeVOUnApproveBP;
import nccloud.bs.hrkq.hrkq.aggbusi.ace.bp.AceMonthOtTimeVOUnSendApproveBP;
import nccloud.bs.hrkq.hrkq.aggbusi.ace.bp.AceMonthOtTimeVOUpdateBP;

public abstract class AceAggbusiMonthOtTimeVOPubServiceImpl {
        // 新增
        public AggMonthOtTimeVO[] pubinsertBills(AggMonthOtTimeVO[] clientFullVOs,
                        AggMonthOtTimeVO[] originBills) throws BusinessException {
                try {
                        // 数据库中数据和前台传递过来的差异VO合并后的结果
                        BillTransferTool<AggMonthOtTimeVO> transferTool = new BillTransferTool<AggMonthOtTimeVO>(
                                        clientFullVOs);
                        // 调用BP
                        AceMonthOtTimeVOInsertBP action = new AceMonthOtTimeVOInsertBP();
                        AggMonthOtTimeVO[] retvos = action.insert(clientFullVOs);
                        // 构造返回数据
//                      return transferTool.getBillForToClient(retvos);
                        return retvos;
                } catch (Exception e) {
                        ExceptionUtils.marsh(e);
                }
                return null;
        }

        // 删除
        public void pubdeleteBills(AggMonthOtTimeVO[] clientFullVOs,
                        AggMonthOtTimeVO[] originBills) throws BusinessException {
                try {
                        // 调用BP
                        new AceMonthOtTimeVODeleteBP().delete(clientFullVOs);
                } catch (Exception e) {
                        ExceptionUtils.marsh(e);
                }
        }

        // 修改
        public AggMonthOtTimeVO[] pubupdateBills(AggMonthOtTimeVO[] clientFullVOs,
                        AggMonthOtTimeVO[] originBills) throws BusinessException {
                try {
                        // 加锁 + 检查ts
                        BillTransferTool<AggMonthOtTimeVO> transferTool = new BillTransferTool<AggMonthOtTimeVO>(
                                        clientFullVOs);
                        AceMonthOtTimeVOUpdateBP bp = new AceMonthOtTimeVOUpdateBP();
                        AggMonthOtTimeVO[] retvos = bp.update(clientFullVOs, originBills);
                        // 构造返回数据
//                      return transferTool.getBillForToClient(retvos);
                        return retvos;
                } catch (Exception e) {
                        ExceptionUtils.marsh(e);
                }
                return null;
        }

        public AggMonthOtTimeVO[] pubquerybills(IQueryScheme queryScheme)
                        throws BusinessException {
                AggMonthOtTimeVO[] bills = null;
                try {
                        this.preQuery(queryScheme);
                        BillLazyQuery<AggMonthOtTimeVO> query = new BillLazyQuery<AggMonthOtTimeVO>(
                                        AggMonthOtTimeVO.class);
                        bills = query.query(queryScheme, null);
                } catch (Exception e) {
                        ExceptionUtils.marsh(e);
                }
                return bills;
        }

        /**
         * 由子类实现，查询之前对queryScheme进行加工，加入自己的逻辑
         * 
         * @param queryScheme
         */
        protected void preQuery(IQueryScheme queryScheme) {
                // 查询之前对queryScheme进行加工，加入自己的逻辑
        }

        // 提交
        public AggMonthOtTimeVO[] pubsendapprovebills(
                        AggMonthOtTimeVO[] clientFullVOs, AggMonthOtTimeVO[] originBills)
                        throws BusinessException {
                AceMonthOtTimeVOSendApproveBP bp = new AceMonthOtTimeVOSendApproveBP();
                AggMonthOtTimeVO[] retvos = bp.sendApprove(clientFullVOs, originBills);
                return retvos;
        }

        // 收回
        public AggMonthOtTimeVO[] pubunsendapprovebills(
                        AggMonthOtTimeVO[] clientFullVOs, AggMonthOtTimeVO[] originBills)
                        throws BusinessException {
                AceMonthOtTimeVOUnSendApproveBP bp = new AceMonthOtTimeVOUnSendApproveBP();
                AggMonthOtTimeVO[] retvos = bp.unSend(clientFullVOs, originBills);
                return retvos;
        };

        // 审批
        public AggMonthOtTimeVO[] pubapprovebills(AggMonthOtTimeVO[] clientFullVOs,
                        AggMonthOtTimeVO[] originBills) throws BusinessException {
                for (int i = 0; clientFullVOs != null && i < clientFullVOs.length; i++) {
                        clientFullVOs[i].getParentVO().setStatus(VOStatus.UPDATED);
                }
                AceMonthOtTimeVOApproveBP bp = new AceMonthOtTimeVOApproveBP();
                AggMonthOtTimeVO[] retvos = bp.approve(clientFullVOs, originBills);
                //回写子表信息
                this.sendPsnSub(retvos);
                return retvos;
        }

        // 弃审

        public AggMonthOtTimeVO[] pubunapprovebills(AggMonthOtTimeVO[] clientFullVOs,
                        AggMonthOtTimeVO[] originBills) throws BusinessException {
                for (int i = 0; clientFullVOs != null && i < clientFullVOs.length; i++) {
                        clientFullVOs[i].getParentVO().setStatus(VOStatus.UPDATED);
                }
                AceMonthOtTimeVOUnApproveBP bp = new AceMonthOtTimeVOUnApproveBP();
                AggMonthOtTimeVO[] retvos = bp.unApprove(clientFullVOs, originBills);
                return retvos;
        }
        
        /**
         * 回写人员信息集子表数据
         * @param aggvos
         */
        public void sendPsnSub(AggMonthOtTimeVO[] aggvos) {
        	if(aggvos.length > 0) {
        		List<Glbdef3VO> voList = new ArrayList<>();
        		for(AggMonthOtTimeVO aggvo : aggvos) {
        			//审批通过才回写
        			int approvestatus = (int) aggvo.getParentVO().getAttributeValue(MonthOtTimeVO.APPROVESTATUS);
        			if(BillStatusEnum.APPROVED.toIntValue() == approvestatus) {
//            			String pk_psndoc = (String) aggvo.getParentVO().getAttributeValue(MonthOtTimeVO.PK_PSNDOC);
            			String pk_monthottime = (String) aggvo.getParentVO().getAttributeValue(MonthOtTimeVO.PK_MONTHOTTIME);
            			List<Glbdef3VO> glList = covertGlbdef3VOS(pk_monthottime);
            			voList.addAll(glList);
        			}
        		}
        		if(voList.size() > 0) {
        			List<Glbdef3VO> insertList = new ArrayList<>();
        			List<Glbdef3VO> updateList = new ArrayList<>();
        			for(Glbdef3VO vo : voList) {
        				if("@@".equals(vo.getPk_psndoc_sub())) {
        					insertList.add(vo);
        				}else if(StringUtils.isNotBlank(vo.getPk_psndoc_sub())) {
        					updateList.add(vo);
        				}
        			}
        			try {
	        			//更新
	        			if(updateList.size() > 0) {
							getBaseDAO().updateVOList(updateList);
	        			}
	        			//新增
	        			if(insertList.size() > 0) {
	        				getBaseDAO().insertVOList(insertList);
	        			}
        			} catch (DAOException e) {
						e.printStackTrace();
					}
        		}
        	}
        }

        private BaseDAO baseDAO;
        
        public BaseDAO getBaseDAO() {
        	if(baseDAO == null) {
        		baseDAO = new BaseDAO();
        	}
        	return baseDAO;
        }
        
        public List<Glbdef3VO> covertGlbdef3VOS(String pk_monthottime){
        	List<Glbdef3VO> list = new ArrayList();
        	StringBuffer sqlstr=new StringBuffer("");
        	sqlstr.append("select viewtemp.pk_psndoc_sub,").append("\r\n");
        	sqlstr.append("       viewtemp.pk_psndoc,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef1,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef2,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef3 + nvl(glbdef3.glbdef3,0) glbdef3,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef4 + nvl(glbdef3.glbdef4,0) glbdef4,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef5 + nvl(glbdef3.glbdef5,0) glbdef5,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef6 + nvl(glbdef3.glbdef6,0) glbdef6,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef7 + nvl(glbdef3.glbdef7,0) glbdef7,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef8 + nvl(glbdef3.glbdef8,0) glbdef8,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef9 + nvl(glbdef3.glbdef9,0) glbdef9,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef10 + nvl(glbdef3.glbdef10,0) glbdef10,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef11 + nvl(glbdef3.glbdef11,0) glbdef11,").append("\r\n");
        	sqlstr.append("       viewtemp.glbdef12 + nvl(glbdef3.glbdef12,0) glbdef12").append("\r\n");
        	sqlstr.append("       from (select").append("\r\n");
        	sqlstr.append("       nvl(hi_psndoc_glbdef3.pk_psndoc_sub,'@@') pk_psndoc_sub,").append("\r\n");
        	sqlstr.append("       nvl(hi_psndoc_glbdef3.pk_psndoc,hrkq_monthottime.pk_psndoc) pk_psndoc,").append("\r\n");
        	sqlstr.append("       substr(hrkq_monthottime_b.otdate,0,4) glbdef1,").append("\r\n");
        	sqlstr.append("       substr(hrkq_monthottime_b.otdate,6,2) glbdef2,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'1',decode(ottimestypedoc.code,'01',nvl(hrkq_monthottime_b.otcosthours,0),0),0)) glbdef3,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'1',decode(ottimestypedoc.code,'02',nvl(hrkq_monthottime_b.otcosthours,0),0),0)) glbdef4,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'1',decode(ottimestypedoc.code,'03',nvl(hrkq_monthottime_b.otcosthours,0),0),0)) glbdef5,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'1',decode(ottimestypedoc.code,'04',nvl(hrkq_monthottime_b.otcosthours,0),0),0)) glbdef6,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'2',decode(otdatetypedoc.code,'01',nvl(hrkq_monthottime_b.otcosthours,0),0),0)) glbdef7,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'2',decode(otdatetypedoc.code,'02',nvl(hrkq_monthottime_b.otcosthours,0),0),0)) glbdef8,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'2',decode(otdatetypedoc.code,'03',nvl(hrkq_monthottime_b.otcosthours,0),0),0)) glbdef9,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'2',decode(otdatetypedoc.code,'01',nvl(hrkq_monthottime_b.leavehours,0),0),0)) glbdef10,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'2',decode(otdatetypedoc.code,'02',nvl(hrkq_monthottime_b.leavehours,0),0),0)) glbdef11,").append("\r\n");
        	sqlstr.append("       sum(decode(hrkq_monthottime.otapplytype,'2',decode(otdatetypedoc.code,'03',nvl(hrkq_monthottime_b.leavehours,0),0),0)) glbdef12").append("\r\n");
        	sqlstr.append("        from hrkq_monthottime_b").append("\r\n");
        	sqlstr.append("       left join hrkq_monthottime").append("\r\n");
        	sqlstr.append("            on hrkq_monthottime.pk_monthottime = hrkq_monthottime_b.pk_monthottime").append("\r\n");
        	sqlstr.append("       left join bd_defdoc ottimestypedoc").append("\r\n");
        	sqlstr.append("            on ottimestypedoc.pk_defdoc = hrkq_monthottime_b.ottimestype").append("\r\n");
        	sqlstr.append("       left join bd_defdoc otdatetypedoc").append("\r\n");
        	sqlstr.append("            on otdatetypedoc.pk_defdoc = hrkq_monthottime_b.otdatetype").append("\r\n");
        	sqlstr.append("       left join hi_psndoc_glbdef3").append("\r\n");
        	sqlstr.append("            on hi_psndoc_glbdef3.pk_psndoc = hrkq_monthottime.pk_psndoc").append("\r\n");
        	sqlstr.append("            and substr(hrkq_monthottime_b.otdate,0,4) = hi_psndoc_glbdef3.glbdef1").append("\r\n");
        	sqlstr.append("            and substr(hrkq_monthottime_b.otdate,6,2) = hi_psndoc_glbdef3.glbdef2").append("\r\n");
        	sqlstr.append("       where nvl(hrkq_monthottime.dr,0) = 0 and nvl(hrkq_monthottime_b.dr,0) = 0").append("\r\n");
        	sqlstr.append("             and hrkq_monthottime.pk_monthottime = '"+pk_monthottime+"'").append("\r\n");
        	sqlstr.append("       group by").append("\r\n");
        	sqlstr.append("             nvl(hi_psndoc_glbdef3.pk_psndoc_sub,'@@'),").append("\r\n");
        	sqlstr.append("             nvl(hi_psndoc_glbdef3.pk_psndoc,hrkq_monthottime.pk_psndoc),").append("\r\n");
        	sqlstr.append("             substr(hrkq_monthottime_b.otdate,0,4),").append("\r\n");
        	sqlstr.append("             substr(hrkq_monthottime_b.otdate,6,2)) viewtemp").append("\r\n");
        	sqlstr.append("       left join hi_psndoc_glbdef3 glbdef3").append("\r\n");
        	sqlstr.append("                  on glbdef3.pk_psndoc_sub = viewtemp.pk_psndoc_sub"); 

        	try {
        		list = (List<Glbdef3VO>) getBaseDAO().executeQuery(sqlstr.toString(), new BeanListProcessor(Glbdef3VO.class));
			} catch (DAOException e) {
				e.printStackTrace();
			}
        	return list;
        }
        
		public List<Map<String, UFDate>> queryHoliday(String pk_psndoc, String pk_org) throws BusinessException {
			List<Map<String, UFDate>> result = new ArrayList();
			

			//查询按人来分配的节假日时间
			String sql = "select ts_holiday.* from ts_holiday\n" +
				"       left join ts_working_calendar\n" + 
				"            on ts_working_calendar.id = ts_holiday.parentid\n" + 
				"       left join ts_attend_rule\n" + 
				"            on ts_attend_rule.work_calendar_id = ts_working_calendar.id\n" + 
				"       left join ts_rule_scope_psn\n" + 
				"            on ts_rule_scope_psn.attend_rule_id = ts_attend_rule.id\n" + 
				"      where ts_rule_scope_psn.staff_id = '"+pk_psndoc+"'";
			
			List<Map<String,Object>> list = (List<Map<String, Object>>) getBaseDAO().executeQuery(sql, new MapListProcessor());
			
			if(list != null && list.size() > 0) {
				
			} else {
				//查询按组织来分配的节假日时间
				sql = "select ts_holiday.* from ts_holiday\n" +
						"       left join ts_working_calendar\n" + 
						"            on ts_working_calendar.id = ts_holiday.parentid\n" + 
						"       left join ts_attend_rule\n" + 
						"            on ts_attend_rule.work_calendar_id = ts_working_calendar.id\n" + 
						"       left join ts_rule_scope_org\n" + 
						"            on ts_rule_scope_org.attend_rule_id = ts_attend_rule.id\n" + 
						"      where ts_rule_scope_org.org_id = '"+pk_org+"'";
				list = (List<Map<String, Object>>) getBaseDAO().executeQuery(sql, new MapListProcessor());
			}
			
			if(list != null && list.size() > 0) {
				for(Map<String,Object> map : list) {
					Map<String, UFDate> dataMap = new HashMap();
					UFDate begintime = new UFDate(map.get("begintime").toString());
					UFDate endtime = new UFDate(map.get("endtime").toString());
					if(map.get("legalholiday") != null) {
						String legalholiday = map.get("legalholiday").toString();
						JSONArray arrjson = JSONArray.parseArray(legalholiday);
						if(!arrjson.isEmpty()) {
							for(int i=0; i < arrjson.size(); i++) {
								long begin = arrjson.getLongValue(i);
								dataMap.put("begintime", new UFDate(begin));
								dataMap.put("endtime", new UFDate(new UFDate(begin).toString().substring(0,10) + " 23:59:59"));
								result.add(dataMap);
							}
						}
					}
				}
			}
			return result;
		}
		
		public List<String> queryDefdoc() throws BusinessException {
			String sql = "select pk_defdoc from bd_defdoc where pk_defdoclist in ('1001ZZ100000000I3UTT','1001ZZ100000000I3UTU') and name = '节假日'";
			return (List<String>) getBaseDAO().executeQuery(sql, new ColumnListProcessor());
		}
		
		public List<DefdocVO> queryDefdoc2() throws BusinessException {
			String sql = "select * from bd_defdoc where pk_defdoclist in ('1001ZZ100000000I3UTT','1001ZZ100000000I3UTU')";
			return (List<DefdocVO>) getBaseDAO().executeQuery(sql, new BeanListProcessor(DefdocVO.class));
		}
		
		public Map<String, UFDouble> queryMonth(String pk_psndoc) throws BusinessException {
			Map<String, UFDouble> resultMap = new HashMap();
			String sql = "select sum(nvl(hrkq_monthottime_b.othours,0)) othours,substr(hrkq_monthottime_b.otdate,0,7) otdate from hrkq_monthottime_b\n" +
							"       left join hrkq_monthottime\n" + 
							"            on hrkq_monthottime_b.pk_monthottime = hrkq_monthottime.pk_monthottime\n" + 
							"       where nvl(hrkq_monthottime_b.dr,0) = 0 and nvl(hrkq_monthottime.dr,0) = 0\n" + 
							"       and hrkq_monthottime.otapplytype = 2 and hrkq_monthottime.pk_psndoc = '"+pk_psndoc+"'\n" + 
							"       and hrkq_monthottime.approvestatus in('1','2','3')\n" + 
							"       group by substr(hrkq_monthottime_b.otdate,0,7)";
			List<Map<String,Object>> listMap = (List<Map<String, Object>>) getBaseDAO().executeQuery(sql, new MapListProcessor());
			if(listMap != null && listMap.size() > 0) {
				for(Map<String,Object> map :listMap) {
					resultMap.put(map.get("otdate").toString(), new UFDouble(map.get("othours").toString()));
				}
			}
			return resultMap;
		}

		public List<MonthOtTimeBVO> queryBVOByPkPsndoc(String pk_psndoc) throws BusinessException {
			String sql = "select hrkq_monthottime_b.* from hrkq_monthottime_b\n" +
					"       left join hrkq_monthottime\n" + 
					"            on hrkq_monthottime_b.pk_monthottime = hrkq_monthottime.pk_monthottime\n" + 
					"       where nvl(hrkq_monthottime_b.dr,0) = 0 and nvl(hrkq_monthottime.dr,0) = 0\n" + 
					"       and hrkq_monthottime.pk_psndoc = '"+pk_psndoc+"' and hrkq_monthottime.approvestatus in('-1','1','2','3')";
			return (List<MonthOtTimeBVO>) getBaseDAO().executeQuery(sql, new BeanListProcessor(MonthOtTimeBVO.class));
		}
			
}