Commit 493326949d23e6cfa8b680202dd674348a92f5e8

Authored by chenhang4442024
1 parent d939bd03

feat1: 优化填写质检信息和跟单信息时自动根据相同的innnerNo和CustomerCode进行复制

feat2:自动审批收款单和付款单
feat3:审核通过的付款单导出时自动附带签名
Showing 55 changed files with 1828 additions and 348 deletions
src/main/java/com/order/erp/common/utils/DateUtils.java
... ... @@ -584,4 +584,72 @@ public class DateUtils {
584 584 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
585 585 return LocalDateTime.parse(dateStr, formatter).toLocalDate();
586 586 }
  587 +
  588 + public static LocalDateTime beginOfQuarter() {
  589 + // 获取当前日期
  590 + LocalDate now = LocalDate.now();
  591 + // 获取当前月份
  592 + Month month = now.getMonth();
  593 + // 根据当前月份确定季度的开始月份
  594 + // 10, 11, 12
  595 + Month quarterStartMonth;
  596 + switch (month.getValue()) {
  597 + case 1:
  598 + case 2:
  599 + case 3:
  600 + quarterStartMonth = Month.JANUARY;
  601 + break;
  602 + case 4:
  603 + case 5:
  604 + case 6:
  605 + quarterStartMonth = Month.APRIL;
  606 + break;
  607 + case 7:
  608 + case 8:
  609 + case 9:
  610 + quarterStartMonth = Month.JULY;
  611 + break;
  612 + default:
  613 + quarterStartMonth = Month.OCTOBER;
  614 + break;
  615 + }
  616 + // 获取当前年的开始日期
  617 + LocalDate quarterStartDate = LocalDate.of(now.getYear(), quarterStartMonth, 1);
  618 + // 返回季度开始的日期和时间
  619 + return LocalDateTime.of(quarterStartDate, java.time.LocalTime.MIDNIGHT);
  620 + }
  621 +
  622 + public static LocalDateTime endOfQuarter() {
  623 + // 获取当前日期
  624 + LocalDate now = LocalDate.now();
  625 + // 获取当前月份
  626 + Month month = now.getMonth();
  627 + // 根据当前月份确定季度的结束月份
  628 + // 10, 11, 12
  629 + Month quarterEndMonth;
  630 + switch (month.getValue()) {
  631 + case 1:
  632 + case 2:
  633 + case 3:
  634 + quarterEndMonth = Month.MARCH;
  635 + break;
  636 + case 4:
  637 + case 5:
  638 + case 6:
  639 + quarterEndMonth = Month.JUNE;
  640 + break;
  641 + case 7:
  642 + case 8:
  643 + case 9:
  644 + quarterEndMonth = Month.SEPTEMBER;
  645 + break;
  646 + default:
  647 + quarterEndMonth = Month.DECEMBER;
  648 + break;
  649 + }
  650 + // 获取当前年的结束日期
  651 + LocalDate quarterEndDate = LocalDate.of(now.getYear(), quarterEndMonth, quarterEndMonth.length(now.isLeapYear()));
  652 + // 返回季度结束的日期和时间
  653 + return LocalDateTime.of(quarterEndDate, LocalTime.MAX);
  654 + }
587 655 }
... ...
src/main/java/com/order/erp/common/utils/EasyPdfUtils.java
... ... @@ -21,6 +21,7 @@ import wiki.xsx.core.pdf.component.image.XEasyPdfImageType;
21 21 import wiki.xsx.core.pdf.component.table.XEasyPdfCell;
22 22 import wiki.xsx.core.pdf.component.table.XEasyPdfRow;
23 23 import wiki.xsx.core.pdf.component.table.XEasyPdfTable;
  24 +import wiki.xsx.core.pdf.component.text.XEasyPdfText;
