# PastReservationCreditLimitTask.java

    package cloud.wconnect.frontoffice.businesstask.pastreservation;

    import cloud.wconnect.commonlib.businesstask.CheckReportMissedService;
    import cloud.wconnect.commonlib.businesstask.rule.MissedRuleByThreshold;
    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.FunctionCons;
    import cloud.wconnect.commonlib.cons.PmsReportEnum;
    import cloud.wconnect.commonlib.pojo.dto.*;
    import cloud.wconnect.commonlib.pojo.dto.line.ReportMissedMsgParm;
    import cloud.wconnect.commonlib.pojo.dto.scheduler.JobParameterDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.service.PropertyInternalService;
    import cloud.wconnect.commonlib.util.*;
    import cloud.wconnect.frontoffice.cons.BusinessEnum;
    import cloud.wconnect.frontoffice.cons.EventSubjectEnum;
    import cloud.wconnect.frontoffice.cons.FunctionPointEnum;
    import cloud.wconnect.frontoffice.cons.pastreservation.PastReservationNotifyEnum;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationEmailConfig;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationEmailTarget;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationSchedulerJob;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationEmailConfigService;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationEmailTargetService;
    import com.alibaba.fastjson.JSONObject;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Lists;
    import jakarta.annotation.Resource;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Component;
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.Context;

    import java.util.Collections;
    import java.util.List;
    import java.util.Objects;
    import java.util.concurrent.TimeUnit;

    /**
     * 定时任务
     *
     * @author yyt
     * 2024/12/12
     */
    @Slf4j
    @Component
    public class PastReservationCreditLimitTask {

        @Resource
        private IPastReservationEmailConfigService pastReservationEmailConfigService;
        @Resource
        private IPastReservationEmailTargetService pastReservationEmailTargetService;
        @Autowired
        private PropertyInternalService propertyInternalService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private CheckReportMissedService checkReportMissedService;
        @Autowired
        private LineMessageUtil lineMessageUtil;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;
        @Autowired
        private BeanMapper beanMapper;
        @Autowired
        private ObjectMapper objectMapper;
        @Autowired
        private TemplateEngine templateEngine;

        @Value("${default.timezone}")
        private String defaultTimezone;

        @Value("${here.link.past-reservation.list}")
        private String hereLink;

        private static final String SUBJECT = EventSubjectEnum.CREDIT_LIMIT.getSubject();

        private static final String BUSINESS = BusinessEnum.PAST_RESERVATION.getBusiness();

        /**
         * 检查报告是否缺失
         *
         * @param schedulerJob 定时任务
         * @author yyt
         * @date 2024/12/12
         */
        @Async
        public void reportMissCheck(PastReservationSchedulerJob schedulerJob) {
            log.info("PastReservationCreditLimitTask.reportMissCheck start...");

            Integer propertyId = schedulerJob.getPropertyId();
            PropertyDTO property = propertyI18nRedisService.get(propertyId);
            if (!property.getStatus()) {
                log.warn("PastReservationCreditLimitTask.reportMissCheck end... the property is closed, no processing required");
                return;
            }

            // 查询邮件配置
            PastReservationEmailConfig emailConfig = pastReservationEmailConfigService.get(propertyId, PastReservationNotifyEnum.MISSING_REPORT_CREDIT_LIMIT.getCode(), true);
            List<PastReservationEmailTarget> emailTargets = Collections.emptyList();
            if (Objects.nonNull(emailConfig)) {
                emailTargets = pastReservationEmailTargetService.list(emailConfig.getId());
            }

            //获取通知配置DTO
            NotifyDTO notifyDTO = getNotifyDTO(property, emailConfig, emailTargets);

            //资产配置的阈值集合
            JobParameterDTO jobParameterDTO = JsonUtils.convertStringToObject(objectMapper, schedulerJob.getParameters(), JobParameterDTO.class);
            ThresholdDTO thresholdDTO = new ThresholdDTO(jobParameterDTO.getThreshold(), TimeUnit.MINUTES, defaultTimezone);

            CheckReportMissedDTO check = CheckReportMissedDTO.builder()
                    .subject(SUBJECT)
                    .business(BUSINESS)
                    .propertyDTO(property)
                    .ruleClazzList(Collections.singletonList(MissedRuleByThreshold.class))
                    .notifyDTO(notifyDTO)
                    .thresholdDTO(thresholdDTO)
                    .build();
            checkReportMissedService.doCheck(check);

            log.info("PastReservationCreditLimitTask.reportMissCheck end...");
        }

        /**
         * 获取通知配置DTO
         *
         * @param propertyDTO 资产
         * @param emailConfig 邮件配置
         * @param targets     邮件通知人集合
         * @return 通知配置
         * @author yyt
         * @date 2024/12/12
         */
        private NotifyDTO getNotifyDTO(PropertyDTO propertyDTO, PastReservationEmailConfig emailConfig, List<PastReservationEmailTarget> targets) {
            if (CollectionUtils.isEmpty(targets)) {
                return null;
            }

            Integer propertyId = propertyDTO.getId();
            String propertyName = propertyDTO.getName();
            String language = propertyDTO.getLanguage();
            String defaultSubject = pastReservationEmailConfigService.getDefaultSubject(propertyId, PastReservationNotifyEnum.MISSING_REPORT_CREDIT_LIMIT.getCode());

            NotifyDTO notifyDTO = new NotifyDTO();
            notifyDTO.setPropertyId(propertyId);
            notifyDTO.setFunctionPoint(FunctionPointEnum.PAST_RESERVATION_REPORT_MISSED.getFunctionPoint());
            notifyDTO.setSubject(StringUtils.isNotBlank(emailConfig.getSubject()) ? emailConfig.getSubject() : defaultSubject);
            notifyDTO.setIdentityList(beanMapper.mapList(targets, NotifyIdentityDTO.class));

            //报告缺失日期 0d
            String timezone = propertyDTO.getTimezone();
            String missDate = InternationalizationUtils.formatDateTime(DateTimeUtils.dateNowTimestamp(timezone),
                    propertyDTO.getInternationalization().getDateTime().getLongDate(), StringUtils.EMPTY, timezone, language);

            String functionName = i18nMessageUtils.message(FunctionCons.PAST_RESERVATION, language);

            // 获取资产配置的 PMS 报告名称
            String reportName = propertyInternalService.getPmsReportConfig(propertyId,
                    propertyDTO.getPmsType(), PmsReportEnum.CREDIT_LIMIT.getSymbol()).getReportName();

            //设置邮件通知内容
            Context context = new Context();
            context.setVariable("propertyName", propertyName);
            context.setVariable("functionName", functionName);
            context.setVariable("reportName", reportName);
            context.setVariable("reportDate", missDate);
            context.setVariable("hereLink", hereLink + "?property=" + propertyDTO.getAbbr() + "&tenant=" + propertyDTO.getTenantSymbol());
            String emailContent = templateEngine.process(EmailUtil.getMissReportTemplateName(language), context);
            notifyDTO.setEmailContent(EmailUtil.getFullEmailContent(defaultSubject, emailContent, language));

            //line通知内容
            ReportMissedMsgParm reportMissedMsgParm = new ReportMissedMsgParm(propertyName, propertyId, functionName, reportName, missDate);
            JSONObject lineMsg = lineMessageUtil.generateReportMissedMsg(reportMissedMsgParm);
            notifyDTO.setLineContent(Lists.newArrayList(lineMsg));
            return notifyDTO;
        }

    }