package com.kingdee.customer.salary.handler;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.ui.ModelMap;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.bill.salary.ISalaryBag;
import com.kingdee.eas.custom.bill.salary.SalaryBagEntryCollection;
import com.kingdee.eas.custom.bill.salary.SalaryBagEntryInfo;
import com.kingdee.eas.custom.bill.salary.SalaryBagFactory;
import com.kingdee.eas.custom.bill.salary.SalaryBagInfo;
import com.kingdee.eas.framework.CoreBaseInfo;
import com.kingdee.eas.hr.base.HRBillStateEnum;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import com.kingdee.shr.base.syssetting.app.io.fileImport.ImportException;
import com.kingdee.shr.base.syssetting.context.SHRContext;
import com.kingdee.shr.base.syssetting.exception.SHRWebException;
import com.kingdee.shr.base.syssetting.exception.ShrWebBizException;
import com.kingdee.shr.base.syssetting.util.MetaDataUtil;
import com.kingdee.shr.base.syssetting.web.handler.EditHandler;
import com.kingdee.shr.base.syssetting.web.json.JSONUtils;


/**
 * 工资包
 * @author issuser
 *
 */
public class SalaryBagEditHandler extends EditHandler{
	
	private static Logger logger =
	        Logger.getLogger("com.kingdee.customer.salary.handler.SalaryBagEditHandler");
	
	/**
	 * 数据初始化
	 * @param request
	 * @param response
	 * @param modelMap
	 */
	public void getSoureBillDataAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
		String billId = request.getParameter("billId");
		System.out.print("工资包变更来源billId========="+billId);
		Context ctx = SHRContext.getInstance().getContext();
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			String selectSql = "SELECT  b.fid as personId,b.FNAME_l2 as personName,"
					+ " c.FID as cmpItemId ,c.FNAME_l2 as cmpItemName,a.CFPaycurrency "
					+ " FROM CT_SAL_SalaryBag a "
					+ " left join t_bd_person b on a.CFPersonID = b.FID "
					+ " left join T_HR_SCmpItem c on a.CFCmpItemID = c.fid "
					+ " where a.fid = '" + billId + "'";
			System.out.print("工资包变更sql========="+selectSql);
			IRowSet rs = DbUtil.executeQuery(ctx, selectSql.toString());
			String cmpItemId = null;
			String cmpItemName = null;
			if(rs.next()){
				cmpItemId = rs.getString("cmpItemId");
				cmpItemName = rs.getString("cmpItemName");
				resultMap.put("personId",rs.getString("personId"));
				resultMap.put("personName",rs.getString("personName"));
				resultMap.put("paycurrency", rs.getString("CFPaycurrency"));
				resultMap.put("cmpItemId",cmpItemId);
				resultMap.put("cmpItemName",cmpItemName);
			}
			SalaryBagInfo salaryBagInfo = SalaryBagFactory.getLocalInstance(ctx).getSalaryBagInfo(new ObjectUuidPK(billId));
			resultMap.put("money", salaryBagInfo.getMoney());
			resultMap.put("startDate", salaryBagInfo.getStartDate());
			resultMap.put("endDate", salaryBagInfo.getEndDate());
			SalaryBagEntryCollection entryCollection = salaryBagInfo.getEntrys();
			List<Map<String,Object>> entryList = new ArrayList<Map<String,Object>>();
			if ((null != entryCollection) && (entryCollection.size() > 0)) {
				int i = 0;
				for (int size = entryCollection.size(); i < size; ++i) {
					SalaryBagEntryInfo info = entryCollection.get(i);
					Map<String,Object> entryMap = new HashMap<String, Object>();
					entryMap.put("months", info.getMonths());
					entryMap.put("paycurrency", salaryBagInfo.get("paycurrency"));
					entryMap.put("cmpItemId", cmpItemId);
					entryMap.put("cmpItemName", cmpItemName);
					entryMap.put("moneys", info.getMoneys());
					entryMap.put("beforeAmount", info.getMoneys());
					entryMap.put("amountPayable", 0);
					entryMap.put("reissueAmount", 0);
					entryList.add(entryMap);
				}
			}
			resultMap.put("entry", entryList);
			System.out.print("工资包resultMap========="+resultMap);
		