24 25 import wiki.xsx.core.pdf.doc.*;
25 26 import wiki.xsx.core.pdf.handler.XEasyPdfHandler;
26 27  
... ... @@ -99,7 +100,7 @@ public class EasyPdfUtils {
99 100 * @param fileName
100 101 * @return
101 102 */
102   - public ProducePdfVO createProducePdf(List<OrderProducePdfVO> pdfVOList, String fileName, String companyName) {
  103 + public ProducePdfVO createProducePdf(List<OrderProducePdfVO> pdfVOList, String fileName, String companyName,boolean isTrue) {
103 104 Set<String> productionDepartments = pdfVOList.stream().map(OrderProducePdfVO::getProductionDepartment).filter(Objects::nonNull)
104 105 .filter(department -> !department.trim().isEmpty())
105 106 .collect(Collectors.toSet());
... ... @@ -108,7 +109,7 @@ public class EasyPdfUtils {
108 109 }
109 110 String pathUri = path + "pdfs" + File.separator + AliOssUtil.getUniqueFileName(companyName);
110 111 OutputStream os = FileUtil.getOutputStream(pathUri);
111   - XEasyPdfDocument document = createProducePdf(pdfVOList, companyName);
  112 + XEasyPdfDocument document = createProducePdf(pdfVOList, companyName,isTrue);
112 113 document.save(os);
113 114 File file = FileUtil.file(pathUri);
114 115 FileRespVO fileRespVO = localStorageService.getFilePath(file,companyName);
... ... @@ -127,7 +128,7 @@ public class EasyPdfUtils {
127 128 * @param pdfVOList
128 129 * @return
129 130 */
130   - public XEasyPdfDocument createProducePdf(List<OrderProducePdfVO> pdfVOList, String companyName) {
  131 + public XEasyPdfDocument createProducePdf(List<OrderProducePdfVO> pdfVOList, String companyName,boolean isTrue) {
131 132 // 构建文档
132 133 XEasyPdfDocument document = XEasyPdfHandler.Document.build();
133 134 /* try {
... ... @@ -211,6 +212,9 @@ public class EasyPdfUtils {
211 212  
212 213 //创建并添加页面
213 214 XEasyPdfPage pdfPage=XEasyPdfHandler.Page.build(pageSize,table);
  215 + if(isTrue){
  216 + addTextWatermark(pdfPage, "已作废");
  217 + }
214 218 document.addPage(pdfPage);
215 219  
216 220 //清空当前页数据,准备下一页
... ... @@ -479,5 +483,18 @@ public class EasyPdfUtils {
479 483 return(currentPageRows+extraRowsForComment)>=maxRowsPerPage;
480 484 }
481 485  
  486 +
  487 + private void addTextWatermark(XEasyPdfPage pdfPage, String watermarkText) {
  488 + // 创建水印文本
  489 + XEasyPdfText watermark = XEasyPdfHandler.Text.build(watermarkText)
  490 + .setFontSize(200F) // 设置字体大小
  491 + .setFontColor(new Color(255, 0, 0)) // 设置红色// 设置字体颜色
  492 + .setAlpha(0.5F) // 设置透明度为 50%
  493 + .enableCenterStyle()
  494 + .setPosition(-250, 550);
  495 + // 将水印添加到页面
  496 + pdfPage.addComponent(watermark);
  497 + }
  498 +
482 499 }
483 500 //待拷贝end。
484 501 \ No newline at end of file
... ...
src/main/java/com/order/erp/common/utils/EmailSendUtils.java
1 1 package com.order.erp.common.utils;
  2 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
2 3 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
3 4 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
4 5 import com.order.erp.common.constant.Constant;
... ... @@ -6,13 +7,20 @@ import com.order.erp.common.constant.ServerResultCode;
6 7 import com.order.erp.common.exception.BusinessException;
7 8 import com.order.erp.domain.EmailTemplateEnum;
8 9 import com.order.erp.domain.FinanceOverEnum;
  10 +import com.order.erp.domain.dto.BaseDO;
  11 +import com.order.erp.domain.dto.admin.AdminUserDO;
  12 +import com.order.erp.domain.dto.order.InvoiceBillOrderDO;
  13 +import com.order.erp.domain.dto.order.ProducePaymentCheckBillOrderDO;
9 14 import com.order.erp.domain.vo.order.FinanceEventJobVO;
  15 +import com.order.erp.domain.vo.order.InvoiceAndCheckBillSendEmailVO;
10 16 import com.order.erp.domain.vo.order.OrderEventJobVO;
  17 +import com.order.erp.service.admin.AdminUserService;
11 18 import freemarker.template.Template;
12 19 import freemarker.template.TemplateException;
13 20 import org.springframework.beans.factory.annotation.Value;
14 21 import org.springframework.mail.javamail.JavaMailSender;
15 22 import org.springframework.mail.javamail.MimeMessageHelper;
  23 +import org.springframework.scheduling.annotation.Async;
16 24 import org.springframework.stereotype.Component;
17 25 import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
18 26 import javax.annotation.Resource;
... ... @@ -35,6 +43,8 @@ public class EmailSendUtils {
35 43 private JavaMailSender javaMailSender;
36 44 @Resource
37 45 private FreeMarkerConfigurer freeMarkerConfigurer;
  46 + @Resource
  47 + private AdminUserService adminUserService;
38 48  
39 49 /**
40 50 * @Description: 发送邮件 发送尾期验货报告,中期验货报告,邮件提醒事件。
... ... @@ -57,11 +67,19 @@ public class EmailSendUtils {
57 67 map.put("data",orderEventJobVO);
58 68 Template template = null;
59 69 //设置收件人
60   - String[] receiveemailListArray = receiveemailList.toArray(new String[receiveemailList.size()]);
  70 + String[] receiveemailListArray=receiveemailList.stream().filter(s->!s.trim().isEmpty()).toArray(String[]::new);
61 71 try {
62 72 helper = new MimeMessageHelper(mimeMessage,true);
63 73 //设置邮件的主题
64   - helper.setSubject(emailTemplateEnum.getTitle());
  74 + if (!EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE.getTitle().equals(emailTemplateEnum.getTitle())
  75 + && !EmailTemplateEnum.MID_CHECK_REPORT_TEMPLATE.getTitle().equals(emailTemplateEnum.getTitle())) {
  76 + // 第三种情况:最常见的条件放在第一位
  77 + helper.setSubject(emailTemplateEnum.getTitle());
  78 + } else if (EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE.getTitle().equals(emailTemplateEnum.getTitle())) {
  79 + helper.setSubject(emailTemplateEnum.getTitle()+Constant.CROSS_BAR_CHARACTER+orderEventJobVO.getInspectionStageInfo().getEndCheckResult());
  80 + } else if (EmailTemplateEnum.MID_CHECK_REPORT_TEMPLATE.getTitle().equals(emailTemplateEnum.getTitle())) {
  81 + helper.setSubject(emailTemplateEnum.getTitle()+Constant.CROSS_BAR_CHARACTER+orderEventJobVO.getInspectionStageInfo().getMidCheckResult());
  82 + }
65 83 //设置发件人
66 84 helper.setFrom(sendEmail);
67 85 helper.setTo(receiveemailListArray);
... ... @@ -85,7 +103,7 @@ public class EmailSendUtils {
85 103 * @throws MessagingException
86 104 * @throws IOException
87 105 */
88   -
  106 + @Async
89 107 public void sendEmail(EmailTemplateEnum emailTemplateEnum, List<String> receiveemailList, OrderEventJobVO orderEventJobVO,String extraString) {
90 108 if(CollectionUtils.isEmpty(receiveemailList) && emailTemplateEnum ==null && ObjectUtils.isNull(orderEventJobVO)){
91 109 throw new BusinessException(ServerResultCode.PARAM_ERROR);
... ... @@ -98,7 +116,7 @@ public class EmailSendUtils {
98 116 map.put("data",orderEventJobVO);
99 117 Template template = null;
100 118 //设置收件人
101   - String[] receiveemailListArray = receiveemailList.toArray(new String[receiveemailList.size()]);
  119 + String[] receiveemailListArray=receiveemailList.stream().filter(s->!s.trim().isEmpty()).toArray(String[]::new);
102 120 try {
103 121 helper = new MimeMessageHelper(mimeMessage,true);
104 122 //设置邮件的主题
... ... @@ -133,7 +151,7 @@ public class EmailSendUtils {
133 151 }
134 152 MimeMessage mimeMessage = javaMailSender.createMimeMessage();
135 153 //设置收件人
136   - String[] receiveemailListArray = receiveemailList.toArray(new String[receiveemailList.size()]);
  154 + String[] receiveemailListArray=receiveemailList.stream().filter(s->!s.trim().isEmpty()).toArray(String[]::new);
137 155 MimeMessageHelper helper = null;
138 156 try {
139 157 helper = new MimeMessageHelper(mimeMessage, true);
... ... @@ -167,7 +185,7 @@ public class EmailSendUtils {
167 185 MimeMessage mimeMessage = javaMailSender.createMimeMessage();
168 186 MimeMessageHelper helper= null;
169 187 //设置收件人
170   - String[] receiveemailListArray = receiveemailList.toArray(new String[receiveemailList.size()]);
  188 + String[] receiveemailListArray=receiveemailList.stream().filter(s->!s.trim().isEmpty()).toArray(String[]::new);
171 189 try {
172 190 helper = new MimeMessageHelper(mimeMessage);
173 191 //设置邮件的主题
... ... @@ -220,4 +238,117 @@ public class EmailSendUtils {
220 238 javaMailSender.send(mimeMessage);
221 239 }
222 240  
  241 + //之所以在创建一个和sendEmail方法一样的方法,完全是给尾期验货和中期验货提供的。
  242 + @Async
  243 + public void sendCheckResultEmail(EmailTemplateEnum emailTemplateEnum, List<String> receiveemailList, OrderEventJobVO orderEventJobVO) {
  244 + if(CollectionUtils.isEmpty(receiveemailList) && emailTemplateEnum ==null && ObjectUtils.isNull(orderEventJobVO)){
  245 + throw new BusinessException(ServerResultCode.PARAM_ERROR);
  246 + }
  247 + MimeMessage mimeMessage = javaMailSender.createMimeMessage();
  248 + MimeMessageHelper helper= null;
  249 + Map<String, Object> map = new HashMap<>();
  250 + map.put("context",emailTemplateEnum.getContent()+orderEventJobVO.getBaseInfo().getProjectNo());
  251 + map.put("title",emailTemplateEnum.getTitle());
  252 + map.put("data",orderEventJobVO);
  253 + Template template = null;
  254 + //设置收件人
  255 + String[] receiveemailListArray=receiveemailList.stream().filter(s->!s.trim().isEmpty()).toArray(String[]::new);
  256 + try {
  257 + helper = new MimeMessageHelper(mimeMessage,true);
  258 + //设置邮件的主题
  259 + if (EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE.getTitle().equals(emailTemplateEnum.getTitle())) {
  260 + helper.setSubject(emailTemplateEnum.getTitle()+Constant.CROSS_BAR_CHARACTER+orderEventJobVO.getInspectionStageInfo().getEndCheckResult());
  261 + } else if (EmailTemplateEnum.MID_CHECK_REPORT_TEMPLATE.getTitle().equals(emailTemplateEnum.getTitle())) {
  262 + helper.setSubject(emailTemplateEnum.getTitle()+Constant.CROSS_BAR_CHARACTER+orderEventJobVO.getInspectionStageInfo().getMidCheckResult());
  263 + }
  264 + //设置发件人
  265 + helper.setFrom(sendEmail);
  266 + helper.setTo(receiveemailListArray);
  267 + helper.setSentDate(new Date());
  268 + template = freeMarkerConfigurer.getConfiguration().getTemplate("mail.ftl");
  269 + StringWriter stringWriter = new StringWriter();
  270 + template.process(map,stringWriter);
  271 + helper.setText(stringWriter.toString(),true);
  272 + } catch (TemplateException | IOException | MessagingException e) {
  273 + throw new RuntimeException("邮件发送失败!");
  274 + }
  275 + javaMailSender.send(mimeMessage);
  276 + }
  277 +
  278 + /**
  279 + * @Description: 发送财务模块的审核状态邮件。
  280 + * @param emailTemplateEnum 应收款,应付款邮件事件类型
  281 + * @param invoiceAndCheckBillSendEmailVO 应收款,应付款订单。
  282 + * @throws IOException
  283 + */
  284 + @Async
  285 + public void sendInvoiceAndCheckEmail(FinanceOverEnum emailTemplateEnum, InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO) {
  286 + if(emailTemplateEnum ==null && ObjectUtils.isNull(invoiceAndCheckBillSendEmailVO)){
  287 + throw new BusinessException(ServerResultCode.PARAM_ERROR);
  288 + }
  289 + MimeMessage mimeMessage = javaMailSender.createMimeMessage();
  290 + MimeMessageHelper helper= null;
  291 + String[] email=null;
  292 + String invoiceNoOrCheckNo;
  293 + if(invoiceAndCheckBillSendEmailVO.getInvoiceBillOrderDO()!=null){
  294 + InvoiceBillOrderDO invoiceBillOrderDO=invoiceAndCheckBillSendEmailVO.getInvoiceBillOrderDO();
  295 + //得到提交人
  296 + AdminUserDO adminUserDO = adminUserService.getOne(new LambdaQueryWrapper<AdminUserDO>()
  297 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  298 + .eq(AdminUserDO::getUserName, invoiceBillOrderDO.getFinancePerson())
  299 + .last("limit 1"));
  300 +
  301 + if(Objects.nonNull(adminUserDO)){
  302 + String emails=adminUserDO.getEmail();
  303 + if(StringUtils.isNotBlank(emails)){
  304 + email = emails.split("[,,]+");
  305 + }
  306 + }
  307 + invoiceNoOrCheckNo = invoiceBillOrderDO.getInvoiceNo();
  308 + }else{
  309 + ProducePaymentCheckBillOrderDO checkBillOrderDO = invoiceAndCheckBillSendEmailVO.getCheckBillOrderDO();
  310 + //得到跟单员和业务员。
  311 + List<AdminUserDO> adminUserDOList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
  312 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  313 + .in(AdminUserDO::getUserName, Arrays.asList(checkBillOrderDO.getTrackerUser(), checkBillOrderDO.getBusinesPerson())));
  314 + email = adminUserDOList.stream().filter(Objects::nonNull).map(AdminUserDO::getEmail).flatMap(emails -> Arrays.asList(emails.split("[,,]+"))
  315 + .stream()).map(String::trim).filter(s -> !s.isEmpty()).toArray(String[]::new);
  316 + invoiceNoOrCheckNo=checkBillOrderDO.getCheckNo();
  317 + }
  318 + if(Objects.nonNull(email)){
  319 + try {
  320 + helper = new MimeMessageHelper(mimeMessage);
  321 + //设置邮件的主题
  322 + helper.setSubject(emailTemplateEnum.getTitle());
  323 + //设置发件人
  324 + helper.setFrom(sendEmail);
  325 + helper.setTo(email);
  326 + helper.setSentDate(new Date());
  327 + // 构建邮件内容(HTML 格式)
  328 + StringBuilder emailContent = new StringBuilder();
  329 + emailContent.append("<html><body>");
  330 + emailContent.append("<p style='font-size:24px;'>")
  331 + .append(emailTemplateEnum.getDesc())
  332 + .append("<span style='color:red; font-weight:bold; font-size:24px;'>")
  333 + .append(invoiceNoOrCheckNo)
  334 + .append("</span>");
  335 + if (StringUtils.isNotEmpty(invoiceAndCheckBillSendEmailVO.getRefuseRemark())) {
  336 + emailContent.append("<p>")
  337 + .append("<span style='font-weight:bold; font-size:24px;'>")
  338 + .append("审核不通过原因为:" + invoiceAndCheckBillSendEmailVO.getRefuseRemark())
  339 + .append("</span>")
  340 + .append("</p>");
  341 + }
  342 + emailContent.append("</p>");
  343 + emailContent.append("<p style='font-size:24px;'>").append(Constant.FINANCE_EVENT_TIME).append("</p>");
  344 + emailContent.append("</body></html>");
  345 + helper.setText(emailContent.toString(), true);
  346 + } catch ( MessagingException e) {
  347 + throw new RuntimeException("邮件发送失败!", e);
  348 + }
  349 + javaMailSender.send(mimeMessage);
  350 + }
  351 +
  352 + }
  353 +
223 354 }
224 355 \ No newline at end of file
... ...
src/main/java/com/order/erp/config/MapResultHandler.java 0 → 100644
  1 +package com.order.erp.config;
  2 +
  3 +import org.apache.ibatis.session.ResultContext;
  4 +import org.apache.ibatis.session.ResultHandler;
  5 +
  6 +import java.util.HashMap;
  7 +import java.util.Map;
  8 +
  9 +/**
  10 + * @author zgt
  11 + * @project order-erp
  12 + * @description
  13 + * @date 2024/8/19
  14 + */
  15 +public class MapResultHandler<K,V> implements ResultHandler<Map<K,V>> {
  16 + private final Map<K,V> mappedResults = new HashMap<>();
  17 +
  18 + @Override
  19 + public void handleResult(ResultContext context) {
  20 + Map map = (Map) context.getResultObject();
  21 + mappedResults.put((K)map.get("key"), (V)map.get("value"));
  22 + }
  23 +
  24 + public Map<K,V> getMappedResults() {
  25 + return mappedResults;
  26 + }
  27 +}
... ...
src/main/java/com/order/erp/controller/IndexController.java
... ... @@ -2,7 +2,9 @@ package com.order.erp.controller;
2 2  
3 3 import com.order.erp.common.constant.ServerResult;
4 4 import com.order.erp.domain.OrderStatusEnum;
  5 +import com.order.erp.domain.dto.order.QuerySalesStatisticeDO;
5 6 import com.order.erp.domain.vo.IndexDataVO;
  7 +import com.order.erp.domain.vo.order.DateTimeVO;
6 8 import com.order.erp.service.order.OrderBaseInfoService;
7 9 import com.order.erp.service.order.OrderCompletionReportService;
8 10 import com.order.erp.service.order.OrderInspectionStageService;
... ... @@ -31,62 +33,31 @@ public class IndexController {
31 33  
32 34 @Resource
33 35 OrderBaseInfoService orderBaseInfoService;
34   -
35   - @Resource
36   - OrderInspectionStageService orderInspectionStageService;
37   -
38   - @Resource
39   - OrderProfitAnalysisService orderProfitAnalysisService;
40   -
41   - @Resource
42   - OrderCompletionReportService orderCompletionReportService;
43   -
44 36 @GetMapping("/data")
45 37 @ApiOperation("首页统计数据")
46   - public ServerResult getData(){
47   - //订单总完成数
48   - long orderTotalFinished = orderBaseInfoService.countByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus());
49   - //订单当月完成数
50   - long orderRecentMonthFinished = orderBaseInfoService.countRecentMonthByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus());
51   -
52   -
53   - //跟单和质检中
54   - long inspecting = orderInspectionStageService.countByOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus());
55   - long recentMonthInspecting = orderInspectionStageService.countRecentMonthByOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus());
56   -
57   - //利润分析表待审核
58   - long orderProfitWaitAudit = orderProfitAnalysisService.countByOrderStatus(OrderStatusEnum.PROFIT_WAIT_AUDIT.getStatus());
59   - long orderRecentWeekProfitWaitAudit = orderProfitAnalysisService.countRecentWeekByOrderStatus(OrderStatusEnum.PROFIT_WAIT_AUDIT.getStatus());
  38 + public ServerResult getData(DateTimeVO dateTimeVO){ return orderBaseInfoService.countByYear(dateTimeVO);}
60 39  
61   - //项目报告书待审核
62   - long orderReport = orderCompletionReportService.countByOrderStatus(OrderStatusEnum.REPORT_WAIT_AUDIT.getStatus());
63   - long orderYearReport = orderCompletionReportService.countYearByOrderStatus(OrderStatusEnum.REPORT_WAIT_AUDIT.getStatus());
64   -
65   - //总订单数
66   - long orderCount = orderBaseInfoService.countAll();
67   - //近一年订单数
68   - long orderRecentYearCount = orderBaseInfoService.countRecentYear();
69   -
70   - IndexDataVO indexDataVo = new IndexDataVO();
71   - indexDataVo.setOrderFinishedCount(orderTotalFinished); //订单完成。
72   - indexDataVo.setOrderRecentMonthFinishedCount(orderRecentMonthFinished);
73   - indexDataVo.setOrderInspectingCount(inspecting); //跟单和质检中。
74   - indexDataVo.setOrderRecentMonthInspectingCount(recentMonthInspecting);
75   - indexDataVo.setOrderProfitWaitAuditCount(orderProfitWaitAudit); //利润分析表待审核。
76   - indexDataVo.setOrderRecentWeekProfitWaitAuditCount(orderRecentWeekProfitWaitAudit);
77   - indexDataVo.setOrderReportWaitAuditCount(orderReport); //项目报告书待审核。
78   - indexDataVo.setOrderReportRecentYearWaitAuditCount(orderYearReport);
79   - indexDataVo.setOrderCount(orderCount); //订单初始化。
80   - indexDataVo.setOrderRecentYearCount(orderRecentYearCount);
  40 + @GetMapping("/chartData")
  41 + @ApiOperation("首页订单趋势")
  42 + public ServerResult getChartData(DateTimeVO dateTimeVO){
  43 + //订单趋势数据
  44 +// List<Map<String,Integer>> chartData = orderBaseInfoService.countDaysOrder();
  45 + return orderBaseInfoService.countByDate(dateTimeVO);
  46 + }
81 47  
82   - return ServerResult.success(indexDataVo);
  48 + @GetMapping("/totalSalesStatistics")
  49 + @ApiOperation("销售额完成情况")
  50 + public ServerResult totalSalesStatistics(QuerySalesStatisticeDO querySalesStatisticeDO){
  51 + //订单趋势数据
  52 + Map<String, String> chartData = orderBaseInfoService.totalSalesStatistics(querySalesStatisticeDO);
  53 + return ServerResult.success(chartData);
83 54 }
84 55  
85   - @GetMapping("/chartData")
86   - @ApiOperation("首页订单趋势")
87   - public ServerResult getChartData(){
  56 + @GetMapping("/salesStatusEveryCustomer")
  57 + @ApiOperation("每个客户销售额情况")
  58 + public ServerResult salesStatusEveryCustomer(QuerySalesStatisticeDO querySalesStatisticeDO){
88 59 //订单趋势数据
89   - List<Map<String,Integer>> chartData = orderBaseInfoService.countDaysOrder();
  60 + Map<String, Map<String, Double>> chartData = orderBaseInfoService.salesStatusEveryCustomer(querySalesStatisticeDO);
90 61 return ServerResult.success(chartData);
91 62 }
92 63 }
... ...
src/main/java/com/order/erp/controller/InvoiceBillOrderController.java
... ... @@ -172,7 +172,7 @@ public class InvoiceBillOrderController {
172 172 */
173 173 @PostMapping("/exportReceipt")
174 174 @AnonymousAccess
175   - public void exportReceipt(HttpServletResponse response, @RequestBody InvoiceBillOrderDO queryVO) throws IOException {
  175 + public void exportReceipt(HttpServletResponse response, @RequestBody InvoiceExportReceiptVO queryVO) throws IOException {
176 176 invoiceBillOrderService.exportReceipt(response,queryVO);
177 177 }
178 178 /**
... ... @@ -194,5 +194,15 @@ public class InvoiceBillOrderController {
194 194 public void byIdAddNotes(@RequestBody InvoiceBillCreateVO createVO) {
195 195 invoiceBillOrderService.byIdAddNotes(createVO);
196 196 }
  197 +
  198 + /**
  199 + *删除扣款单
  200 + * @param deleteVo id
  201 + * @return
  202 + */
  203 + @PostMapping("/deleteDeductUrl_by_id")
  204 + public ServerResult deleteDeductUrlById(@RequestBody InvoiceBillDeductInfoVO deleteVo) {
  205 + return invoiceBillOrderService.deleteDeductUrlById(deleteVo);
  206 + }
197 207 }
198 208  
... ...
src/main/java/com/order/erp/controller/ProducePaymentCheckBillOrderController.java
... ... @@ -184,7 +184,7 @@ public class ProducePaymentCheckBillOrderController {
184 184 */
185 185 @PostMapping("/exportReceipt")
186 186 @AnonymousAccess
187   - public void exportReceipt(HttpServletResponse response, @RequestBody ProducePaymentCheckBillOrderDO queryVO) throws IOException {
  187 + public void exportReceipt(HttpServletResponse response, @RequestBody CheckBillExportReceiptVO queryVO) throws IOException {
188 188 producePaymentCheckBillOrderService.exportReceipt(response,queryVO);
189 189 }
190 190 /**
... ... @@ -207,5 +207,15 @@ public class ProducePaymentCheckBillOrderController {
207 207 public void byIdAddNotes(@RequestBody ProducePaymentCheckBillCreateVO producePaymentCheckBillCreatevo) {
208 208 producePaymentCheckBillOrderService.byIdAddNotes(producePaymentCheckBillCreatevo);
209 209 }
  210 + /**
  211 + * 删除扣款单
  212 + * @param deleteVo id
  213 + * @return
  214 + * */
  215 + @PostMapping("/deleteDeductUrl_by_id")
  216 + public ServerResult deleteDeductUrlById( @RequestBody ProducePaymentCheckBillDeductInfoVO deleteVo){
  217 + return producePaymentCheckBillOrderService.deleteDeductUrlById(deleteVo);
  218 + }
210 219 }
211 220  
  221 +
... ...
src/main/java/com/order/erp/domain/FinanceOverEnum.java
... ... @@ -8,6 +8,12 @@ import lombok.Getter;
8 8 public enum FinanceOverEnum {
9 9 INVOICE_OVERTIME("你有invoice应收款未提交,请查收","Hi All 你以下invoice已超过回款日期,仍未生成应收款对账单提交审核,麻烦财务查询是否已打款,如未打款请业务员及时跟进\n。Invoice号为: "),
10 10 PRODUCE_PAYMENT_CHECK_OVERTIME("你有生产科对账单未提交,请查收","Hi All 你以下生产科对账单已超过应付款日期,麻烦财务查询是否已打款,如未打款请说明原因,如未收到发票,请业务员及时跟进\n。生产科对账单号为: "),
  11 + INVOICE_PASS("你提交的invoice应收款已通过审核","Hi All 你提交的invoice应收款已通过审核,请查收!\nInvoice号为: "),
  12 + CHECK_PASS("你提交的生产科对账单已通过审核","Hi All 你提交的生产科对账单已通过审核,请查收!\n生产科对账单号为: "),
  13 + INVOICE_FAIL("你提交的invoice应收款未通过审核","Hi All 你提交的invoice应收款未通过审核,请重新查看原因并提交审核!\nInvoice号为: "),
  14 + CHECK_FAIL("你提交的生产科对账单未通过审核","Hi All 你提交的生产科对账单未通过审核,请重新查看原因并提交审核!\n生产科对账单号为: "),
  15 + CHECK_INVOICEURL_PASS("你提交的生产科对账单发票通过审核","Hi All 你提交的生产科对账单发票通过审核,你现在可以提交生产科对账单了!\n生产科对账单号为: "),
  16 + CHECK_INVOICEURL_FAIL("你提交的生产科对账单发票未通过审核","Hi All 你提交的生产科对账单未通过审核,请重新查看原因并提交审核!\n生产科对账单号为: "),
11 17 ;
12 18  
13 19 private String title;
... ...
src/main/java/com/order/erp/domain/TimePeriod.java 0 → 100644
  1 +package com.order.erp.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +
  6 +@Getter
  7 +@AllArgsConstructor
  8 +public enum TimePeriod {
  9 + YEAR("年"),
  10 + QUARTER("季度"),
  11 + MONTH("月");
  12 +
  13 + private String description;
  14 +}
  15 +
... ...
src/main/java/com/order/erp/domain/dto/order/ProducePaymentCheckBillOrderDO.java
... ... @@ -106,7 +106,7 @@ public class ProducePaymentCheckBillOrderDO extends BaseDO implements Serializab
106 106 * */
107 107 private String businesPerson;
108 108 /**
109   - * 财务 --审核时使用。
  109 + * 提交人 --审核时使用。
110 110 * */
111 111 private String financePerson;
112 112 /**
... ...
src/main/java/com/order/erp/domain/dto/order/QuerySalesStatisticeDO.java 0 → 100644
  1 +package com.order.erp.domain.dto.order;
  2 +
  3 +
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * @author zgt
  11 + * @project order-erp
  12 + * @description
  13 + * @date 2024/8/19
  14 + */
  15 +
  16 +@Data
  17 +@AllArgsConstructor
  18 +@ToString
  19 +@NoArgsConstructor
  20 +@EqualsAndHashCode(callSuper = false)
  21 +@SuperBuilder
  22 +public class QuerySalesStatisticeDO {
  23 + List<String> customerCodeIn;
  24 + String period;
  25 +}
... ...
src/main/java/com/order/erp/domain/vo/ProducePdfVO.java
... ... @@ -25,5 +25,5 @@ public class ProducePdfVO {
25 25  
26 26 private Boolean isSend;
27 27 private List<String> personList;
28   -
  28 + private Boolean isTrue;
29 29 }
... ...
src/main/java/com/order/erp/domain/vo/order/CheckBillExportReceiptVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.io.Serializable;
  7 +import java.math.BigDecimal;
  8 +import java.util.List;
  9 +
  10 +@Data
  11 +@AllArgsConstructor
  12 +@ToString
  13 +@NoArgsConstructor
  14 +@EqualsAndHashCode(callSuper = false)
  15 +@SuperBuilder
  16 +public class CheckBillExportReceiptVO implements Serializable {
  17 + /**
  18 + * 实际应付金额。
  19 + */
  20 + private BigDecimal actualPayedAmount;
  21 + /**
  22 + * 生产科实际付款日期。
  23 + */
  24 + private String actualPayedDate;
  25 + /**
  26 + * 生产科对账单。
  27 + */
  28 + private String checkNo;
  29 + /**
  30 + * 生产科扣款金额。
  31 + */
  32 + private BigDecimal deductAmount;
  33 + /**
  34 + * 提交人 --审核时使用。
  35 + * */
  36 + private String financePerson;
  37 + /**
  38 + * 生产科应付款日期。
  39 + */
  40 + private String payedDate;
  41 + /**
  42 + * 实际付款金额汇总。
  43 + * */
  44 + private BigDecimal totalActualPayedAmount;
  45 + /**
  46 + * 跟单 --业务创建单子,跟单也能看到。
  47 + * */
  48 + private String trackerUser;
  49 + /**
  50 + * 未付金额。
  51 + * */
  52 + private BigDecimal unPayedAmount;
  53 + /**
  54 + * 状态,是否待审核/审核通过/审核不通过。 需要前端多传递status参数。
  55 + * */
  56 + private Integer status;
  57 + /**
  58 + * 类型,是否为发票类型还是应付账单申请类型。 需要前端多传递type参数。
  59 + * */
  60 + private Integer type;
  61 + /**
  62 + * 项目号
  63 + * */
  64 + private List<String> projectNo;
  65 +
  66 +
  67 +}
... ...
src/main/java/com/order/erp/domain/vo/order/CheckHoldTimeItemVO.java
... ... @@ -28,7 +28,7 @@ public class CheckHoldTimeItemVO implements Serializable {
28 28 /**
29 29 * 订单hold时间
30 30 */
31   - private String holdTime;
  31 + private String productionDepartmentConsignTime;
32 32  
33 33 /**
34 34 * 基础订单信息
... ...
src/main/java/com/order/erp/domain/vo/order/DateTimeVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +import java.util.List;
  8 +
  9 +
  10 +@Data
  11 +@AllArgsConstructor
  12 +@ToString
  13 +@NoArgsConstructor
  14 +@EqualsAndHashCode(callSuper = false)
  15 +@SuperBuilder
  16 +public class DateTimeVO {
  17 + //选择年份。
  18 + private Integer dateTime;
  19 + //选取多个年份 对比年份。
  20 + private List<Integer> dateTimes;
  21 + private String period;
  22 +}
... ...
src/main/java/com/order/erp/domain/vo/order/DateYearMonthTimeVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +@Data
  7 +@AllArgsConstructor
  8 +@ToString
  9 +@NoArgsConstructor
  10 +@EqualsAndHashCode(callSuper = false)
  11 +@SuperBuilder
  12 +public class DateYearMonthTimeVO {
  13 + /**
  14 + * date
  15 + */
  16 + private String date;
  17 +
  18 + /**
  19 + * 总价
  20 + */
  21 + private Long totalPrice;
  22 + /**
  23 + * 年份
  24 + */
  25 + private String yearType;
  26 +
  27 +}
... ...
src/main/java/com/order/erp/domain/vo/order/Datecount.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +
  7 +@Data
  8 +@AllArgsConstructor
  9 +@ToString
  10 +@NoArgsConstructor
  11 +@EqualsAndHashCode(callSuper = false)
  12 +@SuperBuilder
  13 +public class Datecount {
  14 + private Long allCount;
  15 + private Long trackingAndInspectingList;
  16 + private Long profitList;
  17 + private Long reportList;
  18 + private Long orderInitList;
  19 +}
... ...
src/main/java/com/order/erp/domain/vo/order/FinanceOrderResultVO.java
... ... @@ -54,6 +54,7 @@ public class FinanceOrderResultVO extends OrderBaseInfoVO {
54 54 */
55 55 private String orderHodTime;
56 56  
  57 + private String modeleLo;
57 58  
58 59 //invoice信息
59 60 //应收款信息
... ...
src/main/java/com/order/erp/domain/vo/order/InvoiceAndCheckBillSendEmailVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.order.erp.domain.dto.order.InvoiceBillOrderDO;
  4 +import com.order.erp.domain.dto.order.ProducePaymentCheckBillOrderDO;
  5 +import lombok.*;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +@Data
  9 +@AllArgsConstructor
  10 +@ToString
  11 +@NoArgsConstructor
  12 +@EqualsAndHashCode(callSuper = false)
  13 +@SuperBuilder
  14 +public class InvoiceAndCheckBillSendEmailVO {
  15 + /**
  16 + * 应付款
  17 + */
  18 + private InvoiceBillOrderDO invoiceBillOrderDO;
  19 +
  20 + /**
  21 + * 应收款
  22 + * */
  23 +
  24 + private ProducePaymentCheckBillOrderDO checkBillOrderDO;
  25 +
  26 + /**
  27 + * 拒绝原因
  28 + * */
  29 + private String refuseRemark;
  30 +}
... ...
src/main/java/com/order/erp/domain/vo/order/InvoiceExportReceiptVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Data
  10 +@AllArgsConstructor
  11 +@ToString
  12 +@NoArgsConstructor
  13 +@EqualsAndHashCode(callSuper = false)
  14 +@SuperBuilder
  15 +public class InvoiceExportReceiptVO {
  16 + /**
  17 + * 发票单号
  18 + */
  19 + private String invoiceNo;
  20 + /**
  21 + * 实际回款日期
  22 + */
  23 + private String actualRefundDate;
  24 + /**
  25 + * 必须回款日期
  26 + */
  27 + private String backRefundDate;
  28 + /**
  29 + * 发生扣款金额
  30 + */
  31 + private BigDecimal deductAmount;
  32 + /**
  33 + * 财务 --审核时使用。
  34 + * */
  35 + private String financePerson;
  36 + /**
  37 + * 其他费用金额
  38 + */
  39 + private BigDecimal otherAmount;
  40 + /**
  41 + * 收款单位
  42 + * */
  43 + private String payee;
  44 + /**
  45 + * 客户总价金额汇总
  46 + * */
  47 + private BigDecimal totalCustomerAmount;
  48 + /**
  49 + * 实际付款金额汇总
  50 + * */
  51 + private BigDecimal totalPayAmount;
  52 + /**
  53 + * 跟单 --业务创建单子,跟单也能看到。
  54 + * */
  55 + private String trackerUser;
  56 + /**
  57 + * 项目号
  58 + * */
  59 + private List<String> projectNo;
  60 +}
... ...
src/main/java/com/order/erp/domain/vo/order/InvoiceFieldVO.java
... ... @@ -67,5 +67,9 @@ public class InvoiceFieldVO {
67 67 * 财务人员
68 68 * */
69 69 private String financePerson;
  70 + /**
  71 + * 项目号
  72 + * */
  73 + private List<String> projectNo;
70 74  
71 75 }
... ...
src/main/java/com/order/erp/domain/vo/order/InvoiceHoldTimeItemVO.java
... ... @@ -26,9 +26,9 @@ public class InvoiceHoldTimeItemVO implements Serializable {
26 26 private String customerCode;
27 27  
28 28 /**
29   - * 订单hold时间
  29 + * 订单的拖货时间
30 30 */
31   - private String holdTime;
  31 + private String productionDepartmentConsignTime;
32 32  
33 33 /**
34 34 * 基础订单信息
... ...
src/main/java/com/order/erp/domain/vo/order/OrderInfoResultVO.java
... ... @@ -53,5 +53,8 @@ public class OrderInfoResultVO extends OrderBaseInfoVO implements Serializable {
53 53 * 进度条
54 54 */
55 55 private Double schedule;
56   -
  56 + /**
  57 + * 尾期结果
  58 + */
  59 + private String endCheckResult;
57 60 }
... ...
src/main/java/com/order/erp/domain/vo/order/OrderProfitAnalysisVO.java
... ... @@ -110,5 +110,9 @@ public class OrderProfitAnalysisVO implements Serializable {
110 110 * 记录数
111 111 */
112 112 private Integer recordNum;
  113 + /**
  114 + * 尾期验货结果 这个结果让业务员也能选,本来属于质检员填写的,现在改为业务员也能填写。
  115 + */
  116 + private String endCheckResult;
113 117  
114 118 }
... ...
src/main/java/com/order/erp/domain/vo/order/ProducePaymentCheckBillFieldVO.java
... ... @@ -76,5 +76,9 @@ public class ProducePaymentCheckBillFieldVO {
76 76 * 生产科
77 77 * */
78 78 private String productionName;
  79 + /**
  80 + * 项目号
  81 + * */
  82 + private List<String> projectNo;
79 83  
80 84 }
... ...
src/main/java/com/order/erp/job/FinanceJob.java
... ... @@ -53,7 +53,7 @@ public class FinanceJob {
53 53 @Resource
54 54 private OrderBaseInfoService orderBaseInfoService;
55 55 //每天的7:15执行一次
56   - @Scheduled(cron = "0 15 7 * * ?", zone = "Asia/Shanghai")
  56 +// @Scheduled(cron = "0 15 7 * * ?", zone = "Asia/Shanghai")
57 57  
58 58 //每分钟执行一次
59 59 // @Scheduled(cron = "0 * * * * ?", zone = "Asia/Shanghai")
... ...
src/main/java/com/order/erp/job/OrderJob.java
... ... @@ -18,6 +18,7 @@ import org.springframework.stereotype.Component;
18 18  
19 19 import javax.annotation.Resource;
20 20 import java.util.List;
  21 +import java.util.Map;
21 22 import java.util.Objects;
22 23 import java.util.Set;
23 24 import java.util.stream.Collectors;
... ... @@ -53,20 +54,21 @@ public class OrderJob {
53 54 /**
54 55 * 每隔5分执行一次
55 56 */
56   - @Scheduled(cron = "0 */5 * * * ?")
  57 + @Scheduled(cron = "0 */10 * * * ?")
57 58 // @Scheduled(cron = "*/5 * * * * ?")
58 59 public void checkCompleteExecute() {
59 60 log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
60 61 LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>()
61 62 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  63 + //这里如果要改的话,就改成不是扫三个月的,而是全部扫一遍。
62 64 .ge(OrderBaseInfoDO::getCreateTime, DateUtils.format(DateTime.now().minusMonths(Constant.ONE).toDate(), DateUtils.DATE_TIME))
63 65 .le(OrderBaseInfoDO::getCreateTime, DateUtils.format(DateTime.now().toDate(), DateUtils.DATE_TIME))
64 66 .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
65 67 List<OrderBaseInfoDO> ordersDOS = orderBaseInfoService.list(queryWrapper);
66   -//如果都填充完成为 1.25,如果只填写4个,则为1。
  68 +//如果都填充完成为 1.25,如果只填写4个,则为1。 这里面的方法是否是要改成,只要对应的跟单,质检任何一个格子填写了数据,就算上完成就加一。
67 69 List<OrderInfoResultVO> orderInfoResultVOS = orderBaseInfoService.wrapperOrderResultList(false, ordersDOS);
68 70 if (CollectionUtils.isNotEmpty(orderInfoResultVOS)) {
69   - Set<Long> orderIds = orderInfoResultVOS.stream().filter(x -> Objects.nonNull(x.getSchedule()) && Constant.ONE == x.getSchedule()).map(OrderInfoResultVO::getId).collect(Collectors.toSet());
  71 + Set<Long> orderIds = orderInfoResultVOS.stream().filter(x -> Objects.nonNull(x.getSchedule()) && Constant.ONE <= x.getSchedule()).map(OrderInfoResultVO::getId).collect(Collectors.toSet());
70 72 if (CollectionUtils.isNotEmpty(orderIds)) {
71 73 LambdaUpdateWrapper<OrderBaseInfoDO> orderBaseUpdateWrapper = new LambdaUpdateWrapper<OrderBaseInfoDO>()
72 74 .in(OrderBaseInfoDO::getId, orderIds).set(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
... ... @@ -98,7 +100,7 @@ public class OrderJob {
98 100 /**
99 101 * 每隔5分执行一次
100 102 */
101   - @Scheduled(cron = "0 */5 * * * ?")
  103 +
102 104 // @Scheduled(cron = "*/5 * * * * ?")
103 105 public void checkChargeOrderCount() {
104 106 log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
... ... @@ -107,4 +109,108 @@ public class OrderJob {
107 109 }
108 110  
109 111  
  112 + // 以下两个定时任务都是一次性的。
  113 +
  114 + //写一个扫描全部订单。只要有一栏填写了数据,就相当于完成了。 只扫描一次。 每五分钟扫描一次,只要有一栏填写了数据,就相当于完成了。 在填充接口中,设置只要填充了一栏就算上订单完成。
  115 +
  116 +// @Scheduled(cron = "0 3 3 4 1 ?", zone = "Asia/Shanghai")
  117 + //这里扫描全部未完成的订单。重新设置订单完成的状态。
  118 + public void checkFinish() {
  119 + log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
  120 + LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>()
  121 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  122 + .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  123 + List<OrderBaseInfoDO> ordersDOS = orderBaseInfoService.list(queryWrapper);
  124 +
  125 + List<OrderInfoResultVO> orderInfoResultVOS = orderBaseInfoService.wrapperOrderResultList(false, ordersDOS);
  126 + if (CollectionUtils.isNotEmpty(orderInfoResultVOS)) {
  127 + //这里设置为>=的目的是,填充五个的话,就为5,填充4的的话就为4,除4,要么为1要么为1.25。这种情况都算订单完成。
  128 + Set<Long> orderIds = orderInfoResultVOS.stream().filter(x -> Objects.nonNull(x.getSchedule()) && Constant.ONE <= x.getSchedule()).map(OrderInfoResultVO::getId).collect(Collectors.toSet());
  129 + if (CollectionUtils.isNotEmpty(orderIds)) {
  130 + LambdaUpdateWrapper<OrderBaseInfoDO> orderBaseUpdateWrapper = new LambdaUpdateWrapper<OrderBaseInfoDO>()
  131 + .in(OrderBaseInfoDO::getId, orderIds).set(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  132 +
  133 + LambdaUpdateWrapper<OrderCompletionReportDO> reportUpdateWrapper = new LambdaUpdateWrapper<OrderCompletionReportDO>()
  134 + .in(OrderCompletionReportDO::getOrderId, orderIds).set(OrderCompletionReportDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  135 +
  136 + LambdaUpdateWrapper<OrderProfitAnalysisDO> profitUpdateWrapper = new LambdaUpdateWrapper<OrderProfitAnalysisDO>()
  137 + .in(OrderProfitAnalysisDO::getOrderId, orderIds).set(OrderProfitAnalysisDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  138 +
  139 + LambdaUpdateWrapper<OrderTrackStageDO> trackUpdateWrapper = new LambdaUpdateWrapper<OrderTrackStageDO>()
  140 + .in(OrderTrackStageDO::getOrderId, orderIds).set(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  141 +
  142 + LambdaUpdateWrapper<OrderInspectionStageDO> inspectUpdateWrapper = new LambdaUpdateWrapper<OrderInspectionStageDO>()
  143 + .in(OrderInspectionStageDO::getOrderId, orderIds).set(OrderInspectionStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  144 +
  145 + transactionHelper.run(() -> {
  146 + orderBaseInfoService.update(orderBaseUpdateWrapper);
  147 + reportService.update(reportUpdateWrapper);
  148 + profitAnalysisService.update(profitUpdateWrapper);
  149 + trackStageService.update(trackUpdateWrapper);
  150 + inspectionStageService.update(inspectUpdateWrapper);
  151 + });
  152 + }
  153 + }
  154 + log.info("执行结束时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
  155 + }
  156 +
  157 +
  158 + //处理跟单和质检中的状态。
  159 +
  160 +// @Scheduled(cron = "0 3 4 4 1 ?", zone = "Asia/Shanghai")
  161 + public void checkTrackInfoAndInspectionInfoStatus() {
  162 + log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
  163 + List<OrderTrackStageDO> orderTrackStageDOS = trackStageService.list(new LambdaQueryWrapper<OrderTrackStageDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).ne(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus()));
  164 + List<OrderInspectionStageDO> orderInspectionStageDOS = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).ne(OrderInspectionStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus()));
  165 + Set<Long> trackOrderIds = orderTrackStageDOS.stream()
  166 + .map(OrderTrackStageDO::getOrderId)
  167 + .filter(orderId -> orderId != null) // 防止 orderId 为空
  168 + .collect(Collectors.toSet());
  169 +
  170 + Set<Long> inspectionOrderIds = orderInspectionStageDOS.stream()
  171 + .map(OrderInspectionStageDO::getOrderId)
  172 + .filter(orderId -> orderId != null) // 防止 orderId 为空
  173 + .collect(Collectors.toSet());
  174 +//得到交集。
  175 + Set<Long> commonOrderIds = trackOrderIds.stream()
  176 + .filter(inspectionOrderIds::contains)
  177 + .collect(Collectors.toSet());
  178 +
  179 + Map<Long,OrderTrackStageDO> orderTrackStageMap = orderTrackStageDOS.stream()
  180 + .filter(order -> order.getOrderId() != null)
  181 + .collect(Collectors.toMap(
  182 + OrderTrackStageDO::getOrderId,
  183 + order-> order,
  184 + (existing, replacement) -> existing // 处理 key 冲突时,保留现有值
  185 + ));
  186 +
  187 + Map<Long, OrderInspectionStageDO> orderInspectionStageMap = orderInspectionStageDOS.stream()
  188 + .filter(order -> order.getOrderId() != null)
  189 + .collect(Collectors.toMap(
  190 + OrderInspectionStageDO::getOrderId,
  191 + order ->order,
  192 + (existing, replacement) -> existing // 处理 key 冲突时,保留现有值
  193 + ));
  194 + List<OrderInspectionStageDO> orderInspectionList = commonOrderIds.stream().map(order -> {
  195 + OrderInspectionStageDO inspectionStageDO = orderInspectionStageMap.get(order);
  196 + OrderTrackStageDO trackStageDO = orderTrackStageMap.get(order);
  197 + if (Objects.nonNull(inspectionStageDO) && Objects.nonNull(trackStageDO)) {
  198 + Integer trackStageDOOrderStatus = trackStageDO.getOrderStatus();
  199 + Integer inspectionStageDOOrderStatus = inspectionStageDO.getOrderStatus();
  200 + if (Objects.nonNull(trackStageDOOrderStatus) && Objects.nonNull(inspectionStageDOOrderStatus)
  201 + && OrderStatusEnum.TRACK_ING.getStatus().equals(trackStageDOOrderStatus)
  202 + && OrderStatusEnum.INSPECT_ING.getStatus().equals(inspectionStageDOOrderStatus)) {
  203 + //由于跟单和质检,一个订单你操作了跟单或者质检后,然后在操作一次质检或者跟单,在首页统计中跟单和质检就会计算两次,相当于多计算了一次,重复了。所以这里需要去重。
  204 + inspectionStageDO.setOrderStatus(OrderStatusEnum.INSPECT_PASS.getStatus());
  205 + return inspectionStageDO;
  206 + }
  207 + }
  208 + return null;
  209 + }).filter(Objects::nonNull).collect(Collectors.toList());
  210 + if(CollectionUtils.isNotEmpty(orderInspectionList)){
  211 + inspectionStageService.updateBatchById(orderInspectionList);
  212 + }
  213 + log.info("执行结束时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
  214 + }
  215 +
110 216 }
... ...
src/main/java/com/order/erp/job/OrderOverTimeEventJob.java
... ... @@ -184,9 +184,12 @@ public class OrderOverTimeEventJob {
184 184 }
185 185 if (Objects.nonNull(productionDepartmentUser) && CollectionUtils.isNotEmpty(emailList)) {
186 186 List<String> emails = emailList.stream().flatMap(email -> Arrays.stream(email.split("[,,]+"))).collect(Collectors.toList());
187   - List<String> productionEmail = Arrays.asList(productionDepartmentUser.getEmail().split("[,,]+"))
188   - .stream().map(String::trim)
189   - .filter(Objects::nonNull)
  187 + List<String> productionEmail = Optional.ofNullable(productionDepartmentUser.getEmail()) // 确保邮箱不为空
  188 + .map(email -> Arrays.asList(email.split("[,,]+"))) // 拆分邮箱字符串
  189 + .orElse(Collections.emptyList()) // 如果 email 为空,返回一个空的列表
  190 + .stream()
  191 + .map(String::trim) // 去除前后空格
  192 + .filter(StringUtils::isNotBlank) // 确保去除空字符串
190 193 .collect(Collectors.toList());
191 194 List<String> combineEmail = new ArrayList<>(emails);
192 195 if(CollectionUtils.isNotEmpty(produceEmailList)){
... ...
src/main/java/com/order/erp/mapper/order/OrderBaseInfoMapper.java
1 1 package com.order.erp.mapper.order;
2 2  
3 3 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import com.order.erp.config.MapResultHandler;
4 5 import com.order.erp.domain.OrderStatusEnum;
5 6 import com.order.erp.domain.dto.order.OrderBaseInfoDO;
6 7 import com.order.erp.domain.vo.OrderCountVO;
  8 +import com.order.erp.domain.vo.order.DateYearMonthTimeVO;
7 9 import com.order.erp.domain.vo.order.QueryProjectNoAndInnerNoDto;
8 10 import org.apache.ibatis.annotations.Param;
9 11 import org.apache.ibatis.annotations.Select;
10 12  
  13 +import java.time.LocalDate;
  14 +import java.time.LocalDateTime;
11 15 import java.util.List;
12 16 import java.util.Map;
13 17  
... ... @@ -34,5 +38,31 @@ public interface OrderBaseInfoMapper extends BaseMapper&lt;OrderBaseInfoDO&gt; {
34 38 // @Select("SELECT * FROM order_base_info WHERE order_status!=50 and enable_flag=10 and DATE_SUB(CURDATE(), INTERVAL 3 MONTH) <= date(create_time);")
35 39 @Select("SELECT * FROM order_base_info WHERE enable_flag=10 and DATE_SUB(CURDATE(), INTERVAL 3 MONTH) <= date(create_time);")
36 40 List<OrderBaseInfoDO> getEventList();
  41 +
  42 + Double salesAmountStatistics(LocalDateTime begin, LocalDateTime end, List<String> customerCodeIn);
  43 +
  44 + Double salesAmountTarget(List<String> customerCodeIn);
  45 +
  46 + void customerSalesStatus(LocalDateTime begin, LocalDateTime end,
  47 + List<String> customerCodeIn,
  48 + MapResultHandler<String, Double> mapResultHandler);
  49 +
  50 + @Select("SELECT YEAR(obi.create_time) AS date, SUM(opa.customer_total_price) AS totalPrice FROM order_base_info obi JOIN order_profit_analysis opa ON opa.order_id = obi.id AND opa.enable_flag = 10 WHERE obi.enable_flag = 10 GROUP BY YEAR(obi.create_time) ORDER BY date;")
  51 + List<DateYearMonthTimeVO> countRecentYearByOrderStatus();
  52 + @Select("SELECT count(*) AS count FROM order_base_info WHERE order_status=#{orderStatus} and enable_flag=10;")
  53 + long countAllYearByOrderStatus(Integer orderStatus);
  54 + List<DateYearMonthTimeVO> countRecentMonthValueByOrderStatus(List<Integer> years);
  55 + @Select("SELECT count(*) FROM order_base_info WHERE enable_flag=10;")
  56 + long countRecentYearByOrderInit();
  57 + @Select("SELECT count(*) AS count FROM order_base_info WHERE enable_flag=10 AND create_time >= #{startOfYear} AND create_time < #{endOfYear};")
  58 + long countRecentMonthValueByOrderInit(LocalDate startOfYear, LocalDate endOfYear);
  59 + @Select("SELECT count(*) AS count FROM order_base_info WHERE order_status=#{orderStatus} and enable_flag=10 AND create_time >= #{startOfYear} AND create_time < #{endOfYear};")
  60 + long countAllMonthByOrderStatus(Integer orderStatus,LocalDate startOfYear,LocalDate endOfYear);
  61 + @Select("SELECT DATE(obi.create_time) AS date,SUM(opa.customer_total_price) AS totalPrice FROM order_base_info obi JOIN order_profit_analysis opa ON opa.order_id=obi.id AND opa.enable_flag = 10 WHERE obi.enable_flag = 10 AND obi.create_time >=#{startDate} AND obi.create_time < #{endDate} GROUP BY DATE(obi.create_time) ORDER BY date;")
  62 + List<DateYearMonthTimeVO> countRecentDayvalueByOrderStatus(LocalDate startDate, LocalDate endDate);
  63 + @Select("SELECT count(*) AS count FROM order_base_info WHERE order_status=#{orderStatus} AND enable_flag=10 AND create_time >= #{startDate} AND create_time < #{endDate};")
  64 + long countAllDayvalueByOrderStatus(Integer orderStatus, LocalDate startDate, LocalDate endDate);
  65 + @Select("SELECT count(*) AS count FROM order_base_info WHERE enable_flag=10 AND create_time >= #{startDate} AND create_time < #{endDate};")
  66 + long countRecentDayByOrderInit(LocalDate startDate, LocalDate endDate);
37 67 }
38 68  
... ...
src/main/java/com/order/erp/mapper/order/OrderCompletionReportMapper.java
... ... @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 4 import com.order.erp.domain.dto.order.OrderCompletionReportDO;
5 5 import org.apache.ibatis.annotations.Select;
6 6  
  7 +import java.time.LocalDate;
  8 +
7 9 /**
8 10 * 订单-项目完成报告书(OrderCompletionReport)表数据库访问层
9 11 *
... ... @@ -15,5 +17,11 @@ public interface OrderCompletionReportMapper extends BaseMapper&lt;OrderCompletionR
15 17  
16 18 @Select("SELECT count(*) FROM order_completion_report WHERE order_status=#{status} and enable_flag=10 and create_time >= DATE_SUB(NOW(), INTERVAL 1 YEAR);")
17 19 long countYearByOrderStatus(Integer status);
  20 + @Select("SELECT count(*) FROM order_completion_report WHERE order_status=#{status} and enable_flag=10;")
  21 + long countRecentYearByOrderStatus(Integer status);
  22 + @Select("SELECT count(*) AS count FROM order_completion_report WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startOfYear} AND create_time < #{endOfYear};")
  23 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  24 + @Select("SELECT count(*) AS count FROM order_completion_report WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startDate} AND create_time < #{endDate};")
  25 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate);
18 26 }
19 27  
... ...
src/main/java/com/order/erp/mapper/order/OrderFieldLockApplyMapper.java
... ... @@ -2,6 +2,9 @@ package com.order.erp.mapper.order;
2 2  
3 3 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 4 import com.order.erp.domain.dto.order.OrderFieldLockApplyDO;
  5 +import org.apache.ibatis.annotations.Select;
  6 +
  7 +import java.time.LocalDate;
5 8  
6 9 /**
7 10 * 用户订单-字段锁定申请表(OrderFieldLockApply)表数据库访问层
... ... @@ -10,7 +13,12 @@ import com.order.erp.domain.dto.order.OrderFieldLockApplyDO;
10 13 * @since 2023-09-08 15:26:45
11 14 */
12 15 public interface OrderFieldLockApplyMapper extends BaseMapper<OrderFieldLockApplyDO> {
13   -
  16 + @Select("SELECT count(*) FROM order_field_lock_apply WHERE status=0 AND type=#{applyType} and enable_flag=10;")
  17 + long countAllYearByOrderStatus(Integer applyType);
  18 + @Select("SELECT count(*) AS count FROM order_field_lock_apply WHERE status=0 AND type=#{applyType} AND enable_flag=10 AND create_time >= #{startOfYear} AND create_time < #{endOfYear};")
  19 + long countRecentMonthValueByOrderStatus(Integer applyType, LocalDate startOfYear, LocalDate endOfYear);
  20 + @Select("SELECT count(*) AS count FROM order_field_lock_apply WHERE status=0 AND type=#{applyType} AND enable_flag=10 AND create_time >= #{startDate} AND create_time < #{endDate};")
  21 + long countRecentDayvalueByOrderStatus(Integer applyType, LocalDate startDate, LocalDate endDate);
14 22  
15 23 }
16 24  
... ...
src/main/java/com/order/erp/mapper/order/OrderInspectionStageMapper.java
... ... @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 4 import com.order.erp.domain.dto.order.OrderInspectionStageDO;
5 5 import org.apache.ibatis.annotations.Select;
6 6  
  7 +import java.time.LocalDate;
  8 +
7 9 /**
8 10 * 订单-质检环节(OrderInspectionStage)表数据库访问层
9 11 *
... ... @@ -15,5 +17,11 @@ public interface OrderInspectionStageMapper extends BaseMapper&lt;OrderInspectionSt
15 17  
16 18 @Select("SELECT count(*) FROM order_inspection_stage WHERE order_status=#{status} and enable_flag=10 and DATE_SUB(CURDATE(), INTERVAL 1 MONTH) <= date(create_time);")
17 19 long countRecentMonthByOrderStatus(Integer status);
  20 + @Select("SELECT count(*) FROM order_inspection_stage WHERE order_status=#{status} and enable_flag=10;")
  21 + long countRecentYearByOrderStatus(Integer status);
  22 + @Select("SELECT count(*) AS count FROM order_inspection_stage WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startOfYear} AND create_time < #{endOfYear};")
  23 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  24 + @Select("SELECT count(*) AS count FROM order_inspection_stage WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startDate} AND create_time < #{endDate};")
  25 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate);
18 26 }
19 27  
... ...
src/main/java/com/order/erp/mapper/order/OrderProfitAnalysisMapper.java
... ... @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 4 import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
5 5 import org.apache.ibatis.annotations.Select;
6 6  
  7 +import java.time.LocalDate;
  8 +
7 9 /**
8 10 * 订单利润分析表(OrderProfitAnalysis)表数据库访问层
9 11 *
... ... @@ -15,5 +17,11 @@ public interface OrderProfitAnalysisMapper extends BaseMapper&lt;OrderProfitAnalysi
15 17  
16 18 @Select("SELECT count(*) FROM order_profit_analysis WHERE enable_flag=10 and order_status=#{status} and create_time >= DATE_SUB(NOW(), INTERVAL 1 WEEK);")
17 19 long countRecentWeekByOrderStatus(Integer status);
  20 + @Select("SELECT count(*) FROM order_profit_analysis WHERE enable_flag=10 and order_status=#{status};")
  21 + long countRecentYearByOrderStatus(Integer status);
  22 + @Select("SELECT count(*) AS count FROM order_profit_analysis WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startOfYear} AND create_time < #{endOfYear};")
  23 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  24 + @Select("SELECT count(*) AS count FROM order_profit_analysis WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startDate} AND create_time < #{endDate};")
  25 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate);
18 26 }
19 27  
... ...
src/main/java/com/order/erp/mapper/order/OrderTrackStageMapper.java
... ... @@ -2,6 +2,9 @@ package com.order.erp.mapper.order;
2 2  
3 3 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 4 import com.order.erp.domain.dto.order.OrderTrackStageDO;
  5 +import org.apache.ibatis.annotations.Select;
  6 +
  7 +import java.time.LocalDate;
5 8  
6 9 /**
7 10 * 订单-跟单环节(OrderTrackStage)表数据库访问层
... ... @@ -10,7 +13,12 @@ import com.order.erp.domain.dto.order.OrderTrackStageDO;
10 13 * @since 2023-09-08 15:26:48
11 14 */
12 15 public interface OrderTrackStageMapper extends BaseMapper<OrderTrackStageDO> {
13   -
  16 + @Select("SELECT count(*) FROM order_track_stage WHERE order_status=#{status} and enable_flag=10;")
  17 + long countRecentYearByOrderStatus(Integer status);
  18 + @Select("SELECT count(*) AS count FROM order_track_stage WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startOfYear} AND create_time < #{endOfYear};")
  19 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  20 + @Select("SELECT count(*) AS count FROM order_track_stage WHERE order_status=#{status} AND enable_flag=10 AND create_time >= #{startDate} AND create_time < #{endDate};")
  21 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate);
14 22  
15 23 }
16 24  
... ...
src/main/java/com/order/erp/service/admin/impl/DictionaryServiceImpl.java
... ... @@ -12,6 +12,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
12 12 import com.order.erp.common.constant.Constant;
13 13 import com.order.erp.common.constant.ServerResult;
14 14 import com.order.erp.common.utils.TransactionHelper;
  15 +import com.order.erp.config.DataScope;
  16 +import com.order.erp.domain.RoleEnum;
15 17 import com.order.erp.domain.dto.BaseDO;
16 18 import com.order.erp.domain.dto.SystemSettingDO;
17 19 import com.order.erp.domain.dto.admin.DictionaryDO;
... ... @@ -29,6 +31,7 @@ import javax.annotation.Resource;
29 31 import java.util.ArrayList;
30 32 import java.util.List;
31 33 import java.util.Objects;
  34 +import java.util.Optional;
32 35 import java.util.stream.Collectors;
33 36  
34 37 /**
... ... @@ -48,6 +51,9 @@ public class DictionaryServiceImpl extends ServiceImpl&lt;DictionaryMapper, Diction
48 51 @Resource
49 52 private SystemSettingService systemSettingService;
50 53  
  54 + @Resource
  55 + private DataScope dataScope;
  56 +
51 57 /**
52 58 * 通过ID查询单条数据
53 59 * <p>
... ... @@ -117,11 +123,19 @@ public class DictionaryServiceImpl extends ServiceImpl&lt;DictionaryMapper, Diction
117 123 if (CollectionUtils.isEmpty(dictionaryDOList)) {
118 124 return ServerResult.success();
119 125 }
120   - return ServerResult.success(dictionaryDOList.stream().map(x -> {
121   - DictionaryResultVO resultVO = new DictionaryResultVO();
122   - BeanUtils.copyProperties(x, resultVO);
123   - return resultVO;
124   - }).collect(Collectors.toList()));
  126 + //对于质检员,他不能在尾期验货结果中选择FAIL RELEASE,所以不需要这个选项显示。
  127 + RoleEnum role = dataScope.getRole();
  128 + if(Objects.nonNull(role) && RoleEnum.INSPECT_USER.getId().equals(role.getId())){
  129 + Optional<DictionaryDO> elementToRemove = dictionaryDOList.stream().filter(item -> "endCheckResult".equals(item.getDictCode()) && "FAIL RELEASE".equals(item.getDictValue())).findFirst();
  130 + elementToRemove.ifPresent(dictionaryDO -> dictionaryDOList.remove(dictionaryDO));
  131 + return ServerResult.success(dictionaryDOList);
  132 + }else {
  133 + return ServerResult.success(dictionaryDOList.stream().map(x -> {
  134 + DictionaryResultVO resultVO = new DictionaryResultVO();
  135 + BeanUtils.copyProperties(x, resultVO);
  136 + return resultVO;
  137 + }).collect(Collectors.toList()));
  138 + }
125 139 }
126 140  
127 141 /**
... ...
src/main/java/com/order/erp/service/order/InvoiceBillOrderService.java
... ... @@ -111,7 +111,7 @@ public interface InvoiceBillOrderService extends IService&lt;InvoiceBillOrderDO&gt; {
111 111 * @param queryVO
112 112 * @return 是否成功
113 113 */
114   - ServerResult exportReceipt(HttpServletResponse response,InvoiceBillOrderDO queryVO) throws IOException;
  114 + ServerResult exportReceipt(HttpServletResponse response,InvoiceExportReceiptVO queryVO) throws IOException;
115 115  
116 116 List<InvoiceBillOrderDO> getOverEvnetList();
117 117  
... ... @@ -119,4 +119,6 @@ public interface InvoiceBillOrderService extends IService&lt;InvoiceBillOrderDO&gt; {
119 119  
120 120 ServerResult byIdAddNotes(InvoiceBillCreateVO createVO);
121 121  
  122 + ServerResult deleteDeductUrlById(InvoiceBillDeductInfoVO deleteVo);
  123 +
122 124 }
... ...
src/main/java/com/order/erp/service/order/OrderBaseInfoService.java
... ... @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
5 5 import com.order.erp.common.constant.ServerResult;
6 6 import com.order.erp.common.excel4j.exceptions.Excel4JException;
7 7 import com.order.erp.domain.dto.order.OrderBaseInfoDO;
  8 +import com.order.erp.domain.dto.order.QuerySalesStatisticeDO;
8 9 import com.order.erp.domain.vo.ProducePdfVO;
9 10 import com.order.erp.domain.vo.order.*;
10 11 import freemarker.template.TemplateException;
... ... @@ -123,4 +124,11 @@ public interface OrderBaseInfoService extends IService&lt;OrderBaseInfoDO&gt; {
123 124  
124 125 ServerResult send(ProducePdfVO producePdfVO) throws Exception;
125 126  
  127 + Map<String, String> totalSalesStatistics(QuerySalesStatisticeDO query);
  128 +
  129 + Map<String, Map<String, Double>> salesStatusEveryCustomer(QuerySalesStatisticeDO query);
  130 +
  131 + ServerResult countByYear(DateTimeVO dateTimeVO);
  132 +
  133 + ServerResult countByDate(DateTimeVO dateTimeVO);
126 134 }
... ...
src/main/java/com/order/erp/service/order/OrderCompletionReportService.java
... ... @@ -11,6 +11,7 @@ import com.order.erp.domain.vo.order.OrderCompletionReportVO;
11 11  
12 12 import javax.servlet.http.HttpServletResponse;
13 13 import java.io.IOException;
  14 +import java.time.LocalDate;
14 15 import java.util.List;
15 16  
16 17 /**
... ... @@ -83,4 +84,7 @@ public interface OrderCompletionReportService extends IService&lt;OrderCompletionRe
83 84 long countByOrderStatus(Integer status);
84 85  
85 86 long countYearByOrderStatus(Integer status);
  87 + long countRecentYearByOrderStatus(Integer status);
  88 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  89 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate);
86 90 }
... ...
src/main/java/com/order/erp/service/order/OrderFieldLockApplyService.java
... ... @@ -7,6 +7,7 @@ import com.order.erp.domain.vo.order.AuditVO;
7 7 import com.order.erp.domain.vo.order.OrderFieldLockApplyQueryVO;
8 8 import com.order.erp.domain.vo.order.OrderFieldLockApplyVO;
9 9  
  10 +import java.time.LocalDate;
10 11 import java.util.List;
11 12  
12 13 /**
... ... @@ -72,4 +73,8 @@ public interface OrderFieldLockApplyService extends IService&lt;OrderFieldLockApply
72 73 boolean deleteByOrderId(Long orderId);
73 74  
74 75 boolean deleteByOrderIds(List<Long> orderIds);
  76 +
  77 + long countAllYearByOrderStatus(Integer applyType);
  78 + long countRecentMonthValueByOrderStatus(Integer applyType, LocalDate startOfYear, LocalDate endOfYear);
  79 + long countRecentDayvalueByOrderStatus(Integer applyType, LocalDate startDate, LocalDate endDate);
75 80 }
... ...
src/main/java/com/order/erp/service/order/OrderInspectionStageService.java
... ... @@ -7,6 +7,7 @@ import com.order.erp.domain.dto.order.OrderInspectionStageDO;
7 7 import com.order.erp.domain.vo.order.OrderInspectionStageQueryVO;
8 8 import com.order.erp.domain.vo.order.OrderInspectionStageVO;
9 9  
  10 +import java.time.LocalDate;
10 11 import java.util.List;
11 12  
12 13 /**
... ... @@ -64,4 +65,9 @@ public interface OrderInspectionStageService extends IService&lt;OrderInspectionSta
64 65 long countByOrderStatus(Integer orderStatus);
65 66  
66 67 long countRecentMonthByOrderStatus(Integer status);
  68 +
  69 + long countRecentYearByOrderStatus(Integer status);
  70 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  71 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate);
  72 +
67 73 }
... ...
src/main/java/com/order/erp/service/order/OrderProfitAnalysisService.java
... ... @@ -8,6 +8,7 @@ import com.order.erp.domain.vo.order.OrderProfitAnalysisQueryVO;
8 8 import com.order.erp.domain.vo.order.OrderProfitAnalysisVO;
9 9 import com.order.erp.domain.vo.order.ProfitCalculateVO;
10 10  
  11 +import java.time.LocalDate;
11 12 import java.util.List;
12 13  
13 14 /**
... ... @@ -73,4 +74,7 @@ public interface OrderProfitAnalysisService extends IService&lt;OrderProfitAnalysis
73 74 long countByOrderStatus(Integer status);
74 75  
75 76 long countRecentWeekByOrderStatus(Integer status);
  77 + long countRecentYearByOrderStatus(Integer status);
  78 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  79 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate);
76 80 }
... ...
src/main/java/com/order/erp/service/order/OrderTrackStageService.java
... ... @@ -6,6 +6,7 @@ import com.order.erp.domain.dto.order.OrderTrackStageDO;
6 6 import com.order.erp.domain.vo.order.OrderTrackStageQueryVO;
7 7 import com.order.erp.domain.vo.order.OrderTrackStageVO;
8 8  
  9 +import java.time.LocalDate;
9 10 import java.util.List;
10 11  
11 12 /**
... ... @@ -59,4 +60,7 @@ public interface OrderTrackStageService extends IService&lt;OrderTrackStageDO&gt; {
59 60 boolean deleteByOrderId(Long orderId);
60 61  
61 62 boolean deleteByOrderIds(List<Long> orderIds);
  63 + long countRecentYearByOrderStatus(Integer status);
  64 + long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear);
  65 + long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate,LocalDate endDate);
62 66 }
... ...
src/main/java/com/order/erp/service/order/ProducePaymentCheckBillOrderService.java
... ... @@ -105,9 +105,10 @@ public interface ProducePaymentCheckBillOrderService extends IService&lt;ProducePay
105 105 ServerResult getDeductUrlById(ProducePaymentCheckBillOrderQueryVO producePaymentCheckBillOrderQueryVO);
106 106  
107 107 ServerResult getInvoiceUrlById(ProducePaymentCheckBillOrderQueryVO producePaymentCheckBillOrderQueryVO);
108   - ServerResult exportReceipt(HttpServletResponse response, ProducePaymentCheckBillOrderDO queryVO) throws IOException;
  108 + ServerResult exportReceipt(HttpServletResponse response, CheckBillExportReceiptVO queryVO) throws IOException;
109 109  
110 110 List<ProducePaymentCheckBillOrderDO> getOverEventList();
111 111 ServerResult setPayedDate(ProducePaymentCheckBillCreateVO createVO);
112 112 ServerResult byIdAddNotes(ProducePaymentCheckBillCreateVO createVO);
  113 + ServerResult deleteDeductUrlById(ProducePaymentCheckBillDeductInfoVO deleteVo);
113 114 }
... ...
src/main/java/com/order/erp/service/order/impl/InvoiceBillOrderServiceImpl.java
... ... @@ -15,13 +15,11 @@ import com.order.erp.common.constant.ServerResult;
15 15 import com.order.erp.common.constant.ServerResultCode;
16 16 import com.order.erp.common.exception.BusinessException;
17 17 import com.order.erp.common.utils.DateUtils;
  18 +import com.order.erp.common.utils.EmailSendUtils;
18 19 import com.order.erp.common.utils.StringUtils;
19 20 import com.order.erp.common.utils.TransactionHelper;
20 21 import com.order.erp.config.DataScope;
21   -import com.order.erp.domain.ApplyStatusEnum;
22   -import com.order.erp.domain.ApplyTypeEnum;
23   -import com.order.erp.domain.FinanceEnum;
24   -import com.order.erp.domain.RoleEnum;
  22 +import com.order.erp.domain.*;
25 23 import com.order.erp.domain.dto.BaseDO;
26 24 import com.order.erp.domain.dto.SystemSettingDO;
27 25 import com.order.erp.domain.dto.order.*;
... ... @@ -79,9 +77,8 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
79 77  
80 78 @Resource
81 79 private TransactionHelper transactionHelper;
82   -
83 80 @Resource
84   - private ProducePaymentCheckBillOrderService producePaymentCheckBillOrderService;
  81 + private EmailSendUtils emailSendUtils;
85 82  
86 83  
87 84 /**
... ... @@ -918,7 +915,7 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
918 915 */
919 916 private String calculateBackRefundDate(InvoiceHoldTimeItemVO invoiceHoldTimeItemVO) {
920 917 Integer holdDays = getHoldTimeByCustomerCode(invoiceHoldTimeItemVO.getCustomerCode());
921   - LocalDateTime holdTime = DateUtils.parse(invoiceHoldTimeItemVO.getHoldTime(), DateUtils.DATE_TIME).plusDays(holdDays);
  918 + LocalDateTime holdTime = DateUtils.parse(invoiceHoldTimeItemVO.getProductionDepartmentConsignTime(), DateUtils.DATE_TIME).plusDays(holdDays);
922 919 return DateUtils.format(holdTime, DateUtils.DATE);
923 920 }
924 921  
... ... @@ -949,12 +946,12 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
949 946 Map<String, OrderBaseInfoDO> holdTimeMap = new HashMap<String, OrderBaseInfoDO>();
950 947 String maxHoldTime = null;
951 948 for (OrderBaseInfoDO baseInfoDO : orderBaseInfoDOList) {
952   - if (StringUtils.isNotBlank(baseInfoDO.getOrderHodTime())) {
953   - holdTimeMap.put(baseInfoDO.getOrderHodTime(), baseInfoDO);
  949 + if (StringUtils.isNotBlank(baseInfoDO.getProductionDepartmentConsignTime())) {
  950 + holdTimeMap.put(baseInfoDO.getProductionDepartmentConsignTime(), baseInfoDO);
954 951 if (StringUtils.isBlank(maxHoldTime)) {
955   - maxHoldTime = baseInfoDO.getOrderHodTime();
956   - } else if (maxHoldTime.compareTo(baseInfoDO.getOrderHodTime()) <= 0) {
957   - maxHoldTime = baseInfoDO.getOrderHodTime();
  952 + maxHoldTime = baseInfoDO.getProductionDepartmentConsignTime();
  953 + } else if (maxHoldTime.compareTo(baseInfoDO.getProductionDepartmentConsignTime()) <= 0) {
  954 + maxHoldTime = baseInfoDO.getProductionDepartmentConsignTime();
958 955 }
959 956 }
960 957 }
... ... @@ -965,7 +962,7 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
965 962 if (holdTimeMap.containsKey(maxHoldTime)) {
966 963 OrderBaseInfoDO baseInfoDO = holdTimeMap.get(maxHoldTime);
967 964 itemVO.setCustomerCode(baseInfoDO.getCustomerCode());
968   - itemVO.setHoldTime(maxHoldTime);
  965 + itemVO.setProductionDepartmentConsignTime(maxHoldTime);
969 966 itemVO.setBaseInfoDO(baseInfoDO);
970 967 }
971 968 return itemVO;
... ... @@ -1188,6 +1185,7 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1188 1185 otherAmount=otherAmount.add(invoiceBillOrderDo.getOtherAmount()).setScale(2, RoundingMode.HALF_UP);
1189 1186 }
1190 1187 InvoiceFieldVO invoiceFieldVO = InvoiceFieldVO.builder().invoiceNo(invoiceBillOrderDOS.get(0).getInvoiceNo())
  1188 + //invocieId存储所有提交invoice的id集合。
1191 1189 .invoiceId(invoiceBillOrderDOS.stream().filter(Objects::nonNull).map(InvoiceBillOrderDO::getId).collect(Collectors.toList()))
1192 1190 .payee(commitApplyVO.getPayee())
1193 1191 .innerNo(orderBaseInfoDOList.stream().filter(Objects::nonNull).map(orderBaseInfoDO-> orderBaseInfoDO.getInnerNo()).distinct().collect(Collectors.toList()))
... ... @@ -1199,11 +1197,24 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1199 1197 .totalCustomerAmount(totalCustomerAmount)
1200 1198 .deductAmount(deductAmount)
1201 1199 .otherAmount(otherAmount)
1202   - .totalPayAmount(totalPayAmount).build();
1203   - OrderFieldLockApplyDO applyDO = initOrderFieldLockApplyDO(invoiceFieldVO, userId);
  1200 + .totalPayAmount(totalPayAmount)
  1201 + .projectNo(orderBaseInfoDOList.stream().filter(Objects::nonNull).map(orderBaseInfoDO-> orderBaseInfoDO.getProjectNo()).distinct().collect(Collectors.toList())).build();
  1202 + OrderFieldLockApplyDO applyDO;
  1203 + if(totalCustomerAmount.subtract(deductAmount).subtract(otherAmount).setScale(2,BigDecimal.ROUND_HALF_UP).compareTo(totalPayAmount)==0){
  1204 + applyDO= initOrderFieldLockApplyDO(invoiceFieldVO, userId,true);
  1205 + invoiceBillOrderDO.stream().filter(Objects::nonNull).forEach(invoiceBillOrderDos -> invoiceBillOrderDos.setStatus(FinanceEnum.RECEIVED_PAYMENT.getStatus()));
  1206 + orderBaseInfoDOList.stream().filter(Objects::nonNull).forEach(orderBaseInfoDO -> orderBaseInfoDO.setInvoiceStatus(FinanceEnum.RECEIVED_PAYMENT.getStatus()));
  1207 + //发送邮箱通知财务。 这里这个邮箱通知财务,只能提示invoice号,因为一个invoice申请对应多个invoice号,所以会有多个内部编号和项目号等。
  1208 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  1209 + invoiceAndCheckBillSendEmailVO.setInvoiceBillOrderDO(invoiceBillOrderDO.get(0));
  1210 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.INVOICE_PASS,invoiceAndCheckBillSendEmailVO);
  1211 + }else{
  1212 + applyDO = initOrderFieldLockApplyDO(invoiceFieldVO, userId,false);
  1213 + }
1204 1214 transactionHelper.run(() -> {
1205 1215 orderFieldLockApplyService.save(applyDO);
1206 1216 updateBatchById(invoiceBillOrderDO);
  1217 + orderBaseInfoService.updateBatchById(orderBaseInfoDOList);
1207 1218 });
1208 1219 return ServerResult.success();
1209 1220 }
... ... @@ -1259,10 +1270,16 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1259 1270 * @param userId
1260 1271 * @return
1261 1272 */
1262   - private OrderFieldLockApplyDO initOrderFieldLockApplyDO(InvoiceFieldVO invoiceFieldvo, Long userId) {
  1273 + private OrderFieldLockApplyDO initOrderFieldLockApplyDO(InvoiceFieldVO invoiceFieldvo, Long userId,boolean isTrue) {
1263 1274 OrderLockFieldVO lockFieldVO = new OrderLockFieldVO();
1264 1275 lockFieldVO.setInvoiceFieldVO(invoiceFieldvo);
1265 1276 List<Long> financeIds = invoiceFieldvo.getInvoiceId().subList(1, invoiceFieldvo.getInvoiceId().size());
  1277 + Integer status;
  1278 + if(isTrue){
  1279 + status=ApplyStatusEnum.AUDIT_PASS.getStatus();
  1280 + }else{
  1281 + status=ApplyStatusEnum.WAIT_AUDIT.getStatus();
  1282 + }
1266 1283 if (invoiceFieldvo.getInvoiceId().size() > 1) {
1267 1284 //单独针对财务多个订单提交审核来创建的。
1268 1285 return OrderFieldLockApplyDO.builder()
... ... @@ -1273,7 +1290,7 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1273 1290 .financeId(null==financeIds || financeIds.isEmpty() ? "" :financeIds.stream().map(String::valueOf).collect(Collectors.joining(",")))
1274 1291 .type(ApplyTypeEnum.INVOICE_BILL_APPLY.getType())
1275 1292 .remark(ApplyTypeEnum.INVOICE_BILL_APPLY.getDesc())
1276   - .status(ApplyStatusEnum.WAIT_AUDIT.getStatus())
  1293 + .status(status)
1277 1294 //这里设置审核角色有财务并不是让财务审核,会对财务屏蔽审核按钮,只是让它能够看到审核的单子
1278 1295 .auditRoleCodes(RoleEnum.ADMIN.getCode() + Constant.COMMA_CHARACTER + RoleEnum.FINANCE_USER.getCode())
1279 1296 .build();
... ... @@ -1286,7 +1303,7 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1286 1303 .orderId(invoiceFieldvo.getInvoiceId().get(0))
1287 1304 .type(ApplyTypeEnum.INVOICE_BILL_APPLY.getType())
1288 1305 .remark(ApplyTypeEnum.INVOICE_BILL_APPLY.getDesc())
1289   - .status(ApplyStatusEnum.WAIT_AUDIT.getStatus())
  1306 + .status(status)
1290 1307 //这里设置审核角色有财务并不是让财务审核,会对财务屏蔽审核按钮,只是让它能够看到审核的单子
1291 1308 .auditRoleCodes(RoleEnum.ADMIN.getCode() + Constant.COMMA_CHARACTER + RoleEnum.FINANCE_USER.getCode())
1292 1309 .build();
... ... @@ -1394,8 +1411,8 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1394 1411 }
1395 1412  
1396 1413 @Override
1397   - public ServerResult exportReceipt(HttpServletResponse response,InvoiceBillOrderDO queryVO) throws IOException {
1398   -
  1414 + public ServerResult exportReceipt(HttpServletResponse response,InvoiceExportReceiptVO queryVO) throws IOException {
  1415 + //后续添加了扣款单审核这里是否也是需要向应付款一样,进行判断,只有类型为应收款类型,并且通过才能导出?
1399 1416 XSSFWorkbook workbook = new XSSFWorkbook();
1400 1417 Sheet sheet = workbook.createSheet("收款单");
1401 1418 Row row = sheet.createRow(0);
... ... @@ -1422,7 +1439,9 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1422 1439 cell2.setCellValue("提交人:"+queryVO.getTrackerUser());
1423 1440 sheet.addMergedRegion(new CellRangeAddress(3, 4, 0, 1));
1424 1441 Cell cell3 = row2.createCell(2);
1425   - cell3.setCellValue("");
  1442 + cell3.setCellValue("项目号:" + (queryVO.getProjectNo() != null && !queryVO.getProjectNo().isEmpty()
  1443 + ? String.join(",", queryVO.getProjectNo())
  1444 + : ""));
1426 1445 sheet.addMergedRegion(new CellRangeAddress(3, 4, 2, 7));
1427 1446 Cell cell4 = row2.createCell(8);
1428 1447 /*if(StringUtils.isNotBlank(queryVO.getActualRefundDate())){
... ... @@ -1505,6 +1524,24 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1505 1524 return ServerResult.success();
1506 1525 }
1507 1526  
  1527 + @Override
  1528 + public ServerResult deleteDeductUrlById(InvoiceBillDeductInfoVO deleteVo) {
  1529 + if(Objects.isNull(deleteVo.getId())){
  1530 + return ServerResult.fail();
  1531 + }
  1532 + InvoiceBillOrderDO invoiceBillOrderDO = getById(deleteVo.getId());
  1533 + if(Objects.isNull(invoiceBillOrderDO)){
  1534 + throw new BusinessException("应收款单不存在!");
  1535 + }
  1536 + checkApply( new ArrayList<>(Arrays.asList(deleteVo.getId())));
  1537 + if(Objects.nonNull(invoiceBillOrderDO.getStatus()) && FinanceEnum.RECEIVED_PAYMENT.getStatus()==invoiceBillOrderDO.getStatus()){
  1538 + throw new BusinessException("已完成收款,无法删除!");
  1539 + }
  1540 + invoiceBillOrderDO.setDeductUrl("");
  1541 + updateById(invoiceBillOrderDO);
  1542 + return ServerResult.success();
  1543 + }
  1544 +
1508 1545  
1509 1546 public void createMergedCell(Sheet sheet, Workbook workbook, int rowIndex, int colIndex, int startRow, int endRow, int startCol, int endCol, String value) {
1510 1547 // 创建或获取当前行
... ...
src/main/java/com/order/erp/service/order/impl/OrderBaseInfoServiceImpl.java
... ... @@ -23,6 +23,7 @@ import com.order.erp.common.excel4j.exceptions.Excel4JException;
23 23 import com.order.erp.common.exception.BusinessException;
24 24 import com.order.erp.common.utils.*;
25 25 import com.order.erp.config.DataScope;
  26 +import com.order.erp.config.MapResultHandler;
26 27 import com.order.erp.domain.*;
27 28 import com.order.erp.domain.dto.BaseDO;
28 29 import com.order.erp.domain.dto.SystemSettingDO;
... ... @@ -57,6 +58,7 @@ import java.net.URL;
57 58 import java.text.DecimalFormat;
58 59 import java.time.LocalDate;
59 60 import java.time.LocalDateTime;
  61 +import java.time.LocalTime;
60 62 import java.time.Month;
61 63 import java.util.*;
62 64 import java.util.concurrent.TimeUnit;
... ... @@ -147,6 +149,9 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
147 149 @Resource
148 150 private ProducePaymentCheckBillOrderService producePaymentCheckBillOrderService;
149 151  
  152 + @Resource
  153 + private OrderTrackStageService orderTrackStageService;
  154 +
150 155  
151 156  
152 157 /**
... ... @@ -218,8 +223,8 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
218 223 return resultVO;
219 224 }).collect(Collectors.toList());
220 225  
221   - // 填充利润分析
222   - fillProfitAnalysisInfo(resultVOList);
  226 + // 填充利润分析和质检信息
  227 + fillProfitAnalysisInfo(resultVOList,true);
223 228  
224 229 // 填充项目报告
225 230 fillReportInfo(resultVOList);
... ... @@ -227,11 +232,11 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
227 232 // 填充跟单信息
228 233 fillTrackStageInfo(resultVOList);
229 234  
230   - // 填充质检信息
231   - fillInspectionStageInfo(resultVOList);
  235 + // 填充质检信息 在上述的利润分析中已经填充了,这里不需要填充。
  236 +// fillInspectionStageInfo(resultVOList);
232 237  
233 238 // 填充发票信息 对于填充发票信息和填充生产科对账单号,其实不需要在这里写了,而且这里只是填充了invoice号和check号,这里的代码是填充数据,达到一个进度条的效果,既然没有根据是否填充发票来填充进度条,这里就不需要写。
234   - fillInvoiceNo(resultVOList);
  239 +// fillInvoiceNo(resultVOList);
235 240 //第四版 start
236 241 /* //需要填充生产科对账单号信息
237 242 fillCheckNo(resultVOList);
... ... @@ -282,7 +287,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
282 287  
283 288 if (Objects.nonNull(lockFieldVO.getProfitAnalysisFields())) {
284 289 // 填充利润分析
285   - fillProfitAnalysisInfo(resultVOList);
  290 + fillProfitAnalysisInfo(resultVOList,false);
286 291 }
287 292  
288 293 if (Objects.nonNull(lockFieldVO.getReportFields())) {
... ... @@ -852,7 +857,8 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
852 857 /**
853 858 * @param orderInfoResultVOList
854 859 */
855   - private void fillProfitAnalysisInfo(List<OrderInfoResultVO> orderInfoResultVOList) {
  860 + //这里之所以要添加一个boolean,是因为前端无法直接从填充好的质检信息中获取对应尾期验货结果放到利润中对应的尾期验货结果表格中,需要我把尾期验货结果放到利润中。如果为true,就代表需要填充到利润信息中,为false的话,就不需要。
  861 + private void fillProfitAnalysisInfo(List<OrderInfoResultVO> orderInfoResultVOList,Boolean isfillInspectionStage) {
856 862 if (CollectionUtils.isEmpty(orderInfoResultVOList)) {
857 863 return;
858 864 }
... ... @@ -861,7 +867,24 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
861 867 List<OrderProfitAnalysisDO> orderProfitAnalysisDOS = profitAnalysisService.list(new LambdaQueryWrapper<OrderProfitAnalysisDO>()
862 868 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
863 869 .in(OrderProfitAnalysisDO::getOrderId, orderIds));
  870 + if(isfillInspectionStage){
  871 + List<OrderInspectionStageDO> inspectionStageDOS = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>()
  872 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  873 + .in(OrderInspectionStageDO::getOrderId, orderIds));
864 874  
  875 + if (CollectionUtils.isNotEmpty(inspectionStageDOS)) {
  876 + Map<Long, OrderInspectionStageDO> inspectionStageDOMap = inspectionStageDOS.stream().collect(Collectors.toMap(OrderInspectionStageDO::getOrderId, Function.identity(),(existing, replacement) -> existing));
  877 + orderInfoResultVOList.forEach(result -> {
  878 + if (inspectionStageDOMap.containsKey(result.getId())) {
  879 + OrderInspectionStageDO inspectionStageDO = inspectionStageDOMap.get(result.getId());
  880 + OrderInspectionStageVO inspectionStageVO = new OrderInspectionStageVO();
  881 + BeanUtils.copyProperties(inspectionStageDO, inspectionStageVO);
  882 + result.setInspectionStageInfo(inspectionStageVO);
  883 + result.setEndCheckResult(inspectionStageDO.getEndCheckResult());
  884 + }
  885 + });
  886 + }
  887 + }
865 888 if (CollectionUtils.isNotEmpty(orderProfitAnalysisDOS)) {
866 889 Map<Long, OrderProfitAnalysisDO> profitAnalysisDOMap = orderProfitAnalysisDOS.stream().collect(Collectors.toMap(OrderProfitAnalysisDO::getOrderId, Function.identity(), (v1, v2) -> v1));
867 890 orderInfoResultVOList.forEach(result -> {
... ... @@ -870,6 +893,9 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
870 893 OrderProfitAnalysisVO profitAnalysisVO = new OrderProfitAnalysisVO();
871 894 BeanUtils.copyProperties(profitAnalysisDO, profitAnalysisVO);
872 895 profitAnalysisVO.setProfitType(String.valueOf(profitAnalysisDO.getProfitType()));
  896 + if(result.getEndCheckResult()!=null){
  897 + profitAnalysisVO.setEndCheckResult(result.getEndCheckResult());
  898 + }
873 899 result.setProfitAnalysisInfo(profitAnalysisVO);
874 900 }
875 901 });
... ... @@ -1015,36 +1041,36 @@ end
1015 1041 if (Objects.isNull(inspectionStageInfo)) {
1016 1042 return false;
1017 1043 }
1018   - if (StringUtils.isBlank(inspectionStageInfo.getMidCheckApplyTime())) {
1019   - return false;
  1044 + if (StringUtils.isNotBlank(inspectionStageInfo.getMidCheckApplyTime())) {
  1045 + return true;
1020 1046 }
1021   - if (StringUtils.isBlank(inspectionStageInfo.getMidCheckComment())) {
1022   - return false;
  1047 + if (StringUtils.isNotBlank(inspectionStageInfo.getMidCheckComment())) {
  1048 + return true;
1023 1049 }
1024   - if (StringUtils.isBlank(inspectionStageInfo.getMidCheckResult())) {
1025   - return false;
  1050 + if (StringUtils.isNotBlank(inspectionStageInfo.getMidCheckResult())) {
  1051 + return true;
1026 1052 }
1027   - if (StringUtils.isBlank(inspectionStageInfo.getEndCheckApplyTime())) {
1028   - return false;
  1053 + if (StringUtils.isNotBlank(inspectionStageInfo.getEndCheckApplyTime())) {
  1054 + return true;
1029 1055 }
1030   - if (StringUtils.isBlank(inspectionStageInfo.getSpecification())) {
1031   - return false;
  1056 + if (StringUtils.isNotBlank(inspectionStageInfo.getSpecification())) {
  1057 + return true;
1032 1058 }
1033   - if (StringUtils.isBlank(inspectionStageInfo.getFunctionality())) {
1034   - return false;
  1059 + if (StringUtils.isNotBlank(inspectionStageInfo.getFunctionality())) {
  1060 + return true;
1035 1061 }
1036   - if (StringUtils.isBlank(inspectionStageInfo.getElectroplate())) {
1037   - return false;
  1062 + if (StringUtils.isNotBlank(inspectionStageInfo.getElectroplate())) {
  1063 + return true;
1038 1064 }
1039   - if (StringUtils.isBlank(inspectionStageInfo.getBoxPacket())) {
1040   - return false;
  1065 + if (StringUtils.isNotBlank(inspectionStageInfo.getBoxPacket())) {
  1066 + return true;
1041 1067 }
1042 1068 if (StringUtils.isBlank(inspectionStageInfo.getEndCheckResult())) {
1043   - return false;
1044   - } else if ("FAIL".equals(inspectionStageInfo.getEndCheckResult())) {
  1069 + return true;
  1070 + } else if ("FAIL".equals(inspectionStageInfo.getEndCheckResult()) || "FAIL 2ND".equals(inspectionStageInfo.getEndCheckResult()) || "FAIL RELEASE".equals(inspectionStageInfo.getEndCheckResult())) {
1045 1071 return false;
1046 1072 }
1047   - return true;
  1073 + return false;
1048 1074 }
1049 1075  
1050 1076 /**
... ... @@ -1055,46 +1081,46 @@ end
1055 1081 if (Objects.isNull(trackStageVO)) {
1056 1082 return false;
1057 1083 }
1058   - if (StringUtils.isBlank(trackStageVO.getPpTime())) {
1059   - return false;
  1084 + if (StringUtils.isNotBlank(trackStageVO.getPpTime())) {
  1085 + return true;
1060 1086 }
1061   - if (StringUtils.isBlank(trackStageVO.getPpConfirmResult())) {
1062   - return false;
  1087 + if (StringUtils.isNotBlank(trackStageVO.getPpConfirmResult())) {
  1088 + return true;
1063 1089 }
1064   - if (StringUtils.isBlank(trackStageVO.getEsoSampleSendTime())) {
1065   - return false;
  1090 + if (StringUtils.isNotBlank(trackStageVO.getEsoSampleSendTime())) {
  1091 + return true;
1066 1092 }
1067   - if (StringUtils.isBlank(trackStageVO.getShippmentSampleSendTime())) {
1068   - return false;
  1093 + if (StringUtils.isNotBlank(trackStageVO.getShippmentSampleSendTime())) {
  1094 + return true;
1069 1095 }
1070   - if (StringUtils.isBlank(trackStageVO.getShippmentSampleConfirmResult())) {
1071   - return false;
  1096 + if (StringUtils.isNotBlank(trackStageVO.getShippmentSampleConfirmResult())) {
  1097 + return true;
1072 1098 }
1073   - if (StringUtils.isBlank(trackStageVO.getSelfTestPassTime())) {
1074   - return false;
  1099 + if (StringUtils.isNotBlank(trackStageVO.getSelfTestPassTime())) {
  1100 + return true;
1075 1101 }
1076   - if (StringUtils.isBlank(trackStageVO.getAitexTestSendTime())) {
1077   - return false;
  1102 + if (StringUtils.isNotBlank(trackStageVO.getAitexTestSendTime())) {
  1103 + return true;
1078 1104 }
1079   - if (StringUtils.isBlank(trackStageVO.getAitexTestFinishResult())) {
1080   - return false;
  1105 + if (StringUtils.isNotBlank(trackStageVO.getAitexTestFinishResult())) {
  1106 + return true;
1081 1107 }
1082   - if (StringUtils.isBlank(trackStageVO.getSgsTestSendTime())) {
1083   - return false;
  1108 + if (StringUtils.isNotBlank(trackStageVO.getSgsTestSendTime())) {
  1109 + return true;
1084 1110 }
1085   - if (StringUtils.isBlank(trackStageVO.getSgsTestFinishResult())) {
1086   - return false;
  1111 + if (StringUtils.isNotBlank(trackStageVO.getSgsTestFinishResult())) {
  1112 + return true;
1087 1113 }
1088   - if (StringUtils.isBlank(trackStageVO.getBarcodeStickerArrivalTime())) {
1089   - return false;
  1114 + if (StringUtils.isNotBlank(trackStageVO.getBarcodeStickerArrivalTime())) {
  1115 + return true;
1090 1116 }
1091   - if (StringUtils.isBlank(trackStageVO.getLatestArrivalTime())) {
1092   - return false;
  1117 + if (StringUtils.isNotBlank(trackStageVO.getLatestArrivalTime())) {
  1118 + return true;
1093 1119 }
1094   - if (StringUtils.isBlank(trackStageVO.getLatestBkTime())) {
1095   - return false;
  1120 + if (StringUtils.isNotBlank(trackStageVO.getLatestBkTime())) {
  1121 + return true;
1096 1122 }
1097   - return true;
  1123 + return false;
1098 1124 }
1099 1125  
1100 1126  
... ... @@ -1719,6 +1745,7 @@ end
1719 1745 int currentMonth = month.getValue();
1720 1746 int dayOfMonth = currentDate.getDayOfMonth();
1721 1747 OrderOptLogDO optLogDO = new OrderOptLogDO();
  1748 + List<OrderOptLogDO> orderOptLogDOS = null;
1722 1749 List<OrderOpinionLogDO> orderOpinionLogDOList = new ArrayList<>();
1723 1750 if (Objects.nonNull(updateVO.getBaseInfo())) {
1724 1751 //用户编辑时,产品意见与这个订单的上一次产品意见内容不一样。
... ... @@ -1779,6 +1806,35 @@ end
1779 1806  
1780 1807  
1781 1808 if (Objects.nonNull(updateVO.getProfitAnalysisInfo())) {
  1809 + //在填写质检信息时,利润信息肯定是已经填写完了的。所以这里通过if判断利润模块的尾期验货完全没有问题。
  1810 + if(StringUtils.isNotBlank(updateVO.getProfitAnalysisInfo().getEndCheckResult())){
  1811 + List<OrderBaseInfoDO> twoMonthOrderBaseInfo = getTwoMonthOrderBaseInfo(orderBaseInfoDo);
  1812 + List<Long> orderIds = twoMonthOrderBaseInfo.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toList());
  1813 + List<OrderInspectionStageDO> orderInspectionStageDOList = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>()
  1814 + .eq(OrderInspectionStageDO::getEnableFlag, Constant.ENABLE_TEN)
  1815 + .in(OrderInspectionStageDO::getOrderId, orderIds));
  1816 + if(CollectionUtils.isNotEmpty(orderInspectionStageDOList)){
  1817 + orderInspectionStageDOList.stream().forEach(orderInspectionStageDO -> {
  1818 + orderInspectionStageDO.setEndCheckResult(updateVO.getProfitAnalysisInfo().getEndCheckResult());
  1819 + });
  1820 + inspectionStageService.updateBatchById(orderInspectionStageDOList);
  1821 + }
  1822 + //发送邮件通知。
  1823 + List<OrderInspectionStageDO> deduplicatedList = new ArrayList<>(
  1824 + orderInspectionStageDOList.stream()
  1825 + .collect(Collectors.toMap(
  1826 + OrderInspectionStageDO::getOrderId,
  1827 + item -> item,
  1828 + (existing, replacement) -> existing // 如果有重复,保留第一个
  1829 + ))
  1830 + .values()
  1831 + );
  1832 + OrderInspectionStageDO orderInspectionStageDO = deduplicatedList.get(0);
  1833 + OrderInspectionStageVO orderInspectionStageVO = new OrderInspectionStageVO();
  1834 + BeanUtil.copyProperties(orderInspectionStageDO,orderInspectionStageVO);
  1835 + sendOrderInspectionStage(updateVO.getOrderId(),orderInspectionStageVO);
  1836 + return ServerResult.success();
  1837 + }else{
1782 1838 checkApply(updateVO.getOrderId(), userId, ApplyTypeEnum.ORDER_PROFIT_APPLY);
1783 1839 OrderFieldLockApplyDO orderFieldLockApplyDO = handlerProfitRate(updateVO.getProfitAnalysisInfo(), orderBaseInfoDo, userId);
1784 1840  
... ... @@ -1787,7 +1843,7 @@ end
1787 1843 optLogDO = buildOrderOptLogDo(updateVO.getOrderId(), userId, OrderOptTypeEnum.ORDER_PROFIT_EDIT_APPLY.getDesc(), orderFieldLockApplyDO.getFields());
1788 1844 clearLockedField(updateVO.getOrderId(), userId, LockedFieldTypeEnum.ORDER_PROFIT);
1789 1845 }
1790   -
  1846 + }
1791 1847 if (Objects.nonNull(updateVO.getReportInfo())) {
1792 1848 checkApply(updateVO.getOrderId(), userId, ApplyTypeEnum.ORDER_REPORT_APPLY);
1793 1849 OrderFieldLockApplyDO orderFieldLockApplyDO = buildReportFieldLockApplyDO(updateVO.getReportInfo(), userId);
... ... @@ -1801,7 +1857,8 @@ end
1801 1857 if (Objects.nonNull(updateVO.getTrackStageInfo())) {
1802 1858 OrderTrackStageDO trackStageDO = trackStageService.getOne(new LambdaQueryWrapper<OrderTrackStageDO>()
1803 1859 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
1804   - .eq(OrderTrackStageDO::getOrderId, updateVO.getOrderId()));
  1860 + .eq(OrderTrackStageDO::getOrderId, updateVO.getOrderId())
  1861 + .last("limit 1"));
1805 1862 OrderTrackStageVO trackStageInfo = updateVO.getTrackStageInfo();
1806 1863 if (Objects.nonNull(trackStageDO)) {
1807 1864 if (StringUtils.isNotBlank(trackStageInfo.getPpTime())) {
... ... @@ -1984,16 +2041,69 @@ end
1984 2041 setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
1985 2042 }
1986 2043 }
  2044 + List<OrderOpinionLogDO> result = new ArrayList<>();
  2045 + List<OrderBaseInfoDO> orderBaseinfoList = getTwoMonthOrderBaseInfo(orderBaseInfoDo);
  2046 + List<Long> orderIds = orderBaseinfoList.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toList());
  2047 + //如果为1的话,说明相同style的订单只有自己本身一条。
  2048 + if (Constant.ONE != orderIds.size()) {
  2049 + //查找order对应的跟单信息。由于跟单信息和质检信息是在创建订单时就创建了,所以会存在对应的跟单信息。
  2050 + List<OrderTrackStageDO> orderTrackStageDOList = trackStageService.list(new LambdaQueryWrapper<OrderTrackStageDO>()
  2051 + .eq(OrderTrackStageDO::getEnableFlag, Constant.ENABLE_TEN)
  2052 + .in(OrderTrackStageDO::getOrderId, orderIds));
  2053 + //复制trackStageDO到每一个上面。并且也需要设置状态为跟单中。锁了也能解开。
  2054 + //说明存在相同的的多个单子 (应该)
  2055 + if (CollectionUtils.isNotEmpty(orderTrackStageDOList)) {
  2056 + List<OrderTrackStageDO> trackStageDOS = orderTrackStageDOList.stream().map(orderTrackStageDO -> {
  2057 + BeanUtils.copyProperties(updateVO.getTrackStageInfo(), orderTrackStageDO, "id", "orderId");
  2058 + // 这里对于在基本信息订单表上设置跟单中状态没有意义,会被覆盖。应该是要在跟单表中设置跟单中的状态。
  2059 + orderTrackStageDO.setOrderStatus(OrderStatusEnum.TRACK_ING.getStatus());
  2060 + return orderTrackStageDO;
  2061 + }).collect(Collectors.toList());
  2062 + // v-for="item in todos"
  2063 + orderOptLogDOS = orderBaseinfoList.stream().map(x -> {
  2064 + x.setProductionComment(orderBaseInfoDo.getProductionComment());
  2065 + //这里设置JSONObject.toJSONString(updateVO)缺点是,当存在多个orderTrackStageDOList时,会造成在order_opt_log表中的field字段设置的orderId可能与order_opt_log中的orderId字段不一致。
  2066 + //但是不影响,这个field好像没有在哪里使用到,所以应该没有事。
  2067 + OrderOptLogDO orderOptLogDO = buildOrderOptLogDo(x.getId(), userId, OrderOptTypeEnum.ORDER_TRACKER_EDIT_APPLY.getDesc(), JSONObject.toJSONString(updateVO));
  2068 + return orderOptLogDO;
  2069 + }).collect(Collectors.toList());
  2070 +//tiquorderIds到orderbaseinfo中。
  2071 +
  2072 + // 提取 orderOpinionLogDOList 中已有的 orderId 集合
  2073 + Set<Long> existingOrderIds = orderOpinionLogDOList.stream()
  2074 + .map(OrderOpinionLogDO::getOrderId)
  2075 + .collect(Collectors.toSet());
  2076 +
  2077 + orderIds.stream()
  2078 + .filter(id -> !existingOrderIds.contains(id)) // 排除已经存在的 orderId
  2079 + .forEach(id -> {
  2080 + orderOpinionLogDOList.stream().forEach(x -> {
  2081 + OrderOpinionLogDO newLog = new OrderOpinionLogDO();
  2082 + newLog.setOrderId(id);
  2083 + newLog.setOpinionType(x.getOpinionType());
  2084 + newLog.setField(x.getField());
  2085 + //这里不能采用
  2086 + result.add(newLog);
  2087 + });
  2088 + });
  2089 + orderOpinionLogDOList.addAll(result);
  2090 + updateBatchById(orderBaseinfoList);
  2091 + trackStageService.updateBatchById(trackStageDOS);
  2092 + }
  2093 + }
  2094 + //这里是提供给返单操作,即使不是返单也会执行到这里,但是你执行,我最后判断一下,对于返单不进行保存更新,只有返单才会保存更新。
1987 2095 orderBaseInfoDo.setOrderStatus(OrderStatusEnum.TRACK_ING.getStatus());
1988 2096 optLogDO = buildOrderOptLogDo(updateVO.getOrderId(), userId, OrderOptTypeEnum.ORDER_TRACKER_EDIT_APPLY.getDesc(), JSONObject.toJSONString(updateVO));
1989 2097 clearLockedField(updateVO.getOrderId(), userId, LockedFieldTypeEnum.ORDER_TRACKER);
1990 2098 }
1991 2099  
1992 2100 if (Objects.nonNull(updateVO.getInspectionStageInfo())) {
  2101 + //质检信息也是和跟单一样,采用返单查询对应的,反之则不一样。
  2102 + OrderInspectionStageVO inspectionStageInfo = updateVO.getInspectionStageInfo();
1993 2103 OrderInspectionStageDO inspectionStageDO = inspectionStageService.getOne(new LambdaQueryWrapper<OrderInspectionStageDO>()
1994 2104 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
1995   - .eq(OrderInspectionStageDO::getOrderId, updateVO.getOrderId()));
1996   - OrderInspectionStageVO inspectionStageInfo = updateVO.getInspectionStageInfo();
  2105 + .eq(OrderInspectionStageDO::getOrderId, updateVO.getOrderId())
  2106 + .last("limit 1"));
1997 2107 String midCheckResult = inspectionStageInfo.getMidCheckResult();
1998 2108 String endCheckResult = inspectionStageInfo.getEndCheckResult();
1999 2109 if (Objects.nonNull(inspectionStageDO)) {
... ... @@ -2046,15 +2156,9 @@ end
2046 2156 }*/
2047 2157 //第四版时下面这句需要删掉。
2048 2158 inspectionStageDO.setOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus());
2049   -
  2159 + //end
2050 2160 inspectionStageService.updateById(inspectionStageDO);
2051   - OrderBaseInfoDO orderBaseInfoDO = baseInfoService.getById(updateVO.getOrderId());
2052   - AdminUserDO ProductionDepartmentUserDO = userService.getOne(new LambdaQueryWrapper<AdminUserDO>()
2053   - .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2054   - .eq(AdminUserDO::getUserName, orderBaseInfoDO.getProductionDepartment()));
2055   - if (Objects.nonNull(ProductionDepartmentUserDO) && StringUtils.isNotBlank(ProductionDepartmentUserDO.getEmail())) {
2056   - sendOrderInspectionStage(updateVO, midCheckResult, endCheckResult);
2057   - }
  2161 + sendOrderInspectionStage(updateVO, midCheckResult, endCheckResult);
2058 2162 } else {
2059 2163 inspectionStageDO = new OrderInspectionStageDO();
2060 2164 BeanUtils.copyProperties(updateVO.getInspectionStageInfo(), inspectionStageDO);
... ... @@ -2071,33 +2175,81 @@ end
2071 2175 inspectionStageDO.setOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus());
2072 2176 //end
2073 2177 inspectionStageService.save(inspectionStageDO);
2074   - OrderBaseInfoDO orderBaseInfoDO = baseInfoService.getById(updateVO.getOrderId());
2075   - AdminUserDO ProductionDepartmentUserDO = userService.getOne(new LambdaQueryWrapper<AdminUserDO>()
2076   - .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2077   - .eq(AdminUserDO::getUserName, orderBaseInfoDO.getProductionDepartment()));
2078   - if (Objects.nonNull(ProductionDepartmentUserDO) && StringUtils.isNotBlank(ProductionDepartmentUserDO.getEmail())) {
2079   - midCheckResult = "1";
2080   - endCheckResult = "1";
2081   - sendOrderInspectionStage(updateVO, midCheckResult, endCheckResult);
2082   - }
2083   -
  2178 + midCheckResult = Constant.STRING_ONE;
  2179 + endCheckResult = Constant.STRING_ONE;
  2180 + sendOrderInspectionStage(updateVO, midCheckResult, endCheckResult);
2084 2181 }
  2182 + orderOptLogDOS = inspectionCopy(orderBaseInfoDo, updateVO, userId);
2085 2183 orderBaseInfoDo.setOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus());
2086 2184 optLogDO = buildOrderOptLogDo(updateVO.getOrderId(), userId, OrderOptTypeEnum.ORDER_INSPECT_EDIT_APPLY.getDesc(), JSONObject.toJSONString(updateVO));
2087 2185 clearLockedField(updateVO.getOrderId(), userId, LockedFieldTypeEnum.ORDER_INSPECT);
2088 2186 }
2089 2187 updateById(orderBaseInfoDo);
2090   - orderOptLogService.save(optLogDO);
  2188 + if(CollectionUtils.isNotEmpty(orderOptLogDOS)){
  2189 + orderOptLogService.saveBatch(orderOptLogDOS);
  2190 + }else{
  2191 + orderOptLogService.save(optLogDO);
  2192 + }
2091 2193 orderOpinionLogService.saveBatch(orderOpinionLogDOList);
2092 2194 return ServerResult.success();
2093 2195 }
2094 2196 //这个方法的作用就是:她们反应对于内部编号相同的订单,就不需要发送四个测试结果的产品意见信息,不然创建一个订单选择测试结果后就发送四个测试结果,太麻烦了,所以这里根据项目号和测试结果进行区分。
  2197 + //相同的内部编号和相同的结果,就不会再次发送了。
2095 2198 public void setEmailSendUtilsRedis(OrderBaseInfoDO orderBaseInfoDo,String resultText,String productionComment){
2096 2199 if(!redisUtils.hasKey(orderBaseInfoDo.getInnerNo()+Constant.CROSS_BAR_CHARACTER+resultText)){
2097 2200 sendProductionCommentEmail(orderBaseInfoDo,productionComment,resultText);
2098 2201 redisUtils.set(orderBaseInfoDo.getInnerNo()+Constant.CROSS_BAR_CHARACTER+resultText, "1", 90, TimeUnit.DAYS);
2099 2202 }
2100 2203 }
  2204 + //查询最近两个月的数据。
  2205 + private List<OrderBaseInfoDO> getTwoMonthOrderBaseInfo(OrderBaseInfoDO orderBaseInfoDo){
  2206 + LocalDateTime now = LocalDateTime.now();
  2207 + LocalDateTime twoMonthsAgo = now.minusMonths(2);
  2208 + LambdaQueryWrapper<OrderBaseInfoDO> orderBaseInfoDOLambdaQueryWrapper;
  2209 + //这部分代码的目的是,遇到相同style的订单,他们只需要填写其中任何一个订单的跟单信息,就会填写的跟单信息复制到其他订单上。
  2210 + if(Constant.STRING_ZERO.equals(orderBaseInfoDo.getReturnOrder())){
  2211 + //查询所有相同的style的并且不是返单的订单。
  2212 + orderBaseInfoDOLambdaQueryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>().eq(OrderBaseInfoDO::getEnableFlag, Constant.ENABLE_TEN)
  2213 + .eq(OrderBaseInfoDO::getCustomerStyle, orderBaseInfoDo.getCustomerStyle())
  2214 + .eq(OrderBaseInfoDO::getInnerNo, orderBaseInfoDo.getInnerNo())
  2215 + .eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ZERO)
  2216 + .between(OrderBaseInfoDO::getCreateTime, twoMonthsAgo, now);
  2217 + }else{
  2218 + //查询所有相同的style的并且是返单的订单。
  2219 + orderBaseInfoDOLambdaQueryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>().eq(OrderBaseInfoDO::getEnableFlag, Constant.ENABLE_TEN)
  2220 + .eq(OrderBaseInfoDO::getCustomerStyle, orderBaseInfoDo.getCustomerStyle())
  2221 + .eq(OrderBaseInfoDO::getInnerNo, orderBaseInfoDo.getInnerNo())
  2222 + .eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE)
  2223 + .between(OrderBaseInfoDO::getCreateTime, twoMonthsAgo, now);
  2224 + }
  2225 + return list(orderBaseInfoDOLambdaQueryWrapper);
  2226 + }
  2227 +
  2228 + private List<OrderOptLogDO> inspectionCopy(OrderBaseInfoDO orderBaseInfoDo,OrderUpdateVO updateVO,Long userId){
  2229 + List<OrderBaseInfoDO> twoMonthOrderBaseInfo = getTwoMonthOrderBaseInfo(orderBaseInfoDo);
  2230 + List<Long> orderIds = twoMonthOrderBaseInfo.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toList());
  2231 + if(Constant.ONE !=orderIds.size()){
  2232 + //查找质检信息。
  2233 + List<OrderInspectionStageDO> orderInspectionStageDOList = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>()
  2234 + .eq(OrderInspectionStageDO::getEnableFlag, Constant.ENABLE_TEN)
  2235 + .in(OrderInspectionStageDO::getOrderId, orderIds));
  2236 + if(CollectionUtils.isNotEmpty(orderInspectionStageDOList)){
  2237 + List<OrderInspectionStageDO> orderInspectionStageDOS = orderInspectionStageDOList.stream().map(orderInspectionStageDO -> {
  2238 + BeanUtils.copyProperties(updateVO.getInspectionStageInfo(),orderInspectionStageDO,"id","orderId");
  2239 + orderInspectionStageDO.setOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus());
  2240 + return orderInspectionStageDO;
  2241 + }).collect(Collectors.toList());
  2242 + List<OrderOptLogDO> orderOptLogDOS = twoMonthOrderBaseInfo.stream().map(x -> {
  2243 + //这里当存储多个时,会造成跟单信息表中id与field中的id不一样,field字段中的id一直是这个当前改变的那个id,但是这个field好像也没有用到,应该没事。
  2244 + OrderOptLogDO orderOptLogDO = buildOrderOptLogDo(x.getId(), userId, OrderOptTypeEnum.ORDER_INSPECT_EDIT_APPLY.getDesc(), JSONObject.toJSONString(updateVO));
  2245 + return orderOptLogDO;
  2246 + }).collect(Collectors.toList());
  2247 + inspectionStageService.updateBatchById(orderInspectionStageDOS);
  2248 + return orderOptLogDOS;
  2249 + }
  2250 + }
  2251 + return null;
  2252 + }
2101 2253 /**
2102 2254 * @param orderId
2103 2255 * @param userId
... ... @@ -2358,7 +2510,7 @@ end
2358 2510 if(CollectionUtils.isNotEmpty(orderFieldLockApplyDOS)){
2359 2511 return ServerResult.fail("订单中包含利润未审批的订单,无法生成!");
2360 2512 }
2361   - ProducePdfVO producePdf = pdfUtils.createProducePdf(pdfUtils.build(producePdfVO.getIds()), "生产指示书.pdf", producePdfVO.getCompanyName());
  2513 + ProducePdfVO producePdf = pdfUtils.createProducePdf(pdfUtils.build(producePdfVO.getIds()), "生产指示书.pdf", producePdfVO.getCompanyName(),producePdfVO.getIsTrue());
2362 2514 return ServerResult.success(producePdf);
2363 2515 }
2364 2516  
... ... @@ -2400,8 +2552,7 @@ end
2400 2552 public ServerResult checkChargeOrderCount(OrderBaseInfoVO baseInfoVO) {
2401 2553 LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>()
2402 2554 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2403   - .in(CollectionUtils.isNotEmpty(Arrays.asList(baseInfoVO.getId())), OrderBaseInfoDO::getId, Arrays.asList(baseInfoVO.getId()))
2404   - .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  2555 + .in(CollectionUtils.isNotEmpty(Arrays.asList(baseInfoVO.getId())), OrderBaseInfoDO::getId, Arrays.asList(baseInfoVO.getId()));
2405 2556 List<OrderBaseInfoDO> ordersDOS = list(queryWrapper);
2406 2557  
2407 2558 List<OrderInfoResultVO> orderInfoResultVOS = wrapperOrderResultList(false, ordersDOS);
... ... @@ -2510,133 +2661,138 @@ end
2510 2661  
2511 2662 private void sendOrderInspectionStage(OrderUpdateVO updateVO, String midCheckResult, String endCheckResult) {
2512 2663 OrderBaseInfoDO orderBaseInfoDO = baseInfoService.getById(updateVO.getOrderId());
2513   - AdminUserDO ProductionDepartmentUserDO = userService.getOne(new LambdaQueryWrapper<AdminUserDO>()
2514   - .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2515   - .eq(AdminUserDO::getUserName, orderBaseInfoDO.getProductionDepartment()));
2516   - if (Objects.nonNull(ProductionDepartmentUserDO)) {
  2664 + List<String> emailList = new ArrayList<>();
  2665 + //得到配置邮箱。
  2666 + emailList = getEndCheckReportEvent(orderBaseInfoDO);
  2667 + //如果事件配置邮箱不存在,就无需发送有邮件了。
  2668 + if(CollectionUtils.isNotEmpty(emailList)){
  2669 + List<String> productionEmails=new ArrayList<>();
  2670 + List<String> inspectUserEmailList=new ArrayList<>();
  2671 + //生产科邮箱。
  2672 + productionEmails=getProduceEmail(orderBaseInfoDO);
  2673 + //所有质检员邮箱。
  2674 + inspectUserEmailList=getAllInspectEmails();
  2675 +
  2676 + if(CollectionUtils.isNotEmpty(productionEmails)){
  2677 + emailList.addAll(productionEmails);
  2678 + }
  2679 + if(CollectionUtils.isNotEmpty(inspectUserEmailList)){
  2680 + emailList.addAll(inspectUserEmailList);
  2681 + }
  2682 + Set<String> emailsSet =new HashSet<>(emailList);
  2683 + List<String> allEmails=new ArrayList<>(emailsSet);
  2684 + //邮箱收集完毕。
2517 2685 OrderEventJobVO orderEventJobVO = new OrderEventJobVO();
2518 2686 orderEventJobVO.setInspectionStageInfo(updateVO.getInspectionStageInfo());
2519 2687 OrderBaseInfoVO orderBaseInfoVo = BeanUtil.copyProperties(orderBaseInfoDO, OrderBaseInfoVO.class);
2520 2688 orderEventJobVO.setBaseInfo(orderBaseInfoVo);
2521   - List<String> emails = Arrays.asList(ProductionDepartmentUserDO.getEmail().split("[,,]+"))
2522   - .stream().map(String::trim)
2523   - .filter(Objects::nonNull)
2524   - .collect(Collectors.toList());
2525   - //一旦修改完质检信息就自动发送邮件对应的生产科。多次编辑保存多次发送。
  2689 +
  2690 + //一旦修改完质检信息就自动发送邮件对应的生产科。多次编辑保存多次发送。 只有当这次的尾期结果与上一次不一样才不会发送。
2526 2691 if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckResult()) && !(updateVO.getInspectionStageInfo().getEndCheckResult().equals(endCheckResult))) {
2527   - String EndCheckApplyTime = "";
2528   - if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckApplyTime())) {
2529   - EndCheckApplyTime = updateVO.getInspectionStageInfo().getEndCheckApplyTime().substring(0, 10);
2530   - }
  2692 + String EndCheckApplyTime = StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckApplyTime()) ?
  2693 + updateVO.getInspectionStageInfo().getEndCheckApplyTime().substring(0, 10) : "";
2531 2694 String ProductionDepartmentConsignTime = orderBaseInfoDO.getProductionDepartmentConsignTime().substring(0, 10);
2532 2695 orderEventJobVO.getInspectionStageInfo().setEndCheckApplyTime(EndCheckApplyTime);
2533 2696 orderEventJobVO.getBaseInfo().setProductionDepartmentConsignTime(ProductionDepartmentConsignTime);
2534   - LambdaQueryWrapper<ReceiveEmailMappingDO> receiveEmailMappingDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
2535   - receiveEmailMappingDOLambdaQueryWrapper.eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN);
2536   -// if(!orderBaseInfoDO.getCustomerCode().contains("-") && !orderBaseInfoDO.getCustomerCode().contains("——")){
2537   -// receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderBaseInfoDO.getCustomerCode())
2538   -// .last("limit 1");
2539   -// }else{
2540   -// receiveEmailMappingDOLambdaQueryWrapper.like(ReceiveEmailMappingDO::getTypeValue,orderBaseInfoDO.getCustomerCode().split("-")[0])
2541   -// .last("limit 1");
2542   -// }
2543   - receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderBaseInfoDO.getCustomerCode())
2544   - .last("limit 1");
2545   - ReceiveEmailMappingDO receiveEmailMappingDO = receiveEmailMappingService.getOne( receiveEmailMappingDOLambdaQueryWrapper);
2546   - //得到所有的质检员。由于删除了角色,但是用户角色表中的信息没有删除,所以不能直接通过用户角色表拿角色,然后发邮件,需校验。
2547   - List<AdminUserRoleDO> UserRoleList = adminUserRoleService.list(new LambdaQueryWrapper<AdminUserRoleDO>()
2548   - .eq(AdminUserRoleDO::getRoleId, RoleEnum.INSPECT_USER.getId()));
2549   - Set<Long> userIdList = UserRoleList.stream().map(AdminUserRoleDO::getUserId).collect(Collectors.toSet());
2550   - List<AdminUserDO> produceList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
2551   - .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2552   - .in(AdminUserDO::getId, userIdList)
2553   - .eq(AdminUserDO::getStatus,Constant.ENABLE_TEN));
2554   - List<String> produceEmailList = produceList.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull)
2555   - .flatMap(email -> Arrays.asList(email.split("[,,]+")).stream())
2556   - .map(String::trim)
2557   - .filter(s -> !s.isEmpty())
2558   - .collect(Collectors.toList());
2559   -
2560   - List<String> emailList = new ArrayList<>();
2561   - if (Objects.nonNull(receiveEmailMappingDO)) {
2562   - List<ReceiveEmailConfigItemVO> receiveEmailConfigItemVOList = JSON.parseObject(
2563   - receiveEmailMappingDO.getConfigInfos(), new TypeReference<List<ReceiveEmailConfigItemVO>>() {
2564   - });
2565   - for (ReceiveEmailConfigItemVO item : receiveEmailConfigItemVOList) {
2566   - if (OrderEventEnum.END_CHECK_REPORT_EVENT.getEvent().equals(item.getEvent())) {
2567   - emailList = item.getEmails();
2568   - }
2569   - }
2570   - }
2571   - if (CollectionUtils.isNotEmpty(emails) && CollectionUtils.isNotEmpty(emailList)) {
2572   - List<String> emailLists = emailList.stream().flatMap(email -> Arrays.stream(email.split("[,,]+"))).collect(Collectors.toList());
2573   - List<String> combineEmail = new ArrayList<>(emails);
2574   - if(CollectionUtils.isNotEmpty(produceEmailList)){
2575   - combineEmail.addAll(produceEmailList);
2576   - }
2577   - combineEmail.addAll(emailLists);
2578   -
2579   - //尾期验货报告。
2580   - emailSendUtils.sendEmail(EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE, combineEmail, orderEventJobVO);
2581   - }
  2697 + //尾期验货报告。
  2698 + emailSendUtils.sendCheckResultEmail(EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE,allEmails, orderEventJobVO);
2582 2699 } else if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getMidCheckResult()) && !(updateVO.getInspectionStageInfo().getMidCheckResult().equals(midCheckResult))) {
2583   - String MidCheckApplyTime = "";
2584   - if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getMidCheckApplyTime())) {
2585   - MidCheckApplyTime = updateVO.getInspectionStageInfo().getMidCheckApplyTime().substring(0, 10);
2586   - }
  2700 + String MidCheckApplyTime = StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getMidCheckApplyTime()) ?
  2701 + updateVO.getInspectionStageInfo().getMidCheckApplyTime().substring(0, 10) : "";
2587 2702 String ProductionDepartmentConsignTime = orderBaseInfoDO.getProductionDepartmentConsignTime().substring(0, 10);
2588 2703 orderEventJobVO.getInspectionStageInfo().setMidCheckApplyTime(MidCheckApplyTime);
2589 2704 orderEventJobVO.getBaseInfo().setProductionDepartmentConsignTime(ProductionDepartmentConsignTime);
2590   - LambdaQueryWrapper<ReceiveEmailMappingDO> receiveEmailMappingDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
2591   - receiveEmailMappingDOLambdaQueryWrapper.eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN);
2592   - //不再采用匹配类似的客户编码对应的邮箱,而是直接全部精准匹配,所以需要要求在配置邮箱时需要全部都配置。不再采用A05-low会批匹配上A05。
2593   -/* if(!orderBaseInfoDO.getCustomerCode().contains("-") && !orderBaseInfoDO.getCustomerCode().contains("——")){
2594   - receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderBaseInfoDO.getCustomerCode())
2595   - .last("limit 1");
2596   - }else{
2597   - receiveEmailMappingDOLambdaQueryWrapper.like(ReceiveEmailMappingDO::getTypeValue,orderBaseInfoDO.getCustomerCode().split("-")[0])
2598   - .last("limit 1");
2599   - }*/
2600   - receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderBaseInfoDO.getCustomerCode())
2601   - .last("limit 1");
2602   - ReceiveEmailMappingDO receiveEmailMappingDO = receiveEmailMappingService.getOne( receiveEmailMappingDOLambdaQueryWrapper);
2603   - //得到所有的质检员。由于删除了角色,但是用户角色表中的信息没有删除,所以不能直接通过用户角色表拿角色,然后发邮件,需校验。
2604   - List<AdminUserRoleDO> UserRoleList = adminUserRoleService.list(new LambdaQueryWrapper<AdminUserRoleDO>()
2605   - .eq(AdminUserRoleDO::getRoleId, RoleEnum.INSPECT_USER.getId()));
2606   - Set<Long> userIdList = UserRoleList.stream().map(AdminUserRoleDO::getUserId).collect(Collectors.toSet());
2607   - List<AdminUserDO> produceList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
2608   - .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2609   - .in(AdminUserDO::getId, userIdList)
2610   - .eq(AdminUserDO::getStatus,Constant.ENABLE_TEN));
2611   - List<String> produceEmailList = produceList.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull)
2612   - .flatMap(email -> Arrays.asList(email.split("[,,]+")).stream())
2613   - .map(String::trim)
2614   - .filter(s -> !s.isEmpty())
2615   - .collect(Collectors.toList());
2616   - List<String> emailList = new ArrayList<>();
2617   - if (Objects.nonNull(receiveEmailMappingDO)) {
2618   - List<ReceiveEmailConfigItemVO> receiveEmailConfigItemVOList = JSON.parseObject(
2619   - receiveEmailMappingDO.getConfigInfos(), new TypeReference<List<ReceiveEmailConfigItemVO>>() {
2620   - });
2621   - for (ReceiveEmailConfigItemVO item : receiveEmailConfigItemVOList) {
2622   - if (OrderEventEnum.END_CHECK_REPORT_EVENT.getEvent().equals(item.getEvent())) {
2623   - emailList = item.getEmails();
2624   - }
2625   - }
2626   - }
2627   - if (CollectionUtils.isNotEmpty(emails) && CollectionUtils.isNotEmpty(emailList)) {
2628   - List<String> emailLists = emailList.stream().flatMap(email -> Arrays.stream(email.split("[,,]+"))).collect(Collectors.toList());
2629   - List<String> combineEmail = new ArrayList<>(emails);
2630   - if(CollectionUtils.isNotEmpty(produceEmailList)){
2631   - combineEmail.addAll(produceEmailList);
2632   - }
2633   - combineEmail.addAll(emailLists);
2634   - //中期验货报告。
2635   - emailSendUtils.sendEmail(EmailTemplateEnum.MID_CHECK_REPORT_TEMPLATE, combineEmail, orderEventJobVO);
  2705 + //中期验货报告。
  2706 + emailSendUtils.sendCheckResultEmail(EmailTemplateEnum.MID_CHECK_REPORT_TEMPLATE, allEmails, orderEventJobVO);
  2707 + }
  2708 + }else{
  2709 + throw new BusinessException("邮件发送失败,请在系统配置中配置客户编码对应的邮箱!");
  2710 + }
  2711 + }
2636 2712  
  2713 + //专门为业务员添加尾期验货结果时触发的邮件发送。
  2714 + private void sendOrderInspectionStage(Long orderId,OrderInspectionStageVO inspectionStageVO) {
  2715 + OrderBaseInfoDO orderBaseInfoDO = baseInfoService.getById(orderId);
  2716 + List<String> endCheckReportEvent = getEndCheckReportEvent(orderBaseInfoDO);
  2717 + if(CollectionUtils.isNotEmpty(endCheckReportEvent)){
  2718 + List<String> allInspectEmails = getAllInspectEmails();
  2719 + List<String> produceEmail = getProduceEmail(orderBaseInfoDO);
  2720 + if(CollectionUtils.isNotEmpty(allInspectEmails)){
  2721 + endCheckReportEvent.addAll(allInspectEmails);
  2722 + }
  2723 + if(CollectionUtils.isNotEmpty(produceEmail)){
  2724 + endCheckReportEvent.addAll(produceEmail);
  2725 + }
  2726 + Set<String> emailsSet =new HashSet<>(endCheckReportEvent);
  2727 + List<String> allEmails=new ArrayList<>(emailsSet);
  2728 + OrderEventJobVO orderEventJobVO = new OrderEventJobVO();
  2729 + orderEventJobVO.setInspectionStageInfo(inspectionStageVO);
  2730 + OrderBaseInfoVO orderBaseInfoVo = BeanUtil.copyProperties(orderBaseInfoDO, OrderBaseInfoVO.class);
  2731 + orderEventJobVO.setBaseInfo(orderBaseInfoVo);
  2732 + emailSendUtils.sendCheckResultEmail(EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE, allEmails, orderEventJobVO);
  2733 + }else{
  2734 + throw new BusinessException("邮件发送失败,请在系统配置中配置客户编码对应的邮箱!");
  2735 + }
  2736 + }
  2737 + //获取所有质检员邮箱。
  2738 + private List<String> getAllInspectEmails(){
  2739 + List<String> inspectUserEmailList=null;
  2740 + //得到所有的质检员。由于删除了角色,但是用户角色表中的信息没有删除,所以不能直接通过用户角色表拿角色,然后发邮件,需校验。 得到所有质检员的邮箱
  2741 + List<AdminUserRoleDO> UserRoleList = adminUserRoleService.list(new LambdaQueryWrapper<AdminUserRoleDO>()
  2742 + .eq(AdminUserRoleDO::getRoleId, RoleEnum.INSPECT_USER.getId()));
  2743 + if(CollectionUtils.isNotEmpty(UserRoleList)){
  2744 + Set<Long> userIdList = UserRoleList.stream().map(AdminUserRoleDO::getUserId).collect(Collectors.toSet());
  2745 + List<AdminUserDO> inspectUserList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
  2746 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2747 + .in(AdminUserDO::getId, userIdList)
  2748 + .eq(AdminUserDO::getStatus,Constant.ENABLE_TEN));
  2749 +
  2750 + inspectUserEmailList= inspectUserList.stream().map(AdminUserDO::getEmail).filter(emails -> StringUtils.isNotBlank(emails))
  2751 + .flatMap(email -> Arrays.asList(email.split("[,,]+")).stream())
  2752 + .map(String::trim)
  2753 + .filter(s -> !s.isEmpty())
  2754 + .collect(Collectors.toList());
  2755 + }
  2756 + return inspectUserEmailList;
  2757 + }
  2758 +
  2759 + //获取对应客户编码的生产科邮箱。
  2760 + private List<String> getProduceEmail(OrderBaseInfoDO orderBaseInfoDO){
  2761 + List<String> productionEmails=null;
  2762 + //得到生产科
  2763 + AdminUserDO ProductionDepartmentUserDO = userService.getOne(new LambdaQueryWrapper<AdminUserDO>()
  2764 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2765 + .eq(AdminUserDO::getUserName, orderBaseInfoDO.getProductionDepartment()));
  2766 + if(Objects.nonNull(ProductionDepartmentUserDO)){
  2767 + String email = ProductionDepartmentUserDO.getEmail();
  2768 + if(StringUtils.isNotBlank(email)){
  2769 + //得到生产科邮箱
  2770 + productionEmails = Arrays.asList(email.split("[,,]+"))
  2771 + .stream().map(String::trim)
  2772 + .filter(StringUtils::isNotBlank)
  2773 + .collect(Collectors.toList());
  2774 + }
  2775 + }
  2776 + return productionEmails;
  2777 + }
  2778 + private List<String> getEndCheckReportEvent(OrderBaseInfoDO orderBaseInfoDO){
  2779 + List<String> emailList=new ArrayList<>();
  2780 + LambdaQueryWrapper<ReceiveEmailMappingDO> receiveEmailMappingDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
  2781 + receiveEmailMappingDOLambdaQueryWrapper.eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN);
  2782 + receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderBaseInfoDO.getCustomerCode())
  2783 + .last("limit 1");
  2784 + ReceiveEmailMappingDO receiveEmailMappingDO = receiveEmailMappingService.getOne( receiveEmailMappingDOLambdaQueryWrapper);
  2785 + if (Objects.nonNull(receiveEmailMappingDO)) {
  2786 + List<ReceiveEmailConfigItemVO> receiveEmailConfigItemVOList = JSON.parseObject(
  2787 + receiveEmailMappingDO.getConfigInfos(), new TypeReference<List<ReceiveEmailConfigItemVO>>() {
  2788 + });
  2789 + for (ReceiveEmailConfigItemVO item : receiveEmailConfigItemVOList) {
  2790 + if (OrderEventEnum.END_CHECK_REPORT_EVENT.getEvent().equals(item.getEvent())) {
  2791 + emailList = item.getEmails();
2637 2792 }
2638 2793 }
2639 2794 }
  2795 + return emailList;
2640 2796 }
2641 2797  
2642 2798 private void sendProductionCommentEmail(OrderBaseInfoDO orderBaseInfoDo, String productionComment,String lastString) {
... ... @@ -2644,7 +2800,7 @@ end
2644 2800 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2645 2801 .in(AdminUserDO::getUserName, Arrays.asList(orderBaseInfoDo.getBusinessPerson(), orderBaseInfoDo.getCreateBy(), orderBaseInfoDo.getProductionDepartment())));
2646 2802 if (CollectionUtils.isNotEmpty(adminList)) {
2647   - List<String> emailsList = adminList.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull).collect(Collectors.toList());
  2803 + List<String> emailsList = adminList.stream().filter(Objects::nonNull).map(AdminUserDO::getEmail).filter(Objects::nonNull).collect(Collectors.toList());
2648 2804 if (CollectionUtils.isNotEmpty(emailsList)) {
2649 2805 List<String> emailList = emailsList.stream()
2650 2806 .flatMap(email -> Arrays.stream(email.split("[,,]+")))
... ... @@ -2673,9 +2829,248 @@ end
2673 2829 }else{
2674 2830 emailSendUtils.sendEmail(EmailTemplateEnum.PRODUCE_IDEA, emailList, orderEventJobVO,"无更新信息!");
2675 2831 }
  2832 + }
  2833 + }
  2834 + }
  2835 + }
  2836 + @Override
  2837 + public ServerResult countByYear(DateTimeVO dateTimeVO) {
  2838 +
  2839 + /**
  2840 + * 总结:前端默认打开什么参数也不传递,所以只会查询当前月的数据。 ----查询当前月的数据。(默认。)
  2841 + * 1.当传递了dateTimeVO了后,如果dateTimeVO中的period为"年",不管dateTime是否为多少,则查询所有年的所有数据。 ----查询所有年的数据。
  2842 + * 2.当传递了dateTimeVO了后,如果dateTimeVO中的period为"月",则根据dateTime中的年份来查询这个dateTime中的数据。 ----查询指定年的数据。
  2843 + * **/
  2844 + //前端不传递dateTimeVO时,默认查询当前所有月的数据。
  2845 + if(dateTimeVO!=null) {
  2846 + //假设前端传来的时间为String类型,不是Date类型。并且传来的时间格式为yyyy-MM-dd HH:mm:ss格式。
  2847 + //年
  2848 + if (TimePeriod.YEAR.getDescription().equals(dateTimeVO.getPeriod())) {
  2849 + //查询每一年份的已完成订单数据。
  2850 + //查询所有年份的完成订单数据。
  2851 + long allYearCount = this.baseMapper.countAllYearByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus());
  2852 + //查询所有年份的跟单和质检中的数据。
  2853 + long tracking = orderTrackStageService.countRecentYearByOrderStatus(OrderStatusEnum.TRACK_ING.getStatus());
  2854 + long inspecting = orderInspectionStageService.countRecentYearByOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus());
  2855 + //查询所有年份的利润分析表的数据。(从orderFieldLockApplyDo表中查询。)。
  2856 +// long rofit =this.baseMapper.countAllYearByOrderStatus(OrderStatusEnum.PROFIT_WAIT_AUDIT.getStatus());
  2857 + long rofit = orderFieldLockApplyService.countAllYearByOrderStatus(ApplyTypeEnum.ORDER_PROFIT_APPLY.getType());
  2858 + //查询所有年份的项目报告书待审核的数据。
  2859 +// long report=this.baseMapper.countAllYearByOrderStatus(OrderStatusEnum.REPORT_WAIT_AUDIT.getStatus());
  2860 + long report = orderFieldLockApplyService.countAllYearByOrderStatus(ApplyTypeEnum.ORDER_REPORT_APPLY.getType());
  2861 + //查询所有年份的订单初始化的数据。
  2862 + long orderInit = this.baseMapper.countRecentYearByOrderInit();
  2863 +
  2864 + Datecount datecount = new Datecount();
  2865 + datecount.setAllCount(allYearCount);
  2866 + datecount.setTrackingAndInspectingList(tracking+inspecting);
  2867 + datecount.setProfitList(rofit);
  2868 + datecount.setReportList(report);
  2869 + datecount.setOrderInitList(orderInit);
  2870 + return ServerResult.success(datecount);
  2871 + }
  2872 + //月
  2873 + if (TimePeriod.MONTH.getDescription().equals(dateTimeVO.getPeriod())) {
  2874 + Integer dateTime = dateTimeVO.getDateTime();
  2875 + LocalDate startOfYear = LocalDate.of(dateTime, 1, 1);
  2876 + LocalDate endOfYear = startOfYear.plusYears(1);
  2877 + //如果为月,则需要前端传递year,然后得到这个year的数据。
  2878 + //查询这个年每一个月的数据
  2879 + long allMonthCount=this.baseMapper.countAllMonthByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus(),startOfYear,endOfYear);
  2880 + long tracking = orderTrackStageService.countRecentMonthValueByOrderStatus(OrderStatusEnum.TRACK_ING.getStatus(),startOfYear,endOfYear);
  2881 + long inspecting = orderInspectionStageService.countRecentMonthValueByOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus(),startOfYear,endOfYear);
  2882 + long profit = orderFieldLockApplyService.countRecentMonthValueByOrderStatus(ApplyTypeEnum.ORDER_PROFIT_APPLY.getType(),startOfYear,endOfYear);
  2883 + long report = orderFieldLockApplyService.countRecentMonthValueByOrderStatus(ApplyTypeEnum.ORDER_REPORT_APPLY.getType(),startOfYear,endOfYear);
  2884 + //查询年月的项目报告书待审核/订单初始化。
  2885 + long orderinit=this.baseMapper.countRecentMonthValueByOrderInit(startOfYear,endOfYear);
  2886 + Datecount datecount = new Datecount();
  2887 + datecount.setTrackingAndInspectingList(tracking+inspecting);
  2888 + datecount.setAllCount(allMonthCount);
  2889 + datecount.setProfitList(profit);
  2890 + datecount.setReportList(report);
  2891 + datecount.setOrderInitList(orderinit);
  2892 + return ServerResult.success(datecount);
  2893 + }
  2894 + }
  2895 + LocalDate currentDate = LocalDate.now();
  2896 + int currentMonth = currentDate.getMonthValue();
  2897 + int year = currentDate.getYear();
  2898 + LocalDate startDate = LocalDate.of(year, currentMonth, 1);
  2899 + LocalDate endDate = startDate.plusMonths(1);
  2900 + long allDayCount=this.baseMapper.countAllDayvalueByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus(),startDate,endDate);
  2901 + long tracking = orderTrackStageService.countRecentDayvalueByOrderStatus(OrderStatusEnum.TRACK_ING.getStatus(),startDate,endDate);
  2902 + long inspecting = orderInspectionStageService.countRecentDayvalueByOrderStatus(OrderStatusEnum.INSPECT_ING.getStatus(),startDate,endDate);
  2903 + long profit= orderFieldLockApplyService.countRecentDayvalueByOrderStatus(ApplyTypeEnum.ORDER_PROFIT_APPLY.getType(),startDate,endDate);
  2904 + long report=orderFieldLockApplyService.countRecentDayvalueByOrderStatus(ApplyTypeEnum.ORDER_REPORT_APPLY.getType(),startDate,endDate);
  2905 + long orderinit=this.baseMapper.countRecentDayByOrderInit(startDate,endDate);
  2906 + Datecount datecount = new Datecount();
  2907 + datecount.setTrackingAndInspectingList(tracking+inspecting);
  2908 + datecount.setAllCount(allDayCount);
  2909 + datecount.setProfitList(profit);
  2910 + datecount.setReportList(report);
  2911 + datecount.setOrderInitList(orderinit);
  2912 + return ServerResult.success(datecount);
  2913 + }
2676 2914  
  2915 + @Override
  2916 + public ServerResult countByDate(DateTimeVO dateTimeVO) {
  2917 + /**
  2918 + * 1.当dateTimeVO为空时,查询当前月的数据
  2919 + * 2.当dateTimeVO不为空,但是period为"年"时,查询所有年的所有数据。
  2920 + * 3.当dateTimeVO不为空,但是period为"月"时,查询当前DateTime指定年份的数据和对比年份数据。
  2921 + * **/
  2922 + if(dateTimeVO!=null){
  2923 + if (TimePeriod.YEAR.getDescription().equals(dateTimeVO.getPeriod())) {
  2924 + List<DateYearMonthTimeVO> dateYearMonthTimeVOS= this.baseMapper.countRecentYearByOrderStatus();
  2925 + dateYearMonthTimeVOS.stream().forEach(x->x.setYearType(""));
  2926 + return ServerResult.success(dateYearMonthTimeVOS);
  2927 + }
  2928 + if (TimePeriod.MONTH.getDescription().equals(dateTimeVO.getPeriod())) {
  2929 + // 查询当前月份的数据
  2930 + List<DateYearMonthTimeVO> dateYearMonthTimeVOS = this.baseMapper.countRecentMonthValueByOrderStatus(Arrays.asList(dateTimeVO.getDateTime()));
  2931 + List<DateYearMonthTimeVO> combinedList = new ArrayList<>(dateYearMonthTimeVOS);
  2932 +
  2933 + // 查询对比的年份
  2934 + List<Integer> yearList = new ArrayList<>();
  2935 + yearList.add(dateTimeVO.getDateTime());
  2936 + if (CollectionUtils.isNotEmpty(dateTimeVO.getDateTimes())) {
  2937 + List<DateYearMonthTimeVO> dateYearMonthTimeVOS1 = this.baseMapper.countRecentMonthValueByOrderStatus(dateTimeVO.getDateTimes());
  2938 + combinedList.addAll(dateYearMonthTimeVOS1);
  2939 + yearList.addAll(dateTimeVO.getDateTimes());
  2940 + }
  2941 +
  2942 + // 使用 Map 来存储已有的日期信息,避免重复遍历
  2943 + Map<String, DateYearMonthTimeVO> existingDates = new HashMap<>();
  2944 +
  2945 + // 将已有数据存储到 Map 中
  2946 + for (DateYearMonthTimeVO item : combinedList) {
  2947 + existingDates.put(item.getDate(), item);
  2948 + }
  2949 +
  2950 + // 遍历年份和月份,补充缺失月份
  2951 + for (Integer targetYear : yearList) {
  2952 + for (int month = 1; month <= 12; month++) {
  2953 + String monthStr = String.format("%s-%02d", targetYear, month);
  2954 + // 如果该月份没有数据,则补充
  2955 + existingDates.putIfAbsent(monthStr, new DateYearMonthTimeVO(monthStr, 0L ,String.valueOf(targetYear)));
  2956 + }
2677 2957 }
  2958 +
  2959 + // 更新日期前缀
  2960 + existingDates.forEach((key, item) -> {
  2961 + String[] dateParts = item.getDate().split("-");
  2962 + if (dateParts.length == 2) {
  2963 + item.setDate(String.format("%s-%s", dateTimeVO.getDateTime(), dateParts[1]));
  2964 + }
  2965 + });
  2966 +
  2967 + // 返回最终结果
  2968 + return ServerResult.success(new ArrayList<>(existingDates.values()));
2678 2969 }
  2970 +
2679 2971 }
  2972 + LocalDate currentDate = LocalDate.now();
  2973 + int currentMonth = currentDate.getMonthValue();
  2974 + int year = currentDate.getYear();
  2975 + LocalDate startDate = LocalDate.of(year, currentMonth, 1);
  2976 + LocalDate endDate = startDate.plusMonths(1);
  2977 + List<DateYearMonthTimeVO> dateYearMonthTimeVOS= this.baseMapper.countRecentDayvalueByOrderStatus(startDate,endDate);
  2978 + dateYearMonthTimeVOS.stream().forEach(x->x.setYearType(String.valueOf(year)));
  2979 + return ServerResult.success(dateYearMonthTimeVOS);
  2980 + }
  2981 +
  2982 +
  2983 +
  2984 + @Override
  2985 + public Map<String, String> totalSalesStatistics(QuerySalesStatisticeDO query) {
  2986 + Map<String,String> res = new HashMap<>();
  2987 + LocalDateTime yearBegin = LocalDateTime.of(LocalDate.now().getYear(), 1, 1, 0, 0);
  2988 + LocalDateTime yearEnd = LocalDateTime.of(LocalDate.of(LocalDate.now().getYear(), Month.DECEMBER, 31), java.time.LocalTime.MAX);
  2989 + LocalDateTime monthbegin = LocalDateTime.of(LocalDate.now().withDayOfMonth(1), LocalTime.MIN);
  2990 + LocalDateTime monthEnd = LocalDateTime.of(LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()), java.time.LocalTime.MAX);
  2991 + //获取当前季度
  2992 + LocalDate now = LocalDate.now();
  2993 + int currentMonth = now.getMonthValue();
  2994 + int startMonth = ((currentMonth - 1) / 3) * 3 + 1; // 计算季度开始月份
  2995 + LocalDate quarterStart = LocalDate.of(now.getYear(), startMonth, 1);
  2996 + LocalDate quarterEnd = quarterStart.plusMonths(2).withDayOfMonth(quarterStart.plusMonths(2).lengthOfMonth());
  2997 + LocalDateTime quarterBegin = LocalDateTime.of(quarterStart, LocalTime.MIN);
  2998 + LocalDateTime quarterEndDateTime = LocalDateTime.of(quarterEnd, LocalTime.MAX);
  2999 +//查询销售情况,销售金额。
  3000 + double yearSalesAmount = Optional
  3001 + .ofNullable(getBaseMapper().salesAmountStatistics(yearBegin,yearEnd,query.getCustomerCodeIn()))
  3002 + .orElse(0.0);
  3003 + double quarterSalesAmount = Optional
  3004 + .ofNullable(getBaseMapper().salesAmountStatistics(quarterBegin,quarterEndDateTime,query.getCustomerCodeIn()))
  3005 + .orElse(0.0);
  3006 + //月销售额。
  3007 + double monthSalesAmount = Optional
  3008 + .ofNullable(getBaseMapper().salesAmountStatistics(monthbegin,monthEnd,query.getCustomerCodeIn()))
  3009 + .orElse(0.0);
  3010 +//查询给客户编码配置的销售额。
  3011 + double salesAmountTarget = Optional
  3012 + .ofNullable(getBaseMapper().salesAmountTarget(query.getCustomerCodeIn()))
  3013 + .orElse(0.0);
  3014 + //月销售额目标。 -> 季销售目标
  3015 + double quarterlySalesAmountTarget = salesAmountTarget/4;
  3016 + //总销售额完成率。
  3017 + double yearSalesCompletionRate = salesAmountTarget==0?0:yearSalesAmount/salesAmountTarget;
  3018 + //当前月销售额完成率。 ->当前季销售完成率。
  3019 + double quartSalesCompletionRate = salesAmountTarget==0?0:quarterSalesAmount/quarterlySalesAmountTarget;
  3020 +
  3021 + res.put("yearlySalesAmountTarget",String.format("%.2f", salesAmountTarget));
  3022 + res.put("yearlySalesAmountCompletionRate",String.format("%.2f%%", yearSalesCompletionRate * 100));
  3023 + res.put("quarterlySalesAmountTarget",String.format("%.2f", quarterlySalesAmountTarget));
  3024 + res.put("quarterlySalesAmountCompletionRate",String.format("%.2f%%", quartSalesCompletionRate * 100));
  3025 + res.put("monthlySalesAmount",String.format("%.2f", monthSalesAmount));
  3026 +
  3027 + return res;
  3028 + }
  3029 +
  3030 + @Override
  3031 + public Map<String, Map<String, Double>> salesStatusEveryCustomer(QuerySalesStatisticeDO query) {
  3032 + //查询设置的每个客户编码的销售目标 如果没有传递就查询所有客户编码的销售额。
  3033 + List<SystemSettingDO> systemSettingDOS = systemSettingService.lambdaQuery()
  3034 + .in(CollUtil.isNotEmpty(query.getCustomerCodeIn()), SystemSettingDO::getSettingValue, query.getCustomerCodeIn())
  3035 + .eq(SystemSettingDO::getRelationCode, "salesAmount")
  3036 + .list();
  3037 + //对销售额进行累加。
  3038 + Map<String, Double> targetMap = systemSettingDOS.stream().collect(Collectors.toMap(SystemSettingDO::getSettingValue, v->Double.valueOf(v.getRelationValue())));
  3039 + LocalDateTime begin;
  3040 + LocalDateTime end;
  3041 + if (TimePeriod.YEAR.name().equals(query.getPeriod())){
  3042 + begin = LocalDateTime.of(LocalDate.now().getYear(), 1, 1, 0, 0);
  3043 + end = LocalDateTime.of(LocalDate.of(LocalDate.now().getYear(), Month.DECEMBER, 31), java.time.LocalTime.MAX);
  3044 + }else if(TimePeriod.QUARTER.name().equals(query.getPeriod())){
  3045 + begin = DateUtils.beginOfQuarter();
  3046 + end = DateUtils.endOfQuarter();
  3047 + targetMap.keySet().forEach(k->targetMap.put(k,targetMap.get(k)/4));
  3048 + }else {
  3049 + begin = LocalDateTime.of(LocalDate.now().withDayOfMonth(1), LocalTime.MIN);
  3050 + end = LocalDateTime.of(LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()), java.time.LocalTime.MAX);
  3051 + targetMap.keySet().forEach(k->targetMap.put(k,targetMap.get(k)/12));
  3052 + }
  3053 + MapResultHandler<String, Double> mapResultHandler = new MapResultHandler<>();
  3054 + getBaseMapper().customerSalesStatus(begin,end,query.getCustomerCodeIn(),mapResultHandler);
  3055 + Map<String, Double> salesAmountMap = mapResultHandler.getMappedResults();
  3056 + //合并为图表数据
  3057 + Set<String> keySet = new HashSet<>();
  3058 + if (CollUtil.isNotEmpty(salesAmountMap)){
  3059 + keySet.addAll(salesAmountMap.keySet());
  3060 + }
  3061 + if (CollUtil.isNotEmpty(targetMap)){
  3062 + keySet.addAll(targetMap.keySet());
  3063 + }
  3064 + Map<String,Map<String,Double>> res = new HashMap<>();
  3065 + keySet.forEach(key->{
  3066 + HashMap<String, Double> data = new HashMap<>();
  3067 + data.put("salesAmount",Math.round((Objects.isNull(salesAmountMap.get(key))?0:salesAmountMap.get(key)) * 100.0) / 100.0);
  3068 + data.put("target",Math.round((Objects.isNull(targetMap.get(key))?0:targetMap.get(key)) * 100.0) / 100.0);
  3069 + res.put(key,data);
  3070 + });
  3071 + return res;
2680 3072 }
  3073 +
  3074 +
  3075 +
2681 3076 }
... ...
src/main/java/com/order/erp/service/order/impl/OrderCompletionReportServiceImpl.java
... ... @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse;
30 30 import java.io.IOException;
31 31 import java.math.BigDecimal;
32 32 import java.math.RoundingMode;
  33 +import java.time.LocalDate;
33 34 import java.util.*;
34 35 import java.util.function.Function;
35 36 import java.util.stream.Collectors;
... ... @@ -345,4 +346,20 @@ public class OrderCompletionReportServiceImpl extends ServiceImpl&lt;OrderCompletio
345 346 public long countYearByOrderStatus(Integer status) {
346 347 return baseMapper.countYearByOrderStatus(status);
347 348 }
  349 +
  350 +
  351 + @Override
  352 + public long countRecentYearByOrderStatus(Integer status) {
  353 + return baseMapper.countRecentYearByOrderStatus(status);
  354 + }
  355 +
  356 + @Override
  357 + public long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear) {
  358 + return baseMapper.countRecentMonthValueByOrderStatus(status,startOfYear,endOfYear);
  359 + }
  360 +
  361 + @Override
  362 + public long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate) {
  363 + return baseMapper.countRecentDayvalueByOrderStatus(status,startDate,endDate);
  364 + }
348 365 }
... ...
src/main/java/com/order/erp/service/order/impl/OrderFieldLockApplyServiceImpl.java
... ... @@ -14,6 +14,7 @@ import com.order.erp.common.constant.Constant;
14 14 import com.order.erp.common.constant.ServerResult;
15 15 import com.order.erp.common.constant.ServerResultCode;
16 16 import com.order.erp.common.exception.BusinessException;
  17 +import com.order.erp.common.utils.EmailSendUtils;
17 18 import com.order.erp.common.utils.OrderFieldUtils;
18 19 import com.order.erp.common.utils.TransactionHelper;
19 20 import com.order.erp.config.DataScope;
... ... @@ -29,6 +30,7 @@ import org.springframework.stereotype.Service;
29 30 import org.springframework.transaction.annotation.Transactional;
30 31  
31 32 import javax.annotation.Resource;
  33 +import java.time.LocalDate;
32 34 import java.util.*;
33 35 import java.util.function.Function;
34 36 import java.util.stream.Collectors;
... ... @@ -63,12 +65,6 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
63 65  
64 66 @Resource
65 67 private OrderProfitAnalysisService profitAnalysisService;
66   -
67   - @Resource
68   - private OrderTrackStageService trackStageService;
69   -
70   - @Resource
71   - private OrderInspectionStageService inspectionStageService;
72 68 @Resource
73 69 private InvoiceBillOrderService invoiceBillOrderService;
74 70  
... ... @@ -76,6 +72,8 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
76 72 private ProducePaymentCheckBillOrderService checkBillOrderService;
77 73 @Resource
78 74 private TransactionHelper transactionHelper;
  75 + @Resource
  76 + private EmailSendUtils emailSendUtils;
79 77  
80 78 /**
81 79 * 通过ID查询单条数据
... ... @@ -112,13 +110,10 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
112 110 RoleEnum roleEnum = dataScope.getRole();
113 111 String loginUserName = dataScope.getLoginUserName();
114 112 LambdaQueryWrapper<OrderFieldLockApplyDO> queryWrapper = buildQueryByParam(queryVO,roleEnum);
115   - Page page = new Page<>(queryVO.getPage(), queryVO.getPageSize());
116   - IPage<OrderFieldLockApplyDO> iPage = page(page, queryWrapper);
117   -
118   - Page<OrderApplyResultVO> webVOPage = new Page<>();
119   - List<OrderFieldLockApplyDO> applyDOList = iPage.getRecords();
  113 + List<OrderFieldLockApplyDO> applyDOList=list(queryWrapper);
  114 + List<OrderApplyResultVO> resultVOList=new ArrayList<>();
120 115 if (CollectionUtils.isNotEmpty(applyDOList)) {
121   - List<OrderApplyResultVO> resultVOList = applyDOList.stream().map(x -> {
  116 + resultVOList = applyDOList.stream().map(x -> {
122 117 OrderApplyResultVO resultVO = new OrderApplyResultVO();
123 118 BeanUtils.copyProperties(x, resultVO);
124 119 String fields = x.getFields();
... ... @@ -180,9 +175,26 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
180 175 || ApplyTypeEnum.CHECK_BILL_APPLY.getType().equals(x.getType()))) {
181 176 fillOrderInfo(resultVOList);
182 177 }
183   - webVOPage.setRecords(resultVOList);
184 178 }
185   - BeanUtils.copyProperties(page, webVOPage, "records");
  179 + // **手动分页**
  180 + int total = resultVOList.size();
  181 + int pageSize = queryVO.getPageSize();
  182 + int currentPage = queryVO.getPage();
  183 + int fromIndex = (currentPage - 1) * pageSize;
  184 + int toIndex = Math.min(fromIndex + pageSize, total);
  185 +
  186 + List<OrderApplyResultVO> paginatedList = new ArrayList<>();
  187 + if (fromIndex < total) {
  188 + paginatedList = resultVOList.subList(fromIndex, toIndex);
  189 + }
  190 +
  191 + // **构建分页结果**
  192 + Page<OrderApplyResultVO> webVOPage = new Page<>();
  193 + webVOPage.setRecords(paginatedList);
  194 + webVOPage.setTotal(total);
  195 + webVOPage.setPages((int) Math.ceil((double) total / pageSize));
  196 + webVOPage.setCurrent(currentPage);
  197 + webVOPage.setSize(pageSize);
186 198 return ServerResult.success(webVOPage);
187 199 }
188 200  
... ... @@ -554,11 +566,26 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
554 566 orderBaseInfoService.updateBatchById(orderBaseInfoDOS);
555 567 invoiceBillOrderService.updateBatchById(invoiceBillOrderDOS);
556 568 });
  569 + //发送邮箱通知财务。 这里这个邮箱通知财务,只能提示invoice号,因为一个invoice申请对应多个invoice号,所以会有多个内部编号和项目号等。
  570 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  571 + invoiceAndCheckBillSendEmailVO.setInvoiceBillOrderDO(invoiceBillOrderDOS.get(0));
  572 + invoiceAndCheckBillSendEmailVO.setRefuseRemark(refuseRemark);
  573 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.INVOICE_FAIL,invoiceAndCheckBillSendEmailVO);
557 574 }
558 575 } else if (ApplyTypeEnum.CHECK_BILL_APPLY.getType().equals(applyDO.getType())) {
559 576 OrderLockFieldVO lockFieldVO = JSONObject.parseObject(applyDO.getFields(), OrderLockFieldVO.class);
560 577 ProducePaymentCheckBillFieldVO checkBillOrderDO = lockFieldVO.getProducePaymentCheckBillFieldVO();
561 578 List<Long> producePaymentCheckBillId = checkBillOrderDO.getProducePaymentCheckBillId();
  579 + //在提交申请时,是可以多个订单一起提交,并且现在放开了,可以提交发票之后直接提交审核,无需等待发票审核完成之后才能提交审核。所以在审批时,必须保证发票先被审,然后在审核单子,不然造成单子审核之后,发票审核成功之后,也无法设置到对应的单子中去。
  580 + //查询是否存在未审核的发票。
  581 + List<OrderFieldLockApplyDO> producePayCheckBillInvoiceUrlList = list(new LambdaQueryWrapper<OrderFieldLockApplyDO>()
  582 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  583 + .in(OrderFieldLockApplyDO::getOrderId, producePaymentCheckBillId)
  584 + .eq(OrderFieldLockApplyDO::getType, ApplyTypeEnum.DEPARTMENT_INVOICE_APPLY.getType())
  585 + .eq(OrderFieldLockApplyDO::getStatus, ApplyStatusEnum.WAIT_AUDIT));
  586 + if(CollectionUtils.isNotEmpty(producePayCheckBillInvoiceUrlList)){
  587 + throw new BusinessException("该生产科对账单存在未审批的发票,请先审批该对账单的发票!");
  588 + }
562 589 List<ProducePaymentCheckBillOrderDO> producePaymentCheckBillOrderDOList = checkBillOrderService.listByIds(producePaymentCheckBillId);
563 590 if(CollectionUtils.isNotEmpty(producePaymentCheckBillOrderDOList)){
564 591 List<ProducePaymentCheckBillOrderDO> producePaymentCheckBillOrderDOS= producePaymentCheckBillOrderDOList.stream().filter(Objects::nonNull).map(x -> {
... ... @@ -578,6 +605,12 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
578 605 orderBaseInfoService.updateBatchById(orderBaseInfoDOS);
579 606 checkBillOrderService.updateBatchById(producePaymentCheckBillOrderDOS);
580 607 });
  608 + //发送邮件通知跟单员和业务员。
  609 + //发送邮箱通知财务。 这里这个邮箱通知财务,只能提示invoice号,因为一个invoice申请对应多个invoice号,所以会有多个内部编号和项目号等。
  610 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  611 + invoiceAndCheckBillSendEmailVO.setCheckBillOrderDO(producePaymentCheckBillOrderDOS.get(0));
  612 + invoiceAndCheckBillSendEmailVO.setRefuseRemark(refuseRemark);
  613 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.CHECK_FAIL,invoiceAndCheckBillSendEmailVO);
581 614 }
582 615  
583 616 } else if(ApplyTypeEnum.DEPARTMENT_INVOICE_APPLY.getType().equals(applyDO.getType())){
... ... @@ -603,6 +636,12 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
603 636 invoiceInfoDO.setInvoiceUrl(null);
604 637 }
605 638 checkBillOrderService.updateById(invoiceInfoDO);
  639 + //发送邮件通知跟单员和业务员。
  640 + //发送邮箱通知财务。 这里这个邮箱通知财务,只能提示invoice号,因为一个invoice申请对应多个invoice号,所以会有多个内部编号和项目号等。
  641 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  642 + invoiceAndCheckBillSendEmailVO.setCheckBillOrderDO(invoiceInfoDO);
  643 + invoiceAndCheckBillSendEmailVO.setRefuseRemark(refuseRemark);
  644 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.CHECK_INVOICEURL_FAIL,invoiceAndCheckBillSendEmailVO);
606 645 }
607 646  
608 647 OrderAuditLogDO auditLogDO = OrderAuditLogDO.builder().applyId(applyDO.getId()).orderId(applyDO.getOrderId()).optType(ApplyStatusEnum.AUDIT_REFUSE.getDesc()).build();
... ... @@ -726,6 +765,7 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
726 765 orderBaseInfoDO.setOrderStatus(OrderStatusEnum.PROFIT_AUDIT_PASS.getStatus());
727 766 orderBaseInfoService.updateById(orderBaseInfoDO);
728 767 } else if (ApplyTypeEnum.INVOICE_BILL_APPLY.getType().equals(applyDO.getType())) {
  768 + //后期需要判断是否存在存在未审核的扣款单。
729 769 applyDO.setAuditUserId(auditUserId);
730 770 applyDO.setStatus(ApplyStatusEnum.AUDIT_PASS.getStatus());
731 771 OrderLockFieldVO lockFieldVO = JSONObject.parseObject(applyDO.getFields(), OrderLockFieldVO.class);
... ... @@ -750,6 +790,10 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
750 790 orderBaseInfoService.updateBatchById(orderBaseInfoDOS);
751 791 invoiceBillOrderService.updateBatchById(invoiceeBillOrderDOs);
752 792 });
  793 + //发送邮箱通知财务。 这里这个邮箱通知财务,只能提示invoice号,因为一个invoice申请对应多个invoice号,所以会有多个内部编号和项目号等。
  794 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  795 + invoiceAndCheckBillSendEmailVO.setInvoiceBillOrderDO(invoiceeBillOrderDOs.get(0));
  796 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.INVOICE_PASS,invoiceAndCheckBillSendEmailVO);
753 797 }
754 798 } else if (ApplyTypeEnum.CHECK_BILL_APPLY.getType().equals(applyDO.getType())) {
755 799 applyDO.setAuditUserId(auditUserId);
... ... @@ -757,6 +801,16 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
757 801 OrderLockFieldVO lockFieldVO = JSONObject.parseObject(applyDO.getFields(), OrderLockFieldVO.class);
758 802 ProducePaymentCheckBillFieldVO checkBillOrderDO = lockFieldVO.getProducePaymentCheckBillFieldVO();
759 803 List<Long> producePaymentCheckBillId = checkBillOrderDO.getProducePaymentCheckBillId();
  804 + //在提交申请时,是可以多个订单一起提交,并且现在放开了,可以提交发票之后直接提交审核,无需等待发票审核完成之后才能提交审核。所以在审批时,必须保证发票先被审,然后在审核单子,不然造成单子审核之后,发票审核成功之后,也无法设置到对应的单子中去。
  805 + //查询是否存在未审核的发票。
  806 + List<OrderFieldLockApplyDO> producePayCheckBillInvoiceUrlList = list(new LambdaQueryWrapper<OrderFieldLockApplyDO>()
  807 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  808 + .in(OrderFieldLockApplyDO::getOrderId, producePaymentCheckBillId)
  809 + .eq(OrderFieldLockApplyDO::getType, ApplyTypeEnum.DEPARTMENT_INVOICE_APPLY.getType())
  810 + .eq(OrderFieldLockApplyDO::getStatus, ApplyStatusEnum.WAIT_AUDIT));
  811 + if(CollectionUtils.isNotEmpty(producePayCheckBillInvoiceUrlList)){
  812 + throw new BusinessException("该生产科对账单存在未审批的发票,请先审批该对账单的发票!");
  813 + }
760 814 List<ProducePaymentCheckBillOrderDO> checkBillOrderDOS = checkBillOrderService.listByIds(producePaymentCheckBillId);
761 815 if(CollectionUtils.isNotEmpty(checkBillOrderDOS)){
762 816 List<ProducePaymentCheckBillOrderDO> producePaymentCheckBillOrderDOS = checkBillOrderDOS.stream().filter(Objects::nonNull).map(x -> {
... ... @@ -776,6 +830,12 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
776 830 orderBaseInfoService.updateBatchById(orderBaseInfoDOS);
777 831 checkBillOrderService.updateBatchById(producePaymentCheckBillOrderDOS);
778 832 });
  833 + //发送邮件通知跟单员和业务员。
  834 + //发送邮箱通知财务。 这里这个邮箱通知财务,只能提示invoice号,因为一个invoice申请对应多个invoice号,所以会有多个内部编号和项目号等。
  835 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  836 + invoiceAndCheckBillSendEmailVO.setCheckBillOrderDO(producePaymentCheckBillOrderDOS.get(0));
  837 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.CHECK_PASS,invoiceAndCheckBillSendEmailVO);
  838 +
779 839 }
780 840 } else if (ApplyTypeEnum.DEPARTMENT_INVOICE_APPLY.getType().equals(applyDO.getType())) {
781 841 applyDO.setAuditUserId(auditUserId);
... ... @@ -802,6 +862,10 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
802 862 }
803 863 }
804 864 checkBillOrderService.updateById(invoiceInfoDO);
  865 + //发送邮件通知跟单员和业务员。
  866 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  867 + invoiceAndCheckBillSendEmailVO.setCheckBillOrderDO(invoiceInfoDO);
  868 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.CHECK_INVOICEURL_PASS,invoiceAndCheckBillSendEmailVO);
805 869 }
806 870  
807 871 OrderAuditLogDO auditLogDO = OrderAuditLogDO.builder().applyId(applyDO.getId()).orderId(applyDO.getOrderId()).optType(ApplyStatusEnum.AUDIT_PASS.getDesc()).build();
... ... @@ -917,4 +981,19 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
917 981  
918 982 return update(updateWrapper);
919 983 }
  984 +
  985 + @Override
  986 + public long countAllYearByOrderStatus(Integer applyType) {
  987 + return baseMapper.countAllYearByOrderStatus(applyType);
  988 + }
  989 +
  990 + @Override
  991 + public long countRecentMonthValueByOrderStatus(Integer applyType, LocalDate startOfYear, LocalDate endOfYear) {
  992 + return this.baseMapper.countRecentMonthValueByOrderStatus(applyType, startOfYear, endOfYear);
  993 + }
  994 +
  995 + @Override
  996 + public long countRecentDayvalueByOrderStatus(Integer applyType, LocalDate startDate, LocalDate endDate) {
  997 + return this.baseMapper.countRecentDayvalueByOrderStatus(applyType, startDate, endDate);
  998 + }
920 999 }
... ...
src/main/java/com/order/erp/service/order/impl/OrderInspectionStageServiceImpl.java
... ... @@ -17,6 +17,7 @@ import com.order.erp.service.order.OrderInspectionStageService;
17 17 import lombok.extern.slf4j.Slf4j;
18 18 import org.springframework.stereotype.Service;
19 19  
  20 +import java.time.LocalDate;
20 21 import java.util.List;
21 22 import java.util.Objects;
22 23  
... ... @@ -150,4 +151,20 @@ public class OrderInspectionStageServiceImpl extends ServiceImpl&lt;OrderInspection
150 151 public long countRecentMonthByOrderStatus(Integer status) {
151 152 return this.baseMapper.countRecentMonthByOrderStatus(status);
152 153 }
  154 +
  155 +
  156 + @Override
  157 + public long countRecentYearByOrderStatus(Integer status) {
  158 + return this.baseMapper.countRecentYearByOrderStatus(status);
  159 + }
  160 +
  161 + @Override
  162 + public long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear) {
  163 + return this.baseMapper.countRecentMonthValueByOrderStatus(status,startOfYear,endOfYear);
  164 + }
  165 +
  166 + @Override
  167 + public long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate) {
  168 + return this.baseMapper.countRecentDayvalueByOrderStatus(status,startDate,endDate);
  169 + }
153 170 }
... ...
src/main/java/com/order/erp/service/order/impl/OrderProfitAnalysisServiceImpl.java
... ... @@ -27,6 +27,7 @@ import org.springframework.stereotype.Service;
27 27  
28 28 import javax.annotation.Resource;
29 29 import java.math.BigDecimal;
  30 +import java.time.LocalDate;
30 31 import java.util.HashSet;
31 32 import java.util.List;
32 33 import java.util.Objects;
... ... @@ -243,14 +244,14 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly
243 244 productionDepartmentTotalPrice = productionDepartmentTotalPrice.add(new BigDecimal(orderProfit.getProductionDepartmentTotalPrice()));
244 245 }
245 246 List<OrderBaseInfoDO> orderBaseInfoDOS = orderBaseInfoService.listByIds(orderProfits.stream().map(OrderProfitAnalysisDO::getOrderId).collect(Collectors.toSet()));
246   - int orderTotalNum = 0;
247   - Set<String> innerNoSet = new HashSet<>();
248   - for (OrderBaseInfoDO orderBaseInfoDO : orderBaseInfoDOS) {
249   - if (Objects.nonNull(orderBaseInfoDO.getOrderCount())) {
250   - orderTotalNum += orderBaseInfoDO.getOrderCount();
251   - }
252   - innerNoSet.add(orderBaseInfoDO.getInnerNo());
253   - }
  247 + int orderTotalNum = orderBaseInfoDOS.stream()
  248 + .filter(orderBaseInfoDO -> Objects.nonNull(orderBaseInfoDO.getOrderCount()))
  249 + .mapToInt(OrderBaseInfoDO::getOrderCount)
  250 + .sum();
  251 +
  252 + Set<String> uniqueCombinations = orderBaseInfoDOS.stream()
  253 + .map(orderBaseInfoDO -> orderBaseInfoDO.getProjectNo() + "-" + orderBaseInfoDO.getInnerNo())
  254 + .collect(Collectors.toSet());
254 255 OrderProfitAnalysisVO profitAnalysisVO = new OrderProfitAnalysisVO();
255 256 profitAnalysisVO.setPacketTotalPrice(packetTotalPrice.doubleValue());
256 257 profitAnalysisVO.setCustomerTotalPrice(customerTotalPrice.doubleValue());
... ... @@ -262,7 +263,7 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly
262 263 .packetTotalPrice(packetTotalPrice.doubleValue())
263 264 .customerTotalPrice(customerTotalPrice.doubleValue()).build()));
264 265 profitAnalysisVO.setOrderTotalNum(orderTotalNum);
265   - profitAnalysisVO.setRecordNum(innerNoSet.size());
  266 + profitAnalysisVO.setRecordNum(uniqueCombinations.size());
266 267  
267 268 return ServerResult.success(profitAnalysisVO);
268 269 }
... ... @@ -277,4 +278,19 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly
277 278 public long countRecentWeekByOrderStatus(Integer status) {
278 279 return this.baseMapper.countRecentWeekByOrderStatus(status);
279 280 }
  281 +
  282 + @Override
  283 + public long countRecentYearByOrderStatus(Integer status) {
  284 + return this.baseMapper.countRecentYearByOrderStatus(status);
  285 + }
  286 +
  287 + @Override
  288 + public long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear) {
  289 + return this.baseMapper.countRecentMonthValueByOrderStatus(status,startOfYear,endOfYear);
  290 + }
  291 +
  292 + @Override
  293 + public long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate) {
  294 + return this.baseMapper.countRecentDayvalueByOrderStatus(status,startDate,endDate);
  295 + }
280 296 }
... ...
src/main/java/com/order/erp/service/order/impl/OrderTrackStageServiceImpl.java
... ... @@ -14,6 +14,7 @@ import com.order.erp.service.order.OrderTrackStageService;
14 14 import lombok.extern.slf4j.Slf4j;
15 15 import org.springframework.stereotype.Service;
16 16  
  17 +import java.time.LocalDate;
17 18 import java.util.List;
18 19 import java.util.Objects;
19 20  
... ... @@ -141,4 +142,19 @@ public class OrderTrackStageServiceImpl extends ServiceImpl&lt;OrderTrackStageMappe
141 142 .set(OrderTrackStageDO::getEnableFlag, Constant.UNABLE_TWENTY);
142 143 return update(updateWrapper);
143 144 }
  145 +
  146 + @Override
  147 + public long countRecentYearByOrderStatus(Integer status) {
  148 + return this.baseMapper.countRecentYearByOrderStatus(status);
  149 + }
  150 +
  151 + @Override
  152 + public long countRecentMonthValueByOrderStatus(Integer status, LocalDate startOfYear, LocalDate endOfYear) {
  153 + return this.baseMapper.countRecentMonthValueByOrderStatus(status,startOfYear,endOfYear);
  154 + }
  155 +
  156 + @Override
  157 + public long countRecentDayvalueByOrderStatus(Integer status, LocalDate startDate, LocalDate endDate) {
  158 + return this.baseMapper.countRecentDayvalueByOrderStatus(status,startDate,endDate);
  159 + }
144 160 }
... ...
src/main/java/com/order/erp/service/order/impl/ProducePaymentCheckBillOrderServiceImpl.java
... ... @@ -15,13 +15,11 @@ import com.order.erp.common.constant.ServerResult;
15 15 import com.order.erp.common.constant.ServerResultCode;
16 16 import com.order.erp.common.exception.BusinessException;
17 17 import com.order.erp.common.utils.DateUtils;
  18 +import com.order.erp.common.utils.EmailSendUtils;
18 19 import com.order.erp.common.utils.StringUtils;
19 20 import com.order.erp.common.utils.TransactionHelper;
20 21 import com.order.erp.config.DataScope;
21   -import com.order.erp.domain.ApplyStatusEnum;
22   -import com.order.erp.domain.ApplyTypeEnum;
23   -import com.order.erp.domain.FinanceEnum;
24   -import com.order.erp.domain.RoleEnum;
  22 +import com.order.erp.domain.*;
25 23 import com.order.erp.domain.dto.BaseDO;
26 24 import com.order.erp.domain.dto.SystemSettingDO;
27 25 import com.order.erp.domain.dto.order.*;
... ... @@ -33,6 +31,7 @@ import com.order.erp.service.order.*;
33 31 import lombok.extern.slf4j.Slf4j;
34 32 import org.apache.poi.ss.usermodel.*;
35 33 import org.apache.poi.ss.util.CellRangeAddress;
  34 +import org.apache.poi.util.IOUtils;
36 35 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
37 36 import org.springframework.beans.BeanUtils;
38 37 import org.springframework.stereotype.Service;
... ... @@ -40,6 +39,7 @@ import org.springframework.stereotype.Service;
40 39 import javax.annotation.Resource;
41 40 import javax.servlet.http.HttpServletResponse;
42 41 import java.io.IOException;
  42 +import java.io.InputStream;
43 43 import java.math.BigDecimal;
44 44 import java.math.RoundingMode;
45 45 import java.net.URLDecoder;
... ... @@ -81,6 +81,8 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
81 81 private TransactionHelper transactionHelper;
82 82 @Resource
83 83 private InvoiceBillOrderMapper invoiceBillOrderMapper;
  84 + @Resource
  85 + private EmailSendUtils emailSendUtils;
84 86  
85 87  
86 88 /**
... ... @@ -746,7 +748,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
746 748 */
747 749 private String calculatePayedDate(CheckHoldTimeItemVO checkHoldTimeItemVO) {
748 750 Integer holdDays = getHoldTimeByProductionDepartment(checkHoldTimeItemVO.getProductionDepartment());
749   - LocalDateTime holdTime = DateUtils.parse(checkHoldTimeItemVO.getHoldTime(), DateUtils.DATE_TIME).plusDays(holdDays);
  751 + LocalDateTime holdTime = DateUtils.parse(checkHoldTimeItemVO.getProductionDepartmentConsignTime(), DateUtils.DATE_TIME).plusDays(holdDays);
750 752 return DateUtils.format(holdTime, DateUtils.DATE);
751 753 }
752 754  
... ... @@ -777,12 +779,12 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
777 779 Map<String, OrderBaseInfoDO> holdTimeMap = new HashMap<String, OrderBaseInfoDO>();
778 780 String maxHoldTime = null;
779 781 for (OrderBaseInfoDO baseInfoDO : orderBaseInfoDOList) {
780   - if (StringUtils.isNotBlank(baseInfoDO.getOrderHodTime())) {
781   - holdTimeMap.put(baseInfoDO.getOrderHodTime(), baseInfoDO);
  782 + if (StringUtils.isNotBlank(baseInfoDO.getProductionDepartmentConsignTime())) {
  783 + holdTimeMap.put(baseInfoDO.getProductionDepartmentConsignTime(), baseInfoDO);
782 784 if (StringUtils.isBlank(maxHoldTime)) {
783   - maxHoldTime = baseInfoDO.getOrderHodTime();
784   - } else if (maxHoldTime.compareTo(baseInfoDO.getOrderHodTime()) <= 0) {
785   - maxHoldTime = baseInfoDO.getOrderHodTime();
  785 + maxHoldTime = baseInfoDO.getProductionDepartmentConsignTime();
  786 + } else if (maxHoldTime.compareTo(baseInfoDO.getProductionDepartmentConsignTime()) <= 0) {
  787 + maxHoldTime = baseInfoDO.getProductionDepartmentConsignTime();
786 788 }
787 789 }
788 790 }
... ... @@ -793,7 +795,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
793 795 if (holdTimeMap.containsKey(maxHoldTime)) {
794 796 OrderBaseInfoDO baseInfoDO = holdTimeMap.get(maxHoldTime);
795 797 itemVO.setProductionDepartment(baseInfoDO.getProductionDepartment());
796   - itemVO.setHoldTime(maxHoldTime);
  798 + itemVO.setProductionDepartmentConsignTime(maxHoldTime);
797 799 itemVO.setBaseInfoDO(baseInfoDO);
798 800 }
799 801 return itemVO;
... ... @@ -950,7 +952,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
950 952 throw new BusinessException("应付款单据不存在");
951 953 }
952 954 if(Objects.nonNull(checkBillOrderDO.getStatus()) && FinanceEnum.RECEIVED_PAYMENT.getStatus()==checkBillOrderDO.getStatus()){
953   - throw new BusinessException("已完成款,无法更新!");
  955 + throw new BusinessException("已完成款,无法更新!");
954 956 }
955 957 //todo 已完成。
956 958 // checkCommitApply(amountInfoVO.getId());
... ... @@ -1033,7 +1035,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1033 1035 }
1034 1036 boolean anyMatch = producePaymentCheckBillOrderDOList.stream().filter(Objects::nonNull).anyMatch(producePaymentCheckBillOrderDO -> FinanceEnum.RECEIVED_PAYMENT.getStatus().equals(producePaymentCheckBillOrderDO.getStatus()));
1035 1037 if(anyMatch){
1036   - throw new BusinessException("订单中包含已款的数据,无法提交!");
  1038 + throw new BusinessException("订单中包含已款的数据,无法提交!");
1037 1039 }
1038 1040 List<OrderBaseInfoDO> orderBaseInfoDOList = orderBaseInfoService.listByIds(producePaymentCheckBillOrderDOList.stream().filter(Objects::nonNull).map(producePaymentCheckBillOrderDO -> producePaymentCheckBillOrderDO.getOrderId()).collect(Collectors.toSet()));
1039 1041 //实际应付金额
... ... @@ -1044,6 +1046,8 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1044 1046 BigDecimal totalActualPayedAmount=BigDecimal.ZERO;
1045 1047 //未付金额
1046 1048 BigDecimal unPayedAmount=BigDecimal.ZERO;
  1049 + // 生产科总金额
  1050 + BigDecimal totalProductionAmount=BigDecimal.ZERO;
