OrderOverTimeEventJob.java 18.8 KB
package com.order.erp.job;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.order.erp.common.constant.Constant;
import com.order.erp.common.constant.ServerResult;
import com.order.erp.common.utils.EmailSendUtils;
import com.order.erp.common.utils.StringUtils;
import com.order.erp.common.utils.TransactionHelper;
import com.order.erp.domain.EmailTemplateEnum;
import com.order.erp.domain.OrderEventEnum;
import com.order.erp.domain.OrderStatusEnum;
import com.order.erp.domain.dto.BaseDO;
import com.order.erp.domain.dto.order.*;
import com.order.erp.domain.email.OrderProductEmailVO;
import com.order.erp.domain.vo.order.ReceiveEmailConfigItemVO;
import com.order.erp.service.order.*;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.order.erp.domain.EmailTemplateEnum.BIG_SAMPLE_TEMPLATE;


/**
 * @author: xms
 * @description: TODO
 * @date: 2023/6/25 10:35
 * @version: 1.0
 */
@Slf4j
@Component
public class OrderOverTimeEventJob {

    @Resource
    private OrderBaseInfoService orderBaseInfoService;

    @Resource
    private OrderProfitAnalysisService profitAnalysisService;

    @Resource
    private OrderCompletionReportService reportService;

    @Resource
    private OrderTrackStageService trackStageService;

    @Resource
    private OrderInspectionStageService inspectionStageService;

    @Resource
    private TransactionHelper transactionHelper;

    @Resource
    private EmailSendUtils emailSendUtils;

    @Resource
    private ReceiveEmailMappingService receiveEmailMappingService;

