Эх сурвалжийг харах

对账单售后订单列表调整

fgd 1 жил өмнө
parent
commit
7b06ef3a85
35 өөрчлөгдсөн 1007 нэмэгдсэн , 250 устгасан
  1. 0 9
      sd-business/src/main/java/com/sd/business/controller/board/DailyBoardController.java
  2. 8 0
      sd-business/src/main/java/com/sd/business/controller/order/OrderExchangeController.java
  3. 0 8
      sd-business/src/main/java/com/sd/business/controller/statement/StatementOfAccountController.java
  4. 10 0
      sd-business/src/main/java/com/sd/business/entity/bom/constant/BomClassifyConstant.java
  5. 34 0
      sd-business/src/main/java/com/sd/business/entity/order/bo/OrderExchangeAccountBo.java
  6. 4 0
      sd-business/src/main/java/com/sd/business/entity/order/dto/OrderExchangeSelectDto.java
  7. 21 0
      sd-business/src/main/java/com/sd/business/entity/order/po/OrderExchange.java
  8. 10 0
      sd-business/src/main/java/com/sd/business/entity/order/po/OrderExchangeDetail.java
  9. 0 5
      sd-business/src/main/java/com/sd/business/entity/order/vo/OrderExchangeDetailVo.java
  10. 5 0
      sd-business/src/main/java/com/sd/business/entity/statement/bo/ExportDocumentByOrderBo.java
  11. 0 6
      sd-business/src/main/java/com/sd/business/entity/statement/dto/StatementOfAccountSelectDto.java
  12. 0 5
      sd-business/src/main/java/com/sd/business/entity/statement/po/StatementOfAccount.java
  13. 5 0
      sd-business/src/main/java/com/sd/business/entity/statement/vo/DocumentByBomVo.java
  14. 5 0
      sd-business/src/main/java/com/sd/business/entity/statement/vo/DocumentByOrderVo.java
  15. 5 0
      sd-business/src/main/java/com/sd/business/entity/statement/vo/DocumentBySkuVo.java
  16. 0 6
      sd-business/src/main/java/com/sd/business/entity/statement/vo/StatementOfAccountMergePageVo.java
  17. 9 0
      sd-business/src/main/java/com/sd/business/mapper/order/OrderExchangeMapper.java
  18. 0 6
      sd-business/src/main/java/com/sd/business/service/board/DailyBoardService.java
  19. 0 52
      sd-business/src/main/java/com/sd/business/service/board/impl/DailyBoardServiceImpl.java
  20. 15 0
      sd-business/src/main/java/com/sd/business/service/order/OrderExchangeService.java
  21. 3 0
      sd-business/src/main/java/com/sd/business/service/order/impl/OrderExchangeDetailServiceImpl.java
  22. 229 104
      sd-business/src/main/java/com/sd/business/service/order/impl/OrderExchangeServiceImpl.java
  23. 6 6
      sd-business/src/main/java/com/sd/business/service/purchase/impl/PurchaseBomServiceImpl.java
  24. 0 6
      sd-business/src/main/java/com/sd/business/service/statement/StatementOfAccountService.java
  25. 100 0
      sd-business/src/main/java/com/sd/business/service/statement/impl/DocumentByAfterSaleOrderExcelCellMergeStrategy.java
  26. 18 5
      sd-business/src/main/java/com/sd/business/service/statement/impl/StatementOfAccountExportServiceImpl.java
  27. 16 7
      sd-business/src/main/java/com/sd/business/service/statement/impl/StatementOfAccountMergeServiceImpl.java
  28. 468 18
      sd-business/src/main/java/com/sd/business/service/statement/impl/StatementOfAccountServiceImpl.java
  29. 20 7
      sd-business/src/main/java/com/sd/business/strategy/impl/DocumentByOrderExcelExportStrategy.java
  30. 11 0
      sd-business/src/main/resources/mapper/order/OrderExchangeMapper.xml
  31. 5 0
      sd-business/src/main/resources/mapper/order/OrderSalesShipmentStatisticsMapper.xml
  32. BIN
      sd-starter/src/main/resources/template/afterSaleBomDocument.xlsx
  33. BIN
      sd-starter/src/main/resources/template/afterSaleOrderDocument.xlsx
  34. BIN
      sd-starter/src/main/resources/template/afterSaleSkuDocument.xlsx
  35. BIN
      sd-starter/src/main/resources/template/skuDocument.xlsx

+ 0 - 9
sd-business/src/main/java/com/sd/business/controller/board/DailyBoardController.java

@@ -72,13 +72,4 @@ public class DailyBoardController {
     public SelfOrderOutStorageVo getSelfOrderOutStorageInfo(@Validated @RequestBody DailyBoardSelectDto dto) {
         return dailyBoardService.getSelfOrderOutStorageInfo(dto);
     }
-
-    /**
-     * 核对对账单
-     * @return
-     */
-    @PostMapping("/checkStatementOfAccount")
-    public void checkStatementOfAccount(@Validated @RequestBody DailyBoardSelectDto dto) {
-        dailyBoardService.checkStatementOfAccount(dto);
-    }
 }

+ 8 - 0
sd-business/src/main/java/com/sd/business/controller/order/OrderExchangeController.java

@@ -53,6 +53,14 @@ public class OrderExchangeController {
         orderExchangeService.add(orderExchangeDto);
     }
 
+    /**
+     * 订单退换货质检
+     */
+    @PostMapping("/orderExchangeCheck")
+    public void orderExchangeCheck(@RequestBody OrderExchangeDto orderExchangeDto) {
+        orderExchangeService.orderExchangeCheck(orderExchangeDto);
+    }
+
     // /**
     //  * 订单退换货删除
     //  */

+ 0 - 8
sd-business/src/main/java/com/sd/business/controller/statement/StatementOfAccountController.java

@@ -154,12 +154,4 @@ public class StatementOfAccountController {
         return statementOfAccountService.getOrderClassifyTotalCount(idList);
     }
 
-    /**
-     * 获取对账单未签核的数量
-     */
-    @PostMapping("/getNotCheckCount")
-    public Long getNotCheckCount() {
-        return statementOfAccountService.getNotCheckCount();
-    }
-
 }

+ 10 - 0
sd-business/src/main/java/com/sd/business/entity/bom/constant/BomClassifyConstant.java

@@ -15,4 +15,14 @@ public interface BomClassifyConstant {
      */
     Long SKIP_MAT = 1682221128782798850L;
 
+    /**
+     * 网包类
+     */
+    Long MESH_BAG = 1682221356147630081L;
+
+    /**
+     * 背带类
+     */
+    Long SUSPENDERS = 1682221651040755714L;
+
 }

+ 34 - 0
sd-business/src/main/java/com/sd/business/entity/order/bo/OrderExchangeAccountBo.java

@@ -0,0 +1,34 @@
+package com.sd.business.entity.order.bo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 订单退换货对账统计
+ */
+@Getter
+@Setter
+public class OrderExchangeAccountBo {
+
+    /**
+     * 对账单id
+     */
+    private Long statementOfAccountId;
+
+    /**
+     * 退货金额
+     */
+    private BigDecimal returnAmount;
+
+    /**
+     * 订单sku退货数量
+     */
+    private Integer orderSkuNum;
+
+    /**
+     * 订单数量
+     */
+    private Integer orderNum;
+}

+ 4 - 0
sd-business/src/main/java/com/sd/business/entity/order/dto/OrderExchangeSelectDto.java

@@ -39,4 +39,8 @@ public class OrderExchangeSelectDto extends BaseSelectDto {
      */
     private String departmentId;
 
+    /**
+     * 状态 0待质检 1已质检入库
+     */
+    private Integer status;
 }

+ 21 - 0
sd-business/src/main/java/com/sd/business/entity/order/po/OrderExchange.java

@@ -7,6 +7,7 @@ import lombok.Setter;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import java.util.Date;
 
 /**
  * <p>
@@ -45,6 +46,11 @@ public class OrderExchange extends BasePo {
     private Integer type;
 
     /**
+     * 状态 0待质检 1已质检入库
+     */
+    private Integer status;
+
+    /**
      * 退换货原因
      */
     @NotBlank(message = "售后原因不能为空")
@@ -90,4 +96,19 @@ public class OrderExchange extends BasePo {
      */
     private String postcode;
 
+    /**
+     * 完成时间
+     */
+    private Date completionTime;
+
+    /**
+     * 完成时间戳
+     */
+    private Long completionTimestamp;
+
+    /**
+     * 对账单id
+     */
+    private Long statementOfAccountId;
+
 }

+ 10 - 0
sd-business/src/main/java/com/sd/business/entity/order/po/OrderExchangeDetail.java

@@ -50,5 +50,15 @@ public class OrderExchangeDetail extends BasePo {
      */
     private Integer exchangeStatus;
 
+    /**
+     * 退货金额
+     */
+    private BigDecimal returnAmount;
+
+    /**
+     * 质检通过数量(可二次销售)
+     */
+    private BigDecimal checkPassesQuantity;
+
 
 }

+ 0 - 5
sd-business/src/main/java/com/sd/business/entity/order/vo/OrderExchangeDetailVo.java

