package com.engine.kq.cmd.leavetypes;

import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.biz.SimpleBizLogger;
import com.engine.common.constant.BizLogSmallType4Hrm;
import com.engine.common.constant.BizLogType;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.kq.biz.KQAttFlowSetComInfo;
import com.engine.kq.biz.KQLeaveRulesComInfo;
import com.engine.kq.biz.KQUnitBiz;
import com.engine.kq.biz.KQUsageHistoryBiz;
import com.engine.kq.entity.KQUsageHistoryEntity;
import com.engine.kq.util.KQTransMethod;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;

import java.util.*;

/**
 * @Auther: xiaj
 * @Date: 2019-03-07 16:42
 * @Description:
 */
public class EditLeaveTypesCmd extends AbstractCommonCommand<Map<String, Object>> {

    private SimpleBizLogger logger;

    public EditLeaveTypesCmd(Map<String, Object> params, User user) {
        this.user = user;
        this.params = params;
        this.logger = new SimpleBizLogger();

        String ruleId = Util.null2String(params.get("typeId"));
        BizLogContext bizLogContext = new BizLogContext();
        bizLogContext.setLogType(BizLogType.HRM_ENGINE);//模块类型
        bizLogContext.setBelongType(BizLogSmallType4Hrm.HRM_ENGINE_KQ_LEAVETYPES);//所属大类型
        bizLogContext.setLogSmallType(BizLogSmallType4Hrm.HRM_ENGINE_KQ_LEAVETYPES);//当前小类型
        bizLogContext.setParams(params);//当前request请求参数
        logger.setUser(user);//当前操作人
        String mainSql = "select * from kq_leaveRules where (isDelete is null or isDelete<>1) and id =" + ruleId;
        logger.setMainSql(mainSql, "id");//主表sql
        logger.setMainPrimarykey("id");//主日志表唯一key
        logger.setMainTargetNameColumn("leavename");
        logger.before(bizLogContext);
    }

    @Override
    public BizLogContext getLogContext() {
        return null;
    }

    @Override
    public List<BizLogContext> getLogContexts() {
        return logger.getBizLogContexts();
    }

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            boolean canEdit = HrmUserVarify.checkUserRight("KQLeaveRulesEdit:Edit", user);//是否具有编辑权限
            if (!canEdit) {
                resultMap.put("status", "-1");
                resultMap.put("message", SystemEnv.getHtmlLabelName(2012, user.getLanguage()));
                return resultMap;
            }

            KQLeaveRulesComInfo rulesComInfo = new KQLeaveRulesComInfo();
            /*假期类型的ID*/
            String ruleId = Util.null2String(params.get("typeId"));

            /*假期类型的名称*/
            String leaveName = Util.null2String(params.get("leaveName"));

            /*校验名称是否已经有其他假期类型使用*/
            String nameSql = "select * from kq_leaveRules where (isDelete is null or isDelete<>1) and leaveName=? and id<>?";
            RecordSet recordSet = new RecordSet();
            recordSet.executeQuery(nameSql, leaveName, ruleId);
            if (recordSet.next()) {
                resultMap.put("status", "-1");
                resultMap.put("message", SystemEnv.getHtmlLabelName(505662, user.getLanguage()));
                return resultMap;
            }

            /*流程可见范围：0-总部、1-分部(只有在此范围内的人请假的时候才能看见此假期类型)*/
            int scopeType = Util.getIntValue((String) params.get("scopeType"), 0);

            /*流程可见范围为分部时，选择的分部ID*/
            String scopeValue = Util.null2String(params.get("scopeValue"));

            /*最小请假单位：1-按天请假、2-按半天请假、3-按小时请假、4-按整天请假*/
            int minimumUnit = Util.getIntValue((String) params.get("minimumUnit"), 1);

            /*折算方式：1-四舍五入、2-向上取整、3-向下取整*/
            int conversion = Util.getIntValue((String) params.get("conversion"), 1);

            /*假期规则单位变更时的天和小时的换算比例*/
            double proportion = Util.getDoubleValue((String) params.get("proportion"), Util.getDoubleValue(rulesComInfo.getProportion(ruleId), 8.00));

