package nc.ui.hr.baod_orders.ace.handler;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;

import nc.bs.framework.common.NCLocator;
import nc.hr.utils.SpecialDataUtil;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.ui.hr.baod_orders.view.ShowMoneyDialog;
import nc.ui.pubapp.uif2app.event.IAppEventHandler;
import nc.ui.pubapp.uif2app.event.card.CardHeadTailAfterEditEvent;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;

/**
 * 单据表头表尾字段编辑后事件处理类
 * 
 * @since 6.0
 * @version 2011-7-7 下午02:52:22
 * @author duy
 */
public class AceHeadTailAfterEditHandler implements IAppEventHandler<CardHeadTailAfterEditEvent> {

	private IUAPQueryBS bs = NCLocator.getInstance().lookup(IUAPQueryBS.class);
	private SimpleDateFormat sdf = new  SimpleDateFormat("yyyy-MM-dd");
    @Override
    public void handleAppEvent(CardHeadTailAfterEditEvent e) {
    	try {
    		String key = e.getKey();
    		if ("clerkcode".equals(key)) {
    			emptyData(e);	
    			// 获取当前员工号主键
    			String pk_id =  (String) e.getBillCardPanel().getHeadItem("clerkcode").getValueObject();
    	 		if(pk_id != null) {
	       	 		Map<String,String> psnjobmap = getPsnjobByID(pk_id);
	       	 		//姓名
	       	 		e.getBillCardPanel().setHeadItem("clerkname", getPsnName(pk_id));
	       	 		//所在公司
	    	    	e.getBillCardPanel().setHeadItem("def1", psnjobmap.get("hrorgname"));
	   	    	 	//所在部门
	   	    	 	e.getBillCardPanel().setHeadItem("deptname", psnjobmap.get("deptname"));
	   	    	 	//主职岗位
	   	    	 	e.getBillCardPanel().setHeadItem("postname", psnjobmap.get("postname"));
	   	    	 	//保底类型
	   	    	 	//e.getBillCardPanel().setHeadItem("bdtype", psnjobmap.get("bdtype"));
    	 		}
    		}
    		//保底开始周期
    		if("start_cycle".equals(key)) {
		    	specialData(e,"start_cycle");   	 		
		   	 }
    		//保底截止周期
		    if("finish_cycle".equals(key)) {
		    	specialData(e,"finish_cycle");	
		   	 }  
    	} catch (Exception e2) {
    		ExceptionUtils.wrappBusinessException(""+e2.getMessage());
    	}	
   }
    