@@ -43,11 +43,6 @@ public class OrderExchangeDetailVo extends OrderExchangeDetail {
     private BigDecimal buyQuantity;
 
     /**
-     * 退货金额
-     */
-    private BigDecimal returnAmount;
-
-    /**
      * 部门名称
      */
     @ExcelProperty(value = "部门名称", index = 1)

+ 5 - 0
sd-business/src/main/java/com/sd/business/entity/statement/bo/ExportDocumentByOrderBo.java

@@ -89,6 +89,11 @@ public class ExportDocumentByOrderBo {
     private BigDecimal unitPrice;
 
     /**
+     * sku质检费
+     */
+    private BigDecimal checkFee;
+
+    /**
      * 小计
      */
     private BigDecimal subtotal;

+ 0 - 6
sd-business/src/main/java/com/sd/business/entity/statement/dto/StatementOfAccountSelectDto.java

@@ -24,10 +24,4 @@ public class StatementOfAccountSelectDto extends BaseSelectDto {
      */
     private String code;
 
-    /**
-     * 核对状态 1 已核对,0 未核对
-     */
-    private Integer checkStatus;
-
-
 }

+ 0 - 5
sd-business/src/main/java/com/sd/business/entity/statement/po/StatementOfAccount.java

@@ -42,9 +42,4 @@ public class StatementOfAccount extends BasePo {
      */
     private Integer type;
 
-    /**
-     * 核对状态 1 已核对,0 未核对
-     */
-    private Integer checkStatus;
-
 }

+ 5 - 0
sd-business/src/main/java/com/sd/business/entity/statement/vo/DocumentByBomVo.java

@@ -72,6 +72,11 @@ public class DocumentByBomVo {
     private BigDecimal proofingFeeSummary;
 
     /**
+     * 质检费
+     */
+    private BigDecimal checkFeeSummary;
+
+    /**
      * 小计
      */
     private BigDecimal subtotal;

+ 5 - 0
sd-business/src/main/java/com/sd/business/entity/statement/vo/DocumentByOrderVo.java

@@ -116,6 +116,11 @@ public class DocumentByOrderVo {
         private BigDecimal unitPrice;
 
         /**
+         * 质检费
+         */
+        private BigDecimal checkFee;
+
+        /**
          * 小计
          */
         private BigDecimal subtotal;

+ 5 - 0
sd-business/src/main/java/com/sd/business/entity/statement/vo/DocumentBySkuVo.java

@@ -47,6 +47,11 @@ public class DocumentBySkuVo {
     private BigDecimal proofingFee;
 
     /**
+     * 质检费
+     */
+    private BigDecimal checkFee;
+
+    /**
      * 合计
      */
     private BigDecimal total;

+ 0 - 6
sd-business/src/main/java/com/sd/business/entity/statement/vo/StatementOfAccountMergePageVo.java

@@ -43,10 +43,4 @@ public class StatementOfAccountMergePageVo {
      * 合同数量
      */
     private Integer orderQuantity;
-
-    /**
-     * 核对状态 1 已核对,0 未核对
-     */
-    private Integer checkStatus;
-
 }

+ 9 - 0
sd-business/src/main/java/com/sd/business/mapper/order/OrderExchangeMapper.java

@@ -3,10 +3,13 @@ package com.sd.business.mapper.order;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.sd.business.entity.order.bo.OrderExchangeAccountBo;
 import com.sd.business.entity.order.po.OrderExchange;
 import com.sd.business.entity.order.vo.OrderExchangeVo;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 
 /**
  * <p>
@@ -23,4 +26,10 @@ public interface OrderExchangeMapper extends BaseMapper<OrderExchange> {
      */
     Page<OrderExchangeVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<OrderExchange> wrapper);
 
+    /**
+     * 订单退换货对账统计
+     * @param wrapper
+     * @return
+     */
+    List<OrderExchangeAccountBo> orderExchangeAccountStatistics(@Param("ew") IWrapper<OrderExchange> wrapper);
 }

+ 0 - 6
sd-business/src/main/java/com/sd/business/service/board/DailyBoardService.java

@@ -45,10 +45,4 @@ public interface DailyBoardService {
      * @return
      */
     SelfOrderOutStorageVo getSelfOrderOutStorageInfo(DailyBoardSelectDto dto);
-
-    /**
-     * 核对对账单
-     * @param dto
-     */
-    void checkStatementOfAccount(DailyBoardSelectDto dto);
 }

+ 0 - 52
sd-business/src/main/java/com/sd/business/service/board/impl/DailyBoardServiceImpl.java

@@ -6,7 +6,6 @@ import cn.hutool.core.util.ObjectUtil;
 import com.ruoyi.common.constant.StatusConstant;
 import com.ruoyi.common.core.domain.BaseIdPo;
 import com.ruoyi.common.core.domain.BasePo;
-import com.ruoyi.common.exception.ServiceException;
 import com.sd.business.entity.board.dto.DailyBoardSelectDto;
 import com.sd.business.entity.board.vo.*;
 import com.sd.business.entity.bom.bo.BomSpecBo;
@@ -20,9 +19,7 @@ import com.sd.business.entity.order.po.OrderSku;
 import com.sd.business.entity.outbound.po.OutboundOrder;
 import com.sd.business.entity.production.po.ProductionWorkOrder;
 import com.sd.business.entity.sku.po.SkuSpec;
-import com.sd.business.entity.statement.po.StatementOfAccount;
 import com.sd.business.service.board.DailyBoardService;
-import com.sd.business.service.bom.BomSpecService;
 import com.sd.business.service.department.DepartmentService;
 import com.sd.business.service.in.InOutStorageBomService;
 import com.sd.business.service.in.InOutStorageService;
@@ -70,9 +67,6 @@ public class DailyBoardServiceImpl implements DailyBoardService {
     @Autowired
     private DepartmentService departmentService;
 
-    @Autowired
-    private StatementOfAccountService statementOfAccountService;
-
     @Override
     public List<DailyBoardOutStorageBomVo> getProductionOutStorageList(DailyBoardSelectDto dto) {
         Date beginDate = DateUtil.beginOfDay(dto.getBeginDate());
@@ -533,50 +527,4 @@ public class DailyBoardServiceImpl implements DailyBoardService {
         vo.setOutStorageBomList(new ArrayList<>(outStorageBomMap.values()));
         return vo;
     }
-
-    @Override
-    public void checkStatementOfAccount(DailyBoardSelectDto dto) {
-        Date beginDate = DateUtil.beginOfDay(dto.getBeginDate());
-        Date endDate = DateUtil.endOfDay(dto.getEndDate());
-        // 查询佰卓和实业的事业部id
-        List<Department> departmentList = departmentService.list(q -> q.like(Department::getName, "实业").or().eq(Department::getName, "佰卓").select(BaseIdPo::getId));
-        List<Long> departmentIds = departmentList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
-        // 查询今日生成完成任务
-        List<ProductionWorkOrder> productionWorkOrderList = productionWorkOrderService.list(q -> q.between(ProductionWorkOrder::getCompleteTime, beginDate, endDate));
-        long productionOrderCount;
-        if (productionWorkOrderList.isEmpty()) {
-            productionOrderCount = 0L;
-        } else {
-            List<Long> orderIds = productionWorkOrderList.stream().map(ProductionWorkOrder::getOrderId).collect(Collectors.toList());
-            productionOrderCount = orderService.count(q -> q.in(OrderInfo::getDepartmentId, departmentIds).in(BaseIdPo::getId, orderIds));
-        }
-
-        // 查询今日出库单出库数据
-        List<OutboundOrder> outboundOrderList = outboundOrderService.list(q -> q.between(OutboundOrder::getOutboundTime, beginDate, endDate));
-        long wlnOrderCount;
-        if (outboundOrderList.isEmpty()) {
-            wlnOrderCount = 0L;
-        } else {
-            List<String> wlnCodes = outboundOrderList.stream().map(OutboundOrder::getOrderWlnCode).collect(Collectors.toList());
-            wlnOrderCount = orderService.count(q -> q.in(OrderInfo::getDepartmentId, departmentIds).in(OrderInfo::getWlnCode, wlnCodes));
-        }
-        if (ObjectUtil.notEqual(productionOrderCount, wlnOrderCount)) {
-            throw new ServiceException("核对失败,订单总数存在差异!");
-        }
-
-        // 查询bom总数
-        List<ProductionWorkOrder> workOrderList = productionWorkOrderList.stream().filter(item -> Objects.equals(item.getStatus(), 3)).collect(Collectors.toList());
-        BigDecimal productionBomQuantity = new BigDecimal(workOrderList.size());
-        BigDecimal outboundBomQuantity = outboundOrderList.stream().map(OutboundOrder::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
-
-        if (ObjectUtil.notEqual(productionBomQuantity, outboundBomQuantity)) {
-            throw new ServiceException("核对失败,bom出库总数存在差异!");
-        }
-
-        // 更新对账单核对状态
-        statementOfAccountService.update(q -> q
-                .set(StatementOfAccount::getCheckStatus, StatusConstant.YES)
-                .in(StatementOfAccount::getDepartmentId, departmentIds)
-                .between(StatementOfAccount::getTimePeriod, beginDate, endDate));
-    }
 }

+ 15 - 0
sd-business/src/main/java/com/sd/business/service/order/OrderExchangeService.java

@@ -2,11 +2,15 @@ package com.sd.business.service.order;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.service.BaseService;
+import com.sd.business.entity.order.bo.OrderExchangeAccountBo;
 import com.sd.business.entity.order.dto.OrderExchangeDto;
 import com.sd.business.entity.order.dto.OrderExchangeSelectDto;
 import com.sd.business.entity.order.po.OrderExchange;
 import com.sd.business.entity.order.vo.OrderExchangeVo;
 
+import java.util.List;
+import java.util.Map;
+
 
 /**
  * <p>
@@ -38,4 +42,15 @@ public interface OrderExchangeService extends BaseService<OrderExchange> {
      */
     void delete(Long id);
 
+    /**
+     * 订单退换货质检
+     * @param orderExchangeDto
+     */
+    void orderExchangeCheck(OrderExchangeDto orderExchangeDto);
+
+    /**
+     * 订单退换货对账统计
+     * @param statementOfAccountIdList
+     */
+    Map<Long, OrderExchangeAccountBo> orderExchangeAccountStatistics(List<Long> statementOfAccountIdList);
 }

+ 3 - 0
sd-business/src/main/java/com/sd/business/service/order/impl/OrderExchangeDetailServiceImpl.java

@@ -2,6 +2,7 @@ package com.sd.business.service.order.impl;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.constant.StatusConstant;
 import com.ruoyi.common.utils.wrapper.IWrapper;
 import com.sd.business.entity.order.dto.OrderExchangeDetailSelectDto;
 import com.sd.business.entity.order.po.OrderExchange;
@@ -46,6 +47,8 @@ public class OrderExchangeDetailServiceImpl extends ServiceImpl<OrderExchangeDet
         wrapper.eq("oi", OrderInfo::getWlnCode, dto.getOrderWlnCode());
         wrapper.ge("oe", OrderExchange::getCreateTime, dto.getBeginTime());
         wrapper.le("oe", OrderExchange::getCreateTime, dto.getEndTime());
+        // 财务销售退货表只查询已质检的数据
+        wrapper.eq("oe", OrderExchange::getStatus, StatusConstant.YES);
 
         return baseMapper.getPage(dto.getPage(), wrapper);
     }

+ 229 - 104
sd-business/src/main/java/com/sd/business/service/order/impl/OrderExchangeServiceImpl.java

@@ -1,6 +1,7 @@
 package com.sd.business.service.order.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
@@ -14,26 +15,25 @@ import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.wrapper.IWrapper;
 import com.ruoyi.system.utils.UserUtil;
+import com.sd.business.entity.bom.bo.BomSpecBo;
+import com.sd.business.entity.bom.constant.BomClassifyConstant;
 import com.sd.business.entity.department.constant.DepartmentConstant;
 import com.sd.business.entity.department.po.Department;
 import com.sd.business.entity.in.dto.InOutStorageDto;
 import com.sd.business.entity.in.emums.InDetailTypeEnum;
 import com.sd.business.entity.in.emums.InOutTypeEnum;
+import com.sd.business.entity.in.emums.OutDetailTypeEnum;
 import com.sd.business.entity.in.po.InOutStorageBom;
-import com.sd.business.entity.inventory.po.InventoryFinished;
+import com.sd.business.entity.order.bo.OrderExchangeAccountBo;
 import com.sd.business.entity.order.dto.OrderExchangeDto;
 import com.sd.business.entity.order.dto.OrderExchangeSelectDto;
-import com.sd.business.entity.order.enums.OrderClassifyEnum;
-import com.sd.business.entity.order.enums.OrderStatusEnum;
 import com.sd.business.entity.order.po.*;
 import com.sd.business.entity.order.vo.OrderExchangeDetailVo;
 import com.sd.business.entity.order.vo.OrderExchangeVo;
-import com.sd.business.entity.sku.po.SkuSpec;
-import com.sd.business.entity.statement.dto.StatementOfAccountDto;
+import com.sd.business.entity.statement.po.StatementOfAccount;
 import com.sd.business.entity.warehouse.constant.WarehouseConstant;
 import com.sd.business.mapper.order.OrderExchangeMapper;
 import com.sd.business.service.in.InOutStorageService;
-import com.sd.business.service.inventory.InventoryFinishedOrderService;
 import com.sd.business.service.inventory.InventoryFinishedService;
 import com.sd.business.service.order.*;
 import com.sd.business.service.sku.SkuSpecService;
@@ -41,6 +41,7 @@ import com.sd.business.service.statement.StatementOfAccountService;
 import com.sd.business.util.CodeEnum;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.*;
@@ -83,14 +84,12 @@ public class OrderExchangeServiceImpl extends ServiceImpl<OrderExchangeMapper, O
     @Autowired
     private InventoryFinishedService inventoryFinishedService;
 
-    @Autowired
-    private InventoryFinishedOrderService inventoryFinishedOrderService;
-
     @Override
     public Page<OrderExchangeVo> getPage(OrderExchangeSelectDto dto) {
         IWrapper<OrderExchange> wrapper = getWrapper();
         wrapper.orderByDesc("oe", OrderExchange::getId);
         wrapper.eq("oe", OrderExchange::getOrderInfoId, dto.getOrderInfoId());
+        wrapper.eq("oe", OrderExchange::getStatus, dto.getStatus());
         wrapper.like("oe", OrderExchange::getCode, dto.getCode());
         wrapper.like("oi", OrderInfo::getCode, dto.getOrderCode());
         wrapper.like("oi", OrderInfo::getWlnCode, dto.getOrderWlnCode());
@@ -114,13 +113,6 @@ public class OrderExchangeServiceImpl extends ServiceImpl<OrderExchangeMapper, O
         orderSkuService.attributeAssign(orderExchangeDetailList, OrderExchangeDetailVo::getOrderSkuId, (item, orderSku) -> {
             item.setSkuSpecId(orderSku.getSkuSpecId());
             item.setBuyQuantity(orderSku.getQuantity());
-            item.setReturnAmount((orderSku.getUnitPrice()
-                    .add(orderSku.getCustomProcessingFee())
-                    .add(orderSku.getLssueFee())
-                    .add(orderSku.getDeliveryMaterialsFee())
-                    .add(orderSku.getPackingLabor())
-                    .add(orderSku.getPackagingMaterialCost())
-                    .add(orderSku.getManagementFee())).multiply(item.getQuantity()));
         });
 
         // 赋值sku品号品名
@@ -180,11 +172,31 @@ public class OrderExchangeServiceImpl extends ServiceImpl<OrderExchangeMapper, O
                 .collect(Collectors.toList());
 
         // 根据集合查询订单数量
-        Map<Long, BigDecimal> map = orderSkuService.mapKV(BaseIdPo::getId, OrderSku::getQuantity,
+        Map<Long, OrderSku> map = orderSkuService.mapKEntity(BaseIdPo::getId,
                 q -> q.in(BaseIdPo::getId, orderSkuIdList));
+        List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.in(OrderSkuBom::getOrderSkuId, orderSkuIdList));
+        // 筛选掉可二次利用的包材
+        List<Long> bomSpecIdList = orderSkuBomList.stream()
+                .map(OrderSkuBom::getBomSpecId)
+                .distinct()
+                .collect(Collectors.toList());
+        Map<Long, BomSpecBo> bomSpecBoMap = skuSpecService.getBomSpecBoByIdList(bomSpecIdList);
+        List<OrderSkuBom> tempOrderSkuBomList = orderSkuBomList.stream()
+                .filter(item -> {
+                    BomSpecBo bomSpecBo = bomSpecBoMap.get(item.getBomSpecId());
+                    if (bomSpecBo == null
+                            || !(Objects.equals(bomSpecBo.getClassifyId(), BomClassifyConstant.MESH_BAG)
+                                || Objects.equals(bomSpecBo.getClassifyId(), BomClassifyConstant.SUSPENDERS))) {
+                        return false;
+                    }
+                    return true;
+                })
+                .collect(Collectors.toList());
+        Map<Long, List<OrderSkuBom>> orderSkuBomMap = tempOrderSkuBomList.stream().collect(Collectors.groupingBy(OrderSkuBom::getOrderSkuId));
 
         // 已添加订单产品退货列表
         List<OrderExchangeDetail> list = new ArrayList<>();
+        List<OrderSku> tempOrderSkuList = new ArrayList<>();
         if (orderExchangeDto.getType().equals(1)) {
             list = orderExchangeDetailService.list(q -> q.in(OrderExchangeDetail::getOrderSkuId, orderSkuIdList));
         }
@@ -194,10 +206,11 @@ public class OrderExchangeServiceImpl extends ServiceImpl<OrderExchangeMapper, O
             Long orderSkuId = orderExchangeDetail.getOrderSkuId();
 
             // 数量为空,没找到订单sku id
-            BigDecimal quantity = map.get(orderSkuId);
-            if (quantity == null) {
+            OrderSku orderSku = map.get(orderSkuId);
+            if (orderSku == null) {
                 throw new ServiceException("未知订单skuId:" + orderSkuId);
             }
+            BigDecimal quantity = orderSku.getQuantity();
 
             // 退换货数量大于订单产品购买数量
             if (orderExchangeDetail.getQuantity().compareTo(quantity) > 0) {
@@ -214,74 +227,34 @@ public class OrderExchangeServiceImpl extends ServiceImpl<OrderExchangeMapper, O
                 if (returnQuantity.add(orderExchangeDetail.getQuantity()).compareTo(quantity) > 0) {
                     throw new ServiceException("已记录退货数量加本次退货数量大于订单产品购买数量");
                 }
-
             }
 
             orderExchangeDetail.setOrderExchangeId(orderExchangeDto.getId());
             orderExchangeDetail.setReturnStatus(StatusConstant.NO);
             orderExchangeDetail.setExchangeStatus(StatusConstant.NO);
+
+            BigDecimal packagingMaterialCost = orderSkuBomMap.getOrDefault(orderSkuId, Collections.emptyList()).stream()
+                    .map(item -> item.getUnitPrice().multiply(item.getQuantity()))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            orderExchangeDetail.setReturnAmount((orderSku.getUnitPrice()
+                    .add(packagingMaterialCost)).multiply(orderExchangeDetail.getQuantity()));
+
+            // 保存临时入库数据
+            OrderSku tempOrderSku = new OrderSku();
+            tempOrderSku.setId(orderSku.getId());
+            tempOrderSku.setSkuSpecId(orderSku.getSkuSpecId());
+            tempOrderSku.setBomSpecId(orderSku.getBomSpecId());
+            tempOrderSku.setQuantity(orderExchangeDetail.getQuantity());
+            tempOrderSkuList.add(tempOrderSku);
         }
 
         orderExchangeDto.setCode(orderExchangeDto.getType() == 1 ? CodeEnum.TH_CODE.getCode() : CodeEnum.HH_CODE.getCode());
-        save(orderExchangeDto);
-        orderExchangeDetailService.saveBatch(orderExchangeDetailList);
-        ObsFileUtil.saveFile(orderExchangeDto.getFileList(), orderExchangeDto.getId());
+        orderExchangeDto.setStatus(StatusConstant.YES);
 
-        Map<Long, BigDecimal> exchangeDetailMap = orderExchangeDetailList.stream()
-                .filter(item -> item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
-                .collect(Collectors.toMap(OrderExchangeDetail::getOrderSkuId, OrderExchangeDetail::getQuantity));
-        if (ObjectUtil.isEmpty(exchangeDetailMap)) {
-            return;
-        }
-        // 新增售后订单,分类修改为售后订单
         OrderInfo orderInfo = orderService.getById(orderExchangeDto.getOrderInfoId());
-        orderInfo.setId(IdWorker.getId());
-        orderInfo.setWlnUid(null);
-        orderInfo.setClassify(OrderClassifyEnum.AFTER_SALE_ORDER.getKey());
-        orderInfo.setStatus(OrderStatusEnum.EXCHANGE.getKey());
-        orderInfo.setTotalAmount(BigDecimal.ZERO);
-        orderInfo.setProductTotalAmount(BigDecimal.ZERO);
-        orderInfo.setCustomProcessingFee(BigDecimal.ZERO);
-        orderInfo.setLssueFee(BigDecimal.ZERO);
-        orderInfo.setDeliveryMaterialsFee(BigDecimal.ZERO);
-        orderInfo.setPackingLabor(BigDecimal.ZERO);
-        orderInfo.setManagementFee(BigDecimal.ZERO);
-        orderInfo.setPackagingMaterialCost(BigDecimal.ZERO);
-        List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(BaseIdPo::getId, exchangeDetailMap.keySet()));
-        Map<Long, Long> orderSkuIdMap = new HashMap<>();
-        for (OrderSku orderSku : orderSkuList) {
-            BigDecimal quantity = exchangeDetailMap.get(orderSku.getId());
-            long orderSkuId = IdWorker.getId();
-            orderSkuIdMap.put(orderSku.getId(), orderSkuId);
-            orderSku.setQuantity(quantity);
-            orderSku.setId(orderSkuId);
-            orderSku.setOrderId(orderInfo.getId());
-            this.addOrderInfoPrice(orderInfo, orderSku);
-        }
-        List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.in(OrderSkuBom::getOrderSkuId, exchangeDetailMap.keySet()));
-        // 替换订单id和订单sku id
-        for (OrderSkuBom orderSkuBom : orderSkuBomList) {
-            orderSkuBom.setId(null);
-            orderSkuBom.setOrderId(orderInfo.getId());
-            orderSkuBom.setOrderSkuId(orderSkuIdMap.get(orderSkuBom.getOrderSkuId()));
-        }
-
-        // 新增订单信息
-        orderService.save(orderInfo);
-        orderSkuService.saveBatch(orderSkuList);
-        orderSkuBomService.saveBatch(orderSkuBomList);
-        // 生成对账单
-        StatementOfAccountDto statement = new StatementOfAccountDto();
-        statement.setDepartmentId(orderInfo.getDepartmentId());
-        statement.setOrderIdList(Collections.singletonList(orderInfo.getId()));
-        statementOfAccountService.add(statement);
-
-        // 筛选掉赠品sku
-        List<Long> skuSpecIds = orderSkuList.stream().map(OrderSku::getSkuSpecId).collect(Collectors.toList());
-        Set<Long> giftSkuSpecIds = skuSpecService.getGiftIdListByIdList(skuSpecIds);
-        List<OrderSku> tempOrderSkuList = orderSkuList.stream()
-                .filter(item -> giftSkuSpecIds.isEmpty() || !giftSkuSpecIds.contains(item.getSkuSpecId()))
-                .collect(Collectors.toList());
+        // 获取对账单
+        StatementOfAccount statementOfAccount = this.getStatementOfAccount(orderInfo.getDepartmentId());
+        orderExchangeDto.setStatementOfAccountId(statementOfAccount.getId());
 
         // 售后商品入库
         if (Objects.equals(orderExchangeDto.getWarehouseId(), WarehouseConstant.PRODUCTION_DEFECTIVE)) {
@@ -312,9 +285,32 @@ public class OrderExchangeServiceImpl extends ServiceImpl<OrderExchangeMapper, O
             inOutStorageDto.setInOutStorageBomList(inOutStorageBomList);
             inOutStorageService.add(inOutStorageDto);
         } else {
+            // 成品质检通过后出库包材,重新包装
+            Map<Long, OrderSku> finishedOrderSkuMap = tempOrderSkuList.stream().collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
+            orderSkuBomList.removeAll(tempOrderSkuBomList);
+            List<InOutStorageBom> outStorageBomList = orderSkuBomList.stream().map(item -> {
+                InOutStorageBom inOutStorageBom = new InOutStorageBom();
+                inOutStorageBom.setBomSpecId(item.getBomSpecId());
+                inOutStorageBom.setQuantity(item.getQuantity().multiply(finishedOrderSkuMap.get(item.getOrderSkuId()).getQuantity()));
+                return inOutStorageBom;
+            }).collect(Collectors.toList());
+            InOutStorageDto inOutStorageDto = new InOutStorageDto();
+            inOutStorageDto.setType(InOutTypeEnum.OUT.getKey());
+            inOutStorageDto.setDetailType(OutDetailTypeEnum.PRODUCTION.getKey());
+            inOutStorageDto.setWarehouseId(WarehouseConstant.PACKAGING_MATERIAL);
+            inOutStorageDto.setDepartmentId(DepartmentConstant.SD_SPORTS);
+            inOutStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
+            inOutStorageDto.setInOutStorageBomList(outStorageBomList);
+            inOutStorageDto.setLockStorage(StatusConstant.NO);
+            inOutStorageService.add(inOutStorageDto);
             // 入成品库
             inventoryFinishedService.noSourceInWarehousing(tempOrderSkuList);
         }
+
+        // 保存数据
+        save(orderExchangeDto);
+        orderExchangeDetailService.saveBatch(orderExchangeDetailList);
+        ObsFileUtil.saveFile(orderExchangeDto.getFileList(), orderExchangeDto.getId());
     }
 
     @Override
@@ -322,34 +318,163 @@ public class OrderExchangeServiceImpl extends ServiceImpl<OrderExchangeMapper, O
         this.removeById(id);
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void orderExchangeCheck(OrderExchangeDto orderExchangeDto) {
+        OrderExchange orderExchange = this.getById(orderExchangeDto.getId());
+        if (orderExchange == null) {
+            throw new ServiceException("未知订单号");
+        }
+        if (Objects.equals(orderExchange.getStatus(), StatusConstant.YES)) {
+            throw new ServiceException("订单已质检");
+        }
+        orderExchange.setStatus(StatusConstant.YES);
+        List<OrderExchangeDetail> detailList = orderExchangeDto.getOrderExchangeDetailList();
+        if (ObjectUtil.isEmpty(detailList)) {
+            throw new ServiceException("订单商品不能为空");
+        }
+        OrderInfo orderInfo = orderService.getById(orderExchange.getOrderInfoId());
+        List<OrderSku> tempOrderSkuList = new ArrayList<>();
+        List<InOutStorageBom> tempInOutStorageBomList = new ArrayList<>();
+        List<Long> orderSkuIds = detailList.stream().map(OrderExchangeDetail::getOrderSkuId).collect(Collectors.toList());
+        Map<Long, OrderSku> orderSkuMap = orderSkuService.mapKEntity(BaseIdPo::getId, q -> q.in(BaseIdPo::getId, orderSkuIds));
+        for (OrderExchangeDetail detail : detailList) {
+            int compareTo = detail.getQuantity().compareTo(detail.getCheckPassesQuantity());
+            if (compareTo == 0) {
+                // 质检数量和退货数量一致时,全部入库成品仓
+                OrderSku orderSku = new OrderSku();
+                orderSku.setId(detail.getOrderSkuId());
+                orderSku.setSkuSpecId(orderSkuMap.get(detail.getOrderSkuId()).getSkuSpecId());
+                orderSku.setQuantity(detail.getQuantity());
+                tempOrderSkuList.add(orderSku);
+            } else if (compareTo > 0) {
+                // 质检数量和退货数量不一致时,质检通过数量入库成品仓,其它入次品仓
+                OrderSku orderSku = orderSkuMap.get(detail.getOrderSkuId());
+                OrderSku tempOrderSku = new OrderSku();
+                tempOrderSku.setId(orderSku.getId());
+                tempOrderSku.setSkuSpecId(orderSku.getSkuSpecId());
+                tempOrderSku.setQuantity(detail.getCheckPassesQuantity());
+                tempOrderSkuList.add(tempOrderSku);
+                InOutStorageBom inStorageBom = new InOutStorageBom();
+                inStorageBom.setBomSpecId(orderSku.getBomSpecId());
+                inStorageBom.setQuantity(detail.getQuantity().subtract(detail.getCheckPassesQuantity()));
+                tempInOutStorageBomList.add(inStorageBom);
+            } else {
+                throw new ServiceException("质检数量不能超过退货数量!");
+            }
+        }
+
+        // 入库
+        if (!tempOrderSkuList.isEmpty()) {
+            // 成品质检通过后出库包材,重新包装
+            Map<Long, OrderSku> finishedOrderSkuMap = tempOrderSkuList.stream().collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
+            List<Long> orderSkuId = tempOrderSkuList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
+            List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.in(OrderSkuBom::getOrderSkuId, orderSkuId));
+            // 筛选掉可二次利用的包材
+            List<Long> bomSpecIdList = orderSkuBomList.stream()
+                    .map(OrderSkuBom::getBomSpecId)
+                    .distinct()
+                    .collect(Collectors.toList());
+            Map<Long, BomSpecBo> bomSpecBoMap = skuSpecService.getBomSpecBoByIdList(bomSpecIdList);
+            List<OrderSkuBom> tempOrderSkuBomList = orderSkuBomList.stream()
+                    .filter(item -> {
+                        BomSpecBo bomSpecBo = bomSpecBoMap.get(item.getBomSpecId());
+                        if (bomSpecBo == null
+                                || Objects.equals(bomSpecBo.getClassifyId(), BomClassifyConstant.MESH_BAG)
+                                    || Objects.equals(bomSpecBo.getClassifyId(), BomClassifyConstant.SUSPENDERS)) {
+                            return false;
+                        }
+                        return true;
+                    })
+                    .collect(Collectors.toList());
+            if (!tempOrderSkuBomList.isEmpty()) {
+                List<InOutStorageBom> outStorageBomList = tempOrderSkuBomList.stream().map(item -> {
+                    InOutStorageBom inOutStorageBom = new InOutStorageBom();
+                    inOutStorageBom.setBomSpecId(item.getBomSpecId());
+                    inOutStorageBom.setQuantity(item.getQuantity().multiply(finishedOrderSkuMap.get(item.getOrderSkuId()).getQuantity()));
+                    return inOutStorageBom;
+                }).collect(Collectors.toList());
+                InOutStorageDto inOutStorageDto = new InOutStorageDto();
+                inOutStorageDto.setType(InOutTypeEnum.OUT.getKey());
+                inOutStorageDto.setDetailType(OutDetailTypeEnum.PRODUCTION.getKey());
+                inOutStorageDto.setWarehouseId(WarehouseConstant.PACKAGING_MATERIAL);
+                inOutStorageDto.setDepartmentId(DepartmentConstant.SD_SPORTS);
+                inOutStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
+                inOutStorageDto.setInOutStorageBomList(outStorageBomList);
+                inOutStorageDto.setLockStorage(StatusConstant.NO);
+                inOutStorageService.add(inOutStorageDto);
+            }
+
+            inventoryFinishedService.noSourceInWarehousing(tempOrderSkuList);
+        }
+        if (!tempInOutStorageBomList.isEmpty()) {
+            // 合并相同bom规格出库数量
+            List<InOutStorageBom> inOutStorageBomList = new ArrayList<>(tempInOutStorageBomList.stream()
+                    .collect(Collectors.toMap(
+                            InOutStorageBom::getBomSpecId,
+                            Function.identity(),
+                            (v1, v2) -> {
+                                v1.setQuantity(v1.getQuantity().add(v2.getQuantity()));
+                                return v1;
+                            })).values());
+
+            InOutStorageDto inOutStorageDto = new InOutStorageDto();
+            inOutStorageDto.setType(InOutTypeEnum.IN.getKey());
+            inOutStorageDto.setDetailType(InDetailTypeEnum.ABANDON.getKey());
+            inOutStorageDto.setWarehouseId(WarehouseConstant.PRODUCTION_DEFECTIVE);
+            inOutStorageDto.setDepartmentId(DepartmentConstant.SD_SPORTS);
+            inOutStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
+            inOutStorageDto.setRemark("订单:" + orderInfo.getCode() + "订单售后报废入库");
+            inOutStorageDto.setInOutStorageBomList(inOutStorageBomList);
+            inOutStorageService.add(inOutStorageDto);
+        }
+        // 获取对账单
+        StatementOfAccount statementOfAccount = this.getStatementOfAccount(orderInfo.getDepartmentId());
+        orderExchange.setStatementOfAccountId(statementOfAccount.getId());
+
+        // 更新数据
+        this.updateById(orderExchange);
+        orderExchangeDetailService.updateBatchById(detailList);
+
+    }
+
+    @Override
+    public Map<Long, OrderExchangeAccountBo> orderExchangeAccountStatistics(List<Long> statementOfAccountIdList) {
+        IWrapper<OrderExchange> wrapper = getWrapper();
+        wrapper.eq("oe", OrderExchange::getStatus, StatusConstant.YES);
+        wrapper.in("oe", OrderExchange::getStatementOfAccountId, statementOfAccountIdList);
+        wrapper.groupBy("oe.statement_of_account_id");
+
+        List<OrderExchangeAccountBo> list = this.baseMapper.orderExchangeAccountStatistics(wrapper);
+
+        if (list.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        return list.stream().collect(Collectors.toMap(OrderExchangeAccountBo::getStatementOfAccountId, Function.identity()));
+    }
+
     /**
-     * 添加订单价格
+     * 获取对账单
+     * @param departmentId
+     * @return
      */
-    private void addOrderInfoPrice(OrderInfo orderInfo, OrderSku orderSku) {
-        BigDecimal quantity = orderSku.getQuantity();
-
-        BigDecimal productTotalAmount = quantity.multiply(orderSku.getUnitPrice());
-        BigDecimal customProcessingFee = quantity.multiply(orderSku.getCustomProcessingFee());
-        BigDecimal lssueFee = quantity.multiply(orderSku.getLssueFee());
-        BigDecimal deliveryMaterialsFee = quantity.multiply(orderSku.getDeliveryMaterialsFee());
-        BigDecimal packingLabor = quantity.multiply(orderSku.getPackingLabor());
-        BigDecimal packagingMaterialCost = quantity.multiply(orderSku.getPackagingMaterialCost());
-        BigDecimal managementFee = quantity.multiply(orderSku.getManagementFee());
-        BigDecimal totalAmount = productTotalAmount
-                .add(customProcessingFee)
-                .add(lssueFee)
-                .add(deliveryMaterialsFee)
-                .add(packingLabor)
-                .add(packagingMaterialCost)
-                .add(managementFee);
-
-        orderInfo.setProductTotalAmount(orderInfo.getProductTotalAmount().add(productTotalAmount));
-        orderInfo.setCustomProcessingFee(orderInfo.getCustomProcessingFee().add(customProcessingFee));
-        orderInfo.setLssueFee(orderInfo.getLssueFee().add(lssueFee));
-        orderInfo.setDeliveryMaterialsFee(orderInfo.getDeliveryMaterialsFee().add(deliveryMaterialsFee));
-        orderInfo.setPackingLabor(orderInfo.getPackingLabor().add(packingLabor));
-        orderInfo.setManagementFee(orderInfo.getManagementFee().add(managementFee));
-        orderInfo.setPackagingMaterialCost(orderInfo.getPackagingMaterialCost().add(packagingMaterialCost));
-        orderInfo.setTotalAmount(orderInfo.getTotalAmount().add(totalAmount));
+    private StatementOfAccount getStatementOfAccount(Long departmentId) {
+        Date date = new Date();
+        Date beginDate = DateUtil.beginOfDay(date);
+        Date endDate = DateUtil.endOfDay(date);
+        StatementOfAccount statementOfAccount = statementOfAccountService.getOne(q -> q
+                .eq(StatementOfAccount::getDepartmentId, departmentId)
+                .between(StatementOfAccount::getTimePeriod, beginDate, endDate));
+
+        if (statementOfAccount == null) {
+            statementOfAccount = new StatementOfAccount();
+            statementOfAccount.setDepartmentId(departmentId);
+            statementOfAccount.setCode(CodeEnum.STATEMENT_OF_ACCOUNT_CODE.getCode());
+            statementOfAccount.setType(2);
+            statementOfAccount.setTimePeriod(new Date());
+            statementOfAccountService.save(statementOfAccount);
+        }
+        return statementOfAccount;
     }
 }

+ 6 - 6
sd-business/src/main/java/com/sd/business/service/purchase/impl/PurchaseBomServiceImpl.java

@@ -82,9 +82,9 @@ public class PurchaseBomServiceImpl extends ServiceImpl<PurchaseBomMapper, Purch
         wrapper.eq("b", Bom::getEmbossingProcess, dto.getEmbossingProcess());
         wrapper.eq("b", Bom::getFrontGrain, dto.getFrontGrain());
         wrapper.eq("b", Bom::getReverseGrain, dto.getReverseGrain());
-        wrapper.eq("bs", BomSpec::getColour, dto.getColour());
-        wrapper.eq("bs", BomSpec::getCode, dto.getBomSpecCode());
-        wrapper.eq("bs", BomSpec::getName, dto.getBomSpecName());
+        wrapper.like("bs", BomSpec::getColour, dto.getColour());
+        wrapper.like("bs", BomSpec::getCode, dto.getBomSpecCode());
+        wrapper.like("bs", BomSpec::getName, dto.getBomSpecName());
         if (ObjectUtil.isNotNull(dto.getBomClassifyId())) {
             List<Long> childrenIdList = bomClassifyService.getChildrenIdList(dto.getBomClassifyId());
             wrapper.in("b", Bom::getBomClassifyId, childrenIdList);
@@ -105,9 +105,9 @@ public class PurchaseBomServiceImpl extends ServiceImpl<PurchaseBomMapper, Purch
         wrapper = IWrapper.getWrapper();
         wrapper.eq("pb", PurchaseBom::getPurchaseId, dto.getPurchaseId());
         wrapper.in("bs", BomSpec::getBomId, bomIdList);
-        wrapper.eq("bs", BomSpec::getColour, dto.getColour());
-        wrapper.eq("bs", BomSpec::getCode, dto.getBomSpecCode());
-        wrapper.eq("bs", BomSpec::getName, dto.getBomSpecName());
+        wrapper.like("bs", BomSpec::getColour, dto.getColour());
+        wrapper.like("bs", BomSpec::getCode, dto.getBomSpecCode());
+        wrapper.like("bs", BomSpec::getName, dto.getBomSpecName());
         wrapper.orderByDesc("pb", PurchaseBom::getId);
         List<PurchaseBomInfoVo> list = this.baseMapper.getPurchaseBomInfoList(wrapper);
         Map<Long, List<PurchaseBomInfoVo>> bomSpecIdMap = list.stream().collect(Collectors.groupingBy(PurchaseBomInfoVo::getBomId));

+ 0 - 6
sd-business/src/main/java/com/sd/business/service/statement/StatementOfAccountService.java

@@ -92,10 +92,4 @@ public interface StatementOfAccountService extends BaseService<StatementOfAccoun
      * @return
      */
     StatementOrderClassifyTotalCountVo getOrderClassifyTotalCount(List<Long> idList);
-
-    /**
-     * 获取未签核的数量
-     * @return
-     */
-    Long getNotCheckCount();
 }

+ 100 - 0
sd-business/src/main/java/com/sd/business/service/statement/impl/DocumentByAfterSaleOrderExcelCellMergeStrategy.java

@@ -0,0 +1,100 @@
+package com.sd.business.service.statement.impl;
+
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import com.sd.business.entity.statement.vo.DocumentByOrderVo;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DocumentByAfterSaleOrderExcelCellMergeStrategy extends AbstractMergeStrategy {
+
+    // 最大行数
+    private final int maxRow;
+
+    // sku需要合并的列
+    private final List<Integer> skuColIndex = Arrays.asList(3, 4, 5, 16, 17, 18);
+    // sku无需合并的行
+    private final List<Integer> skuRowIndex = new ArrayList<>();
+
+    // 订单需要合并的列
+    private final List<Integer> orderColIndex = Arrays.asList(0, 1, 2, 19);
+    // 订单无需合并的行
+    private final List<Integer> orderRowIndex = new ArrayList<>();
+
+    public DocumentByAfterSaleOrderExcelCellMergeStrategy(List<DocumentByOrderVo> documentByOrderVoList) {
+
+        // 无需合并的行数
+        int mergeRowIndex = 2;
+        skuRowIndex.add(mergeRowIndex);
+        orderRowIndex.add(mergeRowIndex);
+
+        for (DocumentByOrderVo documentByOrderVo : documentByOrderVoList) {
+            List<DocumentByOrderVo.SkuSpec> skuSpecList = documentByOrderVo.getSkuSpecList();
+
+            // 赋值订单无需合并的行
+            Integer size = skuSpecList.stream().map(item -> item.getBomSpecList().size()).reduce(0, Integer::sum);
+            int orderRowIndexNumber = orderRowIndex.isEmpty() ? mergeRowIndex : orderRowIndex.get(orderRowIndex.size() - 1);
+            orderRowIndex.add(size + orderRowIndexNumber);
+
+            // 赋值sku无需合并的行
+            for (DocumentByOrderVo.SkuSpec skuSpec : skuSpecList) {
+                int bomSpecListSize = skuSpec.getBomSpecList().size();
+                int skuRowIndexSize = skuRowIndex.size();
+                int skuRowIndexNumber = skuRowIndexSize == 0 ? mergeRowIndex : skuRowIndex.get(skuRowIndexSize - 1);
+                skuRowIndex.add(bomSpecListSize + skuRowIndexNumber);
+            }
+        }
+
+        maxRow = skuRowIndex.get(skuRowIndex.size() - 1);
+    }
+
+    @Override
+    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+
+        // 当前行列
+        int curRowIndex = cell.getRowIndex();
+
+        // 判断是否是最后一行
+        if (curRowIndex != maxRow) {
+            return;
+        }
+
+        int curColIndex = cell.getColumnIndex();
+
+        // 合并订单列
+        if (orderColIndex.contains(curColIndex)) {
+            for (int i = 1; i < orderRowIndex.size(); i++) {
+                int beginRow = orderRowIndex.get(i - 1) + 1;
+                Integer endRow = orderRowIndex.get(i);
+                mergeWithPrevRow(sheet, beginRow, endRow, curColIndex);
+            }
+        }
+
+        // 合并sku列
+        else if (skuColIndex.contains(curColIndex)) {
+            for (int i = 1; i < skuRowIndex.size(); i++) {
+                int beginRow = skuRowIndex.get(i - 1) + 1;
+                Integer endRow = skuRowIndex.get(i);
+                mergeWithPrevRow(sheet, beginRow, endRow, curColIndex);
+            }
+        }
+
+    }
+
+    /**
+     * 合并单元格
+     */
+    private void mergeWithPrevRow(Sheet sheet, int beginRow, int endRow, int col) {
+        if (beginRow == endRow) {
+            return;
+        }
+        CellRangeAddress cellRangeAddress = new CellRangeAddress(beginRow, endRow, col, col);
+        sheet.addMergedRegionUnsafe(cellRangeAddress);
+    }
+
+}

+ 18 - 5
sd-business/src/main/java/com/sd/business/service/statement/impl/StatementOfAccountExportServiceImpl.java

@@ -13,9 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 @Service
 public class StatementOfAccountExportServiceImpl implements StatementOfAccountExportService {
@@ -37,8 +35,16 @@ public class StatementOfAccountExportServiceImpl implements StatementOfAccountEx
         map.put("endDate", endDate);
         map.put("totalQuantity", StreamUtil.bigDecimalAdd(list, DocumentBySkuVo::getQuantity));
         map.put("totalSubtotal", StreamUtil.bigDecimalAdd(list, DocumentBySkuVo::getSubtotal));
+        map.put("totalCheckFee", StreamUtil.bigDecimalAdd(list, DocumentBySkuVo::getCheckFee));
 
-        TemplateExcelUtil.writeBrowser("skuDocument.xlsx", OrderClassifyEnum.getEnum(orderClassify).getValue() + "-sku对账单", response, list, map);
+        String fileName;
+        if (Objects.equals(orderClassify, OrderClassifyEnum.AFTER_SALE_ORDER.getKey())) {
+            fileName = "afterSaleSkuDocument.xlsx";
+        } else {
+            fileName = "skuDocument.xlsx";
+        }
+
+        TemplateExcelUtil.writeBrowser(fileName, OrderClassifyEnum.getEnum(orderClassify).getValue() + "-sku对账单", response, list, map);
     }
 
     @Override
@@ -58,8 +64,15 @@ public class StatementOfAccountExportServiceImpl implements StatementOfAccountEx
         map.put("totalPackingLaborSummary", StreamUtil.bigDecimalAdd(list, DocumentByBomVo::getPackingLaborSummary));
         map.put("totalManagementFeeSummary", StreamUtil.bigDecimalAdd(list, DocumentByBomVo::getManagementFeeSummary));
         map.put("totalProofingFeeSummary", StreamUtil.bigDecimalAdd(list, DocumentByBomVo::getProofingFeeSummary));
+        map.put("totalCheckFeeSummary", StreamUtil.bigDecimalAdd(list, DocumentByBomVo::getCheckFeeSummary));
 
-        TemplateExcelUtil.writeBrowser("bomDocument.xlsx", OrderClassifyEnum.getEnum(orderClassify).getValue() + "-bom对账单", response, list, map);
+        String fileName;
+        if (Objects.equals(orderClassify, OrderClassifyEnum.AFTER_SALE_ORDER.getKey())) {
+            fileName = "afterSaleBomDocument.xlsx";
+        } else {
+            fileName = "bomDocument.xlsx";
+        }
+        TemplateExcelUtil.writeBrowser(fileName, OrderClassifyEnum.getEnum(orderClassify).getValue() + "-bom对账单", response, list, map);
     }
 
 }