            /*计算请假时长方式：1-按工作日计算请假时长、2-按自然日计算请假时长*/
            int computingMode = Util.getIntValue((String) params.get("computingMode"), 1);

            /*日折算时长(当按自然日计算请假时长时有效)*/
            double hoursToDay = Util.getDoubleValue((String) params.get("hoursToDay"), 8.00);

            /*按自然日计算请假时长，是否过滤节假期：0-不启用，1-启用*/
            String filterHolidays = Util.null2String((String)params.get("filterHolidays"), "0");

            /*启用假期余额：0-不启用、1-启用*/
            int balanceEnable = Util.getIntValue((String) params.get("balanceEnable"), 0);

            double showOrder = Util.getDoubleValue((String) params.get("showOrder"), 0.00);

            /*判断是否改变了假期类型的最小请假单位，是否需要转换员工假期余额 start*/
            int oldMinimumUnit = Util.getIntValue(rulesComInfo.getMinimumUnit(ruleId), 1);

            //半天单位 时间选择方式：1-下拉框选择 、2-具体时间
            int timeselection = Util.getIntValue((String) params.get("timeselection"), 1);

            if (minimumUnit == 1 || minimumUnit == 2 || minimumUnit == 4 && (KQUnitBiz.isLeaveHour(oldMinimumUnit+""))) {
                changeMinimumUnit(ruleId, oldMinimumUnit, minimumUnit, proportion);
            } else if (oldMinimumUnit == 1 || oldMinimumUnit == 2 || oldMinimumUnit == 4 && (KQUnitBiz.isLeaveHour(minimumUnit+""))) {
                changeMinimumUnit(ruleId, oldMinimumUnit, minimumUnit, proportion);
            }
            if(minimumUnit != 2){
              //如果请假类型不再是半天了，需要删除原半天设置
              String del_2_sql = "delete from kq_timeselection where selectiontype=0 and leaveruleid=? and minimumUnit=2";
              boolean is_2_del = recordSet.executeUpdate(del_2_sql,ruleId);
              timeselection = 1;
            }
            /*判断是否改变了假期类型的最小请假单位，是否需要转换员工假期余额 start*/

            String sql = "update kq_LeaveRules set leaveName=?,scopeType=?,scopeValue=?,minimumUnit=?,proportion=?,computingMode=?,hoursToDay=?,filterHolidays=?,balanceEnable=?,showOrder=?,timeselection=?,conversion=? where id=?";
            boolean flag = recordSet.executeUpdate(sql, leaveName, scopeType, scopeValue, minimumUnit, proportion, computingMode, hoursToDay, filterHolidays,balanceEnable, showOrder,timeselection,conversion, ruleId);

