package com.kingdee.eas.custom.projectbonus.app;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.bos.dao.IObjectValue;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.metadata.data.SortType;
import com.kingdee.bos.metadata.entity.*;
import com.kingdee.eas.basedata.org.AdminOrgUnitInfo;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.projectbonus.BonusCycleBusDepProjectAssPersonnelDetailInfo;
import com.kingdee.eas.custom.projectbonus.BonusCycleBusDepProjectInfo;
import com.kingdee.eas.custom.projectbonus.bizEnum.BusDepProjectStateEnum;
import com.kingdee.eas.hr.emp.*;
import com.kingdee.eas.hr.org.IJobGrade;
import com.kingdee.eas.hr.org.JobGradeFactory;
import com.kingdee.eas.hr.org.JobGradeInfo;
import com.kingdee.util.DateTimeUtils;
import com.kingdee.util.StringUtils;
import org.apache.log4j.Logger;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

public class BonusCycleBusDepProjectAssPersonnelDetailControllerBean
        extends AbstractBonusCycleBusDepProjectAssPersonnelDetailControllerBean {
    private static Logger logger =
            Logger.getLogger(BonusCycleBusDepProjectAssPersonnelDetailControllerBean.class);

    /**
     * 保存
     *
     * @param ctx
     * @param model
     * @return
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected IObjectPK _save(Context ctx,
                              IObjectValue model) throws BOSException, EASBizException {
        BonusCycleBusDepProjectAssPersonnelDetailInfo info =
                (BonusCycleBusDepProjectAssPersonnelDetailInfo) model;
        PersonInfo personInfo = info.getPerson();
        //职级系数
        BigDecimal rankCoefficient = null;
        if (personInfo != null) {
            String personId = personInfo.getId().toString();
            //职位
            PersonPositionInfo personPositionInfo = PersonPositionFactory.getLocalInstance(ctx).getPersonPositionInfo("where person.id = '" + personId + "'");
            info.setPosition(personPositionInfo.getPrimaryPosition());
            //职等信息
            JobGradeInfo jobGrade = info.getGrade();
            if (jobGrade == null) {
                jobGrade = getJobGradeInfo(ctx, personId);
                if (jobGrade != null) {
                    rankCoefficient = jobGrade.getBigDecimal("coefficient");
                }
                info.setGrade(jobGrade);
            } else {
                IJobGrade iJobGrade = JobGradeFactory.getLocalInstance(ctx);
                jobGrade = iJobGrade.getJobGradeInfo(new ObjectUuidPK(jobGrade.getId()));
                rankCoefficient = jobGrade.getBigDecimal("coefficient");
            }
        } else {
            throw new BOSException("分配人员不能为空！");
        }
        //奖金期限起算日期
        Date bonusStartingDate = info.getBonusStartingDate();
        //奖金期限截止日期
        Date bonusDueDate = info.getBonusDueDate();
        if (bonusDueDate != null && bonusStartingDate != null) {
            if (bonusStartingDate.compareTo(bonusDueDate) >= 0) {
                throw new BOSException("奖金期限截止日期 不得早于或等于 奖金期限起算日期");
            }
            //出勤率 = (奖金期限截止日期-奖金期限起算日期)/180
            double day = DateTimeUtils.dateDiff(bonusStartingDate, bonusDueDate) / 86400000.0 / 180.0 * 100;
            if (day <= 0) {
                throw new BOSException("出勤率[" + day + "]不能小于等于0!");
            }
            BigDecimal attendanceRate = new BigDecimal(String.valueOf(day)).setScale(0, RoundingMode.HALF_UP);
            info.setAttendanceRate(attendanceRate);
        }
        //Q1绩效系数
        BigDecimal performanceCoeffQ1 = info.getPerformanceCoeffQ1();
        //Q2绩效系数
        BigDecimal performanceCoeffQ2 = info.getPerformanceCoeffQ2();
        if (performanceCoeffQ1 != null && performanceCoeffQ2 != null) {
            //个人考核系数
            BigDecimal assessmentCoeff = performanceCoeffQ1.add(performanceCoeffQ2).divide(BigDecimal.valueOf(2)).setScale(2, RoundingMode.HALF_UP);
            info.setAssessmentCoeff(assessmentCoeff);
        }
        //职能系数
        BigDecimal functionCoefficient = info.getFunctionCoefficient();
        //精力投入系数
        BigDecimal energyInputCoeff = info.getEnergyInputCoeff();
        //出勤率
        BigDecimal attendanceRate = info.getAttendanceRate();
        //个人考核系数
        BigDecimal assessmentCoeff = info.getAssessmentCoeff();
        if (functionCoefficient != null && energyInputCoeff != null
                && rankCoefficient != null && attendanceRate != null && assessmentCoeff != null) {
            //职能系数 * 精力投入系数 * 出勤率 * 职级系数 * 个人考核系数
            BigDecimal cumulative = functionCoefficient.multiply(energyInputCoeff)
                    .multiply(attendanceRate).multiply(rankCoefficient).multiply(assessmentCoeff).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            info.setCumulative(cumulative);
        }
        BigDecimal initialProportion = info.getInitialProportion();
        if (initialProportion != null && (initialProportion.compareTo(BigDecimal.ZERO) < 0 || initialProportion.compareTo(BigDecimal.ONE) > 0)) {
            throw new BOSException("个人初始比例只能在[0,1]之间");
        }
        //总经理审批金额默认等于征求意见金额
        info.setApprovalAmount(info.getOpinionAmount());
        return super._save(ctx, model);
    }

    /**
     * 通过员工id查询员工职层职等信息,返回职等信息
     *
     * @param ctx
     * @param personId
     * @return
     * @throws BOSException
     */
    private JobGradeInfo getJobGradeInfo(Context ctx, String personId) throws BOSException {
        IEmpPostRank iEmpPostRank = EmpPostRankFactory.getLocalInstance(ctx);
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("jobGrade.*");
        FilterInfo filterInfo = new FilterInfo();
        FilterItemCollection filterItems = filterInfo.getFilterItems();
        filterItems.add(new FilterItemInfo("person", personId));
        filterItems.add(new FilterItemInfo("isLatest", 1));
        SorterItemCollection sortItems = new SorterItemCollection();
        SorterItemInfo leffdtSortItem = new SorterItemInfo("LEFFDT");
        leffdtSortItem.setSortType(SortType.DESCEND);
        sortItems.add(leffdtSortItem);
        EntityViewInfo entityViewInfo = EntityViewInfo.getInstance(filterInfo, sic, sortItems);
        EmpPostRankCollection empPostRankCols = iEmpPostRank.getEmpPostRankCollection(entityViewInfo);
        if (empPostRankCols.size() > 0) {
            EmpPostRankInfo empPostRankInfo = empPostRankCols.get(0);
            return empPostRankInfo.getJobGrade();
        }
        return null;
    }

    /**
     * 更新部分
     *
     * @param ctx
     * @param model
     * @param sic
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _updatePartial(Context ctx, IObjectValue model,
                                  SelectorItemCollection sic) throws BOSException, EASBizException {
        BonusCycleBusDepProjectAssPersonnelDetailInfo info = (BonusCycleBusDepProjectAssPersonnelDetailInfo) model;
        String id = info.getId().toString();
        if (StringUtils.isEmpty(id)) {
            throw new BOSException("分配明细表id不能为空！");
        }
        for (int i = 0; i < sic.size(); i++) {
            String propertyName = sic.get(i).getPropertyName();
            if ("person".equals(propertyName)) {
                //如果更新分配人员信息，需要同步更新职位、职等和职级系数
                Object person = info.get("person");
                sic.add("position");
                sic.add("grade");
                if (person != null) {
                    String personId = null;
                    if (person instanceof String) {
                        personId = (String) person;
                    } else {
                        PersonInfo personInfo = (PersonInfo) person;
                        personId = personInfo.getId().toString();
                    }
                    //职位
                    PersonPositionInfo personPositionInfo = PersonPositionFactory.getLocalInstance(ctx).getPersonPositionInfo("where person.id = '" + personId + "'");
                    info.setPosition(personPositionInfo.getPrimaryPosition());
                    //职等信息
                    JobGradeInfo jobGrade = getJobGradeInfo(ctx, personId);
                    info.setGrade(jobGrade);
                } else {
                    throw new BOSException("分配人员不能为空！");
                }
            } else if ("initialProportion".equals(propertyName) && info.getInitialProportion() != null) {
                BigDecimal initialProportion = info.getInitialProportion();
                if (initialProportion.compareTo(BigDecimal.ZERO) < 0 || initialProportion.compareTo(BigDecimal.ONE) > 0) {
                    throw new BOSException("个人初始比例只能在[0,1]之间");
                }
//            } else if ("opinionamount".equals(propertyName) || "opinionAmount".equals(propertyName)) {
//                //总经理审批金额默认等于征求意见金额
//                info.setApprovalAmount(info.getOpinionAmount());
//                sic.add("approvalAmount");
            }
        }
        super._updatePartial(ctx, model, sic);
    }

    /**
     * 删除
     *
     * @param ctx
     * @param pk
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _delete(Context ctx, IObjectPK pk) throws BOSException, EASBizException {
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("parent.state");
        sic.add("parent.project.name");
        sic.add("parent.busDep.name");
        BonusCycleBusDepProjectAssPersonnelDetailInfo info =
                (BonusCycleBusDepProjectAssPersonnelDetailInfo) getValue(ctx, pk, sic);
        BonusCycleBusDepProjectInfo parent = info.getParent();
        BusDepProjectStateEnum state = parent.getState();
        if (!BusDepProjectStateEnum.ENABLE.equals(state)) {
            throw new BOSException(getBusDepMsg(parent) + "非启用状态，不允许删除该项目下的人员数据！");
        }
        super._delete(ctx, pk);
    }

    private String getBusDepMsg(BonusCycleBusDepProjectInfo info) {
        AdminOrgUnitInfo project = info.getProject();
        if (project != null) {
            String projectProject = project.getName();
            return "项目[" + projectProject + "]";
        } else {
            String busdepName = info.getBusDep().getName();
            return "事业部[" + busdepName + "]";
        }
    }
}