   //本次保底周期内请假，完成工作天数赋值
    public void specialData(CardHeadTailAfterEditEvent e,String str) throws Exception {
    	//获取当前员工号主键
    	String clerkcode =  (String) e.getBillCardPanel().getHeadItem("clerkcode").getValueObject(); 	
    	//本次保底开始周期
    	UFDate start_cycle = (UFDate) e.getBillCardPanel().getHeadItem("start_cycle").getValueObject();  	
    	//本次保底截止周期
    	UFDate finish_cycle = (UFDate) e.getBillCardPanel().getHeadItem("finish_cycle").getValueObject();  
    	//员工号、本次保底开始周期、本次保底截止周期都必须填写
    	if(clerkcode != null   && start_cycle != null && finish_cycle != null) {
    		//将日期去除时分秒用于后续比较
    		String start_cycles = start_cycle.toString().substring(0, 10);
    		String finish_cycles = finish_cycle.toString().substring(0, 10);
    		UFDate bdaccepted_period = null;
    		UFDate def2 = null;
	    	UFDate def3 = null;
	    	int def4 = 0;
	    	UFDouble bdaccepted_mount = new UFDouble(UFDouble.ZERO_DBL);
	   	 	List<Map<String,String>> bdmap = getbdData(clerkcode);
	   	 	//时间区间内匹配的保底数据
	   	 	List<Map<String,String>> listmap =  new ArrayList<Map<String,String>>();
	   	 	//本次保底金额
	   	 	UFDouble bdamount = new UFDouble(UFDouble.ZERO_DBL);
	   	 	UFDate bdcontract_period =  null; 
	   	 	String bdtype = "公司决策承诺";
	   	 	//循环保底信息数据
	   	 	for (int i = 0; i < bdmap.size(); i++) {
	   	 		Map<String,String> map = bdmap.get(i);
	   	 		//开始日期
	   	 		UFDate begindate = new UFDate(map.get("begindate"));
	   	 		//结束日期
	   	 		UFDate glbdef7 = new UFDate(map.get("glbdef7"));
	   	 		//本次保底开始时间小于等于结束时间，本次保底截止时间大于等于开始时间
	   	 		if(start_cycle.compareTo(glbdef7) <= 0 && finish_cycle.compareTo(begindate) >= 0) {
	   	 			bdtype = "已签约保底合同";
	   	 			listmap.add(map);
	   	 			bdamount = new UFDouble(String.valueOf(map.get("glbdef2")));
	   	 			//初始化日期
	   	 			if(bdcontract_period == null) {
	   	 				bdcontract_period = begindate;
	   	 				def2 = glbdef7;
	   	 			}
	   	 			// 检查开始日期是否小于当前循环开始日期，如果是，则将开始日期更新为当前循环开始日期
	   	 			if(bdcontract_period.compareTo(begindate) == 1) {
	   	 				bdcontract_period = begindate;
	   	 			}
	   	 			
	   	 			// 检查结束日期是否大于当前循环结束日期，如果是，则将结束日期更新为当前结束开始日期
	   	 			if(def2.compareTo(glbdef7) == -1) {
	   	 				def2 = glbdef7;
	   	 			}
	   	 		}
			}
	   	 	//保底类型
	    	e.getBillCardPanel().setHeadItem("bdtype", bdtype);
	   	 
	   	 	//如果保底数据大于1条保底金额由制单人手工填写,或者等于0条表示总经理口头承诺保底，金额由制单人手工填写
	   	 	if(listmap.size() == 0 ||listmap.size() >= 2) {
	   	 		new ShowMoneyDialog(e,listmap).showModal();
	   	 	}else {
	   	 		//保底合同开始周期
		   	 	e.getBillCardPanel().setHeadItem("bdcontract_period", bdcontract_period);
		   	 	//保底合同截止周期
		   	 	e.getBillCardPanel().setHeadItem("def2", def2);
	   	 		//保底金额
		   	 	e.getBillCardPanel().setHeadItem("bdamount", bdamount.multiply(10000));
		   	 	//保底金额不可修改，用于后续保底金额判断
		   	 	e.getBillCardPanel().setHeadItem("def11", bdamount.multiply(10000));
	   	 	}
	   	 	//已发奖金工作开始日期
	   	 	UFDate def7 = (UFDate) e.getBillCardPanel().getHeadItem("def7").getValueObject();
	   	 	//如果已发奖金工作开始日期等于空才做赋处理，避免重复查询和将已发奖金工作开始日期又赋值空
	   	 	if(def7 == null) {
	   	 		e.getBillCardPanel().setHeadItem("def7", getDate(clerkcode));
	   	 	}
	    	//保底合同周期内已保底数据
	    	List<Map<String,String>> listMap = GetbdDateOrMoney(clerkcode,start_cycles,finish_cycles);
	    	//保底合同周期内已保底数据等于空，保底合同周期内已保底日期为空，金额为0
	    	for (int i = 0; i < listMap.size(); i++) {
	    		Map<String,String> map = listMap.get(i);
	    		//开始日期
	    		UFDate begindate = new UFDate(map.get("begindate"));
    	 		//结束日期
    	 		UFDate enddate = new UFDate(map.get("enddate"));
    	 		//增加保底完成次数
	 			def4 ++;
	 			///初始化日期
	 			if(bdaccepted_period == null) {
	 				bdaccepted_period = begindate;
	 				def3 = enddate;
	 			}
	 			// 检查开始日期是否小于当前循环开始日期，如果是，则将开始日期更新为当前循环开始日期
	 			if(bdaccepted_period.compareTo(begindate) == 1) {
	 				bdaccepted_period = begindate;
	 			}
	 			// 检查结束日期是否大于当前循环结束日期，如果是，则将结束日期更新为当前结束开始日期
	 			if(def3.compareTo(enddate) == -1) {
	 				def3 = enddate;
	 			}
    	 		//合计保底合同周期内已保底金额
    	 		bdaccepted_mount = bdaccepted_mount.add(new UFDouble(String.valueOf(map.get("money"))));
			}
   	    	//保底合同周期内已保底开始日期
   	    	e.getBillCardPanel().setHeadItem("bdaccepted_period", bdaccepted_period);
   	    	//保底合同周期内已保底截至日期
   	    	e.getBillCardPanel().setHeadItem("def3", def3);
   	    	//保底合同周期内已保底金额
   	    	e.getBillCardPanel().setHeadItem("bdaccepted_mount", bdaccepted_mount);
   	    	//保底完成次数
   	    	e.getBillCardPanel().setHeadItem("def4", def4);
   	    	//将三个时间的时分秒去掉用于后续比较
   	    	if(bdcontract_period != null && def2!= null && finish_cycles!= null) {
	   	    	UFDate bdcontract_periodDate = new UFDate(bdcontract_period.toString().substring(0, 10));
	   	    	UFDate def2Date = new UFDate(def2.toString().substring(0, 10));
	   	    	UFDate finish_cycleDate = new UFDate(finish_cycles);
	    		if(finish_cycleDate.compareTo(bdcontract_periodDate) == -1) {
	    			e.getBillCardPanel().setHeadItem(str, null);
	        		ExceptionUtils.wrappBusinessException("本次保底截止时间需大于等于保底合同开始时间！");
	        	}
	        	if(finish_cycleDate.compareTo(def2Date) == 1) {
	        		e.getBillCardPanel().setHeadItem(str, null);
	        		ExceptionUtils.wrappBusinessException("本次保底截止时间需小于等于保底合同截止时间!");
	        	}
   	    	}
    		JSONObject jsonObject = SpecialDataUtil.getWorkDays(start_cycles, finish_cycles, clerkcode);
    		//本次保底周期内请假工作天数
    		UFDouble leave_days = new UFDouble(UFDouble.ZERO_DBL);
    		//本次保底周期内实际完成工作天数
    		UFDouble work_days = new UFDouble(UFDouble.ZERO_DBL);
    		if("1".equals(jsonObject.getString("code"))) {
    			JSONObject data = jsonObject.getJSONObject("data");
    			leave_days = new UFDouble(data.getString("leaveday"));
    			work_days = new UFDouble(data.getString("workday"));
    			e.getBillCardPanel().setHeadItem("leave_days", leave_days);
    			e.getBillCardPanel().setHeadItem("work_days", work_days);
    		}else {
    			e.getBillCardPanel().setHeadItem(str, null);
    			ExceptionUtils.wrappBusinessException("获取请假天数失败:"+jsonObject.get("msg"));
    		}
    		Object startDate = e.getBillCardPanel().getHeadItem("bdcontract_period").getValueObject();
    		Object endDate = e.getBillCardPanel().getHeadItem("def2").getValueObject();
    	   	if(startDate != null && endDate!= null) {
    	   		//获取保底合同周期计薪天数
    	   		JSONObject jsonData = SpecialDataUtil.getWorkDays(startDate.toString().substring(0, 10), endDate.toString().substring(0, 10), clerkcode);
    	   		if("1".equals(jsonData.getString("code"))) {
	    	   		JSONObject data = jsonData.getJSONObject("data");
	    	   		UFDouble leaveday = new UFDouble(data.getString("leaveday"));
	    	   		UFDouble workday = new UFDouble(data.getString("workday"));
	    	   		//计薪天数 = 工作天数+请假天数
	    	   		e.getBillCardPanel().setHeadItem("def9", leaveday.add(workday));
	    	   	}else {
	    	   		ExceptionUtils.wrappBusinessException("获取保底合同周期计薪天数失败:"+jsonObject.get("msg"));
	    	   	}
    	   	}
    	}
    }
    