            if (flag) {
                resultMap.put("sign", "1");
                resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功
            } else {
                resultMap.put("sign", "-1");
                resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
            }
        } catch (Exception e) {
            writeLog(e);
            resultMap.put("sign", "-1");
            resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
        } finally {
            KQLeaveRulesComInfo rulesComInfo = new KQLeaveRulesComInfo();
            KQAttFlowSetComInfo kqAttFlowSetComInfo = new KQAttFlowSetComInfo();
            kqAttFlowSetComInfo.removeKQAttFlowSetComInfoCache();
            rulesComInfo.removeCache();
        }
        return resultMap;
    }

    /**
     * 假期规则的最小请假单位发生变更时，需要重新计算假期余额
     *
     * @param ruleId         指定假期类型的ID
     * @param oldMinimumUnit 变更之前的假期类型的最小请假单位
     * @param newMinimumUnit 变更之后的假期类型的最小请假单位
     */
    private boolean changeMinimumUnit(String ruleId, int oldMinimumUnit, int newMinimumUnit, double proportion) {
        boolean flag = true;
        try {
            List updateValueList = new ArrayList();//每一个所有Update SQL操作的参数集合
            List updateParamList = new ArrayList();//所有所有Update SQL操作的参数集合

            /*员工假期余额变更记录*/
            KQUsageHistoryEntity usageHistoryEntity = new KQUsageHistoryEntity();
            List<KQUsageHistoryEntity> usageHistoryEntityList = new ArrayList<KQUsageHistoryEntity>();

            /*获取当前日期，当前时间*/
            Calendar today = Calendar.getInstance();
            String currentDate = Util.add0(today.get(Calendar.YEAR), 4) + "-" +
                    Util.add0(today.get(Calendar.MONTH) + 1, 2) + "-" +
                    Util.add0(today.get(Calendar.DAY_OF_MONTH), 2);
            String currentTime = Util.add0(today.get(Calendar.HOUR_OF_DAY), 2) + ":" +
                    Util.add0(today.get(Calendar.MINUTE), 2) + ":" +
                    Util.add0(today.get(Calendar.SECOND), 2);

            RecordSet recordSet = new RecordSet();
            if (((oldMinimumUnit == 1 || oldMinimumUnit == 2 || oldMinimumUnit == 4) && (KQUnitBiz.isLeaveHour(newMinimumUnit+"")))) {
                String sql = "select * from kq_BalanceOfLeave where leaveRulesId=" + ruleId;
                recordSet.executeQuery(sql);
                while (recordSet.next()) {
                    String belongYear = recordSet.getString("belongYear");
                    String resourceId = recordSet.getString("resourceId");
                    String balanceId = recordSet.getString("id");
                    double baseAmount = Util.getDoubleValue(recordSet.getString("baseAmount"), 0.00);
                    double extraAmount = Util.getDoubleValue(recordSet.getString("extraAmount"), 0.00);
                    double usedAmount = Util.getDoubleValue(recordSet.getString("usedAmount"), 0.00);
                    double baseAmount2 = Util.getDoubleValue(recordSet.getString("baseAmount2"), 0.00);
                    double extraAmount2 = Util.getDoubleValue(recordSet.getString("extraAmount2"), 0.00);
                    double usedAmount2 = Util.getDoubleValue(recordSet.getString("usedAmount2"), 0.00);
                    double tiaoxiuamount = Util.getDoubleValue(recordSet.getString("tiaoxiuamount"), 0.00);

                    if (baseAmount == 0.00 && extraAmount == 0.00 && usedAmount == 0.00 && baseAmount2 == 0.00 && extraAmount2 == 0.00 && usedAmount2 == 0.00 && tiaoxiuamount == 0.00) {
                        continue;
                    }

                    double newBaseAmount = baseAmount * proportion;
                    double newExtraAmount = extraAmount * proportion;
                    double newUsedAmount = usedAmount * proportion;
                    double newBaseAmount2 = baseAmount2 * proportion;
                    double newExtraAmount2 = extraAmount2 * proportion;
                    double newUsedAmount2 = usedAmount2 * proportion;
                    double newTiaoxiuamount = tiaoxiuamount * proportion;

                    /*组装Update SQL操作的参数 start*/
                    updateValueList = new ArrayList();
                    updateValueList.add(String.format("%.2f", newBaseAmount));
                    updateValueList.add(String.format("%.2f", newExtraAmount));
                    updateValueList.add(String.format("%.2f", newUsedAmount));
                    updateValueList.add(String.format("%.2f", newBaseAmount2));
                    updateValueList.add(String.format("%.2f", newExtraAmount2));
                    updateValueList.add(String.format("%.2f", newUsedAmount2));
                    updateValueList.add(String.format("%.2f", newTiaoxiuamount));
                    updateValueList.add(balanceId);

                    updateParamList.add(updateValueList);
                    /*组装Update SQL操作的参数 end*/

                  if(tiaoxiuamount > 0){
                    extraAmount = extraAmount+tiaoxiuamount;
                  }
                  if(newTiaoxiuamount > 0){
                    newExtraAmount = newExtraAmount+newTiaoxiuamount;
                  }

                    /*组装UsageHistory SQL操作的参数 start*/
                    usageHistoryEntity = new KQUsageHistoryEntity();
                    usageHistoryEntity.setLeaveRulesId(ruleId);
                    usageHistoryEntity.setRelatedId(resourceId);
                    usageHistoryEntity.setOperator("" + user.getUID());
                    usageHistoryEntity.setOperateDate(currentDate);
                    usageHistoryEntity.setOperateTime(currentTime);
                    usageHistoryEntity.setOperateType("0");
                    usageHistoryEntity.setBelongYear(belongYear);
                    usageHistoryEntity.setOldBaseAmount(String.format("%.2f", baseAmount));
                    usageHistoryEntity.setNewBaseAmount(String.format("%.2f", newBaseAmount));
                    usageHistoryEntity.setOldExtraAmount(String.format("%.2f", extraAmount));
                    usageHistoryEntity.setNewExtraAmount(String.format("%.2f", newExtraAmount));
                    usageHistoryEntity.setOldUsedAmount(String.format("%.2f", usedAmount));
                    usageHistoryEntity.setNewUsedAmount(String.format("%.2f", newUsedAmount));
                    usageHistoryEntity.setOldBaseAmount2(String.format("%.2f", baseAmount2));
                    usageHistoryEntity.setNewBaseAmount2(String.format("%.2f", newBaseAmount2));
                    usageHistoryEntity.setOldExtraAmount2(String.format("%.2f", extraAmount2));
                    usageHistoryEntity.setNewExtraAmount2(String.format("%.2f", newExtraAmount2));
                    usageHistoryEntity.setOldUsedAmount2(String.format("%.2f", usedAmount2));
                    usageHistoryEntity.setNewUsedAmount2(String.format("%.2f", newUsedAmount2));
                    usageHistoryEntity.setOldMinimumUnit(String.valueOf(oldMinimumUnit));
                    usageHistoryEntity.setNewMinimumUnit(String.valueOf(newMinimumUnit));
                    usageHistoryEntity.setInsertOrUpdate("update");

                    usageHistoryEntityList.add(usageHistoryEntity);
                    /*组装UsageHistory SQL操作的参数 end*/
                }
            } else if ((KQUnitBiz.isLeaveHour(oldMinimumUnit+"")) && (newMinimumUnit == 1 || newMinimumUnit == 2 || newMinimumUnit == 4)) {
                String sql = "select * from kq_BalanceOfLeave where leaveRulesId=" + ruleId;
                recordSet.executeQuery(sql);
                while (recordSet.next()) {
                    String resourceId = recordSet.getString("resourceId");
                    String belongYear = recordSet.getString("belongYear");
                    String balanceId = recordSet.getString("id");
                    double baseAmount = Util.getDoubleValue(recordSet.getString("baseAmount"), 0.00);
                    double extraAmount = Util.getDoubleValue(recordSet.getString("extraAmount"), 0.00);
                    double usedAmount = Util.getDoubleValue(recordSet.getString("usedAmount"), 0.00);
                    double baseAmount2 = Util.getDoubleValue(recordSet.getString("baseAmount2"), 0.00);
                    double extraAmount2 = Util.getDoubleValue(recordSet.getString("extraAmount2"), 0.00);
                    double usedAmount2 = Util.getDoubleValue(recordSet.getString("usedAmount2"), 0.00);
                    double tiaoxiuamount = Util.getDoubleValue(recordSet.getString("tiaoxiuamount"), 0.00);

                    if (baseAmount == 0.00 && extraAmount == 0.00 && usedAmount == 0.00 && baseAmount2 == 0.00 && extraAmount2 == 0.00 && usedAmount2 == 0.00  && tiaoxiuamount == 0.00) {
                        continue;
                    }

                    double newBaseAmount = baseAmount / proportion;
                    double newExtraAmount = extraAmount / proportion;
                    double newUsedAmount = usedAmount / proportion;
                    double newBaseAmount2 = baseAmount2 / proportion;
                    double newExtraAmount2 = extraAmount2 / proportion;
                    double newUsedAmount2 = usedAmount2 / proportion;
                    double newTiaoxiuamount = tiaoxiuamount / proportion;

                    /*组装Update SQL操作的参数 start*/
                    updateValueList = new ArrayList();
                    updateValueList.add(String.format("%.2f", newBaseAmount));
                    updateValueList.add(String.format("%.2f", newExtraAmount));
                    updateValueList.add(String.format("%.2f", newUsedAmount));
                    updateValueList.add(String.format("%.2f", newBaseAmount2));
                    updateValueList.add(String.format("%.2f", newExtraAmount2));
                    updateValueList.add(String.format("%.2f", newUsedAmount2));
                    updateValueList.add(String.format("%.2f", newTiaoxiuamount));
                    updateValueList.add(balanceId);

                    updateParamList.add(updateValueList);
                    /*组装Update SQL操作的参数 end*/

                  if(tiaoxiuamount > 0){
                    extraAmount = extraAmount+tiaoxiuamount;
                  }
                  if(newTiaoxiuamount > 0){
                    newExtraAmount = newExtraAmount+newTiaoxiuamount;
                  }
                    /*组装UsageHistory SQL操作的参数 start*/
                    usageHistoryEntity = new KQUsageHistoryEntity();
                    usageHistoryEntity.setLeaveRulesId(ruleId);
                    usageHistoryEntity.setRelatedId(resourceId);
                    usageHistoryEntity.setOperator("" + user.getUID());
                    usageHistoryEntity.setOperateDate(currentDate);
                    usageHistoryEntity.setOperateTime(currentTime);
                    usageHistoryEntity.setOperateType("0");
                    usageHistoryEntity.setBelongYear(belongYear);
                    usageHistoryEntity.setOldBaseAmount(String.format("%.2f", baseAmount));
                    usageHistoryEntity.setNewBaseAmount(String.format("%.2f", newBaseAmount));
                    usageHistoryEntity.setOldExtraAmount(String.format("%.2f", extraAmount));
                    usageHistoryEntity.setNewExtraAmount(String.format("%.2f", newExtraAmount));
                    usageHistoryEntity.setOldUsedAmount(String.format("%.2f", usedAmount));
                    usageHistoryEntity.setNewUsedAmount(String.format("%.2f", newUsedAmount));
                    usageHistoryEntity.setOldBaseAmount2(String.format("%.2f", baseAmount2));
                    usageHistoryEntity.setNewBaseAmount2(String.format("%.2f", newBaseAmount2));
                    usageHistoryEntity.setOldExtraAmount2(String.format("%.2f", extraAmount2));
                    usageHistoryEntity.setNewExtraAmount2(String.format("%.2f", newExtraAmount2));
                    usageHistoryEntity.setOldUsedAmount2(String.format("%.2f", usedAmount2));
                    usageHistoryEntity.setNewUsedAmount2(String.format("%.2f", newUsedAmount2));
                    usageHistoryEntity.setOldMinimumUnit(String.valueOf(oldMinimumUnit));
                    usageHistoryEntity.setNewMinimumUnit(String.valueOf(newMinimumUnit));
                    usageHistoryEntity.setInsertOrUpdate("update");

                    usageHistoryEntityList.add(usageHistoryEntity);
                    /*组装UsageHistory SQL操作的参数 end*/
                }
            }

            /**
             * 执行批量更新操作，如果失败，整体回滚
             */
            String updateSql = "update kq_BalanceOfLeave set baseAmount=?,extraAmount=?,usedAmount=?,baseAmount2=?,extraAmount2=?,usedAmount2=?,tiaoxiuamount=? where id=?";
            if (updateParamList.size() > 0) {
                flag = recordSet.executeBatchSql(updateSql, updateParamList);
            }

            /**
             * 执行批量插入使用记录操作，如果失败，插入记录整体回滚
             */
            if (usageHistoryEntityList.size() > 0) {
                KQUsageHistoryBiz usageHistoryBiz = new KQUsageHistoryBiz();
                flag = usageHistoryBiz.save(usageHistoryEntityList);
            }
        } catch (Exception e) {
            writeLog(e);
        }
        return flag;
    }
}
