package com.kingdee.shr.customer.gtiit.handler;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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

import org.springframework.ui.ModelMap;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.eas.base.param.IParamControl;
import com.kingdee.eas.base.param.ParamControlFactory;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import com.kingdee.shr.base.syssetting.context.SHRContext;
import com.kingdee.shr.base.syssetting.exception.SHRWebException;
import com.kingdee.shr.cmpdesign.web.handler.fix.FixAdjustSalaryHandler;

/**
 * 员工定调薪档案扩展handler
 * @author xiaoxin
 *
 */
public class FixAdjustSalaryHandlerEx extends FixAdjustSalaryHandler{

	/**
	 * 添加员工薪酬追溯信息
	 * @param request
	 * @param response
	 * @param modelMap
	 * @return
	 * @throws SHRWebException
	 */
	public String addReviewDataAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap)
			throws SHRWebException {
		Context ctx = SHRContext.getInstance().getContext();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		//生效日期
		String effectDay = request.getParameter("effectDay");
		//追溯发放月份
		String retroactiveDate = request.getParameter("retroactiveDate");
		//人员id
		String personId = request.getParameter("personId");
		//金额
		String money = request.getParameter("money");
		
		try {
			//追溯发放日期
			Date formMonthDate = sdf.parse(retroactiveDate);
			effectDay = effectDay.substring(0, 7);
			retroactiveDate = retroactiveDate.substring(0, 7);
			int endYear = Integer.valueOf(retroactiveDate.substring(0,4));
			int endMonth = Integer.valueOf(retroactiveDate.substring(5,7));
			Date startDate = sdf.parse(effectDay+"-01");
			Date endDate = sdf.parse(YearMonth.of(endYear, endMonth).atEndOfMonth().toString());
			Calendar startCalendar = Calendar.getInstance();
			Calendar endCalendar = Calendar.getInstance();
			startCalendar.setTime(startDate);
			endCalendar.setTime(endDate);
			LocalDate startLocal = new java.sql.Date(startDate.getTime()).toLocalDate();
	        LocalDate endLocal = new java.sql.Date(endDate.getTime()).toLocalDate();
	        long monthsDiff = ChronoUnit.MONTHS.between(startLocal.withDayOfMonth(1), endLocal.withDayOfMonth(1));
	        //调整后月薪
	        BigDecimal monthlyPay = new BigDecimal(money).divide(BigDecimal.valueOf(monthsDiff+1),0,BigDecimal.ROUND_HALF_DOWN);
	        
	        //当月月薪
	        String monthPayField = this.getPayFieldSn(ctx, "monthPayField");
	        //当月平时加班费
	        String overPayField = this.getPayFieldSn(ctx, "overPayField");
	        //平时加班小时
	        String overHourField = this.getPayFieldSn(ctx, "overHourField");
	        //当月休息日加班费
	        String restOverPayField = this.getPayFieldSn(ctx, "restOverPayField");
	        //休息日加班小时
	        String restHourField = this.getPayFieldSn(ctx, "restHourField");
	        //法定节假日加班费
	        String holidaysPayField = this.getPayFieldSn(ctx, "holidaysPayField");
	        //法定节假日加班小时
	        String holidaysHourField = this.getPayFieldSn(ctx, "holidaysHourField");
	        //当月无薪假扣款
	        String unLeavePayField = this.getPayFieldSn(ctx, "unLeavePayField");
	        //当月无薪假小时
	        String unLeaveHourField = this.getPayFieldSn(ctx, "unLeaveHourField");
	        String feilds = monthPayField+","+overPayField+","+overHourField+","+restOverPayField+","+restHourField+","+holidaysPayField+","+holidaysHourField+","+unLeavePayField+","+unLeaveHourField;
	        String sql = "SELECT fid,fpersonid,fperiodyear,fperiodmonth,fisgive,"+feilds+" FROM T_HR_SCMPCALTABLE where FPERSONID = '"+personId+"' and FBEGINDATE >='"+sdf.format(startDate)+"'  and FENDDATE <= '"+sdf.format(endDate)+"'";
	        IRowSet iRowSet = DbUtil.executeQuery(ctx, sql);
	        Map<String, Map<String,Object>> map = new HashMap<>();
			while (iRowSet.next()){
				Map<String,Object> valueMap = new HashMap<>();
				valueMap.put("fisgive", iRowSet.getObject("fisgive").equals("Y")?"1":"0");
				valueMap.put(monthPayField, iRowSet.getObject(monthPayField));
				valueMap.put(overPayField, iRowSet.getObject(overPayField));
				valueMap.put(overHourField, iRowSet.getObject(overHourField));
				valueMap.put(restOverPayField, iRowSet.getObject(restOverPayField));
				valueMap.put(restHourField, iRowSet.getObject(restHourField));
				valueMap.put(holidaysPayField, iRowSet.getObject(holidaysPayField));
				valueMap.put(holidaysHourField, iRowSet.getObject(holidaysHourField));
				valueMap.put(unLeavePayField, iRowSet.getObject(unLeavePayField));
				valueMap.put(unLeaveHourField, iRowSet.getObject(unLeaveHourField));
				map.put(iRowSet.getString("fperiodyear")+iRowSet.getString("fperiodmonth"), valueMap);
			}
			StringBuffer insertBuffer = new StringBuffer();
	        for(int i = 0; i <= monthsDiff; i++) {
	        	BigDecimal zero = BigDecimal.ZERO;
	        	//当月月薪
	        	BigDecimal thatMonthPay = zero;
	        	//当月平时加班费
	        	BigDecimal thatOvertimePay = zero;
	        	//平时加班小时
	        	BigDecimal thatOvertimeHour = zero;
	        	//当月休息日加班费
	        	BigDecimal thatRestOverPay = zero;
	        	//休息日加班小时
	        	BigDecimal restOverHour = zero;
	        	//当月节假日加班费
	        	BigDecimal thatHolidaysOverPay = zero;
	        	//法定节假日加班小时
	        	BigDecimal holidaysOverHour = zero;
	        	//当月无薪假扣款
	        	BigDecimal thatUnpaidDeduction = zero;
	        	//当月无薪假小时
	        	BigDecimal thatUnLeaveHour = zero;
	        	//补发月薪
	        	BigDecimal reissueMonthPay = zero;
	        	//补发平时加班费
	        	BigDecimal reissueOverPay = zero;
	        	//补发休息日加班费
	        	BigDecimal reissueRestOverPay = zero;
	        	//补发节假日加班费
	        	BigDecimal reissueHolidaysOverPay = zero;
	        	//补发无薪假扣款
	        	BigDecimal reissueUnLeaveDeduction = zero;
	        	//补发合计
	        	BigDecimal reissueTotal = zero;
	        	//是否已发薪
	        	String isGive = "";
	        	if(i!=0) {
	        		startCalendar.add(Calendar.MONTH, 1);
	        	}
	        	if(i == monthsDiff) {
	        		monthlyPay = new BigDecimal(money).subtract(monthlyPay.multiply(BigDecimal.valueOf(monthsDiff)));
	        	}
	        	Map<String, Object> valueMap = map.get(startCalendar.get(Calendar.YEAR)+""+(startCalendar.get(Calendar.MONTH)+1));
	        	if(valueMap != null) {
	        		isGive = (String) valueMap.get("fisgive");
	        		thatMonthPay = valueMap.get(monthPayField)==null?zero:((BigDecimal) valueMap.get(monthPayField)).setScale(2);
	        		thatOvertimePay = valueMap.get(overPayField)==null?zero:((BigDecimal) valueMap.get(overPayField)).setScale(2);
	        		thatOvertimeHour = valueMap.get(overHourField)==null?zero:((BigDecimal) valueMap.get(overHourField)).setScale(2);
	        		thatRestOverPay = valueMap.get(restOverPayField)==null?zero:((BigDecimal) valueMap.get(restOverPayField)).setScale(2);
	        		restOverHour = valueMap.get(restHourField)==null?zero:((BigDecimal) valueMap.get(restHourField)).setScale(2);
	        		thatHolidaysOverPay = valueMap.get(holidaysPayField)==null?zero:((BigDecimal) valueMap.get(holidaysPayField)).setScale(2);
	        		holidaysOverHour = valueMap.get(holidaysHourField)==null?zero:((BigDecimal) valueMap.get(holidaysHourField)).setScale(2);
	        		thatUnpaidDeduction = valueMap.get(unLeavePayField)==null?zero:((BigDecimal) valueMap.get(unLeavePayField)).setScale(2);
	        		thatUnLeaveHour = valueMap.get(unLeaveHourField)==null?zero:((BigDecimal) valueMap.get(unLeaveHourField)).setScale(2);
	        		reissueMonthPay = monthlyPay.subtract(thatMonthPay).setScale(2);
	        		reissueOverPay = monthlyPay.divide(BigDecimal.valueOf(174), 2, BigDecimal.ROUND_HALF_UP).multiply(thatOvertimeHour).subtract(thatOvertimePay).setScale(2);
	        		reissueRestOverPay = monthlyPay.divide(BigDecimal.valueOf(174), 2, BigDecimal.ROUND_HALF_UP).multiply(restOverHour).subtract(thatRestOverPay).setScale(2);
	        		reissueHolidaysOverPay = monthlyPay.divide(BigDecimal.valueOf(174), 2, BigDecimal.ROUND_HALF_UP).multiply(holidaysOverHour).subtract(thatHolidaysOverPay).setScale(2);
	        		if(thatUnLeaveHour.remainder(BigDecimal.valueOf(7.5)).compareTo(zero) == 0) {
	        			reissueUnLeaveDeduction = monthlyPay.divide(BigDecimal.valueOf(21.75), 2, BigDecimal.ROUND_HALF_UP).multiply(thatUnLeaveHour.divide(BigDecimal.valueOf(7.5), 2, BigDecimal.ROUND_HALF_UP)).subtract(thatUnpaidDeduction).setScale(2);
	        		}else {
	        			reissueUnLeaveDeduction = monthlyPay.divide(BigDecimal.valueOf(174), 2, BigDecimal.ROUND_HALF_UP).multiply(thatUnLeaveHour).subtract(thatHolidaysOverPay).subtract(thatUnpaidDeduction).setScale(2);
	        		}
	        		reissueTotal = reissueMonthPay.add(reissueOverPay).add(reissueRestOverPay).add(reissueHolidaysOverPay).add(reissueUnLeaveDeduction).setScale(2);
	        	}
	        	
	        	String insertSql = "INSERT INTO CT_CUS_PersonPayForm(fid,CFPersonID,CFMonth,CFPayroll,CFThatMonthPay,CFThatOvertimePay,CFThatOvertimeHour,"
	        			+ "CFThatRestOverPay,CFRestOverHour,CFThatHolidaysOverPay,CFHolidaysOverHour,CFThatUnpaidDeduction,CFThatUnLeaveHour,"
	        			+ "CFReissueMonthPay,CFReissueOverPay,CFReissueRestOverPay,CFReissueHolidaysOverPay,CFReissueUnLeaveDeduction,CFReissueTotal,CFFormMonth )"
	        			+ " VALUES (newbosid('5FB9A7AC'),'"+personId+"','"+sdf.format(startCalendar.getTime())+"','"+isGive+"',"+thatMonthPay.toPlainString()+","
	        			+ thatOvertimePay.toPlainString()+","+thatOvertimeHour.toPlainString()+","+thatRestOverPay.toPlainString()+","+restOverHour.toPlainString()+","
	        			+thatHolidaysOverPay.toPlainString()+","+holidaysOverHour.toPlainString()+","+thatUnpaidDeduction.toPlainString()+","
	        			+thatUnLeaveHour.toPlainString()+","+reissueMonthPay.toPlainString()+","+reissueOverPay.toPlainString()+","
	        			+reissueRestOverPay.toPlainString()+","+reissueHolidaysOverPay.toPlainString()+","+reissueUnLeaveDeduction.toPlainString()+","
	        			+reissueTotal.toPlainString()+",'"+sdf.format(formMonthDate)+"' );";
	        	insertBuffer.append(insertSql);
	        }
	        
	        String delteSql = "delete from CT_CUS_PersonPayForm where cfpersonid='"+personId+"' and cfmonth>='"+sdf.format(startDate)+"' and cfmonth<='"+sdf.format(endDate)+"'";
	        DbUtil.execute(ctx, delteSql);
	        
	        if(insertBuffer.length()>0) {
	        	DbUtil.execute(ctx, insertBuffer.toString());
	        }
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (BOSException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 根据薪酬项目编码获取薪酬项目字段
	 * @param ctx
	 * @param param
	 * @return
	 */
	public String getPayFieldSn(Context ctx, String param) {
		try {
			IParamControl ipc = ParamControlFactory.getLocalInstance(ctx);
			String projectNumber = ipc.getParamValue(null, param);
			String sql = "select FieldSn from T_HR_SCmpItem where fnumber = '"+projectNumber+"'";
			IRowSet iRowSet = DbUtil.executeQuery(ctx, sql);
			while(iRowSet.next()) {
				String fieldSn = iRowSet.getObject("FieldSn")==null?"":iRowSet.getString("FieldSn");
				return "s" + fieldSn;
			}
		} catch (BOSException e) {
			e.printStackTrace();
		} catch (EASBizException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return "";
	}
}