1047 1051 Long userId = dataScope.getLoginUserId();
1048 1052 String loginUserName = dataScope.getLoginUserName();
1049 1053 //todo 审核判断
... ... @@ -1060,7 +1064,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1060 1064 deductAmount=deductAmount.add(paymentCheckBillOrderDO.getDeductAmount()).setScale(2, BigDecimal.ROUND_HALF_UP);
1061 1065 totalActualPayedAmount=totalActualPayedAmount.add(paymentCheckBillOrderDO.getTotalActualPayedAmount()).setScale(2, BigDecimal.ROUND_HALF_UP);
1062 1066 unPayedAmount=unPayedAmount.add(paymentCheckBillOrderDO.getUnPayedAmount()).setScale(2, BigDecimal.ROUND_HALF_UP);
1063   -
  1067 + totalProductionAmount=totalProductionAmount.add(paymentCheckBillOrderDO.getTotalProductionAmount()).setScale(2,BigDecimal.ROUND_HALF_UP);
1064 1068 }
1065 1069 ProducePaymentCheckBillFieldVO producePaymentCheckBillFieldVO = ProducePaymentCheckBillFieldVO.builder().checkNo(producePaymentCheckBillOrderDOS.get(0).getCheckNo())
1066 1070 .producePaymentCheckBillId(producePaymentCheckBillOrderDOS.stream().filter(Objects::nonNull).map(ProducePaymentCheckBillOrderDO::getId).collect(Collectors.toList()))
... ... @@ -1075,12 +1079,29 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1075 1079 .deductAmount(deductAmount)
1076 1080 .actualPayedAmount(actualPayedAmount)
1077 1081 .totalActualPayedAmount(totalActualPayedAmount)
1078   - .unPayedAmount(unPayedAmount).build();
1079   - OrderFieldLockApplyDO applyDO = initOrderFieldLockApplyDO(producePaymentCheckBillFieldVO, userId);
  1082 + .unPayedAmount(unPayedAmount)
  1083 + .projectNo(orderBaseInfoDOList.stream().filter(Objects::nonNull).map(orderBaseInfoDO -> orderBaseInfoDO.getProjectNo()).distinct().collect(Collectors.toList())).build();
  1084 + OrderFieldLockApplyDO applyDO;
  1085 + //在这里判断。 是否自动通过。 总金额-总扣款=总实际付款金额
  1086 + if(totalProductionAmount.subtract(deductAmount).setScale(2, BigDecimal.ROUND_HALF_UP).compareTo(totalActualPayedAmount)==0){
  1087 + applyDO= initOrderFieldLockApplyDO(producePaymentCheckBillFieldVO, userId,true);
  1088 + //设置状态。
  1089 + producePaymentCheckBillOrderDOS.stream().filter(Objects::nonNull).forEach(x->x.setStatus(FinanceEnum.RECEIVED_PAYMENT.getStatus()));
  1090 + //设置订单状态。
  1091 + orderBaseInfoDOList.stream().filter(Objects::nonNull).forEach(x->x.setCheckStatus(FinanceEnum.RECEIVED_PAYMENT.getStatus()));
  1092 + //发送邮箱通知财务。 这里这个邮箱通知财务,只能提示invoice号,因为一个invoice申请对应多个invoice号,所以会有多个内部编号和项目号等。
  1093 + InvoiceAndCheckBillSendEmailVO invoiceAndCheckBillSendEmailVO = new InvoiceAndCheckBillSendEmailVO();
  1094 + invoiceAndCheckBillSendEmailVO.setCheckBillOrderDO(producePaymentCheckBillOrderDOS.get(0));
  1095 + emailSendUtils.sendInvoiceAndCheckEmail(FinanceOverEnum.CHECK_PASS,invoiceAndCheckBillSendEmailVO);
  1096 + }else{
  1097 + applyDO = initOrderFieldLockApplyDO(producePaymentCheckBillFieldVO, userId,false);
  1098 + }
  1099 +