    //根据人员ID查人员名称
    public String getPsnName(String pk_id) throws BusinessException {
    	String sql = "select name from bd_psndoc where pk_psndoc = '"+pk_id+"'";
		return (String) bs.executeQuery(sql, new ColumnProcessor());
    	
    }

   //根据人员ID查询人员对应组织，部门，岗位信息
   public Map<String,String> getPsnjobByID(String pk_id) throws BusinessException{
	   StringBuffer sql = new StringBuffer();
	   sql.append("SELECT");
	   sql.append(" hi_psnjob.clerkcode as clerkcode,");
	   sql.append(" bd_psndoc.name as name,");
	   sql.append(" org_hrorg.name AS hrorgname,");
	   sql.append(" org_dept.name AS deptname,");
	   sql.append(" om_post.postname AS postname");
	   sql.append(" FROM");
	   sql.append(" hi_psnjob hi_psnjob");
	   sql.append(" LEFT JOIN bd_psndoc bd_psndoc ON hi_psnjob.pk_psndoc = bd_psndoc.pk_psndoc");
	   sql.append(" LEFT JOIN org_hrorg org_hrorg ON hi_psnjob.pk_hrorg = org_hrorg.pk_hrorg");
	   sql.append(" LEFT JOIN org_dept org_dept ON hi_psnjob.pk_dept = org_dept.pk_dept");
	   sql.append(" LEFT JOIN om_post om_post ON hi_psnjob.pk_post = om_post.pk_post");
	   sql.append(" WHERE");
	   sql.append(" hi_psnjob.lastflag = 'Y' ");
	   sql.append(" AND hi_psnjob.endflag = 'N' ");
	   sql.append(" AND hi_psnjob.ismainjob = 'Y' ");
	   sql.append(" AND hi_psnjob.pk_psndoc = '"+pk_id+"'");
	   Map<String, String> psnjobmap = (Map<String, String>) bs.executeQuery(sql.toString(), new MapProcessor());
	   //为空添加默认值
	   if(psnjobmap == null) {
		   Map<String, String> map = new HashMap<String, String>(); 
		   map.put("hrorgname", null);
		   map.put("deptname", null);
		   map.put("deptname", null);
		   map.put("bdtype", "公司决策承诺");
		   psnjobmap = map;	
	   }else {
   			psnjobmap.put("bdtype", "已签约保底合同");
	   }
		return psnjobmap;
   }
   
