package com.kingdee.eas.custom.dormitorysystem.application.app;

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.bos.metadata.entity.SelectorItemCollection;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.basedata.person.IPerson;
import com.kingdee.eas.basedata.person.PersonFactory;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.dormitorysystem.application.*;
import com.kingdee.eas.custom.dormitorysystem.application.utils.CheckDuplicateCheckInByBillIdUtil;
import com.kingdee.eas.custom.dormitorysystem.application.utils.ValidateRoomAvailableByBillIdsUtil;
import com.kingdee.eas.custom.dormitorysystem.occupants.IOccupants;
import com.kingdee.eas.custom.dormitorysystem.occupants.OccupantsFactory;
import com.kingdee.eas.custom.dormitorysystem.occupants.OccupantsInfo;
import com.kingdee.eas.custom.dormitorysystem.otherbasicdata.PersonDormitoryTypeInfo;
import com.kingdee.eas.custom.dormitorysystem.waterelectricity.IWaterElectricity;
import com.kingdee.eas.custom.dormitorysystem.waterelectricity.WaterElectricityCollection;
import com.kingdee.eas.custom.dormitorysystem.waterelectricity.WaterElectricityFactory;
import com.kingdee.eas.framework.CoreBaseInfo;
import com.kingdee.eas.hr.affair.AffairBizException;
import com.kingdee.eas.hr.ats.AtsUtil;
import com.kingdee.eas.hr.base.HRBaseException;
import com.kingdee.eas.hr.base.HRBillBaseInfo;
import com.kingdee.eas.hr.base.HRBillStateEnum;
import com.kingdee.eas.hr.emp.IPersonPosition;
import com.kingdee.eas.hr.emp.PersonPositionFactory;
import com.kingdee.eas.hr.emp.PersonPositionInfo;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.shr.base.syssetting.BaseItemException;
import com.kingdee.shr.base.syssetting.BasicItemStateEnum;
import com.kingdee.util.StringUtils;
import org.apache.log4j.Logger;

import java.text.SimpleDateFormat;
import java.util.*;

public class CheckInApplicationControllerBean extends AbstractCheckInApplicationControllerBean {
    private static Logger logger = Logger.getLogger(CheckInApplicationControllerBean.class);

