package com.kingdee.eas.hr.affair.app;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.bos.dao.ormapping.ObjectStringPK;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.metadata.entity.SelectorItemCollection;
import com.kingdee.bos.metadata.entity.SelectorItemInfo;
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.facade.leave.LeaveAllowanceFacadeFactory;
import com.kingdee.eas.custom.facade.plurality.IPluralitySubFacade;
import com.kingdee.eas.custom.facade.plurality.PluralitySubFacadeFactory;
import com.kingdee.eas.custom.utils.SendUtils;
import com.kingdee.eas.framework.CoreBaseInfo;
import com.kingdee.eas.hr.affair.*;
import com.kingdee.eas.hr.base.HRBillBaseEntryInfo;
import com.kingdee.eas.mobile.BOSMsgTypeEnum;
import com.kingdee.eas.mobile.PriorityEnum;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import com.kingdee.util.DateTimeUtils;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

/**
 * @ClassName ResignBizBillControllerBeanEx
 * @Description 离职单controllerbean扩展类
 * @Author VenkoXie
 * @Date 2024/1/25 17:11
 * @Version 1.0
 **/
public class ResignBizBillControllerBeanEx extends ResignBizBillControllerBean{

	private static Logger logger =
	        Logger.getLogger("com.kingdee.eas.hr.affair.app.ResignBizBillControllerBeanEx");
	