		JSONUtils.writeJson(response, resultMap);
		} catch (EASBizException e) {
			e.printStackTrace();
		} catch (BOSException e) {
			e.printStackTrace();
		} catch (SHRWebException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 生成数据明细
	 * @param request
	 * @param response
	 * @param modelMap
	 */
	public void createEntryDetailAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
		String startDateStr = request.getParameter("startDate");
		String endDateStr = request.getParameter("endDate");
		String reissueDateStr = request.getParameter("reissueDate");
		String money = request.getParameter("money");
		String billId = request.getParameter("billId");
		Context ctx = SHRContext.getInstance().getContext();
		try {
			String selectSql = "SELECT  b.fid as personId,b.FNAME_l2 as personName,"
					+ " c.FID as cmpItemId ,c.FNAME_l2 as cmpItemName,a.CFPaycurrency,a.CFendDate "
					+ " FROM CT_SAL_SalaryBag a "
					+ " left join t_bd_person b on a.CFPersonID = b.FID "
					+ " left join T_HR_SCmpItem c on a.CFCmpItemID = c.fid "
					+ " where a.fid = '" + billId + "'";
			System.out.print("工资包变更sql========="+selectSql);
			IRowSet rs = DbUtil.executeQuery(ctx, selectSql.toString());
			String cmpItemId = null;
			String cmpItemName = null;
			String paycurrency = null;
			Date soureEndDate = null;
			if(rs.next()){
				cmpItemId = rs.getString("cmpItemId");
				cmpItemName = rs.getString("cmpItemName");
				paycurrency = rs.getString("CFPaycurrency");
				soureEndDate = rs.getDate("CFendDate");
			}
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			//更新后的最后日期
			Date endDate = sdf.parse(endDateStr);
			Date reissueDate =  sdf.parse(reissueDateStr);
			if(soureEndDate.after(endDate)){
				throw new ImportException("The expiration date cannot be earlier than the expiration date of the original document"); 
			}
			
			//月份拆分
			List<Date> monthList = getMonthDetail(startDateStr,endDateStr);
			System.out.print("月份========="+monthList.size());
			List<Map<String,Object>> resultList = new ArrayList<Map<String,Object>>();
			//总金额
			BigDecimal moneyAmount = new BigDecimal(money);
			//金额
			BigDecimal  avgAmount = moneyAmount.divide(BigDecimal.valueOf(monthList.size()), 0, BigDecimal.ROUND_HALF_UP);
			//已生成额度的金额
			BigDecimal remainder = new BigDecimal(0);
			//补发月应发金额
			BigDecimal amountPayable = new BigDecimal(0);
			BigDecimal lastPay = new BigDecimal(0);
			for(int i = 0 ; i <  monthList.size() ; i ++) {
				Map<String,Object> entryMap = new HashMap<String, Object>();
				Date months = monthList.get(i);
				entryMap.put("months", months);
				entryMap.put("paycurrency", paycurrency);
				entryMap.put("cmpItemId",cmpItemId);
				entryMap.put("cmpItemName",cmpItemName);
				
				if(monthList.size() - i > 1) {
					//已经生成额度的金额
	                remainder = remainder.add(avgAmount);
				}else {
					//最后一个月的金额
					avgAmount = moneyAmount.subtract(remainder);
				}
				//金额
				entryMap.put("moneys", avgAmount);
				BigDecimal beforeAmount = getBeforeAmount(billId,sdf.format(months));
				//变更前金额
				entryMap.put("beforeAmount", beforeAmount);
				//应发金额
				if(monthList.get(i).equals(reissueDate)) {
					//补发金额
					entryMap.put("reissueAmount", 0);
					//应发金额
					entryMap.put("amountPayable", amountPayable.add(avgAmount));
				}else if(monthList.get(i).after(reissueDate)) {//后面的
					entryMap.put("amountPayable", avgAmount);
					entryMap.put("reissueAmount", Integer.valueOf(0));
				}else { //前面的
					entryMap.put("amountPayable", 0);
					//补发金额
					entryMap.put("reissueAmount", avgAmount.subtract(beforeAmount));
					//总应发差额
					amountPayable = amountPayable.add(avgAmount.subtract(beforeAmount));
				}
				logger.error("月份result========="+entryMap);
				resultList.add(entryMap);	
			}
			JSONUtils.writeJson(response, resultList);
		} catch (BOSException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (SHRWebException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
	}
	
	private BigDecimal getBeforeAmount(String billId,String months ) throws BOSException, SQLException {
		Context ctx = SHRContext.getInstance().getContext();
		BigDecimal beforeAmount = new BigDecimal(0);
		String selectSql = "SELECT CFMoneys FROM  CT_SAL_SalaryBagEntry where FBillID = '" + billId + "' and to_char(CFMonths,'yyyy-MM-dd') = '" + months + "'";
		System.out.print("查找变更前金额========="+selectSql);
		IRowSet rs = DbUtil.executeQuery(ctx, selectSql.toString());
		if(rs.next()) {
			beforeAmount = rs.getBigDecimal("CFMoneys");
		}
		return beforeAmount;
	}
	
	/**
	 * 月份拆分
	 * @param startDateStr
	 * @param endDateStr
	 * @return
	 * @throws ParseException 
	 */
	private List<Date> getMonthDetail(String startDateStr,String endDateStr) throws ParseException{
		SimpleDateFormat sdfMonth = new SimpleDateFormat("yyyy-MM");
        Date startDate = sdfMonth.parse(startDateStr);
        Date endDate = sdfMonth.parse( endDateStr);
        Date currentDate = startDate;
        List<Date> monthList = new ArrayList<Date>();
        Calendar calendar = Calendar.getInstance();
        while (endDate.after(currentDate) || currentDate.equals(endDate)) {
        	monthList.add(currentDate);
            calendar.setTime(currentDate);
            calendar.add(Calendar.MONTH, 1);
            currentDate = calendar.getTime();
        }
        return monthList;
	}
	
	
	@Override
	protected void verifyModel(HttpServletRequest request, HttpServletResponse response, CoreBaseInfo model)
			throws SHRWebException {
		SalaryBagInfo billInfo = (SalaryBagInfo) model;
		
		BigDecimal billAmount = billInfo.getMoney();
		BigDecimal entryAmount = BigDecimal.ZERO;
		SalaryBagEntryCollection entryColl = billInfo.getEntrys();
		
		if(entryColl != null) {
			for(int i=0 ;i<entryColl.size(); i++) {
				SalaryBagEntryInfo entry = entryColl.get(i);
				entryAmount = entryAmount.add(entry.getMoneys());
			}
		}
		
		logger.error("单头金额："+billAmount+",分录金额总和："+entryAmount);
		
		//金额是否相同校验
		if( billAmount.compareTo(entryAmount) != 0 ) {
			throw new ShrWebBizException("The amount split does not equal the total amount, please check !"); 
		}
		super.verifyModel(request, response, model);
	}
	
	/**
	 * 员工工资包时间唯一校验
	 * @param request
	 * @param response
	 * @param modelMap
	 * @throws BOSException 
	 * @throws SQLException 
	 * @throws SHRWebException 
	 */
	public void checkDateAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws BOSException, SQLException, SHRWebException {
		boolean flag = true;
		String fid = request.getParameter("fid");
		String personId = request.getParameter("personId");
		String sourceBillId = request.getParameter("sourceBillId");
		String startDate = request.getParameter("startDate");
		String endDate = request.getParameter("endDate");
		String cmpitemId = request.getParameter("cmpitemId");
		System.out.print("sourceBillId========"+sourceBillId);
		System.out.print("cmpitemId========"+cmpitemId);
		Context ctx = SHRContext.getInstance().getContext();
		//员工工资包时间唯一校验
		StringBuffer dateSql = new StringBuffer();
		dateSql.append(" SELECT fnumber FROM CT_SAL_SalaryBag where FBillState = '3' ");
		dateSql.append(" and CFPersonID = '" + personId + "'" );
		dateSql.append(" and (CFStartDate between '" + startDate + "' and '" + endDate + "'" );
		dateSql.append(" or CFEndDate between '" + startDate + "'  and '"+endDate + "')" );
		dateSql.append(" and CFCmpItemID = '" + cmpitemId + "'"  );
		
		if(StringUtils.isNotBlank(fid) && StringUtils.isNotBlank(sourceBillId)) {
			dateSql.append(" and fid not in ('" + fid + "' , '"+ sourceBillId + "')");
		}else if(StringUtils.isNotBlank(fid)) {
			dateSql.append(" and fid != '" + fid + "' ");
		}else if(StringUtils.isNotBlank(sourceBillId)) {
			dateSql.append(" and fid != '" + sourceBillId + "'"  );
		}
		IRowSet rs = DbUtil.executeQuery(ctx, dateSql.toString());
		if(rs.next()){
			flag = false;	
		}
		JSONUtils.writeJson(response, flag);
	}
	
	/**
	 * 提交生效
	 * @param request
	 * @param response
	 * @param modelMap
	 * @throws EASBizException
	 * @throws BOSException
	 * @throws SHRWebException
	 * @throws SQLException
	 */
	public void submitEffectAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws EASBizException, BOSException, SHRWebException, SQLException {
		System.out.println("工资包提交生效====" + modelMap);
		CoreBaseInfo model = (CoreBaseInfo)request.getAttribute("dynamic_model");
	    Context ctx = SHRContext.getInstance().getContext();
	    String currentid = model.getString("id");
	    SalaryBagInfo demoInfo = null;
	    if(StringUtils.isNotEmpty(currentid)) {
		      demoInfo = SalaryBagFactory.getLocalInstance(ctx).getSalaryBagInfo((IObjectPK)new ObjectUuidPK(currentid));
		      HRBillStateEnum status = demoInfo.getBillState();
		      if (status.getValue() != 0) {
		    	  //处于审核流程中或已经被审核过得单据不能提交
		    	  throw new SHRWebException("Documents that are in the process of being audited or have already been audited cannot be submitted !"); 
		      }
	    }else {
	    	demoInfo = (SalaryBagInfo) model;
	    }
	    beforeSave(request, response, model);
	    try {
	    	ISalaryBag idemo = (ISalaryBag)MetaDataUtil.getBizInterface("com.kingdee.eas.custom.bill.salary.app.SalaryBag");
	    	idemo.submitEffect(model);
	    } catch (Exception e) {
	    	JSONUtils.ERROR("Submission validation failure !");
	    } 
	    afterSave(request, response, model);
	    System.out.println("工资单已提交生效 : " + demoInfo.toString());
	    System.out.println("源单据编码：" + demoInfo.getSourceBillId());
	    if(StringUtils.isNotBlank(demoInfo.getSourceBillId())){
	    	String updateSql = "update CT_SAL_SalaryBag set FBillState = '1' where fid = '"+ demoInfo.getSourceBillId() +"'";
			System.out.print("变更单据状态更新========="+updateSql);
	    	DbUtil.execute(ctx, updateSql);
//	        String deleteSql = "delete from CT_SAL_SalaryBag where fid = '" + demoInfo.getSourceBillId() + "'";
//	        System.out.print( deleteSql);
//	        DbUtil.execute(ctx, deleteSql);
	    }
	    String id = model.getId().toString();
	    writeSuccessData(id);
	}

}