+ 16 - 7
sd-business/src/main/java/com/sd/business/service/statement/impl/StatementOfAccountMergeServiceImpl.java

@@ -16,6 +16,7 @@ import com.ruoyi.common.utils.PageUtils;
 import com.sd.business.entity.excel.enums.ExcelTypeEnum;
 import com.sd.business.entity.inventory.po.InventoryFinishedOrder;
 import com.sd.business.entity.inventory.po.InventoryFinishedOrderDetail;
+import com.sd.business.entity.order.bo.OrderExchangeAccountBo;
 import com.sd.business.entity.order.enums.OrderClassifyEnum;
 import com.sd.business.entity.order.enums.OrderStatusEnum;
 import com.sd.business.entity.order.po.OrderInfo;
@@ -32,6 +33,7 @@ import com.sd.business.service.excel.ExcelGenerateLogService;
 import com.sd.business.service.inventory.InventoryFinishedOrderDetailService;
 import com.sd.business.service.inventory.InventoryFinishedOrderService;
 import com.sd.business.service.inventory.InventoryFinishedService;
+import com.sd.business.service.order.OrderExchangeService;
 import com.sd.business.service.order.OrderService;
 import com.sd.business.service.order.OrderSkuProductionCostService;
 import com.sd.business.service.order.OrderSkuService;