   //根据员工号查询人员对应组织，部门，岗位信息
   public Map<String,String> getPsnjobByCode(String code) throws BusinessException{
	   StringBuffer sql = new StringBuffer();
	   sql.append("SELECT");
	   sql.append(" hi_psnjob.pk_psndoc AS pk_psndoc,");
	   sql.append(" org_hrorg.name AS hrorgname,");
	   sql.append(" org_dept.name AS deptname,");
	   sql.append(" om_post.postname AS postname");
	   sql.append(" FROM");
	   sql.append(" hi_psnjob hi_psnjob");
	   sql.append(" LEFT JOIN org_hrorg org_hrorg ON hi_psnjob.pk_hrorg = org_hrorg.pk_hrorg");
	   sql.append(" LEFT JOIN org_dept org_dept ON hi_psnjob.pk_dept = org_dept.pk_dept");
	   sql.append(" LEFT JOIN om_post om_post ON hi_psnjob.pk_post = om_post.pk_post");
	   sql.append(" WHERE");
	   sql.append(" hi_psnjob.lastflag = 'Y' ");
	   sql.append(" AND hi_psnjob.endflag = 'N' ");
	   sql.append(" AND hi_psnjob.ismainjob = 'Y' ");
	   sql.append(" AND hi_psnjob.clerkcode = '"+code+"'");
	   Map<String, String> psnjobmap = (Map<String, String>) bs.executeQuery(sql.toString(), new MapProcessor());
	   //为空添加默认值
	   if(psnjobmap == null) {
		   Map<String, String> map = new HashMap<String, String>(); 
		   map.put("hrorgname", null);
		   map.put("deptname", null);
		   map.put("deptname", null);
		   map.put("bdtype", "公司决策承诺");
		   psnjobmap = map;	
	   }else {
		   psnjobmap.put("bdtype", "已签约保底合同");
	   }
		return psnjobmap;
   }
   
   //查询人员对应的保底信息
   public List<Map<String, String>> getbdData(String clerkcode)throws BusinessException{
	   String sql ="SELECT BEGINDATE,ENDDATE,GLBDEF2,GLBDEF7 FROM hi_psndoc_glbdef15 WHERE  pk_psndoc = '"+clerkcode+"' AND GLBDEF6 = 'Y' ";
	   List<Map<String, String>> bdmap = (List<Map<String, String>>) bs.executeQuery(sql.toString(), new MapListProcessor());
	   return bdmap;   
   }
   