1080 1100 transactionHelper.run(() -> {
1081 1101 orderFieldLockApplyService.save(applyDO);
1082 1102 // checkBillOrderDO.setActualPayedDate(DateUtils.format(LocalDateTime.now(), DateUtils.DATE));
1083 1103 updateBatchById(producePaymentCheckBillOrderDOS);
  1104 + orderBaseInfoService.updateBatchById(orderBaseInfoDOList);
1084 1105 });
1085 1106 return ServerResult.success();
1086 1107 }
... ... @@ -1090,10 +1111,16 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1090 1111 * @param userId
1091 1112 * @return
1092 1113 */
1093   - private OrderFieldLockApplyDO initOrderFieldLockApplyDO(ProducePaymentCheckBillFieldVO producePaymentCheckBillFieldVO, Long userId) {
  1114 + private OrderFieldLockApplyDO initOrderFieldLockApplyDO(ProducePaymentCheckBillFieldVO producePaymentCheckBillFieldVO, Long userId,boolean isTrue) {
1094 1115 OrderLockFieldVO lockFieldVO = new OrderLockFieldVO();
1095 1116 lockFieldVO.setProducePaymentCheckBillFieldVO(producePaymentCheckBillFieldVO);
1096 1117 List<Long> financeIds= producePaymentCheckBillFieldVO.getProducePaymentCheckBillId().subList(1, producePaymentCheckBillFieldVO.getProducePaymentCheckBillId().size());
  1118 + Integer status;
  1119 + if(isTrue){
  1120 + status=ApplyStatusEnum.AUDIT_PASS.getStatus();
  1121 + }else{
  1122 + status=ApplyStatusEnum.WAIT_AUDIT.getStatus();
  1123 + }
1097 1124 if(producePaymentCheckBillFieldVO.getProducePaymentCheckBillId().size()>1){
1098 1125 //针对于财务多个订单提交审核来创建的。
1099 1126 return OrderFieldLockApplyDO.builder()
... ... @@ -1104,7 +1131,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1104 1131 .financeId(null == financeIds || financeIds.isEmpty() ? "" : financeIds.stream().map(String::valueOf).collect(Collectors.joining(","))) //英文逗号
1105 1132 .type(ApplyTypeEnum.CHECK_BILL_APPLY.getType())
1106 1133 .remark(ApplyTypeEnum.CHECK_BILL_APPLY.getDesc())
1107   - .status(ApplyStatusEnum.WAIT_AUDIT.getStatus())
  1134 + .status(status)
1108 1135 //这里设置审核角色有财务并不是让财务审核,会对财务屏蔽审核按钮,只是让它能够看到审核的单子
1109 1136 .auditRoleCodes(RoleEnum.ADMIN.getCode() + Constant.COMMA_CHARACTER + RoleEnum.FINANCE_USER.getCode())
1110 1137 .build();
... ... @@ -1116,7 +1143,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1116 1143 .orderId(producePaymentCheckBillFieldVO.getProducePaymentCheckBillId().get(0))
1117 1144 .type(ApplyTypeEnum.CHECK_BILL_APPLY.getType())
1118 1145 .remark(ApplyTypeEnum.CHECK_BILL_APPLY.getDesc())
1119   - .status(ApplyStatusEnum.WAIT_AUDIT.getStatus())
  1146 + .status(status)
1120 1147 //这里设置审核角色有财务并不是让财务审核,会对财务屏蔽审核按钮,只是让它能够看到审核的单子
1121 1148 .auditRoleCodes(RoleEnum.ADMIN.getCode() + Constant.COMMA_CHARACTER + RoleEnum.FINANCE_USER.getCode())
1122 1149 .build();
... ... @@ -1203,7 +1230,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1203 1230 }
1204 1231 boolean anyPaid = checkBillOrderDOS.stream().anyMatch(checkBillOrderDO -> FinanceEnum.RECEIVED_PAYMENT.getStatus() == checkBillOrderDO.getStatus());
1205 1232 if(anyPaid) {
1206   - throw new BusinessException("包含已款的订单,无法删除!");
  1233 + throw new BusinessException("包含已款的订单,无法删除!");
1207 1234 }
1208 1235 //todo 审核有点问题。审核时是是哪个orderid共用一个orderid作为id,查询的时候是只能查询到第一个。 已完成。
1209 1236 checkApply(ids);
... ... @@ -1238,9 +1265,6 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1238 1265 return ServerResult.fail("扣款单未上传!");
1239 1266 }
1240 1267 Map<String, String> hashMap = new HashMap<>();
1241   - if(StringUtils.isBlank(checkBillOrderDO.getDeductUrl())){
1242   - return ServerResult.success();
1243   - }
1244 1268 //获取每一个url的文件名称
1245 1269 Arrays.stream(checkBillOrderDO.getDeductUrl().split(",")).forEach(x->{
1246 1270 try{
... ... @@ -1300,7 +1324,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1300 1324 throw new BusinessException("生产科对账单不存在!");
1301 1325 }
1302 1326 if(FinanceEnum.RECEIVED_PAYMENT.getStatus()==checkBillOrderDO.getStatus()){
1303   - throw new BusinessException("已完成款,无法修改!");
  1327 + throw new BusinessException("已完成款,无法修改!");
1304 1328 }
1305 1329 //todo 要审核判断一下,判断是否处于审核状态。 已完成。
1306 1330 checkApply(new ArrayList<>(Arrays.asList(createVO.getId())));
... ... @@ -1316,7 +1340,7 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1316 1340 }
1317 1341 ProducePaymentCheckBillOrderDO producePaymentCheckBillOrderDO = getById(createVO.getId());
1318 1342 if(Objects.isNull(producePaymentCheckBillOrderDO)){
1319   - throw new BusinessException("应收款单不存在!");
  1343 + throw new BusinessException("生产科对账单不存在!");
1320 1344 }
1321 1345 //备注信息,审核完应该也能修改。
1322 1346 producePaymentCheckBillOrderDO.setNotes(createVO.getNotes());
... ... @@ -1325,7 +1349,25 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1325 1349 }
1326 1350  
1327 1351 @Override
1328   - public ServerResult exportReceipt(HttpServletResponse response,ProducePaymentCheckBillOrderDO queryVO) throws IOException {
  1352 + public ServerResult deleteDeductUrlById(ProducePaymentCheckBillDeductInfoVO deleteVo) {
  1353 + if(Objects.isNull(deleteVo.getId())){
  1354 + return ServerResult.fail();
  1355 + }
  1356 + ProducePaymentCheckBillOrderDO producePaymentCheckBillOrderDO = getById(deleteVo.getId());
  1357 + if(Objects.isNull(producePaymentCheckBillOrderDO)){
  1358 + throw new BusinessException("生产科对账单不存在!");
  1359 + }
  1360 + checkApply(new ArrayList<>(Arrays.asList(deleteVo.getId())));
  1361 + if(FinanceEnum.RECEIVED_PAYMENT.getStatus()==producePaymentCheckBillOrderDO.getStatus()){
  1362 + throw new BusinessException("已完成付款,无法修改!");
  1363 + }
  1364 + producePaymentCheckBillOrderDO.setDeductUrl("");
  1365 + updateById(producePaymentCheckBillOrderDO);
  1366 + return ServerResult.success();
  1367 + }
  1368 +
  1369 + @Override
  1370 + public ServerResult exportReceipt(HttpServletResponse response,CheckBillExportReceiptVO queryVO) throws IOException {
1329 1371 XSSFWorkbook workbook = new XSSFWorkbook();
1330 1372 Sheet sheet = workbook.createSheet("付款单");
1331 1373 Row row = sheet.createRow(0);
... ... @@ -1352,7 +1394,10 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1352 1394 cell2.setCellValue("提交人:"+(StringUtils.isNotBlank(queryVO.getTrackerUser()) ? queryVO.getTrackerUser() : ""));
1353 1395 sheet.addMergedRegion(new CellRangeAddress(3, 4, 0, 1));
1354 1396 Cell cell3 = row2.createCell(2);
1355   - cell3.setCellValue("");
  1397 + //需要前端传递项目号projectNo 作用:导出单子时添加项目号 invoice对应的是收款单,check对应的是付款单。
  1398 + cell3.setCellValue("项目号:" + (queryVO.getProjectNo() != null && !queryVO.getProjectNo().isEmpty()
  1399 + ? String.join(",", queryVO.getProjectNo())
  1400 + : ""));
1356 1401 sheet.addMergedRegion(new CellRangeAddress(3, 4, 2, 7));
1357 1402 Cell cell4 = row2.createCell(8);
1358 1403 /* if(StringUtils.isNotBlank(queryVO.getActualPayedDate())){
... ... @@ -1387,6 +1432,24 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
1387 1432 createMergedCell(sheet, workbook, 11, 0, 11, 13, 0, 1, "");
1388 1433 createMergedCell(sheet, workbook, 11, 2, 11, 13, 2, 4, "");
1389 1434 createMergedCell(sheet, workbook, 11, 5, 11, 13, 5, 7, "");
  1435 + if(ApplyStatusEnum.AUDIT_PASS.getStatus().equals(queryVO.getStatus()) && ApplyTypeEnum.CHECK_BILL_APPLY.getType().equals(queryVO.getType())){
  1436 + // 插入图片到总经理审核下面的单元格
  1437 + InputStream is = this.getClass().getClassLoader().getResourceAsStream("images/sign.png"); // 假设图片在 resources/static 目录下
  1438 + byte[] bytes = IOUtils.toByteArray(is);
  1439 + int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
  1440 + is.close();
  1441 +
  1442 + Drawing<?> drawing = sheet.createDrawingPatriarch();
  1443 + ClientAnchor anchor = workbook.getCreationHelper().createClientAnchor();
  1444 +// 设置图片位置和大小(行列号对应“总经理审核”下的单元格范围)
  1445 + anchor.setCol1(5); // 起始列:总经理审核格子开始列
  1446 + anchor.setRow1(10); // 起始行:总经理审核格子开始行
  1447 + anchor.setCol2(8); // 结束列:总经理审核格子结束列
  1448 + anchor.setRow2(15); // 结束行:总经理审核格子结束行
  1449 + Picture picture = drawing.createPicture(anchor, pictureIdx);
  1450 +// 如果图片仍然过大,调整缩放比例
  1451 + picture.resize(1.1); // 调整为 80% 的大小
  1452 + }
1390 1453 createMergedCell(sheet, workbook, 11, 8, 11, 13, 8, 9, "");
1391 1454 //第七行
1392 1455 createMergedCell(sheet, workbook, 14, 0, 14, 15, 0, 4, "收款人");
... ...
src/main/resources/application.yml
... ... @@ -3,4 +3,4 @@ server:
3 3  
4 4 spring:
5 5 profiles:
6   - active: test
7 6 \ No newline at end of file
  7 + active: pre-prod
8 8 \ No newline at end of file
... ...
src/main/resources/images/sign.png 0 → 100644

253 KB

src/main/resources/mapper/InvoiceBillOrderMapper.xml
... ... @@ -74,6 +74,7 @@
74 74 o.inner_no AS innerNo, -- 内部编号
75 75 o.small_pic_url AS smallPicUrl, -- 订单图片
76 76 o.order_count AS orderCount, -- 数量
  77 + o.modele_lo AS modeleLo,
77 78 o.production_department_consign_time AS productionDepartmentConsignTime, -- 生产科拖货时间
78 79 o.order_hod_time AS orderHodTime, -- hod时间
79 80 -- 利润信息
... ...
src/main/resources/mapper/OrderBaseInfoMapper.xml
... ... @@ -6,13 +6,104 @@
6 6 SELECT DISTINCT project_no
7 7 FROM order_base_info
8 8 WHERE enable_flag = 10
9   - AND project_no like concat(#{dto.projectNo},'%')
  9 + AND project_no like concat('%',#{dto.projectNo},'%')
10 10 </if>
11 11 <if test="flag == false">
12 12 SELECT DISTINCT inner_no
13 13 FROM order_base_info
14 14 WHERE enable_flag = 10
15   - AND inner_no like concat(#{dto.innerNo},'%')
  15 + AND inner_no like concat('%',#{dto.innerNo},'%')
16 16 </if>
17 17 </select>
  18 + <select id="salesAmountStatistics" resultType="java.lang.Double">
  19 + SELECT SUM(opa.customer_total_price) AS total_price
  20 + FROM order_base_info obi
  21 + JOIN order_profit_analysis opa ON opa.order_id = obi.id and opa.enable_flag = 10
  22 + WHERE obi.enable_flag = 10 <!-- 用于动态添加条件 -->
  23 + <!-- 动态添加 customer_code 条件 -->
  24 + <if test="customerCodeIn != null and customerCodeIn.size() > 0">
  25 + AND customer_code IN
  26 + <foreach collection="customerCodeIn" item="item" open="(" separator="," close=")">
  27 + #{item}
  28 + </foreach>
  29 + </if>
  30 +
  31 + <!-- 动态添加 create_time 范围条件 -->
  32 + <if test="begin != null">
  33 + AND obi.create_time >= #{begin}
  34 + </if>
  35 + <if test="end != null">
  36 + AND obi.create_time <![CDATA[ <= ]]> #{end}
  37 + </if>
  38 + </select>
  39 + <select id="salesAmountTarget" resultType="java.lang.Double">
  40 + SELECT SUM(relation_value) AS total_value
  41 + FROM system_setting
  42 + WHERE relation_code = 'salesAmount'
  43 + and enable_flag = 10
  44 + <!-- 动态添加 setting_name 条件 -->
  45 + <if test="customerCodeIn != null and customerCodeIn.size() > 0">
  46 + AND setting_value IN
  47 + <foreach collection="customerCodeIn" item="item" open="(" separator="," close=")">
  48 + #{item}
  49 + </foreach>
  50 + </if>
  51 + </select>
  52 +
  53 + <resultMap id="mapResult" type="map">
  54 + <result property="key" column="k"/>
  55 + <result property="value" column="v"/>
  56 + </resultMap>
  57 + <select id="customerSalesStatus" resultMap="mapResult">
  58 + SELECT
  59 + obi.customer_code AS k,
  60 + SUM(opa.customer_total_price) AS v
  61 + FROM
  62 + order_base_info obi
  63 + JOIN
  64 + order_profit_analysis opa ON opa.order_id = obi.id AND opa.enable_flag = 10
  65 + WHERE
  66 + obi.enable_flag = 10
  67 + <if test="customerCodeIn != null and customerCodeIn.size() > 0">
  68 + AND obi.customer_code IN
  69 + <foreach item="item" index="index" collection="customerCodeIn" open="(" separator="," close=")">
  70 + #{item}
  71 + </foreach>
  72 + </if>
  73 + <if test="begin != null">
  74 + AND obi.create_time >= #{begin}
  75 + </if>
  76 + <if test="end != null">
  77 + AND obi.create_time <![CDATA[ <= ]]> #{end}
  78 + </if>
  79 + GROUP BY
  80 + obi.customer_code
  81 + </select>
  82 +
  83 +
  84 + <select id="countRecentMonthValueByOrderStatus" resultType="com.order.erp.domain.vo.order.DateYearMonthTimeVO">
  85 + SELECT
  86 + DATE_FORMAT(obi.create_time, '%Y-%m') AS date,
  87 + SUM(opa.customer_total_price) AS totalPrice,
  88 + YEAR(obi.create_time) AS yearType
  89 + FROM
  90 + order_base_info obi
  91 + JOIN
  92 + order_profit_analysis opa
  93 + ON
  94 + opa.order_id = obi.id
  95 + AND opa.enable_flag = 10
  96 + WHERE
  97 + obi.enable_flag = 10
  98 + AND YEAR(obi.create_time) IN
  99 + <foreach item="year" collection="years" open="(" close=")" separator=",">
  100 + #{year}
  101 + </foreach>
  102 + GROUP BY
  103 + DATE_FORMAT(obi.create_time, '%Y-%m'),
  104 + YEAR(obi.create_time)
  105 + ORDER BY
  106 + date;
  107 + </select>
  108 +
18 109 </mapper>
... ...