@@ -105,6 +107,9 @@ public class StatementOfAccountMergeServiceImpl implements StatementOfAccountMer
     @Autowired
     private OutboundOrderService outboundOrderService;
 
+    @Autowired
+    private OrderExchangeService orderExchangeService;
+
     @Override
     public Page<StatementOfAccountMergePageVo> getPage(StatementOfAccountMergePageDto dto) {
 
@@ -176,8 +181,8 @@ public class StatementOfAccountMergeServiceImpl implements StatementOfAccountMer
         Map<Long, List<OrderInfo>> map = orderService.mapKGroup(OrderInfo::getStatementOfAccountId,
                 q -> q.in(OrderInfo::getStatementOfAccountId, statementOfAccountIdList));
 
-        Map<Long, Integer> statementOfAccountMap = statementOfAccountService.mapKV(BaseIdPo::getId, StatementOfAccount::getCheckStatus,
-                q -> q.in(BaseIdPo::getId, statementOfAccountIdList));
+        // 获取售后订单
+        Map<Long, OrderExchangeAccountBo> exchangeAccountBoMap = orderExchangeService.orderExchangeAccountStatistics(statementOfAccountIdList);
 
         for (StatementOfAccountMergePageVo record : records) {
 
@@ -191,6 +196,15 @@ public class StatementOfAccountMergeServiceImpl implements StatementOfAccountMer
                 Long statementOfAccountId = Convert.toLong(statementOfAccountIdStr);
                 List<OrderInfo> tempOrderInfoList = map.get(statementOfAccountId);
 
+                OrderExchangeAccountBo orderExchangeAccountBo = exchangeAccountBoMap.get(statementOfAccountId);
+                if (orderExchangeAccountBo != null) {
+                    // 对账金额减去退货金额,加每个退货sku的两元质检费
+                    record.setOrderQuantity(record.getOrderQuantity() + orderExchangeAccountBo.getOrderNum());
+                    record.setReconcilingAmount(record.getReconcilingAmount()
+                            .subtract(orderExchangeAccountBo.getReturnAmount())
+                            .add(BigDecimal.valueOf(orderExchangeAccountBo.getOrderSkuNum()).multiply(BigDecimal.valueOf(2))));
+                }
+
                 if (ObjectUtil.isEmpty(tempOrderInfoList)) {
                     continue;
                 }
@@ -200,11 +214,6 @@ public class StatementOfAccountMergeServiceImpl implements StatementOfAccountMer
 
                 record.setOrderQuantity(record.getOrderQuantity() + tempOrderInfoList.size());
                 record.setReconcilingAmount(record.getReconcilingAmount().add(reconcilingAmount));
-
-                if (ObjectUtil.notEqual(record.getCheckStatus(), StatusConstant.NO)
-                        && ObjectUtil.equals(statementOfAccountMap.get(statementOfAccountId), StatusConstant.NO)) {
-                    record.setCheckStatus(StatusConstant.NO);
-                }
             }
 
         }

