Bläddra i källkod

新增佰卓销售排行看板,订单成品出库时,增加快递包材出库

fgd 1 år sedan
förälder
incheckning
21bbfa6da6

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

@@ -172,4 +172,13 @@ public class SalesBoardController {
     public List<DepartmentBomSalesBoardVo> getDepartmentBomSalesStatisticsList(@Validated @RequestBody DailyBoardSelectDto dto) {
         return salesBoardService.getDepartmentBomSalesStatisticsList(dto);
     }
+
+    /**
+     * 获取佰卓sku销量前十
+     * @return
+     */
+    @PostMapping("/getBzSkuSalesBoard")
+    public List<BzSkuSalesBoardVo> getBzSkuSalesBoard() {
+        return salesBoardService.getBzSkuSalesBoard();
+    }
 }

+ 41 - 0
sd-business/src/main/java/com/sd/business/entity/board/vo/BzSkuSalesBoardVo.java

@@ -0,0 +1,41 @@
+package com.sd.business.entity.board.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 佰卓sku销量看板数据查询返回值实体
+ *
+ * @since 2024-01-12
+ */
+@Getter
+@Setter
+public class BzSkuSalesBoardVo {
+
+    /**
+     * sku规格编码
+     */
+    private String skuSpecCode;
+
+    /**
+     * sku规格名称
+     */
+    private String skuSpecName;
+
+    /**
+     * 30天日销售量
+     */
+    private BigDecimal dailySales;
+
+    /**
+     * 安全库存(3天销量)
+     */
+    private BigDecimal safetyStock;
+
+    /**
+     * 当前库存数量
+     */
+    private BigDecimal inventoryQuantity;
+}

+ 5 - 0
sd-business/src/main/java/com/sd/business/entity/board/vo/SkuSalesRankingVo.java