    /**
     * 校验单据（流程中使用）
     *
     * @param ctx
     * @param billID
     * @return
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected boolean _validateBillInProcess(Context ctx, BOSUuid billID) throws BOSException, EASBizException {
        boolean isError = super._validateBillInProcess(ctx, billID);
        if (!isError) {
            if (billID == null) {
                throw new BOSException("单据id不能为空!");
            }
            //校验单据
            CheckInApplicationInfo info = getCheckInApplicationInfo(ctx, new ObjectUuidPK(billID));
            try {
                HRBillStateEnum billState = info.getBillState();
                if (HRBillStateEnum.AUDITED.equals(billState)) {
                    throw new BOSException("单据已经审批通过，请勿重复操作！");
                }
                //根据单据id校验房间是否入住(批量)
                ValidateRoomAvailableByBillIdsUtil.startValidate(ctx, billID.toString());
                //检查入住申请单是否重复、入住信息是否重复,时间是否交叉
                CheckDuplicateCheckInByBillIdUtil.startValidate(ctx, billID.toString());
            } catch (Exception e) {
                logger.error(e);
                SelectorItemCollection sic = new SelectorItemCollection();
                sic.add("errorMsg");
                //设置校验信息
                info.setErrorMsg(e.getMessage());
                updatePartial(ctx, info, sic);
                return true;
            }
        }
        return isError;
    }


    @Override
    protected void _setSubmited(Context ctx, BOSUuid billID) throws BOSException, EASBizException {
        super._setSubmited(ctx, billID);
        //清空错误信息
        CheckInApplicationInfo info = getCheckInApplicationInfo(ctx, new ObjectUuidPK(billID));
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("errorMsg");
        //设置校验信息
        info.setErrorMsg(null);
        updatePartial(ctx, info, sic);
    }


    @Override
    protected void _setAuditing(Context ctx, BOSUuid billID) throws BOSException, EASBizException {
        super._setAuditing(ctx, billID);
        //清空错误信息
        CheckInApplicationInfo info = getCheckInApplicationInfo(ctx, new ObjectUuidPK(billID));
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("errorMsg");
        //设置校验信息
        info.setErrorMsg(null);
        updatePartial(ctx, info, sic);
    }

    /**
     * 设置申请通过
     * 流程中调用
     *
     * @param ctx
     * @param billID
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _setAudited(Context ctx, BOSUuid billID) throws BOSException, EASBizException {
        //校验单据
        CheckInApplicationInfo info = getCheckInApplicationInfo(ctx, new ObjectUuidPK(billID));
        IOccupants iOccupants = OccupantsFactory.getLocalInstance(ctx);
        IPersonPosition iPersonPosition = PersonPositionFactory.getLocalInstance(ctx);
        IPerson iPerson = PersonFactory.getLocalInstance(ctx);
        CheckInApplicationEntryCollection entrys = info.getEntrys();
        for (int i = 0; i < entrys.size(); i++) {
            CheckInApplicationEntryInfo entryInfo = entrys.get(i);
            PersonInfo personInfo = entryInfo.getPerson();
            String personId = personInfo.getId().toString();
            personInfo = iPerson.getPersonInfo(new ObjectUuidPK(personId));
            //生成入住人员信息
            PersonPositionInfo pp = iPersonPosition.getPersonPositionInfo(
                    "select personDep.*,primaryPosition.* where person = '" + personId + "'");
            //生成入住人员信息
            OccupantsInfo occupantsInfo = new OccupantsInfo();
            //入住人员
            occupantsInfo.setPerson(personInfo);
            //入住日期
            occupantsInfo.setCheckInDate(entryInfo.getCheckInDate());
            //退宿日期
            occupantsInfo.setCheckOutDate(entryInfo.getCheckoutDate());
            //入住房间
            occupantsInfo.setDormitory(entryInfo.getCheckInRoom());
            //人员宿舍分类
            occupantsInfo.setPersonDormitoryType((PersonDormitoryTypeInfo) personInfo.get("personType"));
            occupantsInfo.setPersonPosition(pp);
            //状态:启用
            occupantsInfo.setState(BasicItemStateEnum.ENABLE);
            iOccupants.addnew(occupantsInfo);
            entryInfo.setOccupants(occupantsInfo);
        }
        //更新
        update(ctx, new ObjectUuidPK(billID), info);
        super._setAudited(ctx, billID);
    }


    /**
     * 删除
     *
     * @param ctx
     * @param pk
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _delete(Context ctx, IObjectPK pk) throws BOSException, EASBizException {
        HRBillBaseInfo info = (HRBillBaseInfo) this._getValue(ctx, pk);
        HRBillStateEnum billState = info.getBillState();
        boolean isRemovable = true;
        //已提交、审批中、审批通过的单据不允许删除
        if (HRBillStateEnum.SUBMITED.equals(billState)
                || HRBillStateEnum.AUDITING.equals(billState)
                || HRBillStateEnum.AUDITED.equals(billState)) {
            isRemovable = false;
        }
        if (!isRemovable) {
            throw new AffairBizException(AffairBizException.BILLCANTDELETE);
        }
        super._delete(ctx, pk);
    }


    /**
     * 提交生效
     *
     * @param ctx
     * @param billId
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected IObjectPK _submitEffect(Context ctx, String billId) throws BOSException, EASBizException {
        if (StringUtils.isEmpty(billId)) {
            throw new BaseItemException(BaseItemException.CUSTOM_EXCEPTION, new Object[]{"单据id不能为空!"});
        }
        //校验单据
        CheckInApplicationInfo info = getCheckInApplicationInfo(ctx, new ObjectUuidPK(billId));
        HRBillStateEnum billState = info.getBillState();
        if (HRBillStateEnum.AUDITED.equals(billState)) {
            throw new BaseItemException(BaseItemException.CUSTOM_EXCEPTION, new Object[]{"单据已经审批通过，请勿重复操作！"});
        }
        try {
            //根据单据id校验房间是否入住(批量)
            ValidateRoomAvailableByBillIdsUtil.startValidate(ctx, billId);
            //检查入住申请单是否重复、入住信息是否重复,时间是否交叉
            CheckDuplicateCheckInByBillIdUtil.startValidate(ctx, billId);
        } catch (Exception e) {
            logger.error(e);
            throw new BaseItemException(BaseItemException.CUSTOM_EXCEPTION, new Object[]{e.getMessage()});
        }
//        IOccupants iOccupants = OccupantsFactory.getLocalInstance(ctx);
//        IPerson iPerson = PersonFactory.getLocalInstance(ctx);
//        IPersonPosition iPersonPosition = PersonPositionFactory.getLocalInstance(ctx);
//        CheckInApplicationEntryCollection entrys = info.getEntrys();
//        for (int i = 0; i < entrys.size(); i++) {
//            CheckInApplicationEntryInfo entryInfo = entrys.get(i);
//            PersonInfo personInfo = entryInfo.getPerson();
//            String personId = personInfo.getId().toString();
//            personInfo = iPerson.getPersonInfo(new ObjectUuidPK(personId));
//            //生成入住人员信息
//            PersonPositionInfo pp = iPersonPosition.getPersonPositionInfo(
//                    "select personDep.*,primaryPosition.* where person = '" + personId + "'");
//            //生成入住人员信息
//            OccupantsInfo occupantsInfo = new OccupantsInfo();
//            //入住人员
//            occupantsInfo.setPerson(personInfo);
//            //入住日期
//            occupantsInfo.setCheckInDate(entryInfo.getCheckInDate());
//            //退宿日期
//            occupantsInfo.setCheckOutDate(entryInfo.getCheckoutDate());
//            //入住房间
//            occupantsInfo.setDormitory(entryInfo.getCheckInRoom());
//            //人员宿舍分类
//            occupantsInfo.setPersonDormitoryType((PersonDormitoryTypeInfo) personInfo.get("personType"));
//            occupantsInfo.setPersonPosition(pp);
//            //状态:启用
//            occupantsInfo.setState(BasicItemStateEnum.ENABLE);
//            iOccupants.addnew(occupantsInfo);
//            entryInfo.setOccupants(occupantsInfo);
//        }
//        //更新
//        update(ctx, new ObjectUuidPK(billId), info);
        //提交
        return super._submitEffect(ctx, info);
    }

    /**
     * 提交生效
     *
     * @param ctx
     * @param model
     * @return
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected IObjectPK _submitEffect(
            Context ctx,
            CoreBaseInfo model
    ) throws BOSException, EASBizException {
        String billId = model.getId().toString();
        return _submitEffect(ctx, billId);
    }

    /**
     * 反审批单据
     *
     * @param ctx
     * @param billId
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _untiCheckBizBill(
            Context ctx,
            String billId
    ) throws BOSException, EASBizException {
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("*");
        sic.add("entrys.*");
        sic.add("entrys.person.*");
        CheckInApplicationInfo info = getCheckInApplicationInfo(ctx, new ObjectUuidPK(billId), sic);
        HRBillStateEnum billState = info.getBillState();
        if (!HRBillStateEnum.AUDITED.equals(billState)) {
            throw new AffairBizException(HRBaseException.BILLSTATECANUNCHECK);
        }
        IOccupants iOccupants = OccupantsFactory.getLocalInstance(ctx);
        IRoomChangeApplicationEntry iRoomChangeApplicationEntry = RoomChangeApplicationEntryFactory.getLocalInstance(ctx);
        ICheckoutApplicationEntry iCheckoutApplicationEntry = CheckoutApplicationEntryFactory.getLocalInstance(ctx);
        IWaterElectricity iWaterElectricity = WaterElectricityFactory.getLocalInstance(ctx);
        Set<String> occupantsIds = new HashSet<String>();
        CheckInApplicationEntryCollection entrys = info.getEntrys();
        StringBuilder errorMsg = new StringBuilder();
        Set<String> entryIds = new HashSet<String>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        for (int i = 0; i < entrys.size(); i++) {
            CheckInApplicationEntryInfo entryInfo = entrys.get(i);
            Date checkInDate = entryInfo.getCheckInDate();
            Date checkoutDate = entryInfo.getCheckoutDate();
            PersonInfo person = entryInfo.getPerson();
            String personId = person.getId().toString();
            OccupantsInfo occupants = entryInfo.getOccupants();
            String occupantsId = occupants.getId().toString();
            //检查是否有退宿流程
            RoomChangeApplicationEntryCollection roomChangeApplicationEntryCollection = iRoomChangeApplicationEntry.getRoomChangeApplicationEntryCollection("select parent.number where oldOccupants = '" + occupantsId + "'");
            if (roomChangeApplicationEntryCollection.size() > 0) {
                RoomChangeApplicationEntryInfo roomChangeApplicationEntryInfo = roomChangeApplicationEntryCollection.get(0);
                String number = roomChangeApplicationEntryInfo.getParent().getNumber();
                errorMsg.append("员工 " + person.getName() + "已有换宿单[ " + number + " ]，不能反审核！\n");
            }
            //检查是否有换宿流程
            CheckoutApplicationEntryCollection checkoutApplicationEntryCollection = iCheckoutApplicationEntry.getCheckoutApplicationEntryCollection("select parent.number where occupants = '" + occupantsId + "'");
            if (checkoutApplicationEntryCollection.size() > 0) {
                CheckoutApplicationEntryInfo checkoutApplicationEntryInfo = checkoutApplicationEntryCollection.get(0);
                String number = checkoutApplicationEntryInfo.getParent().getNumber();
                errorMsg.append("员工 " + person.getName() + "已有退宿单[ " + number + " ]，不能反审核！\n");
            }
            //有水电明细的可以不可以反审批
            String filter = "where person.id = '" + personId + "' and yearMonth >= '" + dateFormat.format(checkInDate) + "' and yearMonth <='" + dateFormat.format(checkoutDate) + "'";
            WaterElectricityCollection waterElectricityCol = iWaterElectricity.getWaterElectricityCollection(filter);
            if (waterElectricityCol.size() > 0) {
                errorMsg.append("员工 " + person.getName() + " 已经产生水电明细，不能反审核！\n");
            }
            occupantsIds.add(occupantsId);
            entryIds.add(entryInfo.getId().toString());
        }
        if (errorMsg.length() > 0) {
            throw new BaseItemException(BaseItemException.CUSTOM_EXCEPTION, new Object[]{errorMsg.toString()});
        }
        super._untiCheckBizBill(ctx, billId);
        if (!occupantsIds.isEmpty()) {
            iOccupants.delete("where id in (" + AtsUtil.convertSetToString(occupantsIds) + ")");
            //更新入住信息为空
            if (!entryIds.isEmpty()) {
                String updateSql = "update CT_APP_CheckInAE set CFOccupantsID = null where fid in (" + AtsUtil.convertSetToString(entryIds) + ")";
                DbUtil.execute(ctx, updateSql);
            }
        }
    }
}