+ 468 - 18
sd-business/src/main/java/com/sd/business/service/statement/impl/StatementOfAccountServiceImpl.java

@@ -17,12 +17,12 @@ import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.wrapper.IWrapper;
 import com.ruoyi.framework.config.ThreadPoolConfig;
 import com.sd.business.entity.bom.bo.BomSpecBo;
+import com.sd.business.entity.bom.constant.BomClassifyConstant;
 import com.sd.business.entity.department.po.Department;
 import com.sd.business.entity.excel.enums.ExcelTypeEnum;
+import com.sd.business.entity.order.bo.OrderExchangeAccountBo;
 import com.sd.business.entity.order.enums.OrderClassifyEnum;
-import com.sd.business.entity.order.po.OrderInfo;
-import com.sd.business.entity.order.po.OrderSku;
-import com.sd.business.entity.order.po.OrderSkuBom;
+import com.sd.business.entity.order.po.*;
 import com.sd.business.entity.sku.po.SkuSpec;
 import com.sd.business.entity.statement.dto.FileUploadDto;
 import com.sd.business.entity.statement.dto.StatementOfAccountDto;
@@ -33,9 +33,7 @@ import com.sd.business.mapper.statement.StatementOfAccountMapper;
 import com.sd.business.service.bom.BomSpecService;
 import com.sd.business.service.department.DepartmentService;
 import com.sd.business.service.excel.ExcelGenerateLogService;
