package com.jpsoft.shinestar.modules.business.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.annotation.Resource;

import cn.hutool.core.date.DateUtil;
import com.jpsoft.shinestar.config.WxConfig;
import com.jpsoft.shinestar.modules.base.entity.ApprovalConfig;
import com.jpsoft.shinestar.modules.base.entity.CompanyInfo;
import com.jpsoft.shinestar.modules.base.entity.PersonInfo;
import com.jpsoft.shinestar.modules.base.entity.PersonPopedom;
import com.jpsoft.shinestar.modules.base.service.ApprovalConfigService;
import com.jpsoft.shinestar.modules.base.service.CompanyInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonPopedomService;
import com.jpsoft.shinestar.modules.business.dto.ExaminePersonDTO;
import com.jpsoft.shinestar.modules.business.dto.UpdatePersonAttendanceDTO;
import com.jpsoft.shinestar.modules.business.service.WorkScheduleAttendanceService;
import com.jpsoft.shinestar.modules.common.utils.JwtUtil2;
import com.jpsoft.shinestar.modules.common.utils.WechatMessageUtil;
import com.jpsoft.shinestar.modules.workflow.entity.*;
import com.jpsoft.shinestar.modules.workflow.service.*;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Hours;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.jpsoft.shinestar.modules.business.dao.RequestForLeaveInfoDAO;
import com.jpsoft.shinestar.modules.business.entity.RequestForLeaveInfo;
import com.jpsoft.shinestar.modules.business.service.RequestForLeaveInfoService;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.github.pagehelper.PageHelper;

@Transactional(rollbackFor = Exception.class)
@Component(value = "requestForLeaveInfoService")
public class RequestForLeaveInfoServiceImpl implements RequestForLeaveInfoService {
    @Resource(name = "requestForLeaveInfoDAO")
    private RequestForLeaveInfoDAO requestForLeaveInfoDAO;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    private ProcessSetService processSetService;

    @Autowired
    private ProcessActivityService processActivityService;

    @Autowired
    private ProcessTemplateService processTemplateService;

    @Autowired
    private TemplateDepartmentService templateDepartmentService;

    @Autowired
    private ProcinstActivityService procinstActivityService;

    @Autowired
    private ProcinstActUserService procinstActUserService;

    @Autowired
    private ProcinstService procinstService;

    @Autowired
    private ApprovalConfigService approvalConfigService;

    @Autowired
    private WorkScheduleAttendanceService workScheduleAttendanceService;

    @Autowired
    RabbitTemplate rabbitTemplate;
    @Value("${jwt.secret}")
    private String jwtSecret;

    @Autowired
    private WxConfig wxConfig;

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private PersonPopedomService personPopedomService;

    @Override
    public RequestForLeaveInfo get(String id) {
        // TODO Auto-generated method stub
        return requestForLeaveInfoDAO.get(id);
    }

    @Override
    public int insert(RequestForLeaveInfo model) {
        // TODO Auto-generated method stub
        //model.setId(UUID.randomUUID().toString());

        return requestForLeaveInfoDAO.insert(model);
    }

    @Override
    public int update(RequestForLeaveInfo model) {
        // TODO Auto-generated method stub
        return requestForLeaveInfoDAO.update(model);
    }

    @Override
    public int delete(String id) {
        // TODO Auto-generated method stub
        return requestForLeaveInfoDAO.delete(id);
    }

    @Override
    public boolean exist(String id) {
        // TODO Auto-generated method stub
        int count = requestForLeaveInfoDAO.exist(id);

        return count > 0 ? true : false;
    }

    @Override
    public List<RequestForLeaveInfo> list() {
        // TODO Auto-generated method stub
        return requestForLeaveInfoDAO.list();
    }

    @Override
    public Page<RequestForLeaveInfo> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<RequestForLeaveInfo> page = PageHelper.startPage(pageNumber, pageSize, count).doSelectPage(() -> {
            requestForLeaveInfoDAO.search(searchParams, sortList);
        });

