Commit f2c66bb253e3eeb4ac4ac6d20783dfec96a59612

Authored by yeqianyong
1 parent 503fbed3

楚江erp: 1、发货明细报表数据生成接口开发;2、发货单增加是否准时发货逻辑;3、应收款台账数据生成时机调整;4、自动生成发货明细统计数据接口开发(用于处理历史数据)

... ... @@ -4,11 +4,9 @@ import com.lframework.starter.mq.core.utils.ExportTaskUtil;
4 4 import com.lframework.xingyun.sc.bo.statistics.shipmentDetail.QueryShipmentDetailStatisticsBo;
5 5 import com.lframework.xingyun.sc.enums.ExportType;
6 6 import com.lframework.xingyun.sc.excel.statistics.ShipmentDetailReportExportTaskWorker;
7   -import com.lframework.xingyun.sc.vo.ledger.receipt.ReceiptLedgerReportVo;
8 7 import com.lframework.xingyun.sc.vo.statistics.shipmentDetail.QueryShipmentDetailStatisticsVo;
9 8 import com.lframework.xingyun.sc.service.statistics.ShipmentDetailStatisticsService;
10 9 import com.lframework.xingyun.sc.vo.statistics.shipmentDetail.CreateShipmentDetailStatisticsVo;
11   -import com.lframework.xingyun.sc.vo.statistics.shipmentDetail.UpdateShipmentDetailStatisticsVo;
12 10 import com.lframework.xingyun.sc.entity.ShipmentDetailStatistics;
13 11 import com.lframework.starter.web.core.utils.PageResultUtil;
14 12 import com.lframework.starter.web.core.components.resp.PageResult;
... ... @@ -45,7 +43,7 @@ public class ShipmentDetailStatisticsController extends DefaultBaseController {
45 43 * 查询列表
46 44 */
47 45 @ApiOperation("查询列表")
48   - @HasPermission({"statistics:shipmentDetail:query"})
  46 + @HasPermission({"statistical-report:delivery-detail:query"})
49 47 @GetMapping("/query")
50 48 public InvokeResult<PageResult<QueryShipmentDetailStatisticsBo>> query(@Valid QueryShipmentDetailStatisticsVo vo) {
51 49
... ... @@ -63,7 +61,7 @@ public class ShipmentDetailStatisticsController extends DefaultBaseController {
63 61 * 新增
64 62 */
65 63 @ApiOperation("新增")
66   - @HasPermission({"statistics:shipmentDetail:add"})
  64 + @HasPermission({"statistical-report:delivery-detail:add"})
67 65 @PostMapping
68 66 public InvokeResult<Void> create(@RequestBody CreateShipmentDetailStatisticsVo vo) {
69 67
... ... @@ -73,23 +71,10 @@ public class ShipmentDetailStatisticsController extends DefaultBaseController {
73 71 }
74 72
75 73 /**
76   - * 修改
77   - */
78   - @ApiOperation("修改")
79   - @HasPermission({"statistics:shipmentDetail:modify"})
80   - @PutMapping
81   - public InvokeResult<Void> update(@Valid UpdateShipmentDetailStatisticsVo vo) {
82   -
83   - shipmentDetailStatisticsService.update(vo);
84   -
85   - return InvokeResultBuilder.success();
86   - }
87   -
88   - /**
89 74 * 查询发货明细数据
90 75 */
91 76 @ApiOperation("查询发货明细数据")
92   - @HasPermission({"statistics:shipmentDetail:add"})
  77 + @HasPermission({"statistical-report:delivery-detail:add"})
93 78 @GetMapping("/queryShipmentDetail")
94 79 public InvokeResult<PageResult<ShipmentDetailStatistics>> queryShipmentDetail(QueryShipmentDetailStatisticsVo vo) {
95 80 return InvokeResultBuilder.success(shipmentDetailStatisticsService.pageShipmentDetail(getPageIndex(vo), getPageSize(vo), vo));
... ... @@ -99,11 +84,23 @@ public class ShipmentDetailStatisticsController extends DefaultBaseController {
99 84 * 发货明细导出
100 85 */
101 86 @ApiOperation("发货明细导出")
102   - @HasPermission({"statistics:shipmentDetail:export"})
  87 + @HasPermission({"statistical-report:delivery-detail:export"})
103 88 @GetMapping("/export")
104 89 public InvokeResult<Void> export(@Valid QueryShipmentDetailStatisticsVo vo) {
105 90 vo.setExportType(ExportType.SHIPMENT_DETAIL_REPORT.getCode());
106 91 ExportTaskUtil.exportTask("发货明细报表", ShipmentDetailReportExportTaskWorker.class, vo);
107 92 return InvokeResultBuilder.success();
108 93 }
  94 +
  95 +
  96 + /**
  97 + * 自动生成发货明细统计数据
  98 + * 主要用于处理历史数据
  99 + */
  100 + @ApiOperation("自动生成发货明细统计数据")
  101 + @GetMapping("/autoGenerate")
  102 + public InvokeResult<Void> autoGenerate() {
  103 + shipmentDetailStatisticsService.autoGenerate();
  104 + return InvokeResultBuilder.success();
  105 + }
109 106 }
... ...
... ... @@ -276,6 +276,11 @@ public class ShipmentDetailStatistics extends BaseEntity implements BaseDto, Exc
276 276 private String customerType;
277 277
278 278 /**
  279 + * 是否系统自动生成
  280 + */
  281 + private Boolean autoGenerate;
  282 +
  283 + /**
279 284 * 创建人ID
280 285 */
281 286 @TableField(fill = FieldFill.INSERT)
... ...
... ... @@ -125,6 +125,17 @@ public class ShipmentsOrderInfo extends BaseEntity implements BaseDto {
125 125 private String status;
126 126
127 127 /**
  128 + * 是否当日发货
  129 + */
  130 + private Boolean onTimeShipment;
  131 +
  132 + /**
  133 + * 新发货日期
  134 + * 仅在 onTimeShipment = false 时,需要填写
  135 + */
  136 + private LocalDate newShipmentDate;
  137 +
  138 + /**
128 139 * 发货明细数据
129 140 */
130 141 @TableField(exist = false)
... ...
1 1 package com.lframework.xingyun.sc.excel.statistics;
2 2
3 3 import com.alibaba.excel.annotation.ExcelProperty;
4   -import com.fasterxml.jackson.annotation.JsonFormat;
5   -import com.lframework.starter.common.constants.StringPool;
6 4 import com.lframework.starter.web.core.components.excel.ExcelModel;
7 5 import lombok.Data;
8 6
9 7 import java.math.BigDecimal;
10   -import java.time.LocalDate;
11 8
12 9 /**
13 10 * <p>
... ... @@ -184,8 +181,7 @@ public class ShipmentDetailStatisticsModel implements ExcelModel {
184 181 * 订货日期
185 182 */
186 183 @ExcelProperty("订货日期")
187   - @JsonFormat(pattern = StringPool.DATE_PATTERN)
188   - private LocalDate orderDate;
  184 + private String orderDate;
189 185
190 186 /**
191 187 * 包装费
... ... @@ -245,8 +241,7 @@ public class ShipmentDetailStatisticsModel implements ExcelModel {
245 241 * 发货日期
246 242 */
247 243 @ExcelProperty("发货日期")
248   - @JsonFormat(pattern = StringPool.DATE_PATTERN)
249   - private LocalDate shipmentDate;
  244 + private String shipmentDate;
250 245
251 246 /**
252 247 * 发货行业
... ...
... ... @@ -34,6 +34,7 @@ import com.lframework.xingyun.sc.service.order.PurchaseOrderLineService;
34 34 import com.lframework.xingyun.sc.service.shipments.ShipmentsOrderInfoService;
35 35 import com.lframework.xingyun.sc.service.shipments.ShipmentsPlanDetailService;
36 36 import com.lframework.xingyun.sc.service.shipments.car.DraftRequestCarTicketService;
  37 +import com.lframework.xingyun.sc.service.statistics.ShipmentDetailStatisticsService;
37 38 import com.lframework.xingyun.sc.utils.CommonUtil;
38 39 import com.lframework.xingyun.sc.vo.ledger.receipt.*;
39 40 import lombok.extern.slf4j.Slf4j;
... ... @@ -88,6 +89,8 @@ public class ReceiptLedgerInfoServiceImpl extends BaseMpServiceImpl<ReceiptLedge
88 89 private DraftRequestCarTicketService draftRequestCarTicketService;
89 90 @Resource
90 91 private FundOrderingUnitDetailService fundOrderingUnitDetailService;
  92 + @Resource
  93 + private ShipmentDetailStatisticsService shipmentDetailStatisticsService;
91 94
92 95
93 96 // 定义状态优先级顺序(从高到低)
... ... @@ -765,22 +768,18 @@ public class ReceiptLedgerInfoServiceImpl extends BaseMpServiceImpl<ReceiptLedge
765 768 @Override
766 769 @Transactional(rollbackFor = Exception.class)
767 770 public void autoGenerate() {
768   - List<String> statusList = new ArrayList<>();
769   - statusList.add("SHIPMENTS");
770   - statusList.add("DELIVERED");
771   - LambdaQueryWrapper<ShipmentsOrderInfo> queryWrapper = Wrappers.lambdaQuery(ShipmentsOrderInfo.class);
772   - queryWrapper.eq(ShipmentsOrderInfo::getShipmentsDate, LocalDate.now())
773   - .in(ShipmentsOrderInfo::getStatus, statusList);
774   - List<ShipmentsOrderInfo> shipmentsOrderInfos = shipmentsOrderInfoService.getBaseMapper().selectList(queryWrapper);
  771 + List<ShipmentsOrderInfo> shipmentsOrderInfos = shipmentsOrderInfoService.queryByShipmentDate(LocalDate.now());
775 772 if (CollectionUtils.isEmpty(shipmentsOrderInfos)) {
776 773 log.info("========================== 没有需要生成台账数据的发货单!");
777 774 return;
778 775 }
779 776 List<String> shipmentOrderIds = shipmentsOrderInfos.stream().map(ShipmentsOrderInfo::getId).collect(Collectors.toList());
  777 + List<String> detailIds = new ArrayList<>();
780 778 Map<String, List<ShipmentsPlanDetail>> shipmentDetailMap = new HashMap<>();
781 779 // 获取发货明细数据
782 780 List<ShipmentsPlanDetail> detailList = shipmentsPlanDetailService.listByShipmentOrderId(shipmentOrderIds);
783 781 for (ShipmentsPlanDetail detail : detailList) {
  782 + detailIds.add(detail.getId());
784 783 String shipmentOrderId = detail.getShipmentOrderId();
785 784 List<ShipmentsPlanDetail> list = shipmentDetailMap.computeIfAbsent(shipmentOrderId, k -> new ArrayList<>());
786 785 list.add(detail);
... ... @@ -792,6 +791,8 @@ public class ReceiptLedgerInfoServiceImpl extends BaseMpServiceImpl<ReceiptLedge
792 791 orderInfo.setDetailList(shipmentDetails);
793 792 }
794 793 generateLedgerInfo(shipmentsOrderInfos);
  794 + // 生成发货明细报表数据
  795 + shipmentDetailStatisticsService.generateStatisticsData(detailIds);
795 796 }
796 797
797 798 @Override
... ...
... ... @@ -286,13 +286,7 @@ public class ShipmentsOrderInfoServiceImpl extends BaseMpServiceImpl<ShipmentsOr
286 286 throw new DefaultClientException("发货单不存在!");
287 287 }
288 288 LambdaUpdateWrapper<ShipmentsOrderInfo> updateWrapper = Wrappers.lambdaUpdate(ShipmentsOrderInfo.class)
289   - .set(ShipmentsOrderInfo::getPlanId, vo.getPlanId())
290   - .set(ShipmentsOrderInfo::getCustomerId, vo.getCustomerId())
291   - .set(ShipmentsOrderInfo::getWorkshopId, vo.getWorkshopId())
292   - .set(ShipmentsOrderInfo::getShipmentsDate, vo.getShipmentsDate())
293   - .set(ShipmentsOrderInfo::getDeptId, vo.getDeptId())
294   - .set(ShipmentsOrderInfo::getDeliveryType, vo.getDeliveryType())
295   - .set(ShipmentsOrderInfo::getDestination, vo.getDestination())
  289 + .set(vo.getNewShipmentDate() != null, ShipmentsOrderInfo::getNewShipmentDate, vo.getNewShipmentDate())
296 290 .eq(ShipmentsOrderInfo::getId, vo.getId());
297 291
298 292 getBaseMapper().update(updateWrapper);
... ... @@ -385,6 +379,11 @@ public class ShipmentsOrderInfoServiceImpl extends BaseMpServiceImpl<ShipmentsOr
385 379 if (orderInfo == null) {
386 380 throw new DefaultClientException("发货单不存在!");
387 381 }
  382 + LambdaUpdateWrapper<ShipmentsOrderInfo> updateWrapper = Wrappers.lambdaUpdate(ShipmentsOrderInfo.class);
  383 + updateWrapper.set(ShipmentsOrderInfo::getOnTimeShipment, vo.getOnTimeShipment())
  384 + .eq(ShipmentsOrderInfo::getId, shipmentsOrderId);
  385 + getBaseMapper().update(updateWrapper);
  386 +
388 387 List<ShipmentsOrderDetailVo> detailList = vo.getDetailList();
389 388 if (CollectionUtils.isEmpty(detailList)) {
390 389 return;
... ... @@ -460,7 +459,7 @@ public class ShipmentsOrderInfoServiceImpl extends BaseMpServiceImpl<ShipmentsOr
460 459 // 判断当前日期是否大于等于发货日期
461 460 LocalDate now = LocalDate.now();
462 461 LocalDate shipmentsDate = orderInfo.getShipmentsDate();
463   - if (!now.isBefore(shipmentsDate)) {
  462 + if (BooleanUtils.isTrue(vo.getOnTimeShipment()) && !now.isBefore(shipmentsDate)) {
464 463 // 生成应收款台账明细数据
465 464 receiptLedgerInfoService.generateLedgerInfo(Collections.singletonList(orderInfo));
466 465 }
... ... @@ -632,6 +631,50 @@ public class ShipmentsOrderInfoServiceImpl extends BaseMpServiceImpl<ShipmentsOr
632 631 return result;
633 632 }
634 633
  634 + @Override
  635 + public List<ShipmentsOrderInfo> queryByShipmentDate(LocalDate shipmentDate) {
  636 + List<String> statusList = new ArrayList<>();
  637 + statusList.add("SHIPMENTS");
  638 + statusList.add("DELIVERED");
  639 + LambdaQueryWrapper<ShipmentsOrderInfo> queryWrapper = Wrappers.lambdaQuery(ShipmentsOrderInfo.class);
  640 + queryWrapper.in(ShipmentsOrderInfo::getStatus, statusList);
  641 + if (shipmentDate != null) {
  642 + LocalDate finalShipmentDate = shipmentDate;
  643 + queryWrapper.and(wrapper -> wrapper
  644 + .eq(ShipmentsOrderInfo::getShipmentsDate, finalShipmentDate)
  645 + .or()
  646 + .eq(ShipmentsOrderInfo::getNewShipmentDate, finalShipmentDate));
  647 + } else {
  648 + // 今天或之前的数据
  649 + shipmentDate = LocalDate.now();
  650 + queryWrapper.and(wrapper -> wrapper
  651 + .le(ShipmentsOrderInfo::getShipmentsDate, LocalDate.now())
  652 + .or()
  653 + .le(ShipmentsOrderInfo::getNewShipmentDate, LocalDate.now()));
  654 + }
  655 + List<ShipmentsOrderInfo> shipmentsOrderInfos = getBaseMapper().selectList(queryWrapper);
  656 + if (CollectionUtils.isEmpty(shipmentsOrderInfos)) {
  657 + return Collections.emptyList();
  658 + }
  659 + // 过滤掉不符合条件的数据
  660 + Iterator<ShipmentsOrderInfo> iterator = shipmentsOrderInfos.iterator();
  661 + while (iterator.hasNext()) {
  662 + ShipmentsOrderInfo next = iterator.next();
  663 + Boolean onTimeShipment = next.getOnTimeShipment();
  664 + if (BooleanUtils.isFalse(onTimeShipment)) {
  665 + LocalDate newShipmentDate = next.getNewShipmentDate();
  666 + if (newShipmentDate == null || newShipmentDate.isAfter(shipmentDate)) {
  667 + iterator.remove();
  668 + }
  669 + } else {
  670 + if (next.getShipmentsDate().isAfter(shipmentDate)) {
  671 + iterator.remove();
  672 + }
  673 + }
  674 + }
  675 + return shipmentsOrderInfos;
  676 + }
  677 +
635 678
636 679 /**
637 680 * 处理批次数据
... ...
1 1 package com.lframework.xingyun.sc.impl.statistics;
2 2
3   -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 4 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
5 5 import com.github.pagehelper.PageInfo;
6 6 import com.lframework.starter.web.inner.entity.SysDataDicItem;
... ... @@ -19,20 +19,21 @@ import com.lframework.starter.web.core.impl.BaseMpServiceImpl;
19 19 import com.lframework.starter.web.core.utils.PageResultUtil;
20 20 import com.lframework.starter.web.core.components.resp.PageResult;
21 21 import com.lframework.starter.web.core.utils.OpLogUtil;
22   -import com.lframework.starter.common.exceptions.impl.DefaultClientException;
23 22 import com.lframework.starter.web.core.utils.IdUtil;
24   -import com.lframework.starter.common.utils.ObjectUtil;
25 23 import com.lframework.starter.web.core.annotations.oplog.OpLog;
26 24 import com.lframework.starter.web.core.utils.PageHelperUtil;
27 25 import com.lframework.starter.common.utils.Assert;
28 26 import com.lframework.starter.web.inner.components.oplog.OtherOpLogType;
  27 +import com.lframework.xingyun.sc.entity.ShipmentsOrderInfo;
  28 +import com.lframework.xingyun.sc.entity.ShipmentsPlanDetail;
29 29 import com.lframework.xingyun.sc.mappers.ShipmentDetailStatisticsMapper;
30   -import com.lframework.xingyun.sc.service.contract.ContractStdProcessingLineService;
31 30 import com.lframework.xingyun.sc.service.customer.CustomerCreditService;
  31 +import com.lframework.xingyun.sc.service.shipments.ShipmentsOrderInfoService;
  32 +import com.lframework.xingyun.sc.service.shipments.ShipmentsPlanDetailService;
32 33 import com.lframework.xingyun.sc.service.statistics.ShipmentDetailStatisticsService;
33 34 import com.lframework.xingyun.sc.vo.statistics.shipmentDetail.CreateShipmentDetailStatisticsVo;
34 35 import com.lframework.xingyun.sc.vo.statistics.shipmentDetail.QueryShipmentDetailStatisticsVo;
35   -import com.lframework.xingyun.sc.vo.statistics.shipmentDetail.UpdateShipmentDetailStatisticsVo;
  36 +import lombok.extern.slf4j.Slf4j;
36 37 import org.apache.commons.collections4.CollectionUtils;
37 38 import org.apache.commons.lang3.StringUtils;
38 39 import org.springframework.stereotype.Service;
... ... @@ -43,6 +44,7 @@ import java.util.*;
43 44 import java.util.function.Function;
44 45 import java.util.stream.Collectors;
45 46
  47 +@Slf4j
46 48 @Service
47 49 public class ShipmentDetailStatisticsServiceImpl extends BaseMpServiceImpl<ShipmentDetailStatisticsMapper, ShipmentDetailStatistics> implements ShipmentDetailStatisticsService {
48 50
... ... @@ -57,9 +59,11 @@ public class ShipmentDetailStatisticsServiceImpl extends BaseMpServiceImpl<Shipm
57 59 @Resource
58 60 private SysDataDicItemService sysDataDicItemService;
59 61 @Resource
60   - private ContractStdProcessingLineService contractStdProcessingLineService;
61   - @Resource
62 62 private WorkshopService workshopService;
  63 + @Resource
  64 + private ShipmentsOrderInfoService shipmentsOrderInfoService;
  65 + @Resource
  66 + private ShipmentsPlanDetailService shipmentsPlanDetailService;
63 67
64 68
65 69 @Override
... ... @@ -131,6 +135,7 @@ public class ShipmentDetailStatisticsServiceImpl extends BaseMpServiceImpl<Shipm
131 135 data.setSupplier(vo.getSupplier());
132 136 data.setCustomerShortName(vo.getCustomerShortName());
133 137 data.setCustomerType(vo.getCustomerType());
  138 + data.setAutoGenerate(Boolean.FALSE);
134 139
135 140 getBaseMapper().insert(data);
136 141
... ... @@ -140,26 +145,6 @@ public class ShipmentDetailStatisticsServiceImpl extends BaseMpServiceImpl<Shipm
140 145 return data.getId();
141 146 }
142 147
143   - @OpLog(type = OtherOpLogType.class, name = "修改发货明细统计,ID:{}", params = {"#id"})
144   - @Transactional(rollbackFor = Exception.class)
145   - @Override
146   - public void update(UpdateShipmentDetailStatisticsVo vo) {
147   -
148   - ShipmentDetailStatistics data = getBaseMapper().selectById(vo.getId());
149   - if (ObjectUtil.isNull(data)) {
150   - throw new DefaultClientException("发货明细统计不存在!");
151   - }
152   -
153   - LambdaUpdateWrapper<ShipmentDetailStatistics> updateWrapper = Wrappers.lambdaUpdate(ShipmentDetailStatistics.class)
154   - .set(ShipmentDetailStatistics::getActualShipmentQuantity, vo.getActualShipmentQuantity())
155   - .eq(ShipmentDetailStatistics::getId, vo.getId());
156   -
157   - getBaseMapper().update(updateWrapper);
158   -
159   - OpLogUtil.setVariable("id", data.getId());
160   - OpLogUtil.setExtra(vo);
161   - }
162   -
163 148 @Override
164 149 public PageResult<ShipmentDetailStatistics> pageShipmentDetail(Integer pageIndex, Integer pageSize, QueryShipmentDetailStatisticsVo vo) {
165 150 Assert.greaterThanZero(pageIndex);
... ... @@ -274,12 +259,17 @@ public class ShipmentDetailStatisticsServiceImpl extends BaseMpServiceImpl<Shipm
274 259 if (StringUtils.isNotBlank(detail.getMaterialProductRatio())) {
275 260 String materialProductRatio = materialAndQuantityRatioMap.get(detail.getMaterialProductRatio());
276 261 if ("10".equals(detail.getMaterialProductRatio())) {
277   - detail.setProcessingOrDistribution(materialProductRatio + "加工");
278   - } else {
279 262 detail.setProcessingOrDistribution(detail.getMaterialProductRatioRemarks() + "加工");
  263 + } else {
  264 + detail.setProcessingOrDistribution(materialProductRatio + "加工");
280 265 }
281 266 } else {
282   - detail.setProcessingOrDistribution("经销");
  267 + if ("INTL_STD_CONTRACT".equals(detail.getContractType()) || "INTL_INVENTORY_AGMT".equals(detail.getContractType())
  268 + || "INTL_OPEN_SPEC_AGMT".equals(detail.getContractType())) {
  269 + detail.setProcessingOrDistribution("外贸");
  270 + } else {
  271 + detail.setProcessingOrDistribution("经销");
  272 + }
283 273 }
284 274 // 发货公司
285 275 String supplier = supplierMap.get(detail.getSupplier());
... ... @@ -287,4 +277,56 @@ public class ShipmentDetailStatisticsServiceImpl extends BaseMpServiceImpl<Shipm
287 277 }
288 278 return shipmentDetailInfo;
289 279 }
  280 +
  281 + @Override
  282 + @Transactional(rollbackFor = Exception.class)
  283 + public void generateStatisticsData(List<String> shipmentDetailIds) {
  284 + if (CollectionUtils.isEmpty(shipmentDetailIds)) {
  285 + log.info("========================= 没有可以生成发货明细报表的数据!");
  286 + return;
  287 + }
  288 + List<String> existShipmentOrderNoList = new ArrayList<>();
  289 + // 获取已有数据
  290 + LambdaQueryWrapper<ShipmentDetailStatistics> queryWrapper = Wrappers.lambdaQuery(ShipmentDetailStatistics.class);
  291 + queryWrapper.eq(ShipmentDetailStatistics::getAutoGenerate, Boolean.TRUE);
  292 + List<ShipmentDetailStatistics> existStatisticsDataList = getBaseMapper().selectList(queryWrapper);
  293 + if (CollectionUtils.isNotEmpty(existStatisticsDataList)) {
  294 + existShipmentOrderNoList = existStatisticsDataList.stream().map(ShipmentDetailStatistics::getShipmentOrderNo)
  295 + .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
  296 + }
  297 + QueryShipmentDetailStatisticsVo vo = new QueryShipmentDetailStatisticsVo();
  298 + vo.setIds(shipmentDetailIds);
  299 + List<ShipmentDetailStatistics> needStatisticsDataList = queryShipmentDetail(vo);
  300 + if (CollectionUtils.isEmpty(needStatisticsDataList)) {
  301 + return;
  302 + }
  303 + Iterator<ShipmentDetailStatistics> iterator = needStatisticsDataList.iterator();
  304 + while (iterator.hasNext()) {
  305 + ShipmentDetailStatistics next = iterator.next();
  306 + String shipmentOrderNo = next.getShipmentOrderNo();
  307 + if (existShipmentOrderNoList.contains(shipmentOrderNo)) {
  308 + // 删掉已存在的发货明细数据,防止重复生成
  309 + // 手动新增的数据可以多次重复操作
  310 + iterator.remove();
  311 + }
  312 + }
  313 + getBaseMapper().batchAdd(needStatisticsDataList);
  314 + }
  315 +
  316 + @Override
  317 + @Transactional(rollbackFor = Exception.class)
  318 + public void autoGenerate() {
  319 + List<ShipmentsOrderInfo> shipmentsOrderInfos = shipmentsOrderInfoService.queryByShipmentDate(null);
  320 + if (CollectionUtils.isEmpty(shipmentsOrderInfos)) {
  321 + log.info("========================== 没有需要生发货明细统计报表数据的发货单!");
  322 + return;
  323 + }
  324 + List<String> shipmentOrderIds = shipmentsOrderInfos.stream().map(ShipmentsOrderInfo::getId).collect(Collectors.toList());
  325 + List<ShipmentsPlanDetail> detailList = shipmentsPlanDetailService.listByShipmentOrderId(shipmentOrderIds);
  326 + if (CollectionUtils.isEmpty(detailList)) {
  327 + return;
  328 + }
  329 + List<String> detailIds = detailList.stream().map(ShipmentsPlanDetail::getId).collect(Collectors.toList());
  330 + generateStatisticsData(detailIds);
  331 + }
290 332 }
... ...
... ... @@ -29,4 +29,11 @@ public interface ShipmentDetailStatisticsMapper extends BaseMapper<ShipmentDetai
29 29 * @return List<ShipmentDetailStatistics>
30 30 */
31 31 List<ShipmentDetailStatistics> getShipmentDetailInfo(@Param("vo") QueryShipmentDetailStatisticsVo vo);
  32 +
  33 + /**
  34 + * 批量新增
  35 + *
  36 + * @param detailStatisticsList 发货明细统计数据
  37 + */
  38 + void batchAdd(List<ShipmentDetailStatistics> detailStatisticsList);
32 39 }
... ...
... ... @@ -4,6 +4,8 @@ import com.lframework.xingyun.sc.vo.shipments.order.*;
4 4 import com.lframework.xingyun.sc.entity.ShipmentsOrderInfo;
5 5 import com.lframework.starter.web.core.service.BaseMpService;
6 6 import com.lframework.starter.web.core.components.resp.PageResult;
  7 +
  8 +import java.time.LocalDate;
7 9 import java.util.List;
8 10 import java.util.Map;
9 11
... ... @@ -116,4 +118,12 @@ public interface ShipmentsOrderInfoService extends BaseMpService<ShipmentsOrderI
116 118 * @return Map<Integer, Long>
117 119 */
118 120 Map<String, Long> countWaitDeliveredOrder(List<String> customerNames);
  121 +
  122 + /**
  123 + * 根据发货日期获取已发货、已签收的数据
  124 + *
  125 + * @param shipmentDate 发货日期
  126 + * @return List<ShipmentsOrderInfo>
  127 + */
  128 + List<ShipmentsOrderInfo> queryByShipmentDate(LocalDate shipmentDate);
119 129 }
... ...
... ... @@ -45,13 +45,6 @@ public interface ShipmentDetailStatisticsService extends BaseMpService<ShipmentD
45 45 String create(CreateShipmentDetailStatisticsVo vo);
46 46
47 47 /**
48   - * 修改
49   - *
50   - * @param vo 数据实体
51   - */
52   - void update(UpdateShipmentDetailStatisticsVo vo);
53   -
54   - /**
55 48 * 获取发货明细数据
56 49 *
57 50 * @param QueryShipmentDetailStatisticsVo 查询条件
... ... @@ -66,4 +59,17 @@ public interface ShipmentDetailStatisticsService extends BaseMpService<ShipmentD
66 59 * @return List<ShipmentDetailStatistics>
67 60 */
68 61 List<ShipmentDetailStatistics> queryShipmentDetail(QueryShipmentDetailStatisticsVo vo);
  62 +
  63 + /**
  64 + * 生成发货明细统计数据
  65 + * 支持批量生成
  66 + *
  67 + * @param shipmentDetailIds 发货单明细ID集合
  68 + */
  69 + void generateStatisticsData(List<String> shipmentDetailIds);
  70 +
  71 + /**
  72 + * 自动生成发货明细统计数据
  73 + */
  74 + void autoGenerate();
69 75 }
... ...
... ... @@ -7,6 +7,7 @@ import lombok.Data;
7 7 import javax.validation.Valid;
8 8 import javax.validation.constraints.NotBlank;
9 9 import javax.validation.constraints.NotEmpty;
  10 +import javax.validation.constraints.NotNull;
10 11 import java.io.Serializable;
11 12 import java.util.List;
12 13
... ... @@ -36,4 +37,11 @@ public class ShipmentsOrderVo implements BaseVo, Serializable {
36 37 @NotEmpty(message = "发货单明细不能为空!")
37 38 @Valid
38 39 private List<ShipmentsOrderDetailVo> detailList;
  40 +
  41 + /**
  42 + * 是否当日发货
  43 + */
  44 + @ApiModelProperty(value = "是否当日发货", required = true)
  45 + @NotNull(message = "是否当日发货不能为空!")
  46 + private Boolean onTimeShipment;
39 47 }
... ...
... ... @@ -4,10 +4,7 @@ import lombok.Data;
4 4 import javax.validation.constraints.NotBlank;
5 5 import java.time.LocalDate;
6 6 import com.lframework.starter.web.core.vo.BaseVo;
7   -import javax.validation.constraints.NotNull;
8   -import com.lframework.starter.web.core.components.validation.TypeMismatch;
9 7 import io.swagger.annotations.ApiModelProperty;
10   -import org.hibernate.validator.constraints.Length;
11 8 import java.io.Serializable;
12 9
13 10 @Data
... ... @@ -23,59 +20,9 @@ public class UpdateShipmentsOrderInfoVo implements BaseVo, Serializable {
23 20 private String id;
24 21
25 22 /**
26   - * 发货计划ID
  23 + * 新发货日期
27 24 */
28   - @ApiModelProperty(value = "发货计划ID", required = true)
29   - @NotBlank(message = "请输入发货计划ID!")
30   - @Length(message = "发货计划ID最多允许32个字符!")
31   - private String planId;
32   -
33   - /**
34   - * 购货单位ID
35   - */
36   - @ApiModelProperty(value = "购货单位ID", required = true)
37   - @NotBlank(message = "请输入购货单位ID!")
38   - @Length(message = "购货单位ID最多允许32个字符!")
39   - private String customerId;
40   -
41   - /**
42   - * 厂房ID
43   - */
44   - @ApiModelProperty(value = "厂房ID", required = true)
45   - @NotBlank(message = "请输入厂房ID!")
46   - @Length(message = "厂房ID最多允许32个字符!")
47   - private String workshopId;
48   -
49   - /**
50   - * 发货日期
51   - */
52   - @ApiModelProperty(value = "发货日期", required = true)
53   - @TypeMismatch(message = "发货日期格式有误!")
54   - @NotNull(message = "请输入发货日期!")
55   - private LocalDate shipmentsDate;
56   -
57   - /**
58   - * 办事处ID
59   - */
60   - @ApiModelProperty(value = "办事处ID", required = true)
61   - @NotBlank(message = "请输入办事处ID!")
62   - @Length(message = "办事处ID最多允许500个字符!")
63   - private String deptId;
64   -
65   - /**
66   - * 交货方式
67   - */
68   - @ApiModelProperty(value = "交货方式", required = true)
69   - @NotBlank(message = "请输入交货方式!")
70   - @Length(message = "交货方式最多允许100个字符!")
71   - private String deliveryType;
72   -
73   - /**
74   - * 目的地
75   - */
76   - @ApiModelProperty(value = "目的地", required = true)
77   - @NotBlank(message = "请输入目的地!")
78   - @Length(message = "目的地最多允许100个字符!")
79   - private String destination;
  25 + @ApiModelProperty(value = "新发货日期")
  26 + private LocalDate newShipmentDate;
80 27
81 28 }
... ...
... ... @@ -150,7 +150,7 @@
150 150 o.workshop_id,
151 151 o.delivery_method,
152 152 so.code as shipment_order_no,
153   - so.create_time as shipment_date,
  153 + so.shipments_date as shipment_date,
154 154 sc.id as contract_id,
155 155 sc.type as contract_type,
156 156 sc.packaging_requirements,
... ... @@ -171,11 +171,102 @@
171 171 </foreach>
172 172 </if>
173 173 <if test="vo.orderNo != null and vo.orderNo != ''">
174   - AND o.order_no LIKE CONCAT('%', #{vo.orderNo}, '%')
  174 + and o.order_no like concat('%', #{vo.orderNo}, '%')
175 175 </if>
176 176 <if test="vo.shipmentOrderNo != null and vo.shipmentOrderNo != ''">
177   - AND so.code LIKE CONCAT('%', #{vo.shipmentOrderNo}, '%')
  177 + and so.code like concat('%', #{vo.shipmentOrderNo}, '%')
178 178 </if>
179 179 </where>
  180 + order by so.create_time desc
180 181 </select>
  182 +
  183 + <insert id="batchAdd">
  184 + INSERT INTO shipments_detail_statistics (
  185 + id,
  186 + shipment_order_no,
  187 + workshop_name,
  188 + dept_name,
  189 + region_name,
  190 + ordering_unit_name,
  191 + brand,
  192 + thickness,
  193 + width,
  194 + length,
  195 + status,
  196 + quantity,
  197 + actual_shipment_quantity,
  198 + sales_price,
  199 + thickness_tol_pos,
  200 + thickness_tol_neg,
  201 + width_tol_pos,
  202 + width_tol_neg,
  203 + length_tol_pos,
  204 + length_tol_neg,
  205 + assessment_exceeds_agreement,
  206 + shipping_cost,
  207 + return_freight,
  208 + industry,
  209 + stock_up_company_name,
  210 + order_no,
  211 + yield_batch_no,
  212 + invoicing_status,
  213 + order_date,
  214 + packaging_fee,
  215 + quality,
  216 + num,
  217 + settlement_terms,
  218 + processing_or_distribution,
  219 + packaging_requirements,
  220 + shipment_date,
  221 + supplier,
  222 + customer_short_name,
  223 + customer_type,
  224 + delivery_method
  225 + ) VALUES
  226 + <foreach collection="list" item="item" separator=",">
  227 + (
  228 + #{item.id},
  229 + #{item.shipmentOrderNo},
  230 + #{item.workshopName},
  231 + #{item.deptName},
  232 + #{item.regionName},
  233 + #{item.orderingUnitName},
  234 + #{item.brand},
  235 + #{item.thickness},
  236 + #{item.width},
  237 + #{item.length},
  238 + #{item.status},
  239 + #{item.quantity},
  240 + #{item.actualShipmentQuantity},
  241 + #{item.salesPrice},
  242 + #{item.thicknessTolPos},
  243 + #{item.thicknessTolNeg},
  244 + #{item.widthTolPos},
  245 + #{item.widthTolNeg},
  246 + #{item.lengthTolPos},
  247 + #{item.lengthTolNeg},
  248 + #{item.assessmentExceedsAgreement},
  249 + #{item.shippingCost},
  250 + #{item.returnFreight},
  251 + #{item.industry},
  252 + #{item.stockUpCompanyName},
  253 + #{item.orderNo},
  254 + #{item.yieldBatchNo},
  255 + #{item.invoicingStatus},
  256 + #{item.orderDate},
  257 + #{item.packagingFee},
  258 + #{item.quality},
  259 + #{item.num},
  260 + #{item.settlementTerms},
  261 + #{item.processingOrDistribution},
  262 + #{item.packagingRequirements},
  263 + #{item.shipmentDate},
  264 + #{item.supplier},
  265 + #{item.customerShortName},
  266 + #{item.customerType},
  267 + #{item.deliveryMethod}
  268 + )
  269 + </foreach>
  270 + </insert>
  271 +
181 272 </mapper>
... ...