-import com.sd.business.service.order.OrderService;
-import com.sd.business.service.order.OrderSkuBomService;
-import com.sd.business.service.order.OrderSkuService;
+import com.sd.business.service.order.*;
 import com.sd.business.service.sku.SkuSpecService;
 import com.sd.business.service.statement.StatementOfAccountExportService;
 import com.sd.business.service.statement.StatementOfAccountService;
@@ -99,13 +97,18 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
     @Autowired
     private ExcelGenerateLogService excelGenerateLogService;
 
+    @Autowired
+    private OrderExchangeService orderExchangeService;
+
+    @Autowired
+    private OrderExchangeDetailService orderExchangeDetailService;
+
     @Override
     public Page<StatementOfAccountVo> getPage(StatementOfAccountSelectDto dto) {
 
         IWrapper<StatementOfAccount> wrapper = getWrapper();
         wrapper.like("soa", StatementOfAccount::getCode, dto.getCode());
         wrapper.eq("soa", StatementOfAccount::getDepartmentId, dto.getDepartmentId());
-        wrapper.eq("soa", StatementOfAccount::getCheckStatus, dto.getCheckStatus());
         wrapper.ge("soa", StatementOfAccount::getTimePeriod, dto.getBeginTime());
         wrapper.le("soa", StatementOfAccount::getTimePeriod, dto.getEndTime());
         wrapper.orderByDesc("soa", StatementOfAccount::getCode);
@@ -136,6 +139,9 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
                         Function.identity()
                 ));
 
+        // 获取售后订单
+        Map<Long, OrderExchangeAccountBo> exchangeAccountBoMap = orderExchangeService.orderExchangeAccountStatistics(idList);
+
         for (StatementOfAccountVo record : records) {
             record.setReceiptFileList(receiptFileMap.getOrDefault(record.getId(), Collections.emptyList()));
             record.setProofFileList(proofFileMap.getOrDefault(record.getId(), Collections.emptyList()));
@@ -147,6 +153,14 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
                 record.setOrderNum(Convert.toInt(tempMap.get("orderNum"), 0));
                 record.setAmount(Convert.toBigDecimal(tempMap.get("amount"), BigDecimal.ZERO));
             }
+            OrderExchangeAccountBo orderExchangeAccountBo = exchangeAccountBoMap.get(record.getId());
+            if (orderExchangeAccountBo != null) {
+                // 对账金额减去退货金额,加每个退货sku的两元质检费
+                record.setOrderNum(record.getOrderNum() + orderExchangeAccountBo.getOrderNum());
+                record.setAmount(record.getAmount()
+                        .subtract(orderExchangeAccountBo.getReturnAmount())
+                        .add(BigDecimal.valueOf(orderExchangeAccountBo.getOrderSkuNum()).multiply(BigDecimal.valueOf(2))));
+            }
         }
 
         return page;
