package cn.iocoder.yudao.module.bpm.job.workovertime;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAOvertimeDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAOvertimeItemDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAOvertimeMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAOvertimeItemService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAOvertimeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class WorkOvertimeJob {

    // TODO: 2024/11/04  - 每天凌晨2点执行

    /**
     * 加班定时任务
     **/

    @Resource
    private BpmOAOvertimeService overtimeService;
    @Resource
    private BpmOAOvertimeMapper overtimeMapper;
    @Resource
    private BpmOAOvertimeItemService overtimeItemService;

    @XxlJob("workOvertimeJob")
    @TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意
    public ReturnT<String> execute() throws Exception {
        log.info("开始 加班定时任务");
        LocalDateTime now = LocalDateTime.now();
        List<BpmOAOvertimeDO> bpmOAOvertimeDOS = overtimeMapper.selectList(new LambdaQueryWrapper<BpmOAOvertimeDO>()
                .eq(BpmOAOvertimeDO::getSettlementFlag, 0)
                .eq(BpmOAOvertimeDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult())
                .le(BpmOAOvertimeDO::getEndTime, now));
        if (CollectionUtil.isNotEmpty(bpmOAOvertimeDOS)) {
            List<Long> ids = bpmOAOvertimeDOS.stream().map(BpmOAOvertimeDO::getId).collect(Collectors.toList());
            List<BpmOAOvertimeItemDO> items = overtimeItemService.getByOvertimeIds(ids);
            Map<Long, List<BpmOAOvertimeItemDO>> map = items.stream().collect(Collectors.groupingBy(BpmOAOvertimeItemDO::getOaOvertimeId));
            for (BpmOAOvertimeDO bpmOAOvertimeDO : bpmOAOvertimeDOS) {
                List<BpmOAOvertimeItemDO> bpmOAOvertimeItemDOS = map.get(bpmOAOvertimeDO.getId());
                if (CollectionUtil.isEmpty(bpmOAOvertimeItemDOS)) {
                    continue;
                }
                try {
                    overtimeService.handlingOvertime(bpmOAOvertimeDO, bpmOAOvertimeItemDOS, now);
                } catch (Exception e) {
                    log.error("处理加班失败", e);
                }
            }
        }
        log.info("结束 加班定时任务");
        // 返回执行成功
        return ReturnT.SUCCESS;
    }

}