    /**
     * 审批通过
     * @param ctx
     * @param entry
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _entryEffectOthers(Context ctx, HRBillBaseEntryInfo entry) throws BOSException, EASBizException {
        super._entryEffectOthers(ctx, entry);
        // HRAffairBizBillEntryInfo affairEntry = (HRAffairBizBillEntryInfo)entry;
        // PersonInfo pInfo = PersonFactory.getLocalInstance(ctx).getPersonInfo(new ObjectUuidPK(affairEntry.getPerson().getId()));
        // LeaveAllowanceFacadeFactory.getLocalInstance(ctx).createAnnualLeave(0, pInfo.getNumber());
    }

    @Override
    protected void _auditEntryEffect(Context ctx, BOSUuid billID) throws BOSException, EASBizException {
        super._auditEntryEffect(ctx, billID);
        ResignBizBillEntryCollection entryCollection = ResignBizBillEntryFactory.getLocalInstance(ctx).getResignBizBillEntryCollection("where bill.id = '" + billID + "'");
        int year = DateTimeUtils.getYear(new Date());
        for (int i = 0; i < entryCollection.size(); i++) {
            HRAffairBizBillEntryInfo affairEntry = (HRAffairBizBillEntryInfo)entryCollection.get(i);
            PersonInfo pInfo = PersonFactory.getLocalInstance(ctx).getPersonInfo(new ObjectUuidPK(affairEntry.getPerson().getId()));
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).createAnnualLeave(year, pInfo.getNumber());
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).creareNursingLeave(year, pInfo.getNumber());
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).creareParentalLeave(year, pInfo.getNumber());
            ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
            scheduledThreadPoolExecutor.schedule(()->{
                try {
                    LeaveAllowanceFacadeFactory.getLocalInstance(ctx).createAnnualLeave(year, pInfo.getNumber());
                } catch (BOSException e) {
                    e.printStackTrace();
                }
            }, 1, TimeUnit.MINUTES);
        }
        
        //离职后更新薪酬结构失效日期
        for (int i = 0; i < entryCollection.size(); i++) {
        	HRAffairBizBillEntryInfo affairEntry = (HRAffairBizBillEntryInfo)entryCollection.get(i);
           	//兼职终止单; 202503
        	ResignBizBillEntryInfo resignBizBillEntryInfo = entryCollection.get(i);
        	createPDelFromEntry(ctx, resignBizBillEntryInfo);
        	//更新人员档案上的兼职失效日期
        	updateJobEndTime(ctx, resignBizBillEntryInfo.getId().toString());
        	
        	String personId = affairEntry.getPerson().getId().toString();
        	String sql = "/*dialect*/update T_HR_SFixAdjustSalary a set CFHisLeffectDay = FLeffectDay,FLeffectDay = b.FBIZDATE from T_HR_ResignBizBillEntry b where a.FPERSONID = b.FPERSONID and a.FLEFFECTDAY > b.FBIZDATE and a.FPERSONID = '"+personId+"'";
        	logger.error("更新薪酬结构失效日期SQL："+sql);
        	DbUtil.execute(ctx, sql);
        }
        
        //邮件发送移动至此方法;
        try {
			sendResignMessage(ctx, entryCollection);
		} catch (SQLException e) {
			e.printStackTrace();
		}
    }
    
    @Override
    protected IObjectPK _submitEffect(Context ctx, CoreBaseInfo model) throws BOSException, EASBizException {
    	IObjectPK objectPk = super._submitEffect(ctx, model);
    	//邮件发送移动
//    	ResignBizBillInfo resignBizBillInfo = ResignBizBillFactory.getLocalInstance(ctx).getResignBizBillInfo(objectPk);
//    	ResignBizBillEntryCollection entrys = resignBizBillInfo.getEntrys();
//    	try {
//			sendResignMessage(ctx, entrys);
//		} catch (SQLException e) {
//			e.printStackTrace();
//		}
    	return objectPk;
    }
    
    private void sendResignMessage(Context ctx, ResignBizBillEntryCollection entryCollection) throws BOSException, SQLException, EASBizException {
    	System.out.print("进来了邮件的方法");
    	for (int i = 0; i < entryCollection.size(); i++) {
    		HRAffairBizBillEntryInfo affairEntry = (HRAffairBizBillEntryInfo)entryCollection.get(i);
        	String personId = affairEntry.getPerson().getId().toString();
//        	String personName = affairEntry.getPerson().getName();
//        	String sql = "SELECT a.*,b.fid userid FROM T_HR_EmpOrgRelation a left join t_pm_user b on a.fpersonid = b.fpersonid where a.fpersonid = '"+personId+"' and a.fislatestinaday = '1' and a.cfhourlywage is not null and a.cfhourlywage <> 0 and year(a.fleffdt) = 2199";
//        	String sql="SELECT a.*,c.fid as userid,d.fname_l1 as personName FROM T_HR_EmpOrgRelation a right join (SELECT max(a.fleffdt)as fleffdt,a.cfhourlywage as cfhourlywage, a.fpersonid as fpersonid FROM T_HR_EmpOrgRelation a where a.fpersonid='"+personId+"'   and a.cfhourlywage is not null and a.cfhourlywage <> 0   and a.fislatestinaday = '1' group by a.fpersonid,a.cfhourlywage)b\r\n" +
//        			"on a.fpersonid=b.fpersonid and a.fleffdt=b.fleffdt and a.cfhourlywage =b.cfhourlywage\r\n" +
//        			" left join t_pm_user c on a.fpersonid = c.fpersonid left join t_bd_person d on d.fid =a.fpersonid\r\n" +
//        			" where a.fpersonid='"+personId+"'  and a.cfhourlywage is not null and a.cfhourlywage <> 0  and a.fislatestinaday = '1' ";
			//202511改,使用最新的一条变动记录来进行判断, (处理再入职人员的场景)
			String sql = "SELECT " +
					"    a.*, " +
					"    c.fid as userid, " +
					"    d.fname_l1 as personName " +
					"FROM T_HR_EmpOrgRelation a " +
					"RIGHT JOIN ( " +
					"    SELECT " +
					"        a.fpersonid, " +
					"        MAX(a.fleffdt) as max_fleffdt " +
					"    FROM T_HR_EmpOrgRelation a " +
					"    WHERE a.fpersonid = ? " +
					"        AND a.fislatestinaday = '1' " +
					"    GROUP BY a.fpersonid " +
					") b ON a.fpersonid = b.fpersonid AND a.fleffdt = b.max_fleffdt " +
					"LEFT JOIN t_pm_user c ON a.fpersonid = c.fpersonid " +
					"LEFT JOIN t_bd_person d ON d.fid = a.fpersonid " +
					"WHERE a.fpersonid = ? " +
					"    AND a.fislatestinaday = '1' " +
					"    AND a.cfhourlywage is not null " +
					"    AND a.cfhourlywage <> 0";


			logger.error("查询变动记录SQL："+sql);
        	IRowSet row = DbUtil.executeQuery(ctx, sql, new String[]{personId, personId});
        	String userId = "";
        	while(row.next()) {
        		userId = row.getString("userid");
        		Date bizDate = affairEntry.getBizDate();
//        		Instant instant = bizDate.toInstant();  
        		// 使用系统默认的时区来获取 LocalDate  
//                ZoneId zoneId = ZoneId.systemDefault();  
//                LocalDate currentDate = instant.atZone(zoneId).toLocalDate();
        		// 格式化为英文月份
//        		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM", Locale.ENGLISH);
//        		String thisMonthName = currentDate.format(formatter);
        		String bizDateStr = com.kingdee.eas.custom.utils.DateTimeUtils.dateFormat(bizDate, "yyyy-MM-dd");
        		List<String> list = new ArrayList<String>();
        		list.add(userId);
        		String title = "Reminder: Working hours submission";
        		StringBuffer body = new StringBuffer();
        		body.append("Dear "+row.getString("personName")+","); 
        		body.append("\r\n"); 
        		body.append("As your part-time assignment will end on "+bizDateStr+", please remember to submit working hours in the system if you have unapplied working hours. ");
        		body.append("Please refer to below instruction and select [Working hours submission for employees with ending PT assignments] in submission scheme in the system."); 
        		body.append("\r\n"); 
        		body.append("\r\n"); 
        		body.append("Please submit working hours before "+bizDateStr+", otherwise you cannot login to the system to submit it and late submission will not be accepted.");
        		body.append("\r\n"); 
        		body.append("\r\n"); 
        		body.append("This is an automatic workflow email. Do not reply to this mail.");
        		body.append("\r\n");
        		body.append("\r\n"); 
        		body.append("\r\n"); 
        		body.append("Best regards,");
        		body.append("\r\n"); 
        		body.append("Human Resources Department");
        		logger.error("离职发送邮件内容："+body.toString());
        		SendUtils.msgGroupSend(ctx, title, PriorityEnum.HIGHT_VALUE, false, body.toString(), list, BOSMsgTypeEnum.V_TYPE_EMAIL, null);
        	}
    	}
    }

    @Override
    protected void _setAudited(Context ctx, BOSUuid billID) throws BOSException, EASBizException {
        super._setAudited(ctx, billID);
        ResignBizBillEntryCollection entryCollection = ResignBizBillEntryFactory.getLocalInstance(ctx).getResignBizBillEntryCollection("where bill.id = '" + billID + "'");
        int year = DateTimeUtils.getYear(new Date());
        for (int i = 0; i < entryCollection.size(); i++) {
            HRAffairBizBillEntryInfo affairEntry = (HRAffairBizBillEntryInfo)entryCollection.get(i);
            PersonInfo pInfo = PersonFactory.getLocalInstance(ctx).getPersonInfo(new ObjectUuidPK(affairEntry.getPerson().getId()));
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).createAnnualLeave(year, pInfo.getNumber());
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).creareNursingLeave(year, pInfo.getNumber());
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).creareParentalLeave(year, pInfo.getNumber());
            ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
            scheduledThreadPoolExecutor.schedule(()->{
                try {
                    LeaveAllowanceFacadeFactory.getLocalInstance(ctx).createAnnualLeave(year, pInfo.getNumber());
                } catch (BOSException e) {
                    e.printStackTrace();
                }
            }, 2, TimeUnit.MINUTES);
        }
 
        
    }

    /**
     * 反审批
     * @param ctx
     * @param billId
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _passUnaudit(Context ctx, BOSUuid billId) throws BOSException, EASBizException {
        super._passUnaudit(ctx, billId);
        ResignBizBillEntryCollection entryCollection = ResignBizBillEntryFactory.getLocalInstance(ctx).getResignBizBillEntryCollection("where bill.id = '" + billId + "'");
        int year = DateTimeUtils.getYear(new Date());
        for (int i = 0; i < entryCollection.size(); i++) {
            HRAffairBizBillEntryInfo affairEntry = (HRAffairBizBillEntryInfo)entryCollection.get(i);
            PersonInfo pInfo = PersonFactory.getLocalInstance(ctx).getPersonInfo(new ObjectUuidPK(affairEntry.getPerson().getId()));
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).createAnnualLeave(year, pInfo.getNumber());
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).creareNursingLeave(year, pInfo.getNumber());
            LeaveAllowanceFacadeFactory.getLocalInstance(ctx).creareParentalLeave(year, pInfo.getNumber());
        }
        
        //离职反审批后还原薪酬结构失效日期
        for (int i = 0; i < entryCollection.size(); i++) {
        	//更新人员档案上的兼职失效日期
        	ResignBizBillEntryInfo resignBizBillEntryInfo = entryCollection.get(i);
        	reJobEndTime(ctx, resignBizBillEntryInfo.getId() );
        	HRAffairBizBillEntryInfo affairEntry = (HRAffairBizBillEntryInfo)entryCollection.get(i);
        	String personId = affairEntry.getPerson().getId().toString();
        	String sql = "/*dialect*/update T_HR_SFixAdjustSalary set FLeffectDay = CFHisLeffectDay where CFHisLeffectDay is not null "
        			+ " and FPERSONID = '"+personId+"' and FLEFFECTDAY = (SELECT max(FLEFFECTDAY) FROM T_HR_SFixAdjustSalary where FPERSONID = '"+personId+"')";
        	logger.error("更新薪酬结构失效日期SQL："+sql);
        	DbUtil.execute(ctx, sql);
        }
    }
    
    
    
    /**
     * 创建兼职终止单等二开内容
     * 202503  暂未调用; 已有其他方法调用其中总内容
     * @throws BOSException 
     * @throws EASBizException 
     */
    private void createPDelBizBill(Context ctx, BOSUuid billId) throws EASBizException, BOSException {
    	//兼职单与兼职终止的关系;
    	//人员 , 开始时间, 职位,部门,  兼职时薪
		ResignBizBillInfo billInfo = ResignBizBillFactory.getLocalInstance(ctx).getResignBizBillInfo(new ObjectUuidPK(billId));
		ResignBizBillEntryCollection entrys = billInfo.getEntrys();
		//暂未调用;
//		for(int i = 0 ; i<entrys.size();i++){
//			ResignBizBillEntryInfo resignBizBillEntryInfo = entrys.get(i);
//			createPDelFromEntry(ctx, resignBizBillEntryInfo);
//			BOSUuid id = resignBizBillEntryInfo.getId();
//			updateJobEndTime(ctx,id.toString()  );
//		}
    }
    
    
    
    /**
     * 根据离职单分录的数据生成兼职单
     * @param ctx
     * @param resignBizBillEntryInfo
     * @throws BOSException
     * @throws EASBizException
     */
    private void  createPDelFromEntry(Context ctx, ResignBizBillEntryInfo resignBizBillEntryInfo) throws BOSException, EASBizException {
    	String personId = resignBizBillEntryInfo.getPerson().getId().toString();
		Date bizDate = resignBizBillEntryInfo.getBizDate();
        String dateStr   = DateTimeUtils.format(bizDate, "yyyy-MM-dd");
		IPluralitySubFacade pluralityIns = PluralitySubFacadeFactory.getLocalInstance(ctx);
		pluralityIns.resignCreateEnd(personId, dateStr);
    }
    
    
    
    @Override
    protected void _entryEffectCommon(Context ctx, BOSUuid billId) throws BOSException, EASBizException {
    	super._entryEffectCommon(ctx, billId);
    	
	}
    
    
    /**
     * 审核后,更新人员档案上的兼职人员任职结束时间
     * 全职或兼职 等于 兼职 人员离职时，离职时间更新到员工提报单中的结束时间，如果离职单反审批，员工提报单主职则继续使用人员档案兼职类人员任职结束时间时间；
     * @param ctx
     * @param billId
     * @throws BOSException
     * @throws EASBizException
     */
    private void updateJobEndTime(Context ctx, String billId) throws BOSException, EASBizException {
    	//全职或兼职 等于 兼职 人员离职时，离职时间更新到员工提报单中的结束时间，如果离职单反审批，员工提报单主职则继续使用人员档案兼职类人员任职结束时间时间；
    	IResignBizBillEntry reEnIns = ResignBizBillEntryFactory .getLocalInstance(ctx);
		ResignBizBillEntryInfo enInfo =  reEnIns.getResignBizBillEntryInfo( new ObjectUuidPK(billId.toString()));
		PersonInfo person = enInfo.getPerson();
		//离职日期
		Date bizDate = enInfo.getBizDate();
		IPerson pIns = PersonFactory.getLocalInstance(ctx);
	 
		SelectorItemCollection sic = new SelectorItemCollection();
		sic.add(new SelectorItemInfo("ftorpt.number"));
		sic.add(new SelectorItemInfo("ftorpt"));
		sic.add(new SelectorItemInfo("jobEndTime"));
		PersonInfo personInfo = pIns.getPersonInfo(new ObjectUuidPK(person.getId().toString()),sic);
		CoreBaseInfo torpt  = (CoreBaseInfo) personInfo.get("ftorpt");
		
		if(null != torpt)  {
			String torptNum = torpt.getString("number");
			if(StringUtils.equals(torptNum, "PART")) {
				Date jobEndTime = personInfo.getDate("jobEndTime");
				PersonInfo upPerson = pIns.getPersonInfo(new ObjectUuidPK(person.getId().toString()));
				upPerson.put( "jobEndTime", bizDate) ; 
				pIns.update(new ObjectStringPK(upPerson.getId().toString()), upPerson) ;
				enInfo.put("oldJobEndTime", jobEndTime );
				reEnIns.update(new ObjectStringPK(enInfo.getId().toString()), enInfo) ;
			}
		}
    }
    
   
    /**
     * 反审核后,恢复人员档案上的兼职人员任职结束时间
     * 全职或兼职 等于 兼职 人员离职时，离职时间更新到员工提报单中的结束时间，如果离职单反审批，员工提报单主职则继续使用人员档案兼职类人员任职结束时间时间；
     * @param ctx
     * @param billId
     * @throws BOSException
     * @throws EASBizException
     */
    private void reJobEndTime(Context ctx, BOSUuid billId) throws BOSException, EASBizException {
    	//全职或兼职 等于 兼职 人员离职时，离职时间更新到员工提报单中的结束时间，如果离职单反审批，员工提报单主职则继续使用人员档案兼职类人员任职结束时间时间；
    	IResignBizBillEntry reEnIns = ResignBizBillEntryFactory .getLocalInstance(ctx);
		ResignBizBillEntryInfo enInfo =  reEnIns.getResignBizBillEntryInfo( new ObjectUuidPK(billId.toString()));
		PersonInfo person = enInfo.getPerson();
		//离职日期
		Date oldETime = enInfo.getDate("oldJobEndTime");
		IPerson pIns = PersonFactory.getLocalInstance(ctx);
		SelectorItemCollection sic = new SelectorItemCollection();
		sic.add(new SelectorItemInfo("ftorpt.number"));
		sic.add(new SelectorItemInfo("ftorpt"));
		PersonInfo personInfo = pIns.getPersonInfo(new ObjectUuidPK(person.getId().toString()),sic);
		CoreBaseInfo torpt  = (CoreBaseInfo) personInfo.get("ftorpt");
		if( null != torpt ) {
			String torptNum = torpt.getString("number");
			if( StringUtils.equals(torptNum, "PART") ) {
				PersonInfo upPerson = pIns.getPersonInfo(new ObjectUuidPK(person.getId().toString()));
				if(null!= oldETime) {
					upPerson.put( "jobEndTime", oldETime) ; 
					pIns.update(new ObjectStringPK(upPerson.getId().toString()), upPerson) ;
				}
			}
		}
    }
    
    
    
}