@@ -255,6 +269,10 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
 
     @Override
     public List<DocumentBySkuVo> getSkuDocument(List<Long> statementOfAccountIdList, Integer orderClassify) {
+        // 获取售后sku记录
+        if (Objects.equals(orderClassify, OrderClassifyEnum.AFTER_SALE_ORDER.getKey())) {
+            return getAfterSaleSkuDocument(statementOfAccountIdList);
+        }
 
         // 获取订单id列表
         List<Long> orderIdList = getOrderIdList(statementOfAccountIdList, orderClassify);
@@ -329,6 +347,10 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
 
     @Override
     public List<DocumentByBomVo> getBomDocument(List<Long> statementOfAccountIdList, Integer orderClassify) {
+        // 获取售后bom记录
+        if (Objects.equals(orderClassify, OrderClassifyEnum.AFTER_SALE_ORDER.getKey())) {
+            return getAfterSaleBomDocument(statementOfAccountIdList);
+        }
 
         // 获取订单id列表
         List<Long> orderIdList = getOrderIdList(statementOfAccountIdList, orderClassify);
@@ -356,7 +378,7 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
                         .laserMitochondrialSummary((Objects.equals(item.getCustomProcessingType(), "10")
                                 ? item.getCustomProcessingFee().multiply(item.getQuantity()) : BigDecimal.ZERO))
                         .lssueFeeSummary(item.getLssueFee().multiply(item.getQuantity()))
-                        .deliveryMaterialsFeeSummary(item.getDeliveryMaterialsFee().multiply(item.getQuantity()))
+                        .deliveryMaterialsFeeSummary(item.getDeliveryMaterialsFee().multiply(item.getQuantity()).setScale(2, RoundingMode.HALF_UP))
                         .packingLaborSummary(item.getPackingLabor().multiply(item.getQuantity()))
                         .managementFeeSummary(item.getManagementFee().multiply(item.getQuantity()))
                         .proofingFeeSummary(item.getProofingFee())
@@ -452,6 +474,12 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
     public List<DocumentByOrderVo> getOrderDocument(List<Long> statementOfAccountId, Integer orderClassify) {
 
         Assert.notEmpty(statementOfAccountId, "对账单id不能为空");
+
+        // 获取售后bom记录
+        if (Objects.equals(orderClassify, OrderClassifyEnum.AFTER_SALE_ORDER.getKey())) {
+            return getAfterSaleOrderDocument(statementOfAccountId);
+        }
+
         List<OrderInfo> orderList = orderService.list(q -> q
                 .in(OrderInfo::getStatementOfAccountId, statementOfAccountId)
                 .eq(OrderInfo::getClassify, orderClassify));
@@ -569,16 +597,21 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
     @Override
     public StatementOrderClassifyTotalCountVo getOrderClassifyTotalCount(List<Long> idList) {
         Assert.notEmpty(idList, "对账单id不能为空");
-        return orderService.getOrderClassifyTotalCount(idList);
-    }
-
-    @Override
-    public Long getNotCheckCount() {
-        // 查询佰卓和实业的事业部id
-        List<Department> departmentList = departmentService.list(q -> q.like(Department::getName, "实业").or().eq(Department::getName, "佰卓").select(BaseIdPo::getId));
-        List<Long> departmentIds = departmentList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
-        return this.count(q -> q.in(StatementOfAccount::getDepartmentId, departmentIds)
-                .eq(StatementOfAccount::getCheckStatus, StatusConstant.NO));
+        StatementOrderClassifyTotalCountVo vo = orderService.getOrderClassifyTotalCount(idList);
+        if (vo == null) {
+            vo = new StatementOrderClassifyTotalCountVo();
+            vo.setWlnOrderCount(0);
+            vo.setPurchaseOrderCount(0);
+            vo.setOutsourceOrderCount(0);
+            vo.setAfterSaleOrderCount(0);
+            vo.setNoReasonOrderCount(0);
+        }
+        // 查询售后订单数量
+        long count = orderExchangeService.count(q -> q
+                .eq(OrderExchange::getStatus, StatusConstant.YES)
+                .in(OrderExchange::getStatementOfAccountId, idList));
+        vo.setAfterSaleOrderCount((int) count);
+        return vo;
     }
 
     /**
@@ -691,4 +724,421 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
         return bomSpecList;
     }
 
+    /**
+     * 获取售后订单bom
+     */
+    private List<DocumentByOrderVo.BomSpec> getAfterSaleBomSpecList(List<OrderSku> orderSkuList, List<OrderSkuBom> orderSkuBomList) {
+        // 主材
+        List<DocumentByOrderVo.BomSpec> bomSpecList = orderSkuList.stream()
+                .map(item -> {
+                    DocumentByOrderVo.BomSpec bomSpec = new DocumentByOrderVo.BomSpec();
+                    bomSpec.setOrderSkuId(item.getId());
+                    bomSpec.setBomSpecId(item.getBomSpecId());
+                    bomSpec.setQuantity(item.getQuantity());
+                    bomSpec.setUnitPrice(item.getUnitPrice());
+                    bomSpec.setCustomProcessingType(item.getCustomProcessingType());
+                    bomSpec.setLaserLogoSummary((Objects.equals(item.getCustomProcessingType(), "20")
+                            ? item.getCustomProcessingFee() : BigDecimal.ZERO));
+                    bomSpec.setLaserMitochondrialSummary((Objects.equals(item.getCustomProcessingType(), "10")
+                            ? item.getCustomProcessingFee() : BigDecimal.ZERO));
+                    bomSpec.setLssueFeeSummary(item.getLssueFee());
+                    bomSpec.setDeliveryMaterialsFeeSummary(item.getDeliveryMaterialsFee());
+                    bomSpec.setPackingLaborSummary(item.getPackingLabor());
+                    bomSpec.setManagementFeeSummary(item.getManagementFee());
+                    bomSpec.setProofingFeeSummary(item.getProofingFee().divide(item.getQuantity(), 2, RoundingMode.HALF_UP));
+                    return bomSpec;
+                })
+                .collect(Collectors.toList());
+
+        Map<Long, BigDecimal> map = bomSpecList.stream().collect(
+                Collectors.toMap(DocumentByOrderVo.BomSpec::getOrderSkuId, DocumentByOrderVo.BomSpec::getQuantity));
+
+        // 包材
+        List<DocumentByOrderVo.BomSpec> packBomSpecList = orderSkuBomList.stream()
+                .map(item -> {
+                    DocumentByOrderVo.BomSpec bomSpec = new DocumentByOrderVo.BomSpec();
+                    bomSpec.setOrderSkuId(item.getOrderSkuId());
+                    bomSpec.setBomSpecId(item.getBomSpecId());
+                    bomSpec.setQuantity(item.getQuantity());
+                    bomSpec.setUnitPrice(item.getUnitPrice());
+                    return bomSpec;
+                })
+                .peek(item -> item.setQuantity(ObjectUtil.equals(map.get(item.getOrderSkuId()), BigDecimal.ZERO) ? item.getQuantity() : map.get(item.getOrderSkuId()).multiply(item.getQuantity())))
+                .collect(Collectors.toList());
+
+        // 赋值
+        bomSpecList.addAll(packBomSpecList);
+
+        List<Long> bomSpecIdList = bomSpecList.stream().map(DocumentByOrderVo.BomSpec::getBomSpecId).collect(Collectors.toList());
+        Map<Long, BomSpecBo> bomSpecBoMap = skuSpecService.getBomSpecBoByIdList(bomSpecIdList);
+
+        for (DocumentByOrderVo.BomSpec bomSpec : bomSpecList) {
+            BomSpecBo bomSpecBo = bomSpecBoMap.get(bomSpec.getBomSpecId());
+
+            bomSpec.setBomSpecCode(bomSpecBo.getBomSpecCode());
+            bomSpec.setBomSpecName(bomSpecBo.getBomSpecName());
+            bomSpec.setClassifyName(bomSpecBo.getClassifyName());
+            bomSpec.setUnit(bomSpecBo.getUnit());
+        }
+
+        return bomSpecList;
+    }
+
+    /**
+     * 获取售后订单记录
+     * @param statementOfAccountId
+     * @return
+     */
+    private List<DocumentByOrderVo> getAfterSaleOrderDocument(List<Long> statementOfAccountId) {
+        // 获取订单id列表
+        List<OrderExchange> list = orderExchangeService.list(q -> q
+                        .eq(OrderExchange::getStatus, StatusConstant.YES)
+                        .in(OrderExchange::getStatementOfAccountId, statementOfAccountId)
+                        .select(BaseIdPo::getId, OrderExchange::getOrderInfoId));
+        if (list.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<Long> orderExchangeIdList = list.stream().map(BaseIdPo::getId).collect(Collectors.toList());
+        List<Long> orderIdList = list.stream().map(OrderExchange::getOrderInfoId).collect(Collectors.toList());
+
+        List<OrderExchangeDetail> exchangeDetailList = orderExchangeDetailService.list(q -> q
+                .in(OrderExchangeDetail::getOrderExchangeId, orderExchangeIdList));
+
+        if (exchangeDetailList.isEmpty()) {
+            return Collections.emptyList();
+        }
+        Map<Long, BigDecimal> exchangeDetailMap = exchangeDetailList.stream().collect(Collectors.toMap(
+                OrderExchangeDetail::getOrderSkuId,
+                OrderExchangeDetail::getQuantity,
+                BigDecimal::add));
+
+        // 获取订单
+        List<OrderInfo> orderList = orderService.list(q -> q.in(BaseIdPo::getId, orderIdList));
+        // 获取订单sku
+        List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(BaseIdPo::getId, exchangeDetailMap.keySet()));
+
+        List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.in(OrderSkuBom::getOrderSkuId, exchangeDetailMap.keySet()));
+        // 筛选出可二次利用的包材
+        List<OrderSkuBom> tempOrderSkuBomList = this.getReusableOrderSkuBomList(orderSkuBomList);
+        Map<Long, BigDecimal> packagingMaterialCostMap = tempOrderSkuBomList.stream()
+                .peek(item -> item.setUnitPrice(item.getUnitPrice().negate()))
+                .collect(Collectors.toMap(
+                        OrderSkuBom::getOrderSkuId,
+                        v -> v.getUnitPrice().multiply(v.getQuantity()),
+                        BigDecimal::add
+                ));
+
+        // 将订单sku数量更新为退货数量,退货只退裸垫单价和可二次利用的包材费
+        for (OrderSku orderSku : orderSkuList) {
+            orderSku.setQuantity(exchangeDetailMap.get(orderSku.getId()));
+            orderSku.setProofingFee(BigDecimal.ZERO);
+            orderSku.setLssueFee(BigDecimal.ZERO);
+            orderSku.setPackingLabor(BigDecimal.ZERO);
+            orderSku.setCustomProcessingFee(BigDecimal.ZERO);
+            orderSku.setUnitPrice(orderSku.getUnitPrice().negate());
+            orderSku.setDeliveryMaterialsFee(BigDecimal.ZERO);
+            orderSku.setManagementFee(BigDecimal.ZERO);
+            orderSku.setPackagingMaterialCost(packagingMaterialCostMap.getOrDefault(orderSku.getId(), BigDecimal.ZERO));
+        }
+
+        List<DocumentByOrderVo> result = orderList.stream().map(item -> {
+            DocumentByOrderVo documentByOrderVo = new DocumentByOrderVo();
+            documentByOrderVo.setOrderId(item.getId());
+            documentByOrderVo.setWlnCreateTime(ObjectUtil.defaultIfNull(item.getWlnCreateTime(), item.getCreateTime()));
+            documentByOrderVo.setCode(item.getCode());
+            documentByOrderVo.setWlnCode(item.getWlnCode());
+
+            documentByOrderVo.setSourcePlatform(item.getSourcePlatform());
+            documentByOrderVo.setShopName(item.getShopName());
+            documentByOrderVo.setDepartmentId(item.getDepartmentId());
+
+            return documentByOrderVo;
+        }).collect(Collectors.toList());
+
+        SecurityContext context = SecurityContextHolder.getContext();
+
+        CompletableFuture<List<DocumentByOrderVo.SkuSpec>> skuSpecListCompletableFuture = CompletableFuture.supplyAsync(
+                () -> {
+                    SecurityContextHolder.setContext(context);
+                    return getSkuSpecList(orderSkuList);
+                }, threadPoolExecutor);
+
+        CompletableFuture<List<DocumentByOrderVo.BomSpec>> bomSpecListCompletableFuture = CompletableFuture.supplyAsync(
+                () -> {
+                    SecurityContextHolder.setContext(context);
+                    return getAfterSaleBomSpecList(orderSkuList, tempOrderSkuBomList);
+                }, threadPoolExecutor);
+
+        // 获取订单bom
+        List<DocumentByOrderVo.BomSpec> bomSpecList = bomSpecListCompletableFuture.join();
+
+        // sku赋值bom
+        Map<Long, List<DocumentByOrderVo.BomSpec>> bomSpecMap = bomSpecList.stream()
+                .collect(Collectors.groupingBy(DocumentByOrderVo.BomSpec::getOrderSkuId));
+
+        // 获取订单sku
+        List<DocumentByOrderVo.SkuSpec> skuSpecList = skuSpecListCompletableFuture.join();
+
+        for (DocumentByOrderVo.SkuSpec skuSpec : skuSpecList) {
+            skuSpec.setBomSpecList(bomSpecMap.getOrDefault(skuSpec.getOrderSkuId(), Collections.emptyList()));
+            // 保存质检费,sku小计增加质检费
+            skuSpec.setCheckFee(BigDecimal.valueOf(2).multiply(skuSpec.getQuantity()));
+            skuSpec.setSubtotal(skuSpec.getSubtotal()
+                    .add(skuSpec.getCheckFee()));
+        }
+
+        // 订单赋值sku
+        Map<Long, List<DocumentByOrderVo.SkuSpec>> skuSpecMap = skuSpecList.stream()
+                .collect(Collectors.groupingBy(DocumentByOrderVo.SkuSpec::getOrderId));
+        result.forEach(item -> {
+            List<DocumentByOrderVo.SkuSpec> specList = skuSpecMap.getOrDefault(item.getOrderId(), Collections.emptyList());
+            item.setSkuSpecList(specList);
+            BigDecimal total = specList.stream().map(DocumentByOrderVo.SkuSpec::getSubtotal).reduce(BigDecimal.ZERO, BigDecimal::add);
+            item.setTotal(total);
+        });
+
+        return result;
+    }
+
+    /**
+     * 获取售后bom记录
+     * @param statementOfAccountIdList
+     * @return
+     */
+    private List<DocumentByBomVo> getAfterSaleBomDocument(List<Long> statementOfAccountIdList) {
+        Assert.notEmpty(statementOfAccountIdList, "对账单id不能为空");
+        // 获取订单id列表
+        List<Long> orderExchangeIdList = orderExchangeService.list(q -> q
+                        .eq(OrderExchange::getStatus, StatusConstant.YES)
+                        .in(OrderExchange::getStatementOfAccountId, statementOfAccountIdList)
+                        .select(BaseIdPo::getId))
+                .stream().map(BaseIdPo::getId).collect(Collectors.toList());
+
+        if (orderExchangeIdList.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<OrderExchangeDetail> exchangeDetailList = orderExchangeDetailService.list(q -> q
+                .in(OrderExchangeDetail::getOrderExchangeId, orderExchangeIdList));
+
+        if (exchangeDetailList.isEmpty()) {
+            return Collections.emptyList();
+        }
+        Map<Long, BigDecimal> exchangeDetailMap = exchangeDetailList.stream().collect(Collectors.toMap(
+                OrderExchangeDetail::getOrderSkuId,
+                OrderExchangeDetail::getQuantity,
+                BigDecimal::add));
+
+        // 获取订单sku
+        List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(BaseIdPo::getId, exchangeDetailMap.keySet()));
+
+        // 主材bom
+        List<DocumentByBomVo> result = orderSkuList.stream()
+                .map(item -> DocumentByBomVo.builder()
+                        .bomSpecId(item.getBomSpecId())
+                        .orderId(item.getOrderId())
+                        .quantity(exchangeDetailMap.get(item.getId()))
+                        .unitPrice(item.getUnitPrice().negate())
+                        .laserLogoSummary(BigDecimal.ZERO)
+                        .laserMitochondrialSummary(BigDecimal.ZERO)
+                        .lssueFeeSummary(BigDecimal.ZERO)
+                        .deliveryMaterialsFeeSummary(BigDecimal.ZERO)
+                        .packingLaborSummary(BigDecimal.ZERO)
+                        .managementFeeSummary(BigDecimal.ZERO)
+                        .checkFeeSummary(BigDecimal.valueOf(2).multiply(exchangeDetailMap.get(item.getId())))
+                        .build())
+                .peek(item -> item.setSubtotal(
+                        item.getUnitPrice()
+                                .multiply(item.getQuantity())
+                                .add(item.getLaserLogoSummary())
+                                .add(item.getLaserMitochondrialSummary())
+                                .add(item.getLssueFeeSummary())
+                                .add(item.getDeliveryMaterialsFeeSummary())
+                                .add(item.getPackingLaborSummary())
+                                .add(item.getManagementFeeSummary())
+                                .add(item.getCheckFeeSummary())
+                                .setScale(2, RoundingMode.HALF_UP)
+                ))
+                .peek(item -> item.setTotal(item.getSubtotal()))
+                .collect(Collectors.toList());
+
+        // 赋值主材bom品名品号
+        bomSpecService.attributeAssign(result, DocumentByBomVo::getBomSpecId, (item, bomSpec) -> {
+            item.setBomSpecCode(bomSpec.getCode());
+            item.setBomSpecName(bomSpec.getName());
+        });
+
+        // 合并同加个同规格主材bom,数量相加
+        Collection<DocumentByBomVo> documentByBomVoCollection = result.stream()
+                .sorted(comparing(DocumentByBomVo::getBomSpecCode))
+                .collect(Collectors.toMap(
+                        item -> item.getUnitPrice() + ":" + item.getBomSpecId(),
+                        Function.identity(),
+                        (v1, v2) -> {
+                            v1.setQuantity(v1.getQuantity().add(v2.getQuantity()));
+                            v1.setLaserLogoSummary(v1.getLaserLogoSummary().add(v2.getLaserLogoSummary()));
+                            v1.setLaserMitochondrialSummary(v1.getLaserMitochondrialSummary().add(v2.getLaserMitochondrialSummary()));
+                            v1.setLssueFeeSummary(v1.getLssueFeeSummary().add(v2.getLssueFeeSummary()));
+                            v1.setDeliveryMaterialsFeeSummary(v1.getDeliveryMaterialsFeeSummary().add(v2.getDeliveryMaterialsFeeSummary()));
+                            v1.setPackingLaborSummary(v1.getPackingLaborSummary().add(v2.getPackingLaborSummary()));
+                            v1.setManagementFeeSummary(v1.getManagementFeeSummary().add(v2.getManagementFeeSummary()));
+                            v1.setProofingFeeSummary(v1.getProofingFeeSummary().add(v2.getProofingFeeSummary()));
+                            v1.setSubtotal(v1.getSubtotal().add(v2.getSubtotal()));
+                            v1.setTotal(v1.getSubtotal());
+                            return v1;
+                        }
+                )).values();
+
+        // 赋值合并后结果
+        result = new ArrayList<>(documentByBomVoCollection);
+        // 按品名升序排序
+        result.sort(comparing(DocumentByBomVo::getBomSpecName));
+
+        Map<Long, BigDecimal> orderSkuMap = orderSkuList.stream().collect(Collectors.toMap(BaseIdPo::getId, OrderSku::getQuantity));
+
+        // 包材bom
+        List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.in(OrderSkuBom::getOrderSkuId, exchangeDetailMap.keySet()));
+        // 筛选出可二次利用的包材
+        List<OrderSkuBom> tempOrderSkuBomList = this.getReusableOrderSkuBomList(orderSkuBomList);
+
+        List<DocumentByBomVo> bomVoList = tempOrderSkuBomList.stream()
+                .map(item ->
+                        DocumentByBomVo.builder()
+                                .bomSpecId(item.getBomSpecId())
+                                .quantity(item.getQuantity().multiply(orderSkuMap.get(item.getOrderSkuId())))
+                                .unitPrice(item.getUnitPrice().negate())
+                                .subtotal(item.getUnitPrice().multiply(item.getQuantity().multiply(orderSkuMap.get(item.getOrderSkuId()))).negate())
+                                .total(item.getUnitPrice().multiply(item.getQuantity().multiply(orderSkuMap.get(item.getOrderSkuId()))).negate())
+                                .build()
+                ).collect(Collectors.toList());
+
+        // 赋值包材bom品名品号
+        bomSpecService.attributeAssign(bomVoList, DocumentByBomVo::getBomSpecId, (item, bomSpec) -> {
+            item.setBomSpecCode(bomSpec.getCode());
+            item.setBomSpecName(bomSpec.getName());
+        });
+
+        // 合并同加个同规格包材bom,数量相加
+        Collection<DocumentByBomVo> bomValues = bomVoList.stream()
+                .sorted(comparing(DocumentByBomVo::getBomSpecCode))
+                .collect(Collectors.toMap(
+                        item -> item.getUnitPrice() + ":" + item.getBomSpecId(),
+                        Function.identity(),
+                        (v1, v2) -> {
+                            v1.setQuantity(v1.getQuantity().add(v2.getQuantity()));
+                            v1.setSubtotal(v1.getSubtotal().add(v2.getSubtotal()));
+                            v1.setTotal(v1.getSubtotal());
+                            return v1;
+                        }
+                )).values();
+
+        // 合并主材包材
+        result.addAll(bomValues);
+
+        return result;
+    }
+
+    /**
+     * 获取售后sku记录
+     * @param statementOfAccountIdList
+     * @return
+     */
+    private List<DocumentBySkuVo> getAfterSaleSkuDocument(List<Long> statementOfAccountIdList) {
+        Assert.notEmpty(statementOfAccountIdList, "对账单id不能为空");
+        // 获取订单id列表
+        List<Long> orderExchangeIdList = orderExchangeService.list(q -> q
+                        .eq(OrderExchange::getStatus, StatusConstant.YES)
+                        .in(OrderExchange::getStatementOfAccountId, statementOfAccountIdList)
+                        .select(BaseIdPo::getId))
+                .stream().map(BaseIdPo::getId).collect(Collectors.toList());
+
+        if (orderExchangeIdList.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<OrderExchangeDetail> exchangeDetailList = orderExchangeDetailService.list(q -> q
+                .in(OrderExchangeDetail::getOrderExchangeId, orderExchangeIdList));
+        Map<Long, BigDecimal> exchangeDetailMap = exchangeDetailList.stream().collect(Collectors.toMap(
+                OrderExchangeDetail::getOrderSkuId,
+                OrderExchangeDetail::getQuantity,
+                BigDecimal::add));
+        if (exchangeDetailList.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        // 获取订单sku
+        List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(BaseIdPo::getId, exchangeDetailMap.keySet()));
+        List<Long> orderSkuIds = orderSkuList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
+        // 获取可二次利用的包材金额
+        List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.in(OrderSkuBom::getOrderSkuId, orderSkuIds));
+        List<OrderSkuBom> tempOrderSkuBomList = this.getReusableOrderSkuBomList(orderSkuBomList);
+        Map<Long, BigDecimal> packagingMaterialCostMap = tempOrderSkuBomList.stream()
+                .collect(Collectors.toMap(OrderSkuBom::getOrderSkuId, v -> v.getUnitPrice().multiply(v.getQuantity()), BigDecimal::add));
+
+        // 生成结果集
+        List<DocumentBySkuVo> documentBySkuVoList = orderSkuList.stream()
+                .map(item -> DocumentBySkuVo.builder()
+                        .skuSpecId(item.getSkuSpecId())
+                        .orderId(item.getOrderId())
+                        .quantity(exchangeDetailMap.get(item.getId()))
+                        .unitPrice(item.getUnitPrice()
+                                .add(packagingMaterialCostMap.getOrDefault(item.getId(), BigDecimal.ZERO))
+                                .negate()
+                        )
+                        .checkFee(BigDecimal.valueOf(2).multiply(exchangeDetailMap.get(item.getId())))
+                        .build())
+                .peek(item ->
+                        item.setSubtotal(item.getQuantity()
+                                .multiply(item.getUnitPrice())
+                                .add(item.getCheckFee())
+                                .setScale(2, RoundingMode.HALF_UP)))
+                .peek(item -> item.setTotal(item.getSubtotal()))
+                .collect(Collectors.toList());
+
+        // 赋值sku规格品名和品号
+        skuSpecService.attributeAssign(documentBySkuVoList, DocumentBySkuVo::getSkuSpecId, (item, skuSpec) -> {
+            item.setSkuSpecCode(skuSpec.getCode());
+            item.setSkuSpecName(skuSpec.getName());
+        });
+
+        // 合并单价、小计、sku规格id系统的对账数据
+        Collection<DocumentBySkuVo> documentBySkuVoCollection = documentBySkuVoList.stream()
+                .sorted(comparing(DocumentBySkuVo::getSkuSpecCode))
+                .collect(Collectors.toMap(
+                        item -> item.getUnitPrice() + ":" + item.getSkuSpecId(),
+                        Function.identity(),
+                        (v1, v2) -> {
+                            v1.setQuantity(v1.getQuantity().add(v2.getQuantity()));
+                            v1.setSubtotal(v1.getSubtotal().add(v2.getSubtotal()));
+                            v1.setTotal(v1.getTotal().add(v2.getTotal()));
+                            return v1;
+                        }
+                )).values();
+
+        return new ArrayList<>(documentBySkuVoCollection);
+    }
+
+    /**
+     * 获取可二次利用的包材
+     * @param orderSkuBomList
+     * @return
+     */
+    private List<OrderSkuBom> getReusableOrderSkuBomList(List<OrderSkuBom> orderSkuBomList) {
+        List<Long> bomSpecIdList = orderSkuBomList.stream()
+                .map(OrderSkuBom::getBomSpecId)
+                .distinct()
+                .collect(Collectors.toList());
+        Map<Long, BomSpecBo> bomSpecBoMap = skuSpecService.getBomSpecBoByIdList(bomSpecIdList);
+        return orderSkuBomList.stream()
+                .filter(item -> {
+                    BomSpecBo bomSpecBo = bomSpecBoMap.get(item.getBomSpecId());
+                    if (bomSpecBo == null
+                            || !(Objects.equals(bomSpecBo.getClassifyId(), BomClassifyConstant.MESH_BAG)
+                                || Objects.equals(bomSpecBo.getClassifyId(), BomClassifyConstant.SUSPENDERS))) {
+                        return false;
+                    }
+                    return true;
+                }).collect(Collectors.toList());
+    }
+
 }