    /**
     * 凌晨1点执行,一天一次
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void checkOverTimeExecute() {
        /*首先判断字符串。如果没有ok并且次数达到了三次(统计fail是否存在三次),就提醒。
         * 如果有ok,取出ok前的日期,得到日期,那这个日期与HOD日期进行判断*/
        List<OrderBaseInfoDO> orderBaseInfoList = orderBaseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>()
                .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
                .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus()));
        Set<Long> orderList = orderBaseInfoList.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toSet());
        Map<Long, OrderBaseInfoDO> baseInfoDOMap = orderBaseInfoList.stream().collect(Collectors.toMap(OrderBaseInfoDO::getId, Function.identity(), (x, y) -> x));
        List<OrderInspectionStageDO> orderInspectionStageList = inspectionStageService.listByIds(orderList);
        Map<Long, OrderInspectionStageDO> inspectionStageDOMap = orderInspectionStageList.stream().collect(Collectors.toMap(OrderInspectionStageDO::getOrderId, Function.identity(), (x, y) -> x));
        List<OrderTrackStageDO> orderTrackStageList = trackStageService.listByIds(orderList);
        OrderProductEmailVO orderProductEmailVO = new OrderProductEmailVO();
        System.out.println("1111111111111111111111111");
        //只有跟单信息不为空时,才会有时间和状态。
        if (CollectionUtils.isNotEmpty(orderTrackStageList)) {
            System.out.println("orderId"+baseInfoDOMap);
            System.out.println("order Base Info"+inspectionStageDOMap);
            orderTrackStageList.stream().forEach(x -> {
                System.out.println("orderId"+x.getOrderId());
                System.out.println("order Base Info"+baseInfoDOMap.get(x.getOrderId()));
                        if (StringUtils.isBlank(baseInfoDOMap.get(x.getOrderId()).getOrderHodTime())) {
//                            return ServerResult.fail("HODTime不能为空");
                        }
                        if (baseInfoDOMap.get(x.getOrderId()).getId() == x.getOrderId()) {
                            orderProductEmailVO.setBaseInfo(baseInfoDOMap.get(x.getOrderId()));
                            try {
                                System.out.println("222222222222222222222");
                                test(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE, x.getPpConfirmResult(), orderProductEmailVO);
                                System.out.println("2333333333333333333333");
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            try {
                                test(EmailTemplateEnum.CONFIRM_SAMPLE_TEMPLATE, x.getShippmentSampleConfirmResult(), orderProductEmailVO);
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            try {
                                test(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE, x.getAitexTestFinishResult(), orderProductEmailVO);
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            try {
                                test(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE, x.getSgsTestFinishResult(), orderProductEmailVO);
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            try {
                                test(EmailTemplateEnum.OTHER_SAMPLE_TEMPLATE, x.getEsoSampleSendTime(), orderProductEmailVO);
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            try {
                                test(EmailTemplateEnum.BARCODE_ARRIVAL_TEMPLATE, x.getLatestArrivalTime(), orderProductEmailVO);
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            try {
                                test(EmailTemplateEnum.LATEST_DC_TEMPLATE, x.getLatestBkTime(), orderProductEmailVO);
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        if (baseInfoDOMap.get(x.getOrderId()).getId() == x.getOrderId() &&
                                baseInfoDOMap.get(x.getOrderId()).getId() == inspectionStageDOMap.get(x.getOrderId()).getOrderId()) {
                            orderProductEmailVO.setInspectionStageInfo(inspectionStageDOMap.get(x.getOrderId()));
                            orderProductEmailVO.setBaseInfo(baseInfoDOMap.get(x.getOrderId()));
                            //尾期验货日期。尾期放这里写是因为尾期验货日期需要从inspectionStageDOMap中获取。
                            try {
                                test(EmailTemplateEnum.END_CHECK_DATE_TEMPLATE, inspectionStageDOMap.get(x.getOrderId()).getEndCheckApplyTime(), orderProductEmailVO);
                            } catch (MessagingException e) {
                                throw new RuntimeException(e);
                            } catch (TemplateException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            /*加上中期验货报告和尾期验货报告的发送,因为他需要发送inspectionStageDOMap实体类中的数据*/
                            //todo
                        }

                    }
            );
        }

    }

    //    写一下检测方法。
    /*@param event 代表的含义,这个是对应的枚举类型。
     *@param str 代表的含义,这个是状态日期。
     *@param orderProductEmailVO 代表的含义,这个邮件要发送的内容。
     * */
    //todo 还需要判断其他时间,不能单独只判断po时间。
    public void test(EmailTemplateEnum eventEnum, String str, OrderProductEmailVO orderProductEmailVO) throws MessagingException, TemplateException, IOException {
        //获取邮件收件人。
        System.out.println("22222222222222222222--1111111111111");
        List<List<String>> emails = getEmails(eventEnum, orderProductEmailVO);
        if (StringUtils.isNotBlank(str)) {
            //如果为确认样确认,或者AITEX/SGS测试判断是否存在ok。
            if (eventEnum.getTitle().equals(EmailTemplateEnum.CONFIRM_SAMPLE_TEMPLATE.getTitle()) ||
                    eventEnum.getTitle().equals(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE.getTitle()) ||
                    eventEnum.getTitle().equals(BIG_SAMPLE_TEMPLATE.getTitle())) {
                System.out.println("2222222222-22222222222222");
                //不包含ok并且三次输入机会都为fail了
                if (!str.contains("ok") && org.apache.commons.lang3.StringUtils.countMatches(str, "fail") == 3) {
                    //直接发邮件。
                    for (List email : emails) {
                        emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                    }
                    //设置状态为1,下次不扫描。
                } else if (str.contains("ok") || org.apache.commons.lang3.StringUtils.countMatches(str, "fail") < 3) {
                    //只会有几种种情况,一种是fail,一种是fail+fail。一种是fail+ok,一种是ok,得到最后状态前的值就可以了,前面的不用管。
                    String[] parats = str.split("\\+");
                    //获取最后状态前的时间。
                    String time = parats[str.length() - 3];
                    LocalDate parse1 = LocalDate.parse(time, DateTimeFormatter.ofPattern("yyyy-M-d"));
                    //得到订单的截止时间。
                    String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime();
                    LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
                    //计算两个时间之间的天数间隔。parse2-parse1
                    long daysBetween = ChronoUnit.DAYS.between(parse2, parse1);
                    if (eventEnum.getTitle().equals(EmailTemplateEnum.CONFIRM_SAMPLE_TEMPLATE.getTitle())) {
                        if (daysBetween == 21) {
                            //直接发邮件。
                            for (List email : emails) {
                                emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                            }
                        }
                    } else if (eventEnum.getTitle().equals(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE.getTitle())) {
                        if (daysBetween == 3) {
                            //直接发邮件。
                            for (List email : emails) {
                                emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                            }
                        }
                    } else {
                        if (daysBetween == 7) {
                            //直接发邮件。
                            for (List email : emails) {
                                emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                            }
                        }
                    }
                }
            }
            //没有ok或者fail状态,只通过时间来判断。
            if (eventEnum.getTitle().equals(EmailTemplateEnum.OTHER_SAMPLE_TEMPLATE.getTitle())) {
                String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime();
                LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d"));
                //订单的HOD截止时间。
                LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
                long daysBetween = ChronoUnit.DAYS.between(parse2, parse1);
                if (daysBetween == 14) {
                    for (List email : emails) {
                        emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                    }
                }

            } else if (eventEnum.getTitle().equals(EmailTemplateEnum.BARCODE_ARRIVAL_TEMPLATE.getTitle())) {
                String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime();
                LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d"));
                //订单的HOD截止时间。
                LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
                long daysBetween = ChronoUnit.DAYS.between(parse2, parse1);
                if (daysBetween == 7) {
                    for (List email : emails) {
                        emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                    }
                }

            } else if (eventEnum.getTitle().equals(EmailTemplateEnum.LATEST_DC_TEMPLATE.getTitle())) {
                String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime();
                LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d"));
                //订单的HOD截止时间。
                LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
                long daysBetween = ChronoUnit.DAYS.between(parse2, parse1);
                if (daysBetween == 10) {
                    for (List email : emails) {
                        emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                    }
                }

            } else if (eventEnum.getTitle().equals(EmailTemplateEnum.END_CHECK_DATE_TEMPLATE.getTitle())) {
                String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime();
                LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d"));
                //订单的HOD截止时间。
                LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
                long daysBetween = ChronoUnit.DAYS.between(parse2, parse1);
                if (daysBetween == 2) {
                    for (List email : emails) {
                        emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
                    }
                }
            }
        }
    }

    /*发送中期验货报告和尾期验货报告,疑问,是什么时候发送,质检信息中有中期验货字段,是否是填写了中期验货字段就发送还是说填写了跟单信息发送*/
    public void send() {

    }

    /*发送生产指示书*/
    public void sende(File file) {

    }

    /*返回邮箱
     * 解释:根据订单的客户编码和事件类型,得到这个客户编码配置好的邮箱配置,返回邮箱*/
    public List<List<String>> getEmails(EmailTemplateEnum eventEnum, OrderProductEmailVO orderProductEmailVO) {
        String customerCode = orderProductEmailVO.getBaseInfo().getCustomerCode();
        List<ReceiveEmailMappingDO> receiveEmailMappingDOList = receiveEmailMappingService.list(new LambdaQueryWrapper<ReceiveEmailMappingDO>()
                .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
                .eq(ReceiveEmailMappingDO::getTypeValue, customerCode));
        Set<List<String>> emailList = receiveEmailMappingDOList.stream().map(x -> {
            ReceiveEmailConfigItemVO receiveEmailConfigItemVO = JSON.parseObject(x.getConfigInfos(), ReceiveEmailConfigItemVO.class);
            if (eventEnum.getTemplateId() == OrderEventEnum.getEventEnum(receiveEmailConfigItemVO.getEvent()).getTemplateId()) {
                List<String> emailsList = receiveEmailConfigItemVO.getEmails();
                return emailsList;
            }
            return null;
        }).collect(Collectors.toSet());
        return new ArrayList<>(emailList);
    }


  /*  public void a(String str, OrderProductEmailVO orderProductEmailVO) {
        //包含ok。
        String[] parats = str.split("\\+");
        //获取ok前的时间。
        String time = parats[str.length() - 3];
        LocalDate parse1 = LocalDate.parse(time, DateTimeFormatter.ofPattern("yyyy-M-d"));
        //得到订单的截止时间。
        String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime();
        LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
        //计算两个时间之间的天数间隔。parse2-parse1
        long daysBetween = ChronoUnit.DAYS.between(parse2, parse1);
        if (daysBetween == 21) {
            //直接发邮件。
            for (List email : emails) {
                emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO);
            }
        }
    }*/

}