        return page;
    }

    @Override
    public Page<RequestForLeaveInfo> pageMobileSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<RequestForLeaveInfo> page = PageHelper.startPage(pageNumber, pageSize, count).doSelectPage(() -> {
            requestForLeaveInfoDAO.mobileSearch(searchParams, sortList);
        });
        return page;
    }

    @Override
    public Set<String> findHalfDaysByPersonIdAndDate(Long personId, Date startDate, Date endDate) {
        Set<String> halfDays = new HashSet<>();

        List<RequestForLeaveInfo> list = requestForLeaveInfoDAO.findByPersonIdAndDate(personId, startDate, endDate);

        for (RequestForLeaveInfo requestForLeaveInfo : list) {
            DateTime startTime = new DateTime(requestForLeaveInfo.getStartTime());
            DateTime endTime = new DateTime(requestForLeaveInfo.getEndTime());

            //注意请假以半天为单位
            if ("0".equals(requestForLeaveInfo.getStartTimeQuantum())) {
                //从上午开始请假
                halfDays.add(startTime.toString("yyyy-MM-dd") + " 上午");
            } else {
                halfDays.add(startTime.toString("yyyy-MM-dd") + " 下午");
            }

            int days = Days.daysBetween(startTime, endTime).getDays();

            if (days > 0) {
                //请假时间>=1天,则肯定包含请假开始时间的下午
                halfDays.add(startTime.toString("yyyy-MM-dd") + " 下午");
            }

            for (int i = 1; i < days; i++) {
                DateTime curTime = startTime.plusDays(i);
                halfDays.add(curTime.toString("yyyy-MM-dd") + " 上午");
                halfDays.add(curTime.toString("yyyy-MM-dd") + " 下午");
            }

            if ("0".equals(requestForLeaveInfo.getEndTimeQuantum())) {
                //请假到上午截止
                halfDays.add(endTime.toString("yyyy-MM-dd") + " 上午");
            } else {
                halfDays.add(endTime.toString("yyyy-MM-dd") + " 上午");
                halfDays.add(endTime.toString("yyyy-MM-dd") + " 下午");
            }
        }

        return halfDays;
    }

    @Override
    public List<RequestForLeaveInfo> findByPersonIdAndDate(Long personId, Date startTime, Date endTime) {
        return requestForLeaveInfoDAO.findByPersonIdAndDate(personId, startTime, endTime);
    }

    @Override
    public RequestForLeaveInfo findByPersonId(Long personId, String requestForLeaveTime) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String shortDate = requestForLeaveTime.substring(0, requestForLeaveTime.indexOf(" "));

        String startTimeStr = shortDate + " 00:00:00";
        String isMorningTimeStr = shortDate + " 12:00:00";

        Date startTime = sdf.parse(startTimeStr);
        Date isMorningTime = sdf.parse(isMorningTimeStr);

        Date leaveTime = sdf.parse(requestForLeaveTime);

        boolean isMorning = belongCalendar(leaveTime, startTime, isMorningTime);

        String timeQuantum;

        if (isMorning) {
            //上午
            timeQuantum = "0";
        } else {
            //下午
            timeQuantum = "1";
        }

        RequestForLeaveInfo requestForLeaveInfo = requestForLeaveInfoDAO.findByPersonIdAndTimeQuantum(personId, startTime, timeQuantum);

        return requestForLeaveInfo;

    }

    @Override
    public List<RequestForLeaveInfo> findByPersonAndStatus(Long personId, String status) {
        return requestForLeaveInfoDAO.findByPersonAndStatus(personId, status);
    }

    @Override
    public void approvalRequestForLeave(PersonInfo personInfo, String ids, String approvalOpinions, String approvalExplain, int status) throws Exception {

        //审核人
        PersonPopedom personPopedom = personPopedomService.get(personInfo.getPopedom());
        List<String> idList = Arrays.asList(ids.split(","));
        if (idList.size() > 0) {
            for (String id : idList) {
                RequestForLeaveInfo requestForLeaveInfo = get(id);
                if (requestForLeaveInfo.getStatus() == 0) {
                    //申请人
                    PersonPopedom personPopedom1 = personPopedomService.get(requestForLeaveInfo.getPersonPopedomId());
                    PersonInfo personInfo1 = personInfoService.get(personPopedom1.getPersonId());

                    if (!requestForLeaveInfo.getApprovedPersonPopedomId().equals(personInfo.getPopedom())) {
                        throw new Exception("无权审核");
                    }
                    String approvalPersonIdStr = requestForLeaveInfo.getApprovalPersonIdStr();
                    String approvalStatusStr = requestForLeaveInfo.getApprovalStatusStr();
                    String approvalTimeStr = requestForLeaveInfo.getApprovalTimeStr();
                    String approvalContentStr = requestForLeaveInfo.getApprovalContentStr();


                    //同意
                    if (status == 1) {
                        if ("4".equals(requestForLeaveInfo.getLeaveType())) {
                            int workOverTime = personPopedom1.getWorkOverTime();
                            Double needHours = new Double(requestForLeaveInfo.getDays()) * 8;
                            if (workOverTime < needHours) {
                                throw new Exception(personInfo1.getName() + "的调休时长不够");
                            }
                        }


                        List<PersonPopedom> personPopedomList = new ArrayList<>();

                        String companyId = "";
                        //申请人的公司
                        CompanyInfo companyInfo = companyInfoService.get(personPopedom1.getCompanyId());

                        if (!"1".equals(companyInfo.getUnitType())) {

                            CompanyInfo parent = null;
                            int loopNum = 10;
                            int zIndex = 0;
                            if (org.apache.commons.lang3.StringUtils.isNotEmpty(companyInfo.getParentId())) {
                                parent = companyInfoService.get(companyInfo.getParentId());
                            }
                            while (parent != null && zIndex < loopNum) {
                                ApprovalConfig approvalConfig = approvalConfigService.findByCompanyIdAndType(companyInfo.getId(), "4");
                                if (approvalConfig != null) {
                                    companyId = companyInfo.getId();
                                    break;
                                } else if (org.apache.commons.lang3.StringUtils.isBlank(companyInfo.getParentId())) {
                                    break;
                                } else {
                                    parent = companyInfoService.get(parent.getParentId());
                                    companyInfo = companyInfoService.get(companyInfo.getParentId());
                                    zIndex++;
                                }
                            }

							/*CompanyInfo parent = null;
							int loopNum = 10;
							int zIndex = 0;

							if (StringUtils.isNotEmpty(companyInfo.getParentId())) {
								parent = companyInfoService.get(companyInfo.getParentId());
							}
							while (parent != null && zIndex < loopNum) {

								if ("1".equals(parent.getUnitType())) {
									//如果是单位类型是公司或没有上级单位，则不再往上级查找
									companyId = parent.getId();
									break;
								}
								else if (StringUtils.isEmpty(companyInfo.getParentId())){
									break;
								}
								else {
									parent = companyInfoService.get(parent.getParentId());
									zIndex++;
								}
							}*/


                        } else {
                            companyId = companyInfo.getId();
                        }

                        //默认审核层级
                        int level = 2;

                        if (StringUtils.isNotBlank(companyId)) {

                            ApprovalConfig approvalConfig = approvalConfigService.findByCompanyIdAndType(companyId, "4");
                            if (approvalConfig != null) {
                                BigDecimal days = new BigDecimal(approvalConfig.getDays());
                                if (days.compareTo(new BigDecimal(requestForLeaveInfo.getDays())) > 0) {
                                    level = Integer.valueOf(approvalConfig.getLevel());
                                } else {
                                    level = 10;
                                }
                            } else {
                                if (new BigDecimal(3).compareTo(new BigDecimal(requestForLeaveInfo.getDays())) <= 0) {
                                    level = 10;
                                }
                            }

                        }

                        //计算当前审核的是第几级审批
                        int nowLevel = 1;
                        if (StringUtils.isNotBlank(approvalPersonIdStr)) {
                            nowLevel = nowLevel + Arrays.asList(approvalPersonIdStr.split(",")).size();
                        }
                        //判断已审核人总数和需要审核级数
                        if (nowLevel < level) {
                            List<PersonPopedom> dataList = personPopedomService.findApprovalList(personInfo, "4", null, null);
                            if (dataList.size() > 0) {
                                personPopedomList.add(dataList.get(0));
                            }

                        }

                        //判断审批人数量,审批人数据为0，审批流程走完
                        if (personPopedomList.size() == 0) {
                            requestForLeaveInfo.setApprovedTime(new Date());
                            requestForLeaveInfo.setStatus(status);
                            requestForLeaveInfo.setApprovalOpinions(approvalOpinions);
                            requestForLeaveInfo.setApprovalExplain(approvalExplain);
                            requestForLeaveInfo.setUpdateBy(personInfo.getPopedom());
                            requestForLeaveInfo.setUpdateTime(new Date());
                            update(requestForLeaveInfo);

                            //调休时申请人减去加班工时
                            if ("4".equals(requestForLeaveInfo.getLeaveType())) {
                                int oldHours = personPopedom1.getWorkOverTime();
                                personPopedom1.setWorkOverTime(oldHours - (int) (new Double(requestForLeaveInfo.getDays()) * 8));
                                personPopedomService.update(personPopedom1);
                            }


                            int a1 = "0".equals(requestForLeaveInfo.getStartTimeQuantum()) ? 0 : 43200000;
                            int a2 = "0".equals(requestForLeaveInfo.getEndTimeQuantum()) ? 43200000 : 86400000;
                            ;

                            Date startLong = new Date(requestForLeaveInfo.getStartTime().getTime() + a1);
                            Date endLong = new Date(requestForLeaveInfo.getEndTime().getTime() + a2);

                            //时间符合为休假，

                            String initStatus = personInfo1.getWorkStatus();
                            if (startLong.getTime() < new Date().getTime() && endLong.getTime() > new Date().getTime()) {
                                personInfo1.setWorkStatus("4");//请假
                                personInfo1.setUpdateBy(personPopedom.getPersonId().toString());
                                personInfo1.setUpdateTime(new Date());
                                personInfoService.update(personInfo1);
                            }

                            if (personInfo1.getWorkStatus() == null) {
                                personInfo1.setWorkStatus("1");
                                initStatus = "1";
                            }
                            //休假，还没开始
                            if (startLong.getTime() > new Date().getTime()) {

                                //防止连续请假，造成的时间重叠
                                Long milliseconds = startLong.getTime() - new Date().getTime() + 5000;
                                String p = "A_" + personInfo1.getId() + "_" + personInfo1.getWorkStatus() + "_" + personPopedom.getPersonId();
                                rabbitTemplate.convertAndSend("updateWorkStatusExchange", "updateWorkStatus", p, (message) -> {
                                    //延时单位毫秒
                                    message.getMessageProperties().setHeader("x-delay", milliseconds);
                                    return message;
                                });
                            }
                            //休假，结束
                            if (endLong.getTime() > new Date().getTime()) {
                                String p = "B_" + personInfo1.getId() + "_" + initStatus + "_" + personPopedom.getPersonId();
                                //防止连续请假，造成的时间重叠
                                Long milliseconds = endLong.getTime() - new Date().getTime() - 5000;

                                rabbitTemplate.convertAndSend("updateWorkStatusExchange", "updateWorkStatus", p, (message) -> {
                                    //延时单位毫秒
                                    message.getMessageProperties().setHeader("x-delay", milliseconds);
                                    return message;
                                });
                            }


                        }
                        //审批人数据不为0
                        else {
                            PersonPopedom personPopedom2 = personPopedomList.get(0);
                            if (StringUtils.isNotBlank(approvalPersonIdStr)) {
                                requestForLeaveInfo.setApprovalPersonIdStr(approvalPersonIdStr + "," + requestForLeaveInfo.getApprovedPersonPopedomId());
                                requestForLeaveInfo.setApprovalStatusStr(approvalStatusStr + "," + status);
                                requestForLeaveInfo.setApprovalTimeStr(approvalTimeStr + "," + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm"));
                                requestForLeaveInfo.setApprovalContentStr(approvalContentStr + "," + approvalExplain);
                            } else {
                                requestForLeaveInfo.setApprovalPersonIdStr(requestForLeaveInfo.getApprovedPersonPopedomId());
                                requestForLeaveInfo.setApprovalStatusStr(String.valueOf(status));
                                requestForLeaveInfo.setApprovalTimeStr(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm"));
                                requestForLeaveInfo.setApprovalContentStr(approvalExplain);
                            }

                            requestForLeaveInfo.setApprovedPersonPopedomId(personPopedom2.getId());
                            requestForLeaveInfo.setStatus(0);
                            requestForLeaveInfo.setApprovalOpinions("");
                            requestForLeaveInfo.setApprovedTime(null);
                            update(requestForLeaveInfo);

                            new Thread(() -> {
                                PersonInfo approvalPerson = personInfoService.get(personPopedom2.getPersonId());

                                String typeN = "请假";
                                String url = "master/attendance/verifyLeaveInfo?id=";

                                String accessToken = JwtUtil2.createToken(jwtSecret, approvalPerson.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
                                WechatMessageUtil.sendEvenMessage(approvalPerson.getOpenId(), "有一条新的" + typeN + "信息待审核", personInfo1.getName(), requestForLeaveInfo.getId().substring(0, 5), "前往处理", wxConfig.getPortalUrl() + url + requestForLeaveInfo.getId() + "&exchange=1&role_id=" + personPopedom2.getId() + "&token=" + accessToken, wxConfig.getAppId(), wxConfig.getAppSecret());

                            }).start();


                        }

                        //     }


                    }
                    //拒绝
                    if (status == 2) {
                        requestForLeaveInfo.setApprovedTime(new Date());
                        requestForLeaveInfo.setStatus(status);
                        requestForLeaveInfo.setApprovalOpinions(approvalOpinions);
                        requestForLeaveInfo.setApprovalExplain(approvalExplain);
                        requestForLeaveInfo.setUpdateBy(personPopedom.getId());
                        requestForLeaveInfo.setUpdateTime(new Date());
                        update(requestForLeaveInfo);

                    }

                    //通知申请人

                    if (requestForLeaveInfo.getStatus() != 0) {
                        new Thread(() -> {
                            String firstMessage = "";
                            String getstatus = "";

                            if (1 == status) {
                                firstMessage = "审核通过";
                                getstatus = "1";

                            } else {
                                firstMessage = "审核拒绝";
                                getstatus = "2";
                            }


                            String url = "master/attendance/leaveInfo";


                            String accessToken = JwtUtil2.createToken(jwtSecret, personInfo1.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
                            WechatMessageUtil.sendExamine(personInfo1.getOpenId(), firstMessage, personInfo1.getName(), getstatus, firstMessage, "请假", "前往查看", wxConfig.getPortalUrl() + url + "?id=" + requestForLeaveInfo.getId() + "&exchange=1&role_id=" + personPopedom1.getId() + "&token=" + accessToken, wxConfig.getAppId(), wxConfig.getAppSecret());
                        }).start();


                    }
                }
            }
        }
    }

    @Override
    public String leaveSubmit(PersonPopedom personPopedom, String leaveType, String startTime, String endTime, String startTimeQuantum, String endTimeQuantum, String imageUrl, String reason, String days, String formId, String activity, String draft, String id) throws Exception {
        try {
            RequestForLeaveInfo requestForLeaveInfo = null;
            if (StringUtils.isNotEmpty(id)) {
                requestForLeaveInfo = requestForLeaveInfoDAO.get(id);

            } else {
                requestForLeaveInfo = new RequestForLeaveInfo();
                requestForLeaveInfo.setId(UUID.randomUUID().toString());
            }

            requestForLeaveInfo.setLeaveType(leaveType);

            String startTimeStr = DateUtil.format(DateUtil.parse(startTime), "yyyy-MM-dd");
            String endTimeStr = DateUtil.format(DateUtil.parse(endTime), "yyyy-MM-dd");
            if ("0".equals(startTimeQuantum)) {
                startTimeStr = startTimeStr + " " + "00:00:00";
            }
            if ("1".equals(startTimeQuantum)) {
                startTimeStr = startTimeStr + " " + "12:00:00";
            }
            if ("0".equals(endTimeQuantum)) {
                endTimeStr = endTimeStr + " " + "12:00:00";
            }
            if ("1".equals(endTimeQuantum)) {
                endTimeStr = endTimeStr + " " + "23:59:59";
            }
            requestForLeaveInfo.setStartTime(DateUtil.parse(startTimeStr, "yyyy-MM-dd HH:mm:ss"));
			/*if (days.contains(".")){
				Integer n  = days.indexOf(".");
				String intDays = days.substring(0,n);
				requestForLeaveInfo.setEndTime(DateUtil.offsetDay(requestForLeaveInfo.getStartTime(),Integer.parseInt(intDays)));
				requestForLeaveInfo.setEndTime(DateUtil.offsetHour(requestForLeaveInfo.getStartTime(),12));
			}else {
				requestForLeaveInfo.setEndTime(DateUtil.offsetDay(requestForLeaveInfo.getStartTime(),Integer.parseInt(days)));
			}*/


            requestForLeaveInfo.setEndTime(DateUtil.parse(endTimeStr, "yyyy-MM-dd HH:mm:ss"));
            requestForLeaveInfo.setImageUrl(imageUrl);
            requestForLeaveInfo.setReason(reason);
            requestForLeaveInfo.setPersonId(personPopedom.getPersonId());
            requestForLeaveInfo.setPersonPopedomId(personPopedom.getId());
            requestForLeaveInfo.setCreateTime(new Date());
            requestForLeaveInfo.setStatus(-99);

            requestForLeaveInfo.setStartTimeQuantum(startTimeQuantum);
            requestForLeaveInfo.setEndTimeQuantum(endTimeQuantum);
            requestForLeaveInfo.setDays(days);
            if (StringUtils.isNotEmpty(id)) {

                update(requestForLeaveInfo);
            } else {
                insert(requestForLeaveInfo);
            }

            String ide = requestForLeaveInfo.getId();

            if ("1".equals(draft)) {
                Map<String, Object> conditions = new HashMap<>();
                conditions.put("day", Double.valueOf(days));
                conditions.put("leaveType", Double.valueOf(leaveType));

                String procInstId = procinstService.addProcInst(ide, "请假", formId, personPopedom, activity, null, conditions);

                requestForLeaveInfo.setProcinstId(procInstId);
                requestForLeaveInfo.setStatus(0);
                update(requestForLeaveInfo);


                ProcinstActivity procinstActivity = procinstActivityService.findByActivityIndexAndProcinstId(1, procInstId);


                if (procinstActivity != null) {

                    List<ProcinstActUser> procinstActUserList = procinstActUserService.findByProcinstActivityIdActionType(procinstActivity.getId(), "0", "1");
                    if (procinstActUserList.size() > 0) {

                        new Thread(() -> {
                            for (ProcinstActUser procinstActUser : procinstActUserList) {
                                try {
                                    PersonInfo personInfo = personInfoService.get(Long.parseLong(procinstActUser.getUserId()));

                                    //提交人
                                    PersonInfo personInfo1 = personInfoService.get(personPopedom.getPersonId());
                                    String accessToken = JwtUtil2.createToken(jwtSecret, personInfo.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
                                    WechatMessageUtil.sendEvenMessage(personInfo.getOpenId(), "有一条新的请假信息待审核", personInfo1.getName(), com.jpsoft.shinestar.modules.common.utils.StringUtils.getApprovalNo(), "前往处理", wxConfig.getPortalUrl() + "xsy/approval/infosp?id=" + ide + "&procinstActUserId=" + procinstActUser.getId() + "&formId=" + formId + "&token=" + accessToken, wxConfig.getAppId(), wxConfig.getAppSecret());
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }

                            }
                        }).start();
                    }
                }
            }

            return ide;

        } catch (Exception ex) {
            throw new Exception(ex.getMessage());
        }
    }

    public boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        return nowTime.getTime() >= beginTime.getTime() && nowTime.getTime() <= endTime.getTime();
    }

    @Override
    public List<RequestForLeaveInfo> findByPersonIdAndAttendanceDate(Long personId, Date attendanceDate) {
        return requestForLeaveInfoDAO.findByPersonIdAndAttendanceDate(personId, attendanceDate);
    }

    @Override
    public void logic(RequestForLeaveInfo requestForLeaveInfo) throws Exception {
        PersonPopedom personPopedom = personPopedomService.get(requestForLeaveInfo.getPersonPopedomId());
        PersonInfo personInfo = personInfoService.get(personPopedom.getPersonId());

        Date start = requestForLeaveInfo.getStartTime();
        Date end = requestForLeaveInfo.getEndTime();
        Date now = new Date();


        if (start.compareTo(now) <= 0) {
            //start<=now<=end
            if (end.compareTo(now) > 0) {
                personInfo.setWorkStatus("4");
                String approvalPersonIdStr = requestForLeaveInfo.getApprovalPersonIdStr();

                if (StringUtils.isNotEmpty(approvalPersonIdStr)) {
                    String[] approvalPersonIds = approvalPersonIdStr.split(",");

                    if (approvalPersonIds.length > 0) {
                        personInfo.setUpdateBy(approvalPersonIds[approvalPersonIds.length - 1]);
                    }
                }

                personInfoService.update(personInfo);
                Long millisecond = DateUtil.betweenMs(DateUtil.date(), end) + 60000;

                rabbitTemplate.convertAndSend("requestForLeaveDelayExchange", "submit",
                        requestForLeaveInfo.getId(), (message) -> {
                            message.getMessageProperties().setHeader("x-delay", millisecond);
                            return message;
                        });
            }

            //now>=end
            if (end.compareTo(now) <= 0) {
                personInfo.setWorkStatus("1");
                personInfoService.update(personInfo);
            }
        }

        //start>now
        if (start.compareTo(now) > 0) {
            Long millisecond = DateUtil.betweenMs(DateUtil.date(), start);

            //请假开始后设置状态为请假
            rabbitTemplate.convertAndSend("requestForLeaveDelayExchange", "submit",
                    requestForLeaveInfo.getId(), (message) -> {
                        message.getMessageProperties().setHeader("x-delay", millisecond);
                        return message;
                    });

            //请假结束后设置状态为工作
            Long millisecond2 = DateUtil.betweenMs(DateUtil.date(), end) + 60000;
            rabbitTemplate.convertAndSend("requestForLeaveDelayExchange", "submit",
                    requestForLeaveInfo.getId(), (message) -> {
                        message.getMessageProperties().setHeader("x-delay", millisecond2);
                        return message;
                    });
        }

        //start<now
        if (start.before(now)) {
            //补请假则更新考勤记录
            UpdatePersonAttendanceDTO updatePersonAttendanceDTO = new UpdatePersonAttendanceDTO(
                    personInfo.getId(), requestForLeaveInfo.getStartTime(), requestForLeaveInfo.getEndTime());

            rabbitTemplate.convertAndSend("updatePersonAttendanceQueue", updatePersonAttendanceDTO);
        }
    }

    @Override
    public List<RequestForLeaveInfo> listSearch(Map<String, Object> searchParams, List<Sort> sortList) {
        return requestForLeaveInfoDAO.search(searchParams, sortList);
    }

    @Override
    public String cancelLeaveSubmit(PersonPopedom personPopedom, String id, String imageUrl, String formId) throws Exception {

        RequestForLeaveInfo requestForLeaveInfo = get(id);
        if (requestForLeaveInfo.getStatus() != 1) {
            throw new Exception("请假状态错误");
        }

        if (!requestForLeaveInfo.getEnableCancel()) {
            throw new Exception("此记录不可核销");
        }
        if ("1".equals(requestForLeaveInfo.getCancelStatus())) {
            throw new Exception("此记录已核销");
        }
        if (StringUtils.isBlank(imageUrl)) {
            throw new Exception("销假需上传凭证");
        }

        requestForLeaveInfo.setCancelStatus("0");
        requestForLeaveInfo.setCancelImages(imageUrl);
        requestForLeaveInfo.setEnableCancel(false);
        update(requestForLeaveInfo);


        TemplateDepartment templateDepartment = templateDepartmentService.findByFormId(formId);
        if (templateDepartment == null) {
            throw new Exception("您的部门没有相应流程模板");
        }

        ProcessTemplate processTemplate = processTemplateService.get(templateDepartment.getProcessTemplateId());

        //	List<ProcessActivity> processActivityList = processActivityService.findByTemplateIdAndRoleId(processTemplate.getId(),personPopedom.getPersonRoleId());
        ExaminePersonDTO examinePersonDTO = processSetService.getExaminePerson(requestForLeaveInfo.getProcinstId(), processTemplate.getId(), personPopedom, 1, null);

        List<String> personIdList = Arrays.asList(examinePersonDTO.getPersonIds().split(","));
        if (personIdList.size() > 0) {
            new Thread(() -> {
                for (String personId : personIdList) {
                    try {
                        PersonInfo personInfo = personInfoService.get(Long.parseLong(personId));
                        //提交人
                        PersonInfo personInfo1 = personInfoService.get(personPopedom.getPersonId());
                        String accessToken = JwtUtil2.createToken(jwtSecret, personInfo.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
                        WechatMessageUtil.sendEvenMessage(personInfo.getOpenId(), "有一条新的销假信息待审核", personInfo1.getName(), com.jpsoft.shinestar.modules.common.utils.StringUtils.getApprovalNo(), "请登录电脑端处理", wxConfig.getPortalUrl() + "xsy/approval/infosp?id=" + id + "&procinstActUserId=" + id + "&formId=" + formId + "&token=" + accessToken, wxConfig.getAppId(), wxConfig.getAppSecret());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                }
            }).start();

        }

		/*for (int n = 1; n <= processActivityList.size(); n++) {



			ExaminePersonDTO examinePersonDTO = processSetService.getExaminePerson(requestForLeaveInfo.getProcinstId(), processTemplate.getId(), personPopedom, n);


			//创建流程主表


			*//*adjustShift.setProcinstId(procinst.getId());
			update(adjustShift);*//*

			//创建流程二级表
			ProcinstActivity procinstActivity = new ProcinstActivity();
			procinstActivity.setId(UUID.randomUUID().toString());
			procinstActivity.setProcinstId(requestForLeaveInfo.getProcinstId());
			procinstActivity.setActivityIndex(n+size);
			procinstActivity.setActivityId(examinePersonDTO.getActivityId());
			if (n == 1) {
				procinstActivity.setStatus("1");
			} else {
				procinstActivity.setStatus("0");
			}

			procinstActivity.setAction("0");
			procinstActivity.setRemark("待审核");
			procinstActivity.setCreateTime(new Date());
			procinstActivityService.insert(procinstActivity);

			//创建流程三级表,写入审核人
			List<String> personIdList = Arrays.asList(examinePersonDTO.getPersonIds().split(","));
			if (personIdList.size() > 0) {
				for (String personId : personIdList) {
					ProcinstActUser procinstActUser = new ProcinstActUser();
					procinstActUser.setId(UUID.randomUUID().toString());
					procinstActUser.setProcinstActivityId(procinstActivity.getId());
					procinstActUser.setUserId(personId);
					procinstActUser.setType("1");
					procinstActUser.setAction("0");
					procinstActUser.setRemark("待审核");
					procinstActUser.setCreateTime(new Date());
					procinstActUserService.insert(procinstActUser);
				}
			}

			//写入抄送人
			String ccPersonIds = examinePersonDTO.getCcPersonIds();
			if (StringUtils.isNotBlank(ccPersonIds)) {
				List<String> ccPersonIdList = Arrays.asList(ccPersonIds);
				for (String ccPersonId : ccPersonIdList) {
					ProcinstActUser procinstActUser = new ProcinstActUser();
					procinstActUser.setId(UUID.randomUUID().toString());
					procinstActUser.setProcinstActivityId(procinstActivity.getId());
					procinstActUser.setUserId(ccPersonId);
					procinstActUser.setType("2");
					procinstActUser.setAction("0");
					procinstActUser.setRemark("待抄送");
					procinstActUser.setCreateTime(new Date());
					procinstActUserService.insert(procinstActUser);
				}
			}


		}
*/

		/*ProcinstActivity procinstActivity = procinstActivityService.findByActivityIndexAndProcinstId(size+1, requestForLeaveInfo.getProcinstId());

		if (procinstActivity != null) {
			List<ProcinstActUser> procinstActUserList = procinstActUserService.findByProcinstActivityIdActionType(procinstActivity.getId(), "0", "1");
			if (procinstActUserList.size() > 0) {

				new Thread(() -> {
					for (ProcinstActUser procinstActUser : procinstActUserList) {
						try{
							PersonInfo personInfo = personInfoService.get(Long.parseLong(procinstActUser.getUserId()));

							//提交人
							PersonInfo personInfo1 = personInfoService.get(personPopedom.getPersonId());
							String accessToken = JwtUtil2.createToken(jwtSecret, personInfo.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
							WechatMessageUtil.sendEvenMessage(personInfo.getOpenId(), "有一条新的销假信息待审核", personInfo1.getName(), com.jpsoft.shinestar.modules.common.utils.StringUtils.getApprovalNo(), "前往处理", wxConfig.getPortalUrl() + "xsy/approval/infosp?id=" + id + "&procinstActUserId=" + procinstActUser.getId() + "&formId=" + formId + "&token=" + accessToken, wxConfig.getAppId(), wxConfig.getAppSecret());
						}catch (Exception ex){
							ex.printStackTrace();
						}

					}
				}).start();
			}
		}*/
        return id;
    }

    @Override
    public BigDecimal sumDaysByPersonIdAndTimeRange(Long personId, Date startDate, Date endDate) {
        //查询时间段与出差交集部分
        List<RequestForLeaveInfo> list = requestForLeaveInfoDAO.findByPersonIdAndDate(personId, startDate, endDate);
        BigDecimal totalDays = BigDecimal.ZERO;

        for (RequestForLeaveInfo item : list) {
            //查询交集部分小时数
            Date maxStartDate = item.getStartTime().compareTo(startDate) > 0 ? item.getStartTime() : startDate;
            Date minEndDate = item.getEndTime().compareTo(endDate) < 0 ? item.getEndTime() : endDate;

            int hours = Hours.hoursBetween(new DateTime(maxStartDate), new DateTime(minEndDate)).getHours();
            BigDecimal days = new BigDecimal(hours).divide(new BigDecimal(24), 1, RoundingMode.HALF_UP);

            totalDays = totalDays.add(days);
        }

        return totalDays;
    }
}