+ 20 - 7
sd-business/src/main/java/com/sd/business/strategy/impl/DocumentByOrderExcelExportStrategy.java

@@ -7,14 +7,17 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.handler.WriteHandler;
 import com.alibaba.excel.write.metadata.WriteSheet;
 import com.alibaba.excel.write.metadata.fill.FillConfig;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.ruoyi.common.exception.ServiceException;
+import com.sd.business.entity.order.enums.OrderClassifyEnum;
 import com.sd.business.entity.statement.bo.ExportDocumentByOrderBo;
 import com.sd.business.entity.statement.vo.DocumentByOrderVo;
 import com.sd.business.service.statement.StatementOfAccountService;
+import com.sd.business.service.statement.impl.DocumentByAfterSaleOrderExcelCellMergeStrategy;
 import com.sd.business.service.statement.impl.DocumentByOrderExcelCellMergeStrategy;
 import com.sd.business.strategy.ExcelExportStrategy;
 import lombok.extern.slf4j.Slf4j;
@@ -24,10 +27,7 @@ import java.io.*;
 import java.math.BigDecimal;
 import java.nio.file.Files;
 import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 订单对账单
@@ -70,6 +70,7 @@ public class DocumentByOrderExcelExportStrategy implements ExcelExportStrategy<M
                             .skuSpecName(skuSpec.getSkuSpecName())
                             .quantity(skuSpec.getQuantity())
                             .unitPrice(skuSpec.getUnitPrice())
+                            .checkFee(skuSpec.getCheckFee())
                             .subtotal(skuSpec.getSubtotal())
                             .wlnCreateTime(documentByOrderVo.getWlnCreateTime())
                             .code(documentByOrderVo.getCode())
@@ -114,7 +115,14 @@ public class DocumentByOrderExcelExportStrategy implements ExcelExportStrategy<M
                 tempExcel.mkdir();
             }
 
-            ClassPathResource classPathResource = new ClassPathResource("template" + File.separator + "orderDocument.xlsx");
+            String fileName;
+            if (Objects.equals(orderClassify, OrderClassifyEnum.AFTER_SALE_ORDER.getKey())) {
+                fileName = "afterSaleOrderDocument.xlsx";
+            } else {
+                fileName = "orderDocument.xlsx";
+            }
+
+            ClassPathResource classPathResource = new ClassPathResource("template" + File.separator + fileName);
             InputStream is = null;
             BufferedOutputStream os = null;
             ExcelWriter excelWriter = null;
@@ -122,8 +130,13 @@ public class DocumentByOrderExcelExportStrategy implements ExcelExportStrategy<M
                 is = classPathResource.getInputStream();
                 os = new BufferedOutputStream(Files.newOutputStream(Paths.get(filePath)));
                 excelWriter = EasyExcel.write(os).withTemplate(is).build();
-                DocumentByOrderExcelCellMergeStrategy strategy = new DocumentByOrderExcelCellMergeStrategy(list);
-                WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(strategy).build();
+                WriteHandler writeHandler;
+                if (Objects.equals(orderClassify, OrderClassifyEnum.AFTER_SALE_ORDER.getKey())) {
+                    writeHandler = new DocumentByAfterSaleOrderExcelCellMergeStrategy(list);
+                } else {
+                    writeHandler = new DocumentByOrderExcelCellMergeStrategy(list);
+                }
+                WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(writeHandler).build();
                 FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
 
                 excelWriter.fill(data, fillConfig, writeSheet);

+ 11 - 0
sd-business/src/main/resources/mapper/order/OrderExchangeMapper.xml

@@ -19,6 +19,7 @@
                oe.create_time,
                oe.update_user,
                oe.update_time,
+               oe.status,
                oi.code     orderCode,
                oi.wln_code orderWlnCode,
                d.name      departmentName
@@ -28,4 +29,14 @@
             ${ew.customSqlSegment}
     </select>
 
+    <select id="orderExchangeAccountStatistics" resultType="com.sd.business.entity.order.bo.OrderExchangeAccountBo">
+        select oe.statement_of_account_id,
+               count(DISTINCT oe.id) orderNum,
+               sum(oed.quantity) orderSkuNum,
+               ifnull(sum(oed.return_amount), 0) returnAmount
+        from order_exchange oe
+                 left join order_exchange_detail oed on oe.id = oed.order_exchange_id
+            ${ew.customSqlSegment}
+    </select>
+
 </mapper>

+ 5 - 0
sd-business/src/main/resources/mapper/order/OrderSalesShipmentStatisticsMapper.xml

@@ -9,7 +9,12 @@
             bs.name bomSpecName,
             bs.width,
             bs.height,
+            b.species,
+            b.selling_price_system,
+            b.front_grain,
+            b.reverse_grain,
             b.chromatophore,
+            bs.colour,
             sum(case when oi.shipping_time >= date(date_sub(now(), interval 90 day)) then os.quantity else 0 end) ninetyDaysSalesQuantity,
             sum(case when oi.shipping_time >= date(date_sub(now(), interval 60 day)) then os.quantity else 0 end) sixtyDaysSalesQuantity,
             sum(case when oi.shipping_time >= date(date_sub(now(), interval 30 day)) then os.quantity else 0 end) thirtyDaysSalesQuantity

BIN
sd-starter/src/main/resources/template/afterSaleBomDocument.xlsx


BIN
sd-starter/src/main/resources/template/afterSaleOrderDocument.xlsx


BIN
sd-starter/src/main/resources/template/afterSaleSkuDocument.xlsx


BIN
sd-starter/src/main/resources/template/skuDocument.xlsx