@@ -17,6 +17,11 @@ import java.math.BigDecimal;
 public class SkuSalesRankingVo {
 
     /**
+     * sku规格id
+     */
+    private Long skuSpecId;
+
+    /**
      * sku品号
      */
     @ColumnWidth(15)

+ 5 - 0
sd-business/src/main/java/com/sd/business/entity/department/constant/DepartmentConstant.java

@@ -7,4 +7,9 @@ public interface DepartmentConstant {
      */
     Long SD_SPORTS = 0L;
 
+    /**
+     * 佰卓
+     */
+    Long BZ = 1689164627162529793L;
+
 }

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

@@ -64,4 +64,10 @@ public interface SalesBoardService {
      * @return
      */
     List<DepartmentBomSalesBoardVo> getDepartmentBomSalesStatisticsList(DailyBoardSelectDto dto);
+
+    /**
+     * 获取佰卓sku销量前十
+     * @return
+     */
+    List<BzSkuSalesBoardVo> getBzSkuSalesBoard();
 }

+ 45 - 0
sd-business/src/main/java/com/sd/business/service/board/impl/SalesBoardServiceImpl.java

@@ -12,7 +12,9 @@ import com.sd.business.entity.bom.bo.BomSpecBo;
 import com.sd.business.entity.bom.po.Bom;
 import com.sd.business.entity.bom.po.BomClassify;
 import com.sd.business.entity.bom.po.BomSpec;
+import com.sd.business.entity.department.constant.DepartmentConstant;
 import com.sd.business.entity.department.po.Department;
+import com.sd.business.entity.inventory.po.InventoryFinishedOrder;
 import com.sd.business.entity.order.enums.OrderClassifyEnum;
 import com.sd.business.entity.order.enums.OrderStatusEnum;
 import com.sd.business.entity.order.po.OrderInfo;
@@ -20,6 +22,7 @@ import com.sd.business.entity.order.po.OrderSku;
 import com.sd.business.mapper.board.SalesBoardMapper;
 import com.sd.business.service.board.SalesBoardService;
 import com.sd.business.service.department.DepartmentService;
+import com.sd.business.service.inventory.InventoryFinishedOrderService;
 import com.sd.business.service.order.OrderService;
 import com.sd.business.service.order.OrderSkuService;
 import com.sd.business.service.sku.SkuSpecService;
@@ -28,6 +31,7 @@ import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -60,6 +64,9 @@ public class SalesBoardServiceImpl implements SalesBoardService {
     @Autowired
     private SkuSpecService skuSpecService;
 
+    @Autowired
+    private InventoryFinishedOrderService inventoryFinishedOrderService;
+
     @Override
     public Page<SkuSalesRankingVo> getSkuSalesRankingPage(SalesBoardSelectDto dto) {
         IWrapper<SkuSalesRankingVo> wrapper = IWrapper.getWrapper();
@@ -262,4 +269,42 @@ public class SalesBoardServiceImpl implements SalesBoardService {
         list.add(0, sumBomVo);
         return list;
     }
+
+    @Override
+    public List<BzSkuSalesBoardVo> getBzSkuSalesBoard() {
+        IWrapper<SkuSalesRankingVo> wrapper = IWrapper.getWrapper();
+        wrapper.eq("bc", BomClassify::getParentId, 1);
+        wrapper.eq("oi", OrderInfo::getDepartmentId, DepartmentConstant.BZ);
+        wrapper.eq("oi", OrderInfo::getStatus, OrderStatusEnum.COMPLETION_PRODUCTION.getKey());
+        wrapper.ge("oi", OrderInfo::getShippingTime, DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -30)));
+        wrapper.groupBy("ss.id");
+        wrapper.orderByDesc("salesQuantity");
+        Page<SkuSalesRankingVo> page = salesBoardMapper.getSkuSalesRankingPage(new Page<>(1, 10), wrapper);
+        List<SkuSalesRankingVo> records = page.getRecords();
+        if (records.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        // 获取所有无源可出库的库存
+        List<InventoryFinishedOrder> inventoryFinishedOrderList = inventoryFinishedOrderService.list(q -> q
+                .eq(InventoryFinishedOrder::getStatus, 1)
+                .isNull(InventoryFinishedOrder::getOrderInfoId));
+        Map<Long, BigDecimal> inventoryFinishedMap = inventoryFinishedOrderList.stream()
+                .collect(Collectors.toMap(
+                        InventoryFinishedOrder::getSkuSpecId,
+                        InventoryFinishedOrder::getExistingQuantity,
+                        BigDecimal::add));
+
+        List<BzSkuSalesBoardVo> salesBoardVoList = records.stream().map(item -> {
+            BzSkuSalesBoardVo vo = new BzSkuSalesBoardVo();
+            vo.setSkuSpecCode(item.getSkuSpecCode());
+            vo.setSkuSpecName(item.getSkuSpecName());
+            vo.setDailySales(item.getSalesQuantity().divide(BigDecimal.valueOf(30), 2, RoundingMode.HALF_UP));
+            vo.setSafetyStock(vo.getDailySales().multiply(BigDecimal.valueOf(3)));
+            vo.setInventoryQuantity(inventoryFinishedMap.getOrDefault(item.getSkuSpecId(), BigDecimal.ZERO));
+            return vo;
+        }).collect(Collectors.toList());
+
+        return salesBoardVoList;
+    }
 }

+ 8 - 0
sd-business/src/main/java/com/sd/business/service/production/impl/ProductionOrderServiceImpl.java

@@ -8,6 +8,7 @@ import com.ruoyi.common.core.domain.BaseSelectDto;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.sd.business.entity.department.constant.DepartmentConstant;
 import com.sd.business.entity.order.enums.OrderStatusEnum;
 import com.sd.business.entity.order.po.OrderInfo;
 import com.sd.business.entity.order.po.OrderPackageBom;
@@ -191,6 +192,13 @@ public class ProductionOrderServiceImpl implements ProductionOrderService {
                 .set(BasePo::getUpdateTime, date)
                 .set(BasePo::getUpdateUser, SecurityUtils.getUserId()));
 
+        if (Objects.equals(orderInfo.getDepartmentId(), DepartmentConstant.SD_SPORTS)) {
+            // 胜德体育的订单,不生成对账单,直接入无源成品做备货使用
+            List<OrderSku> orderSkuList = orderSkuService.list(q -> q.eq(OrderSku::getOrderId, id));
+            inventoryFinishedService.noSourceInWarehousing(orderSkuList);
+            return;
+        }
+
         // 生成对账单
         StatementOfAccountDto statement = new StatementOfAccountDto();
         statement.setDepartmentId(orderInfo.getDepartmentId());

+ 58 - 3
sd-business/src/main/java/com/sd/business/service/production/impl/StockPreparationServiceImpl.java

@@ -315,7 +315,7 @@ public class StockPreparationServiceImpl implements StockPreparationService {
 
         // 成品库出库
         if (Objects.equals(dto.getOrderStockType(), 1)) {
-            orderFinishedDelivery(list);
+            orderFinishedDelivery(list, dto);
             return;
         }
 
@@ -384,9 +384,24 @@ public class StockPreparationServiceImpl implements StockPreparationService {
 
     }
 
-    private void orderFinishedDelivery(List<StockPreparationVo> list) {
-        // 成品出库
+    private void orderFinishedDelivery(List<StockPreparationVo> list, StockPreparationDto dto) {
         List<Long> orderIdList = list.stream().map(StockPreparationVo::getOrderId).distinct().collect(Collectors.toList());
+
+        // 出库快递包装包材
+        List<OrderPackageBom> orderPackageBomList = orderPackageBomService.list(q -> q.in(OrderPackageBom::getOrderId, orderIdList));
+        if (!orderPackageBomList.isEmpty()) {
+            // 快递包材
+            List<InOutStorageBom> outStorageBomList = orderPackageBomList.stream()
+                    .map(item -> {
+                        InOutStorageBom inOutStorageBom = new InOutStorageBom();
+                        inOutStorageBom.setBomSpecId(item.getBomSpecId());
+                        inOutStorageBom.setQuantity(item.getQuantity());
+                        return inOutStorageBom;
+                    })
+                    .collect(Collectors.toList());
+            productionOut(WarehouseConstant.PACKAGING_MATERIAL, dto, outStorageBomList, StatusConstant.NO);
+        }
+        // 成品出库
         inventoryFinishedService.noSourceSaleOutOfWarehouse(orderIdList);
 
         // 生产工单
@@ -662,6 +677,46 @@ public class StockPreparationServiceImpl implements StockPreparationService {
             outSkuVo.setInventoryQuantity(inventoryMap.getOrDefault(skuSpecId, BigDecimal.ZERO));
         }
 
+        // 获取快递包装包材
+        List<OrderPackageBom> orderPackageBomList = orderPackageBomService.list(q -> q.in(OrderPackageBom::getOrderId, orderIdList));
+        if (orderPackageBomList.isEmpty()) {
+            return outBomVoList;
+        }
+        // 快递包材
+        Map<Long, OutSkuVo> skuPackageBomVoMap = orderPackageBomList.stream()
+                .map(item -> {
+                    OutSkuVo outSkuVo = new OutSkuVo();
+                    outSkuVo.setSkuSpecId(item.getBomSpecId());
+                    outSkuVo.setOutQuantity(item.getQuantity());
+                    return outSkuVo;
+                })
+                .collect(Collectors.toMap(
+                        OutSkuVo::getSkuSpecId,
+                        Function.identity(),
+                        (v1, v2) -> {
+                            v1.setOutQuantity(v1.getOutQuantity().add(v2.getOutQuantity()));
+                            return v1;
+                        })
+                );
+        List<OutSkuVo> skuPackageBomVoList = new ArrayList<>(skuPackageBomVoMap.values());
+        Map<Long, BomSpec> bomSpecMap = bomSpecService.mapKEntity(BomSpec::getBomId, q -> q.in(BaseIdPo::getId, skuPackageBomVoMap.keySet()));
+        // 查询库存
+        Map<Long, BigDecimal> skuPackageBomInventoryMap = inventoryService.mapKV(Inventory::getBomSpecId, Inventory::getQuantity, q -> q
+                .eq(Inventory::getWarehouseId, WarehouseConstant.PACKAGING_MATERIAL)
+                .eq(Inventory::getDepartmentId, outDepartmentId)
+                .in(Inventory::getBomSpecId, skuPackageBomVoMap.keySet()));
+        for (OutSkuVo outSkuVo : skuPackageBomVoList) {
+            Long bomSpecId = outSkuVo.getSkuSpecId();
+            BomSpec bomSpec = bomSpecMap.get(bomSpecId);
+            outSkuVo.setSkuSpecCode(bomSpec.getCode());
+            outSkuVo.setSkuSpecName(bomSpec.getName());
+            outSkuVo.setWarehouseId(WarehouseConstant.PACKAGING_MATERIAL);
+            outSkuVo.setWarehouseName("包材仓");
+            outSkuVo.setInventoryQuantity(skuPackageBomInventoryMap.getOrDefault(bomSpecId, BigDecimal.ZERO));
+        }
+        // 添加快递包材
+        outBomVoList.addAll(skuPackageBomVoList);
+
         return outBomVoList;
     }
 

+ 1 - 0
sd-business/src/main/resources/mapper/board/SalesBoardMapper.xml

@@ -4,6 +4,7 @@
 
     <select id="getSkuSalesRankingPage" resultType="com.sd.business.entity.board.vo.SkuSalesRankingVo">
         select
+            ss.id skuSpecId,
             ss.name skuSpecName,
             ss.code skuSpecCode,
             sum(os.quantity) salesQuantity