   //变更人员后先清空表单数据
   public void emptyData(CardHeadTailAfterEditEvent e)throws BusinessException{
	   e.getBillCardPanel().setHeadItem("attrname", null);
	   e.getBillCardPanel().setHeadItem("bdaccepted_mount", null);
	   e.getBillCardPanel().setHeadItem("bdaccepted_period", null);
	   e.getBillCardPanel().setHeadItem("bdamount", null);
	   e.getBillCardPanel().setHeadItem("bdcontract_period", null);
	   e.getBillCardPanel().setHeadItem("bdtype", null);
	   e.getBillCardPanel().setHeadItem("clerkname", null);
	   e.getBillCardPanel().setHeadItem("days_ratio", null);
	   e.getBillCardPanel().setHeadItem("def1", null);
	   e.getBillCardPanel().setHeadItem("def2", null);
	   e.getBillCardPanel().setHeadItem("def3", null);
	   e.getBillCardPanel().setHeadItem("def4", null);
	   e.getBillCardPanel().setHeadItem("def5", null);
	   e.getBillCardPanel().setHeadItem("def6", null);
	   e.getBillCardPanel().setHeadItem("def7", null);
	   e.getBillCardPanel().setHeadItem("def8", null);
	   e.getBillCardPanel().setHeadItem("def9", null);
	   e.getBillCardPanel().setHeadItem("def11", null);
	   e.getBillCardPanel().setHeadItem("deptname", null);
	   e.getBillCardPanel().setHeadItem("dfbonus_total", null);
	   e.getBillCardPanel().setHeadItem("dfdesign_bonus", null);
	   e.getBillCardPanel().setHeadItem("dfmanage_bonus", 0.00);
	   e.getBillCardPanel().setHeadItem("dfmarket_bonus", null);
	   e.getBillCardPanel().setHeadItem("dfservice_charge", null);
	   e.getBillCardPanel().setHeadItem("dfteam_bonus", null);
	   e.getBillCardPanel().setHeadItem("finish_cycle", null);
	   e.getBillCardPanel().setHeadItem("income_total", null);
	   e.getBillCardPanel().setHeadItem("leave_days", null);
	   e.getBillCardPanel().setHeadItem("mount_total", null);
	   e.getBillCardPanel().setHeadItem("postname", null);
	   e.getBillCardPanel().setHeadItem("remark", null);
	   e.getBillCardPanel().setHeadItem("scheme", null);
	   e.getBillCardPanel().setHeadItem("baod_type", null);
	   e.getBillCardPanel().setHeadItem("start_cycle", null);
	   e.getBillCardPanel().setHeadItem("subsidy_mount", null);
	   e.getBillCardPanel().setHeadItem("this_amount", null);
	   e.getBillCardPanel().setHeadItem("work_days", null);
	   e.getBillCardPanel().setHeadItem("yfbonus_total", null);
	   e.getBillCardPanel().setHeadItem("yfdesign_bonus", null);
	   e.getBillCardPanel().setHeadItem("yfmanage_bonus", null);
	   e.getBillCardPanel().setHeadItem("yfmarket_bonus", null);
	   e.getBillCardPanel().setHeadItem("yfmonthly_pay", null);
	   e.getBillCardPanel().setHeadItem("yfpredict_bonus", null);
	   e.getBillCardPanel().setHeadItem("yfservice_charge", null);
	   e.getBillCardPanel().setHeadItem("yfteam_bonus", null);  
   }
   
   public String getDate(String clerkcode) throws Exception {
	   String sql = "select MAX(def8) as def8 from baod_order where clerkcode = '"+clerkcode+"' and dr = 0 and approvestatus = '1' order by def8 desc";
	   String def8 = (String) bs.executeQuery(sql, new ColumnProcessor());
	   if(def8 != null) {
		   Calendar calendar = Calendar.getInstance(); 
		   calendar.setTime(sdf.parse(def8)); 
		   calendar.add(Calendar.DAY_OF_MONTH, 1); // 将天数加 1  
		   return sdf.format(calendar.getTime());  
	   }
	   return null;
   }
   
   //查询保底合同已保底截止日期大于保底合同截止日期数据
   public List<Map<String, String>> GetbdDateOrMoney(String clerkcode, String startdate, String enddate) throws Exception{
	   //查询员工保底补贴申请表数据
	   String sql = "select income_total as money,start_cycle as begindate,finish_cycle as enddate from baod_order  where clerkcode ='"+clerkcode+"' "
	   		+ "and (SUBSTR(finish_cycle,1,10) >= '"+startdate+"'and SUBSTR(start_cycle,1,10) <= '"+enddate+"') and approvestatus = '1' and dr = 0";
	   List<Map<String,String>> listMap = (List<Map<String, String>>) bs.executeQuery(sql, new MapListProcessor());
	   //如果员工保底补贴申请表没有查询到该员工数据转而取期初数据,如果有对应数据则不取期初的
	   if(listMap.size() == 0) {
		   //查询期初数据
		    sql = "select guaranteed_start_date as begindate,guaranteed_end_date as enddate,guaranteed_amount as money "
		   		+ "from employees_guarantee_contract where pk_psndoc = '"+clerkcode+"' and (contract_start_date >='"+startdate+"' and contract_end_date <= '"+enddate+"')"; 
		    listMap = (List<Map<String, String>>) bs.executeQuery(sql, new MapListProcessor());
	   }
	   return listMap;
   }
}
