Răsfoiți Sursa

新增生产错误、计划外超领

fgd 1 an în urmă
părinte
comite
780d46b84f
26 a modificat fișierele cu 1123 adăugiri și 141 ștergeri
  1. 33 4
      sd-business/src/main/java/com/sd/business/controller/production/ProductionExceedReceiveController.java
  2. 26 0
      sd-business/src/main/java/com/sd/business/entity/order/dto/SkuSpecPackageBomDto.java
  3. 46 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/OutBomDto.java
  4. 13 14
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveDto.java
  5. 31 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSelectDto.java
  6. 18 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSkuDto.java
  7. 41 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSkuSelectDto.java
  8. 40 0
      sd-business/src/main/java/com/sd/business/entity/production/po/ProductionExceedReceive.java
  9. 61 0
      sd-business/src/main/java/com/sd/business/entity/production/po/ProductionExceedReceiveSku.java
  10. 41 0
      sd-business/src/main/java/com/sd/business/entity/production/vo/ProductionExceedReceiveSkuVo.java
  11. 25 0
      sd-business/src/main/java/com/sd/business/entity/production/vo/ProductionExceedReceiveVo.java
  12. 1 1
      sd-business/src/main/java/com/sd/business/entity/warehouse/constant/WarehouseConstant.java
  13. 27 0
      sd-business/src/main/java/com/sd/business/mapper/production/ProductionExceedReceiveMapper.java
  14. 27 0
      sd-business/src/main/java/com/sd/business/mapper/production/ProductionExceedReceiveSkuMapper.java
  15. 4 0
      sd-business/src/main/java/com/sd/business/service/inventory/InventoryFinishedService.java
  16. 2 1
      sd-business/src/main/java/com/sd/business/service/inventory/impl/InventoryFinishedServiceImpl.java
  17. 42 0
      sd-business/src/main/java/com/sd/business/service/production/ProductionExceedReceiveService.java
  18. 22 0
      sd-business/src/main/java/com/sd/business/service/production/ProductionExceedReceiveSkuService.java
  19. 0 7
      sd-business/src/main/java/com/sd/business/service/production/ProductionOrderService.java
  20. 417 0
      sd-business/src/main/java/com/sd/business/service/production/impl/ProductionExceedReceiveServiceImpl.java
  21. 40 0
      sd-business/src/main/java/com/sd/business/service/production/impl/ProductionExceedReceiveSkuServiceImpl.java
  22. 0 114
      sd-business/src/main/java/com/sd/business/service/production/impl/ProductionOrderServiceImpl.java
  23. 9 0
      sd-business/src/main/java/com/sd/business/service/sku/SkuSpecService.java
  24. 104 0
      sd-business/src/main/java/com/sd/business/service/sku/impl/SkuSpecServiceImpl.java
  25. 21 0
      sd-business/src/main/resources/mapper/production/ProductionExceedReceiveMapper.xml
  26. 32 0
      sd-business/src/main/resources/mapper/production/ProductionExceedReceiveSkuMapper.xml

+ 33 - 4
sd-business/src/main/java/com/sd/business/controller/production/ProductionExceedReceiveController.java

@@ -1,10 +1,13 @@
 package com.sd.business.controller.production;
 
 import com.ruoyi.common.core.domain.BaseSelectDto;
+import com.sd.business.entity.order.dto.SkuSpecPackageBomDto;
 import com.sd.business.entity.order.vo.OrderSkuVo;
 import com.sd.business.entity.production.dto.ProductionExceedReceiveDto;
+import com.sd.business.entity.production.vo.OutBomVo;
 import com.sd.business.service.order.OrderSkuService;
-import com.sd.business.service.production.ProductionOrderService;
+import com.sd.business.service.production.ProductionExceedReceiveService;
+import com.sd.business.service.sku.SkuSpecService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -22,17 +25,20 @@ import java.util.List;
 public class ProductionExceedReceiveController {
 
     @Autowired
-    private ProductionOrderService productionOrderService;
+    private OrderSkuService orderSkuService;
 
     @Autowired
-    private OrderSkuService orderSkuService;
+    private SkuSpecService skuSpecService;
+
+    @Autowired
+    private ProductionExceedReceiveService productionExceedReceiveService;
 
     /**
      * 生产超领
      */
     @PostMapping("/exceedReceive")
     public void exceedReceive(@Validated @RequestBody ProductionExceedReceiveDto dto) {
-        productionOrderService.exceedReceive(dto);
+        productionExceedReceiveService.exceedReceive(dto);
     }
 
     /**
@@ -43,4 +49,27 @@ public class ProductionExceedReceiveController {
         return orderSkuService.getOrderSkuList(dto.getId());
     }
 
+    /**
+     * 获取sku所有材料明细列表
+     */
+    @PostMapping("/getSkuSpecMaterialList")
+    public List<OutBomVo> getSkuSpecMaterialList(@RequestBody SkuSpecPackageBomDto dto) {
+        return skuSpecService.getSkuSpecMaterialList(dto);
+    }
+
+    /**
+     * 生产错误超领
+     */
+    @PostMapping("/errorExceedReceive")
+    public void errorExceedReceive(@Validated @RequestBody ProductionExceedReceiveDto dto) {
+        productionExceedReceiveService.errorExceedReceive(dto);
+    }
+
+    /**
+     * 计划外超领生产
+     */
+    @PostMapping("/unplannedExceedReceive")
+    public void unplannedExceedReceive(@Validated @RequestBody ProductionExceedReceiveDto dto) {
+        productionExceedReceiveService.unplannedExceedReceive(dto);
+    }
 }

+ 26 - 0
sd-business/src/main/java/com/sd/business/entity/order/dto/SkuSpecPackageBomDto.java

@@ -0,0 +1,26 @@
+package com.sd.business.entity.order.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 订单sku包装bom列表查询入参实体
+ *
+ * @author
+ * @since 2023-11-06
+ */
+@Getter
+@Setter
+public class SkuSpecPackageBomDto {
+
+    /**
+     * 订单sku信息
+     */
+    @Valid
+    @NotEmpty(message = "规格不能为空")
+    private List<SkuSpecPriceDto> skuSpecList;
+}

+ 46 - 0
sd-business/src/main/java/com/sd/business/entity/production/dto/OutBomDto.java

@@ -0,0 +1,46 @@
+package com.sd.business.entity.production.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+@Getter
+@Setter
+public class OutBomDto {
+
+    /**
+     * bom规格id
+     */
+    private Long bomSpecId;
+
+    /**
+     * 仓库id
+     */
+    private Long warehouseId;
+
+    /**
+     * 库存数量
+     */
+    private BigDecimal inventoryQuantity;
+
+    /**
+     * 出库数量
+     */
+    private BigDecimal outQuantity;
+
+    /**
+     * 分类id
+     */
+    private Long classifyId;
+
+    /**
+     * 分类名称
+     */
+    private String classifyName;
+
+    /**
+     * 分类父id
+     */
+    private Long classifyParentId;
+}

+ 13 - 14
sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveDto.java

@@ -1,31 +1,30 @@
 package com.sd.business.entity.production.dto;
 
-import com.sd.business.entity.order.dto.OrderSkuDto;
+import com.sd.business.entity.production.po.ProductionExceedReceive;
 import lombok.Getter;
 import lombok.Setter;
 
 import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
 import java.util.List;
 
+/**
+ * 生产超领新增编辑入参实体
+ *
+ * @author
+ * @since 2023-11-19
+ */
 @Getter
 @Setter
-public class ProductionExceedReceiveDto {
-    /**
-     * 订单id
-     */
-    @NotNull(message = "订单id不能为空")
-    private Long orderId;
+public class ProductionExceedReceiveDto extends ProductionExceedReceive {
 
     /**
-     * 超领原因 1-制作损坏,2-裸垫质量不良
+     * 订单sku超领明细
      */
-    @NotNull(message = "超领原因不能为空")
-    private Integer exceedReceiveReason;
+    @NotEmpty(message = "订单sku超领明细列表不能为空")
+    private List<ProductionExceedReceiveSkuDto> productionExceedReceiveSkuList;
 
     /**
-     * 订单sku超领明细
+     * 超领bom明细
      */
-    @NotEmpty(message = "订单sku超领明细列表不能为空")
-    private List<OrderSkuDto> productionCostList;
+    private List<OutBomDto> productionExceedReceiveBomList;
 }

+ 31 - 0
sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSelectDto.java

@@ -0,0 +1,31 @@
+package com.sd.business.entity.production.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 生产超领列表查询入参实体
+ *
+ * @author
+ * @since 2023-11-09
+ */
+@Getter
+@Setter
+public class ProductionExceedReceiveSelectDto extends BaseSelectDto {
+
+    /**
+     * 超领类型
+     */
+    private Integer type;
+
+    /**
+     * 订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 订单万里牛编号
+     */
+    private String orderWlnCode;
+}

+ 18 - 0
sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSkuDto.java

@@ -0,0 +1,18 @@
+package com.sd.business.entity.production.dto;
+
+import com.sd.business.entity.production.po.ProductionExceedReceiveSku;
+import lombok.Getter;
+import lombok.Setter;
+
+
+/**
+ * 生产超领sku新增编辑入参实体
+ *
+ * @author
+ * @since 2023-11-09
+ */
+@Getter
+@Setter
+public class ProductionExceedReceiveSkuDto extends ProductionExceedReceiveSku {
+
+}

+ 41 - 0
sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSkuSelectDto.java

@@ -0,0 +1,41 @@
+package com.sd.business.entity.production.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 生产超领明细列表查询入参实体
+ *
+ * @author
+ * @since 2023-11-09
+ */
+@Getter
+@Setter
+public class ProductionExceedReceiveSkuSelectDto  extends BaseSelectDto {
+
+    /**
+     * 超领类型
+     */
+    private Integer type;
+
+    /**
+     * 订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 订单万里牛编号
+     */
+    private String orderWlnCode;
+
+    /**
+     * sku规格品号
+     */
+    private String skuSpecCode;
+
+    /**
+     * sku规格品名
+     */
+    private String skuSpecName;
+}

+ 40 - 0
sd-business/src/main/java/com/sd/business/entity/production/po/ProductionExceedReceive.java

@@ -0,0 +1,40 @@
+package com.sd.business.entity.production.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 生产超领
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+@Getter
+@Setter
+@TableName("production_exceed_receive")
+public class ProductionExceedReceive extends BasePo {
+
+    /**
+     * 类型 1制作损坏 2裸垫质量不良 3生产错误 4计划外超领
+     */
+    @NotNull(message = "超领类型不能为空")
+    private Integer type;
+
+    /**
+     * 订单id
+     */
+    @NotNull(message = "订单id不能为空")
+    private Long orderId;
+
+    /**
+     * 责任人
+     */
+    private String responsible;
+}

+ 61 - 0
sd-business/src/main/java/com/sd/business/entity/production/po/ProductionExceedReceiveSku.java

@@ -0,0 +1,61 @@
+package com.sd.business.entity.production.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 生产超领sku
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+@Getter
+@Setter
+@TableName("production_exceed_receive_sku")
+public class ProductionExceedReceiveSku extends BasePo {
+
+    /**
+     * 订单生产超领id
+     */
+    private Long productionExceedReceiveId;
+
+    /**
+     * 订单id
+     */
+    private Long orderId;
+
+    /**
+     * 订单sku id
+     */
+    @NotNull(message = "订单sku id不能为空")
+    private Long orderSkuId;
+
+    /**
+     * sku规格id
+     */
+    @NotNull(message = "sku规格id不能为空")
+    private Long skuSpecId;
+
+    /**
+     * 异常sku规格id
+     */
+    private Long exceptionSkuSpecId;
+
+    /**
+     * 数量
+     */
+    @NotNull(message = "数量不能为空")
+    private BigDecimal quantity;
+
+    /**
+     * 仓库id
+     */
+    private Long warehouseId;
+}

+ 41 - 0
sd-business/src/main/java/com/sd/business/entity/production/vo/ProductionExceedReceiveSkuVo.java

@@ -0,0 +1,41 @@
+package com.sd.business.entity.production.vo;
+
+import com.sd.business.entity.production.po.ProductionExceedReceiveSku;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 生产超领sku列表查询返回值实体
+ *
+ * @author
+ * @since 2023-11-08
+ */
+@Getter
+@Setter
+public class ProductionExceedReceiveSkuVo extends ProductionExceedReceiveSku {
+
+    /**
+     * sku规格品号
+     */
+    private String skuSpecCode;
+
+    /**
+     * sku规格品名
+     */
+    private String skuSpecName;
+
+    /**
+     * 订单号
+     */
+    private String orderCode;
+
+    /**
+     * 万里牛订单号
+     */
+    private String orderWlnCode;
+
+    /**
+     * 仓库名称
+     */
+    private String warehouseName;
+}

+ 25 - 0
sd-business/src/main/java/com/sd/business/entity/production/vo/ProductionExceedReceiveVo.java

@@ -0,0 +1,25 @@
+package com.sd.business.entity.production.vo;
+
+import com.sd.business.entity.production.po.ProductionExceedReceive;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 生产超领列表查询返回值实体
+ *
+ * @author
+ * @since 2023-11-08
+ */
+@Getter
+@Setter
+public class ProductionExceedReceiveVo extends ProductionExceedReceive {
+    /**
+     * 订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 订单万里牛编号
+     */
+    private String orderWlnCode;
+}

+ 1 - 1
sd-business/src/main/java/com/sd/business/entity/warehouse/constant/WarehouseConstant.java

@@ -16,7 +16,7 @@ public interface WarehouseConstant {
     Long PACKAGING_MATERIAL = 1684037201379213314L;
 
     /**
-     * 采购次品仓
+     * 采购次品仓(供退仓)
      */
     Long PURCHASE_DEFECTIVE = 1684037092708990977L;
 

+ 27 - 0
sd-business/src/main/java/com/sd/business/mapper/production/ProductionExceedReceiveMapper.java

@@ -0,0 +1,27 @@
+package com.sd.business.mapper.production;
+
+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.production.po.ProductionExceedReceive;
+import com.sd.business.entity.production.vo.ProductionExceedReceiveVo;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 生产超领 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+public interface ProductionExceedReceiveMapper extends BaseMapper<ProductionExceedReceive> {
+
+    /**
+     * 生产超领分页
+     * @param page
+     * @param wrapper
+     * @return
+     */
+    Page<ProductionExceedReceiveVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<ProductionExceedReceive> wrapper);
+}

+ 27 - 0
sd-business/src/main/java/com/sd/business/mapper/production/ProductionExceedReceiveSkuMapper.java

@@ -0,0 +1,27 @@
+package com.sd.business.mapper.production;
+
+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.production.po.ProductionExceedReceiveSku;
+import com.sd.business.entity.production.vo.ProductionExceedReceiveSkuVo;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 生产超领sku Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+public interface ProductionExceedReceiveSkuMapper extends BaseMapper<ProductionExceedReceiveSku> {
+
+    /**
+     * 生产超领sku明细分页
+     * @param page
+     * @param wrapper
+     * @return
+     */
+    Page<ProductionExceedReceiveSkuVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<ProductionExceedReceiveSku> wrapper);
+}

+ 4 - 0
sd-business/src/main/java/com/sd/business/service/inventory/InventoryFinishedService.java

@@ -50,4 +50,8 @@ public interface InventoryFinishedService extends BaseService<InventoryFinished>
      */
     void excelExport(InventoryFinishedSelectDto dto);
 
+    /**
+     * 成品仓sku规格出入库
+     */
+    void inOut(List<InventoryFinished> list, boolean isIn);
 }

+ 2 - 1
sd-business/src/main/java/com/sd/business/service/inventory/impl/InventoryFinishedServiceImpl.java

@@ -136,7 +136,8 @@ public class InventoryFinishedServiceImpl extends ServiceImpl<InventoryFinishedM
     /**
      * 成品仓sku规格出入库
      */
-    private void inOut(List<InventoryFinished> list, boolean isIn) {
+    @Override
+    public void inOut(List<InventoryFinished> list, boolean isIn) {
 
         if (list.isEmpty()) {
             return;

+ 42 - 0
sd-business/src/main/java/com/sd/business/service/production/ProductionExceedReceiveService.java

@@ -0,0 +1,42 @@
+package com.sd.business.service.production;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.service.BaseService;
+import com.sd.business.entity.production.dto.ProductionExceedReceiveDto;
+import com.sd.business.entity.production.dto.ProductionExceedReceiveSelectDto;
+import com.sd.business.entity.production.po.ProductionExceedReceive;
+import com.sd.business.entity.production.vo.ProductionExceedReceiveVo;
+
+/**
+ * <p>
+ * 生产超领 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+public interface ProductionExceedReceiveService extends BaseService<ProductionExceedReceive> {
+
+    /**
+     * 生产超领分页
+     */
+    Page<ProductionExceedReceiveVo> getPage(ProductionExceedReceiveSelectDto dto);
+
+    /**
+     * 生产超领
+     * @param dto
+     */
+    void exceedReceive(ProductionExceedReceiveDto dto);
+
+    /**
+     * 生产错误超领
+     * @param dto
+     */
+    void errorExceedReceive(ProductionExceedReceiveDto dto);
+
+    /**
+     * 计划外超领生产
+     * @param dto
+     */
+    void unplannedExceedReceive(ProductionExceedReceiveDto dto);
+}

+ 22 - 0
sd-business/src/main/java/com/sd/business/service/production/ProductionExceedReceiveSkuService.java

@@ -0,0 +1,22 @@
+package com.sd.business.service.production;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.service.BaseService;
+import com.sd.business.entity.production.dto.ProductionExceedReceiveSkuSelectDto;
+import com.sd.business.entity.production.po.ProductionExceedReceiveSku;
+import com.sd.business.entity.production.vo.ProductionExceedReceiveSkuVo;
+
+/**
+ * <p>
+ * 生产超领sku 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+public interface ProductionExceedReceiveSkuService extends BaseService<ProductionExceedReceiveSku> {
+    /**
+     * 生产超领明细分页
+     */
+    Page<ProductionExceedReceiveSkuVo> getPage(ProductionExceedReceiveSkuSelectDto dto);
+}

+ 0 - 7
sd-business/src/main/java/com/sd/business/service/production/ProductionOrderService.java

@@ -2,7 +2,6 @@ package com.sd.business.service.production;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.BaseSelectDto;
-import com.sd.business.entity.production.dto.ProductionExceedReceiveDto;
 import com.sd.business.entity.production.dto.ProductionOrderDto;
 import com.sd.business.entity.production.dto.RapidPackagingDto;
 import com.sd.business.entity.production.dto.SetTagDto;
@@ -30,10 +29,4 @@ public interface ProductionOrderService {
      * 一键包装
      */
     void rapidPackaging(RapidPackagingDto dto);
-
-    /**
-     * 生产超领
-     * @param dto
-     */
-    void exceedReceive(ProductionExceedReceiveDto dto);
 }

+ 417 - 0
sd-business/src/main/java/com/sd/business/service/production/impl/ProductionExceedReceiveServiceImpl.java

@@ -0,0 +1,417 @@
+package com.sd.business.service.production.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+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.SecurityUtils;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.sd.business.entity.bom.bo.BomSpecBo;
+import com.sd.business.entity.bom.po.BomSpec;
+import com.sd.business.entity.department.constant.DepartmentConstant;
+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.enums.OrderStatusEnum;
+import com.sd.business.entity.order.po.OrderInfo;
+import com.sd.business.entity.order.po.OrderSku;
+import com.sd.business.entity.order.po.OrderSkuProductionCost;
+import com.sd.business.entity.production.dto.ProductionExceedReceiveDto;
+import com.sd.business.entity.production.dto.ProductionExceedReceiveSelectDto;
+import com.sd.business.entity.production.dto.ProductionExceedReceiveSkuDto;
+import com.sd.business.entity.production.po.ProductionExceedReceive;
+import com.sd.business.entity.production.po.ProductionExceedReceiveSku;
+import com.sd.business.entity.production.vo.ProductionExceedReceiveVo;
+import com.sd.business.entity.sku.po.SkuSpec;
+import com.sd.business.entity.warehouse.constant.WarehouseConstant;
+import com.sd.business.mapper.production.ProductionExceedReceiveMapper;
+import com.sd.business.service.bom.BomSpecService;
+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.inventory.InventoryService;
+import com.sd.business.service.order.OrderService;
+import com.sd.business.service.order.OrderSkuProductionCostService;
+import com.sd.business.service.order.OrderSkuService;
+import com.sd.business.service.production.ProductionExceedReceiveService;
+import com.sd.business.service.production.ProductionExceedReceiveSkuService;
+import com.sd.business.service.sku.SkuSpecService;
+import com.sd.framework.util.Assert;
+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.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 生产超领 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+@Service
+public class ProductionExceedReceiveServiceImpl extends ServiceImpl<ProductionExceedReceiveMapper, ProductionExceedReceive> implements ProductionExceedReceiveService {
+
+    @Autowired
+    private OrderService orderService;
+
+    @Autowired
+    private OrderSkuService orderSkuService;
+
+    @Autowired
+    private SkuSpecService skuSpecService;
+
+    @Autowired
+    private InventoryService inventoryService;
+
+    @Autowired
+    private InOutStorageService inOutStorageService;
+
+    @Autowired
+    private BomSpecService bomSpecService;
+
+    @Autowired
+    private OrderSkuProductionCostService orderSkuProductionCostService;
+
+    @Autowired
+    private ProductionExceedReceiveSkuService productionExceedReceiveSkuService;
+
+    @Autowired
+    private InventoryFinishedService inventoryFinishedService;
+
+    @Autowired
+    private InventoryFinishedOrderService inventoryFinishedOrderService;
+
+    @Override
+    public Page<ProductionExceedReceiveVo> getPage(ProductionExceedReceiveSelectDto dto) {
+        IWrapper<ProductionExceedReceive> wrapper = getWrapper();
+        wrapper.orderByDesc("per", ProductionExceedReceive::getId);
+        wrapper.eq("per", ProductionExceedReceive::getType, dto.getType());
+        wrapper.like("oi", OrderInfo::getCode, dto.getOrderCode());
+        wrapper.like("oi", OrderInfo::getWlnCode, dto.getOrderWlnCode());
+        Page<ProductionExceedReceiveVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        return page;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void exceedReceive(ProductionExceedReceiveDto dto) {
+        Long orderId = dto.getOrderId();
+        OrderInfo orderInfo = orderService.getById(orderId);
+        Assert.notNull(orderInfo, "未知订单");
+        Assert.eqTrue(Objects.equals(orderInfo.getStatus(), OrderStatusEnum.IN_PRODUCTION.getKey()), "操作失败,请选择生产中的订单");
+
+        // 筛选数量为0的数据
+        List<ProductionExceedReceiveSkuDto> dtoList = dto.getProductionExceedReceiveSkuList();
+        List<ProductionExceedReceiveSkuDto> exceedReceiveSkuList = dtoList.stream()
+                .filter(item -> item.getQuantity() != null
+                        && item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
+                .collect(Collectors.toList());
+        Assert.notEmpty(exceedReceiveSkuList, "操作失败,订单sku超领明细列表不能为空");
+
+        List<Long> orderSkuIds = exceedReceiveSkuList.stream().map(ProductionExceedReceiveSku::getOrderSkuId).collect(Collectors.toList());
+        Map<Long, OrderSku> orderSkuMap = orderSkuService.byIdsToMap(orderSkuIds);
+        List<Long> bomSpecIds = orderSkuMap.values().stream().map(OrderSku::getBomSpecId).collect(Collectors.toList());
+        Map<Long, BomSpec> bomSpecMap = bomSpecService.byIdsToMap(bomSpecIds);
+        Map<Long, BigDecimal> map = exceedReceiveSkuList.stream().collect(Collectors.toMap(
+                item -> orderSkuMap.get(item.getOrderSkuId()).getBomSpecId(),
+                ProductionExceedReceiveSkuDto::getQuantity,
+                BigDecimal::add));
+        boolean result = inventoryService.lockStorage(map, WarehouseConstant.SEMI_FINISHED_PRODUCT);
+        Assert.eqTrue(result, "库存不足,超领失败!");
+
+        // 出入库信息
+        List<InOutStorageBom> inOutStorageBomList = map.keySet().stream().map(item -> {
+            InOutStorageBom inOutStorageBom = new InOutStorageBom();
+            inOutStorageBom.setBomSpecId(item);
+            inOutStorageBom.setQuantity(map.get(item));
+            return inOutStorageBom;
+        }).collect(Collectors.toList());
+        // 出库
+        String remark = "订单:" + orderInfo.getCode()
+                + (StrUtil.isBlank(orderInfo.getWlnCode()) ? StringPool.EMPTY : "(" + orderInfo.getWlnCode() + ")");
+        this.inOutStorageAdd(InOutTypeEnum.OUT.getKey(),
+                OutDetailTypeEnum.PRODUCTION.getKey(),
+                WarehouseConstant.SEMI_FINISHED_PRODUCT,
+                remark + "超领出库",
+                JSON.parseArray(JSON.toJSONString(inOutStorageBomList), InOutStorageBom.class),
+                StatusConstant.YES);
+        // 入库
+        // 制作损坏入库到生产次品仓,裸垫质量不良入库到采购次品仓
+        Long warehouseId;
+        if (Objects.equals(dto.getType(), 1)) {
+            warehouseId = WarehouseConstant.PRODUCTION_DEFECTIVE;
+        } else {
+            warehouseId = WarehouseConstant.PURCHASE_DEFECTIVE;
+        }
+        this.inOutStorageAdd(InOutTypeEnum.IN.getKey(),
+                InDetailTypeEnum.ABANDON.getKey(),
+                warehouseId,
+                remark + "超领报废入库",
+                inOutStorageBomList,
+                StatusConstant.NO);
+        // 人为损坏, 新增订单生产成本的材料成本
+        if (Objects.equals(dto.getType(), 1)) {
+            Map<Long, OrderSkuProductionCost> orderSkuProductionCostMap = orderSkuProductionCostService.mapKEntity(
+                    OrderSkuProductionCost::getOrderSkuId,
+                    q -> q.eq(OrderSkuProductionCost::getOrderId, orderId)
+                            .in(OrderSkuProductionCost::getOrderSkuId, orderSkuIds)
+            );
+            for (ProductionExceedReceiveSkuDto exceedReceiveSkuDto : exceedReceiveSkuList) {
+                OrderSku orderSku = orderSkuMap.get(exceedReceiveSkuDto.getOrderSkuId());
+                BomSpec bomSpec = bomSpecMap.get(orderSku.getBomSpecId());
+                OrderSkuProductionCost orderSkuProductionCost = orderSkuProductionCostMap.get(exceedReceiveSkuDto.getOrderSkuId());
+                // 计算当前sku超领的材料成本
+                BigDecimal materialCost = exceedReceiveSkuDto.getQuantity().multiply(bomSpec.getInternalSellingPrice());
+
+                orderSkuProductionCost.setMaterialCost(orderSkuProductionCost.getMaterialCost().add(materialCost));
+            }
+            // 更新订单生产成本的材料成本
+            orderSkuProductionCostService.updateBatchById(new ArrayList<>(orderSkuProductionCostMap.values()));
+        }
+        // 保存超领数据
+        this.save(dto);
+        List<ProductionExceedReceiveSku> productionExceedReceiveSkuList = exceedReceiveSkuList.stream()
+                .peek(item -> {
+                    item.setProductionExceedReceiveId(dto.getId());
+                    item.setOrderId(dto.getOrderId());
+                    item.setExceptionSkuSpecId(item.getSkuSpecId());
+                    item.setWarehouseId(warehouseId);
+                })
+                .collect(Collectors.toList());
+        productionExceedReceiveSkuService.saveBatch(productionExceedReceiveSkuList);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void errorExceedReceive(ProductionExceedReceiveDto dto) {
+        Long orderId = dto.getOrderId();
+        OrderInfo orderInfo = orderService.getById(orderId);
+        Assert.notNull(orderInfo, "未知订单");
+        Assert.eqTrue(Objects.equals(orderInfo.getStatus(), OrderStatusEnum.IN_PRODUCTION.getKey())
+                || Objects.equals(orderInfo.getStatus(), OrderStatusEnum.COMPLETION_PRODUCTION.getKey()),
+                "操作失败,请选择生产中或生产完成的订单");
+
+        List<ProductionExceedReceiveSkuDto> productionCostList = dto.getProductionExceedReceiveSkuList();
+        List<ProductionExceedReceiveSkuDto> exceedReceiveSkuList = productionCostList.stream()
+                .filter(item -> item.getQuantity() != null
+                        && item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
+                .filter(item -> Objects.nonNull(item.getExceptionSkuSpecId()))
+                .collect(Collectors.toList());
+        Assert.notEmpty(exceedReceiveSkuList, "操作失败,订单sku超领明细列表不能为空");
+        Assert.notNull(dto.getProductionExceedReceiveBomList(), "操作失败,超领bom明细列表不能为空");
+
+        List<InOutStorageBom> outStorageBomList = dto.getProductionExceedReceiveBomList().stream()
+                .filter(item -> item.getOutQuantity() != null
+                        && item.getOutQuantity().compareTo(BigDecimal.ZERO) > 0)
+                .map(item -> {
+                    InOutStorageBom inOutStorageBom = new InOutStorageBom();
+                    inOutStorageBom.setBomSpecId(item.getBomSpecId());
+                    inOutStorageBom.setQuantity(item.getOutQuantity());
+                   return inOutStorageBom;
+                })
+                .collect(Collectors.toList());
+        Assert.notEmpty(outStorageBomList, "操作失败,超领bom明细列表不能为空");
+
+        List<Long> bomSpecIds = outStorageBomList.stream().map(InOutStorageBom::getBomSpecId).distinct().collect(Collectors.toList());
+        Map<Long, BomSpecBo> bomSpecBoMap = skuSpecService.getBomSpecBoByIdList(bomSpecIds);
+
+        // 半成品出库
+        List<InOutStorageBom> semiFinishedProductInOutStorageBomList = outStorageBomList.stream()
+                .filter(item -> Objects.equals(bomSpecBoMap.get(item.getBomSpecId()).getClassifyParentId(), 1L))
+                .collect(Collectors.toList());
+        String remark = "订单:" + orderInfo.getCode()
+                + (StrUtil.isBlank(orderInfo.getWlnCode()) ? StringPool.EMPTY : "(" + orderInfo.getWlnCode() + ")");
+        this.inOutStorageAdd(InOutTypeEnum.OUT.getKey(),
+                OutDetailTypeEnum.PRODUCTION.getKey(),
+                WarehouseConstant.SEMI_FINISHED_PRODUCT,
+                remark + "生产错误超领出库",
+                semiFinishedProductInOutStorageBomList,
+                StatusConstant.NO);
+
+        // 包材出库
+        List<InOutStorageBom> packagingMaterialInOutStorageBomList = outStorageBomList.stream()
+                .filter(item -> !Objects.equals(bomSpecBoMap.get(item.getBomSpecId()).getClassifyParentId(), 1L))
+                .collect(Collectors.toList());
+        this.inOutStorageAdd(InOutTypeEnum.OUT.getKey(),
+                OutDetailTypeEnum.PRODUCTION.getKey(),
+                WarehouseConstant.PACKAGING_MATERIAL,
+                remark + "生产错误超领出库",
+                packagingMaterialInOutStorageBomList,
+                StatusConstant.NO);
+
+        // 入库
+        List<Long> skuSpecIds = exceedReceiveSkuList.stream().map(ProductionExceedReceiveSku::getExceptionSkuSpecId).collect(Collectors.toList());
+        Map<Long, SkuSpec> skuSpecMap = skuSpecService.byIdsToMap(skuSpecIds);
+        List<InOutStorageBom> inOutStorageBomList = new ArrayList<>();
+        List<InventoryFinished> inventoryFinishedList = new ArrayList<>();
+        for (ProductionExceedReceiveSkuDto exceedReceiveSkuDto : exceedReceiveSkuList) {
+            SkuSpec skuSpec = skuSpecMap.get(exceedReceiveSkuDto.getExceptionSkuSpecId());
+            if (Objects.equals(exceedReceiveSkuDto.getWarehouseId(), WarehouseConstant.PRODUCTION_DEFECTIVE)) {
+                InOutStorageBom inStorageBom = new InOutStorageBom();
+                inStorageBom.setBomSpecId(skuSpec.getBomSpecId());
+                inStorageBom.setQuantity(exceedReceiveSkuDto.getQuantity());
+                inOutStorageBomList.add(inStorageBom);
+            } else {
+                InventoryFinished inventoryFinished = new InventoryFinished();
+                inventoryFinished.setSkuSpecId(skuSpec.getId());
+                inventoryFinished.setQuantity(exceedReceiveSkuDto.getQuantity());
+                inventoryFinishedList.add(inventoryFinished);
+            }
+        }
+
+        if (!inOutStorageBomList.isEmpty()) {
+            this.inOutStorageAdd(InOutTypeEnum.IN.getKey(),
+                    InDetailTypeEnum.ABANDON.getKey(),
+                    WarehouseConstant.PRODUCTION_DEFECTIVE,
+                    remark + "生产错误超领报废入库",
+                    inOutStorageBomList,
+                    StatusConstant.NO);
+        }
+        if (!inventoryFinishedList.isEmpty()) {
+            List<OrderSku> orderSkuList = inventoryFinishedList.stream().map(item -> {
+                OrderSku orderSku = new OrderSku();
+                orderSku.setSkuSpecId(item.getSkuSpecId());
+                orderSku.setQuantity(item.getQuantity());
+                return orderSku;
+            }).collect(Collectors.toList());
+            // 成品入库,并生成明细
+            inventoryFinishedService.inOut(inventoryFinishedList, true);
+            inventoryFinishedOrderService.productionWarehousing(orderSkuList);
+        }
+
+        // 保存超领数据
+        this.save(dto);
+        List<ProductionExceedReceiveSku> productionExceedReceiveSkuList = exceedReceiveSkuList.stream()
+                .peek(item -> {
+                    item.setProductionExceedReceiveId(dto.getId());
+                    item.setOrderId(dto.getOrderId());
+                })
+                .collect(Collectors.toList());
+        productionExceedReceiveSkuService.saveBatch(productionExceedReceiveSkuList);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void unplannedExceedReceive(ProductionExceedReceiveDto dto) {
+        Long orderId = dto.getOrderId();
+        OrderInfo orderInfo = orderService.getById(orderId);
+        Assert.notNull(orderInfo, "未知订单");
+        Assert.eqTrue(Objects.equals(orderInfo.getStatus(), OrderStatusEnum.COMPLETION_PRODUCTION.getKey()), "操作失败,请选择生产完成的订单");
+
+        List<ProductionExceedReceiveSkuDto> productionCostList = dto.getProductionExceedReceiveSkuList();
+        List<ProductionExceedReceiveSkuDto> exceedReceiveSkuList = productionCostList.stream()
+                .filter(item -> item.getQuantity() != null
+                        && item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
+                .collect(Collectors.toList());
+        Assert.notEmpty(exceedReceiveSkuList, "操作失败,订单sku超领明细列表不能为空");
+        Assert.notNull(dto.getProductionExceedReceiveBomList(), "操作失败,超领bom明细列表不能为空");
+
+        List<InOutStorageBom> outStorageBomList = dto.getProductionExceedReceiveBomList().stream()
+                .filter(item -> item.getOutQuantity() != null
+                        && item.getOutQuantity().compareTo(BigDecimal.ZERO) > 0)
+                .map(item -> {
+                    InOutStorageBom inOutStorageBom = new InOutStorageBom();
+                    inOutStorageBom.setBomSpecId(item.getBomSpecId());
+                    inOutStorageBom.setQuantity(item.getOutQuantity());
+                    return inOutStorageBom;
+                })
+                .collect(Collectors.toList());
+        Assert.notEmpty(outStorageBomList,"操作失败,超领bom明细列表不能为空");
+
+        List<Long> bomSpecIds = outStorageBomList.stream().map(InOutStorageBom::getBomSpecId).distinct().collect(Collectors.toList());
+        Map<Long, BomSpecBo> bomSpecBoMap = skuSpecService.getBomSpecBoByIdList(bomSpecIds);
+
+        // 半成品出库
+        List<InOutStorageBom> semiFinishedProductInOutStorageBomList = outStorageBomList.stream()
+                .filter(item -> Objects.equals(bomSpecBoMap.get(item.getBomSpecId()).getClassifyParentId(), 1L))
+                .collect(Collectors.toList());
+        String remark = "订单:" + orderInfo.getCode()
+                + (StrUtil.isBlank(orderInfo.getWlnCode()) ? StringPool.EMPTY : "(" + orderInfo.getWlnCode() + ")");
+        this.inOutStorageAdd(InOutTypeEnum.OUT.getKey(),
+                OutDetailTypeEnum.PRODUCTION.getKey(),
+                WarehouseConstant.SEMI_FINISHED_PRODUCT,
+                remark + "计划外超领出库",
+                JSON.parseArray(JSON.toJSONString(semiFinishedProductInOutStorageBomList), InOutStorageBom.class),
+                StatusConstant.NO
+        );
+
+        // 包材出库
+        List<InOutStorageBom> packagingMaterialInOutStorageBomList = outStorageBomList.stream()
+                .filter(item -> !Objects.equals(bomSpecBoMap.get(item.getBomSpecId()).getClassifyParentId(), 1L))
+                .collect(Collectors.toList());
+        this.inOutStorageAdd(InOutTypeEnum.OUT.getKey(),
+                OutDetailTypeEnum.PRODUCTION.getKey(),
+                WarehouseConstant.PACKAGING_MATERIAL,
+                remark + "计划外超领出库",
+                packagingMaterialInOutStorageBomList,
+                StatusConstant.NO);
+
+        // 半成品入库次品仓
+        this.inOutStorageAdd(InOutTypeEnum.IN.getKey(),
+                InDetailTypeEnum.ABANDON.getKey(),
+                WarehouseConstant.PRODUCTION_DEFECTIVE,
+                remark + "计划外超领报废入库",
+                semiFinishedProductInOutStorageBomList,
+                StatusConstant.NO);
+
+        // 保存超领数据
+        this.save(dto);
+        List<ProductionExceedReceiveSku> productionExceedReceiveSkuList = exceedReceiveSkuList.stream()
+                .peek(item -> {
+                    item.setProductionExceedReceiveId(dto.getId());
+                    item.setOrderId(dto.getOrderId());
+                    item.setExceptionSkuSpecId(item.getSkuSpecId());
+                    item.setWarehouseId(WarehouseConstant.PRODUCTION_DEFECTIVE);
+                })
+                .collect(Collectors.toList());
+        productionExceedReceiveSkuService.saveBatch(productionExceedReceiveSkuList);
+    }
+
+
+    /**
+     * 出入库新增
+     * @param type
+     * @param detailType
+     * @param warehouseId
+     * @param remark
+     * @param inOutStorageBomList
+     * @param lockStorage
+     */
+    private void inOutStorageAdd(Integer type, Integer detailType, Long warehouseId, String remark, List<InOutStorageBom> inOutStorageBomList, Integer lockStorage) {
+        if (ObjectUtil.isEmpty(inOutStorageBomList)) {
+            return;
+        }
+
+        // 合并相同bom规格出库数量
+        List<InOutStorageBom> list = new ArrayList<>(inOutStorageBomList.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(type);
+        inOutStorageDto.setDetailType(detailType);
+        inOutStorageDto.setWarehouseId(warehouseId);
+        inOutStorageDto.setDepartmentId(DepartmentConstant.SD_SPORTS);
+        inOutStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
+        inOutStorageDto.setRemark(remark);
+        inOutStorageDto.setInOutStorageBomList(list);
+        inOutStorageDto.setLockStorage(lockStorage);
+        inOutStorageService.add(inOutStorageDto);
+    }
+}

+ 40 - 0
sd-business/src/main/java/com/sd/business/service/production/impl/ProductionExceedReceiveSkuServiceImpl.java

@@ -0,0 +1,40 @@
+package com.sd.business.service.production.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.sd.business.entity.order.po.OrderInfo;
+import com.sd.business.entity.production.dto.ProductionExceedReceiveSkuSelectDto;
+import com.sd.business.entity.production.po.ProductionExceedReceive;
+import com.sd.business.entity.production.po.ProductionExceedReceiveSku;
+import com.sd.business.entity.production.vo.ProductionExceedReceiveSkuVo;
+import com.sd.business.entity.production.vo.ProductionExceedReceiveVo;
+import com.sd.business.entity.sku.po.SkuSpec;
+import com.sd.business.mapper.production.ProductionExceedReceiveSkuMapper;
+import com.sd.business.service.production.ProductionExceedReceiveSkuService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 生产超领sku 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-11-09
+ */
+@Service
+public class ProductionExceedReceiveSkuServiceImpl extends ServiceImpl<ProductionExceedReceiveSkuMapper, ProductionExceedReceiveSku> implements ProductionExceedReceiveSkuService {
+
+    @Override
+    public Page<ProductionExceedReceiveSkuVo> getPage(ProductionExceedReceiveSkuSelectDto dto) {
+        IWrapper<ProductionExceedReceiveSku> wrapper = getWrapper();
+        wrapper.orderByDesc("pers", ProductionExceedReceive::getId);
+        wrapper.eq("per", ProductionExceedReceive::getType, dto.getType());
+        wrapper.like("oi", OrderInfo::getCode, dto.getOrderCode());
+        wrapper.like("oi", OrderInfo::getWlnCode, dto.getOrderWlnCode());
+        wrapper.like("ss", SkuSpec::getCode, dto.getSkuSpecCode());
+        wrapper.like("ss", SkuSpec::getName, dto.getSkuSpecName());
+        Page<ProductionExceedReceiveSkuVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        return page;
+    }
+}

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

@@ -1,30 +1,16 @@
 package com.sd.business.service.production.impl;
 
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson2.JSON;
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.constant.StatusConstant;
 import com.ruoyi.common.core.domain.BaseIdPo;
 import com.ruoyi.common.core.domain.BasePo;
 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.bom.po.BomSpec;
-import com.sd.business.entity.department.constant.DepartmentConstant;
-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.order.dto.OrderSkuDto;
 import com.sd.business.entity.order.enums.OrderStatusEnum;
 import com.sd.business.entity.order.po.OrderInfo;
 import com.sd.business.entity.order.po.OrderPackageBom;
 import com.sd.business.entity.order.po.OrderSku;
-import com.sd.business.entity.order.po.OrderSkuProductionCost;
-import com.sd.business.entity.production.dto.ProductionExceedReceiveDto;
 import com.sd.business.entity.production.dto.ProductionOrderDto;
 import com.sd.business.entity.production.dto.RapidPackagingDto;
 import com.sd.business.entity.production.dto.SetTagDto;
@@ -33,15 +19,11 @@ import com.sd.business.entity.production.vo.ProductionOrderDetailVo;
 import com.sd.business.entity.production.vo.ProductionOrderScheduleVo;
 import com.sd.business.entity.production.vo.ProductionOrderVo;
 import com.sd.business.entity.statement.dto.StatementOfAccountDto;
-import com.sd.business.entity.warehouse.constant.WarehouseConstant;
 import com.sd.business.mapper.production.ProductionOrderMapper;
 import com.sd.business.service.bom.BomSpecService;
-import com.sd.business.service.in.InOutStorageService;
 import com.sd.business.service.inventory.InventoryFinishedService;
-import com.sd.business.service.inventory.InventoryService;
 import com.sd.business.service.order.OrderPackageBomService;
 import com.sd.business.service.order.OrderService;
-import com.sd.business.service.order.OrderSkuProductionCostService;
 import com.sd.business.service.order.OrderSkuService;
 import com.sd.business.service.production.ProductionOrderService;
 import com.sd.business.service.production.ProductionWorkOrderService;
@@ -51,9 +33,7 @@ import com.sd.framework.util.Assert;
 import com.sd.mq.enums.WorkOrderStatusEnum;
 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.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -83,15 +63,6 @@ public class ProductionOrderServiceImpl implements ProductionOrderService {
     private StatementOfAccountService statementOfAccountService;
 
     @Autowired
-    private InventoryService inventoryService;
-
-    @Autowired
-    private InOutStorageService inOutStorageService;
-
-    @Autowired
-    private OrderSkuProductionCostService orderSkuProductionCostService;
-
-    @Autowired
     private InventoryFinishedService inventoryFinishedService;
 
     @Autowired
@@ -188,91 +159,6 @@ public class ProductionOrderServiceImpl implements ProductionOrderService {
 
     }
 
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void exceedReceive(ProductionExceedReceiveDto dto) {
-        Long orderId = dto.getOrderId();
-        OrderInfo orderInfo = orderService.getById(orderId);
-        if (orderInfo == null) {
-            throw new ServiceException("未知订单");
-        }
-        if (!Objects.equals(orderInfo.getStatus(), OrderStatusEnum.IN_PRODUCTION.getKey())) {
-            throw new ServiceException("操作失败,请选择生产中的订单");
-        }
-        List<OrderSkuDto> productionCostList = dto.getProductionCostList();
-        List<OrderSkuDto> exceedReceiveSkuList = productionCostList.stream()
-                .filter(item -> item.getQuantity() != null
-                        && item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
-                .collect(Collectors.toList());
-        if (exceedReceiveSkuList.isEmpty()) {
-            throw new ServiceException("操作失败,订单sku超领明细列表不能为空");
-        }
-        Map<Long, BigDecimal> map = exceedReceiveSkuList.stream().collect(Collectors.toMap(
-                OrderSkuDto::getBomSpecId, OrderSkuDto::getQuantity, BigDecimal::add));
-        boolean result = inventoryService.lockStorage(map, WarehouseConstant.SEMI_FINISHED_PRODUCT);
-        if (!result) {
-            throw new ServiceException("库存不足,超领失败!");
-        }
-        // 出入库信息
-        List<InOutStorageBom> inOutStorageBomList = map.keySet().stream().map(item -> {
-            InOutStorageBom inOutStorageBom = new InOutStorageBom();
-            inOutStorageBom.setBomSpecId(item);
-            inOutStorageBom.setQuantity(map.get(item));
-            return inOutStorageBom;
-        }).collect(Collectors.toList());
-        // 出库
-        InOutStorageDto lockPurchaseDefective = new InOutStorageDto();
-        lockPurchaseDefective.setType(InOutTypeEnum.OUT.getKey());
-        lockPurchaseDefective.setDetailType(OutDetailTypeEnum.PRODUCTION.getKey());
-        lockPurchaseDefective.setWarehouseId(WarehouseConstant.SEMI_FINISHED_PRODUCT);
-        lockPurchaseDefective.setDepartmentId(DepartmentConstant.SD_SPORTS);
-        lockPurchaseDefective.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
-        lockPurchaseDefective.setRemark("订单:" + orderInfo.getCode()
-                + (StrUtil.isBlank(orderInfo.getWlnCode()) ? StringPool.EMPTY : "(" + orderInfo.getWlnCode() + ")")
-                + "超领出库");
-        lockPurchaseDefective.setLockStorage(StatusConstant.YES);
-        lockPurchaseDefective.setInOutStorageBomList(JSON.parseArray(JSON.toJSONString(inOutStorageBomList), InOutStorageBom.class));
-        inOutStorageService.add(lockPurchaseDefective);
-        // 入库
-        InOutStorageDto inStorageDto = new InOutStorageDto();
-        inStorageDto.setType(InOutTypeEnum.IN.getKey());
-        inStorageDto.setDetailType(InDetailTypeEnum.ABANDON.getKey());
-        // 制作损坏入库到生产次品仓,裸垫质量不良入库到采购次品仓
-        if (Objects.equals(dto.getExceedReceiveReason(), 1)) {
-            inStorageDto.setWarehouseId(WarehouseConstant.PRODUCTION_DEFECTIVE);
-        } else {
-            inStorageDto.setWarehouseId(WarehouseConstant.PURCHASE_DEFECTIVE);
-        }
-        inStorageDto.setDepartmentId(DepartmentConstant.SD_SPORTS);
-        inStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
-        inStorageDto.setRemark("订单:" + orderInfo.getCode()
-                + (StrUtil.isBlank(orderInfo.getWlnCode()) ? StringPool.EMPTY : "(" + orderInfo.getWlnCode() + ")")
-                + "超领报废入库");
-        inStorageDto.setInOutStorageBomList(inOutStorageBomList);
-        inOutStorageService.add(inStorageDto);
-        // 人为损坏, 新增订单生产成本的材料成本
-        if (Objects.equals(dto.getExceedReceiveReason(), 1)) {
-            List<Long> bomSpecIds = exceedReceiveSkuList.stream().map(OrderSku::getBomSpecId).collect(Collectors.toList());
-            List<Long> orderSkuIds = exceedReceiveSkuList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
-            Map<Long, BomSpec> bomSpecMap = bomSpecService.mapKEntity(BaseIdPo::getId, q -> q.in(BaseIdPo::getId, bomSpecIds));
-            Map<Long, OrderSkuProductionCost> orderSkuProductionCostMap = orderSkuProductionCostService.mapKEntity(
-                    OrderSkuProductionCost::getOrderSkuId,
-                    q -> q.eq(OrderSkuProductionCost::getOrderId, orderId)
-                            .in(OrderSkuProductionCost::getOrderSkuId, orderSkuIds)
-            );
-            for (OrderSkuDto orderSkuDto : exceedReceiveSkuList) {
-                BomSpec bomSpec = bomSpecMap.get(orderSkuDto.getBomSpecId());
-                OrderSkuProductionCost orderSkuProductionCost = orderSkuProductionCostMap.get(orderSkuDto.getId());
-                // 计算当前sku超领的材料成本
-                BigDecimal materialCost = orderSkuDto.getQuantity().multiply(bomSpec.getInternalSellingPrice());
-
-                orderSkuProductionCost.setMaterialCost(orderSkuProductionCost.getMaterialCost().add(materialCost));
-            }
-            // 更新订单生产成本的材料成本
-            orderSkuProductionCostService.updateBatchById(new ArrayList<>(orderSkuProductionCostMap.values()));
-        }
-    }
-
     private List<ProductionOrderDetailVo.SkuSpec> getSkuSpecList(Long orderId) {
 
         // 获取订单sku规格

+ 9 - 0
sd-business/src/main/java/com/sd/business/service/sku/SkuSpecService.java

@@ -5,6 +5,8 @@ import com.ruoyi.common.core.service.BaseService;
 import com.sd.business.entity.board.dto.SkuSpecQuotationDto;
 import com.sd.business.entity.board.vo.SkuSpecQuotationVo;
 import com.sd.business.entity.bom.bo.BomSpecBo;
+import com.sd.business.entity.order.dto.SkuSpecPackageBomDto;
+import com.sd.business.entity.production.vo.OutBomVo;
 import com.sd.business.entity.sku.bo.SkuSpecBo;
 import com.sd.business.entity.sku.dto.SkuSpecDto;
 import com.sd.business.entity.sku.dto.SkuSpecSelectDto;
@@ -78,4 +80,11 @@ public interface SkuSpecService extends BaseService<SkuSpec> {
      * @return
      */
     List<SkuSpecQuotationVo> getSkuSpecQuotationList(SkuSpecQuotationDto dto);
+
+    /**
+     * 获取sku所有材料明细列表
+     * @param dto
+     * @return
+     */
+    List<OutBomVo> getSkuSpecMaterialList(SkuSpecPackageBomDto dto);
 }

+ 104 - 0
sd-business/src/main/java/com/sd/business/service/sku/impl/SkuSpecServiceImpl.java

@@ -16,10 +16,14 @@ import com.sd.business.entity.board.vo.SkuSpecQuotationVo;
 import com.sd.business.entity.bom.bo.BomSpecBo;
 import com.sd.business.entity.bom.po.Bom;
 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.Inventory;
+import com.sd.business.entity.order.dto.SkuSpecPackageBomDto;
+import com.sd.business.entity.order.dto.SkuSpecPriceDto;
 import com.sd.business.entity.price.po.PriceBillingStandard;
 import com.sd.business.entity.price.po.PriceBillingStandardDetail;
+import com.sd.business.entity.production.vo.OutBomVo;
 import com.sd.business.entity.sku.bo.SkuSpecBo;
 import com.sd.business.entity.sku.dto.SkuSpecDto;
 import com.sd.business.entity.sku.dto.SkuSpecSelectDto;
@@ -321,4 +325,104 @@ public class SkuSpecServiceImpl extends ServiceImpl<SkuSpecMapper, SkuSpec> impl
         return skuSpecList;
     }
 
+    @Override
+    public List<OutBomVo> getSkuSpecMaterialList(SkuSpecPackageBomDto dto) {
+        List<SkuSpecPriceDto> list = dto.getSkuSpecList().stream()
+                .filter(item -> item.getQuantity() != null
+                        && item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
+                .collect(Collectors.toList());
+       if (list.isEmpty()) {
+           return Collections.emptyList();
+       }
+
+        List<Long> skuSpecIds = list.stream().map(SkuSpecPriceDto::getSkuSpecId).collect(Collectors.toList());
+        Map<Long, SkuSpec> skuSpecMap = this.byIdsToMap(skuSpecIds);
+        Map<Long, List<SkuSpecLink>> skuSpecLinkMap = skuSpecLinkService.mapKGroup(
+                SkuSpecLink::getSkuSpecId,
+                q -> q.in(SkuSpecLink::getSkuSpecId, skuSpecIds));
+
+        // 获取所有bom数据
+        Set<Long> bomSpecIds = skuSpecMap.values().stream().map(SkuSpec::getBomSpecId).collect(Collectors.toSet());
+        List<Long> linkBomSpecIds = skuSpecLinkMap.values().stream().flatMap(item -> item.stream().map(SkuSpecLink::getBomSpecId)).collect(Collectors.toList());
+        bomSpecIds.addAll(linkBomSpecIds);
+        Map<Long, BomSpecBo> bomSpecBoMap = this.getBomSpecBoByIdList(bomSpecIds);
+
+        List<OutBomVo> outBomVoList = new ArrayList<>();
+        for (SkuSpecPriceDto skuSpecPriceDto : list) {
+            SkuSpec skuSpec = skuSpecMap.get(skuSpecPriceDto.getSkuSpecId());
+            BomSpecBo bomSpecBo = bomSpecBoMap.get(skuSpec.getBomSpecId());
+            OutBomVo outBomVo = new OutBomVo();
+            outBomVo.setBomSpecId(skuSpec.getBomSpecId());
+            outBomVo.setOutQuantity(skuSpecPriceDto.getQuantity());
+            outBomVo.setBomSpecCode(bomSpecBo.getBomSpecCode());
+            outBomVo.setBomSpecName(bomSpecBo.getBomSpecName());
+            if (Objects.equals(bomSpecBo.getClassifyParentId(), 1L)) {
+                outBomVo.setWarehouseId(WarehouseConstant.SEMI_FINISHED_PRODUCT);
+                outBomVo.setWarehouseName("半成品仓");
+            } else {
+                outBomVo.setWarehouseId(WarehouseConstant.PACKAGING_MATERIAL);
+                outBomVo.setWarehouseName("包材仓");
+            }
+            outBomVoList.add(outBomVo);
+
+            List<SkuSpecLink> skuSpecLinkList = skuSpecLinkMap.getOrDefault(skuSpecPriceDto.getSkuSpecId(), Collections.emptyList());
+            List<OutBomVo> skuSpecLinkOutBomVoList = skuSpecLinkList.stream().map(item -> {
+                BomSpecBo bomSpec = bomSpecBoMap.get(item.getBomSpecId());
+                OutBomVo vo = new OutBomVo();
+                vo.setBomSpecId(item.getBomSpecId());
+                vo.setOutQuantity(item.getQuantity().multiply(skuSpecPriceDto.getQuantity()));
+                vo.setBomSpecCode(bomSpec.getBomSpecCode());
+                vo.setBomSpecName(bomSpec.getBomSpecName());
+                vo.setWarehouseId(WarehouseConstant.PACKAGING_MATERIAL);
+                vo.setWarehouseName("包材仓");
+                return vo;
+            }).collect(Collectors.toList());
+            outBomVoList.addAll(skuSpecLinkOutBomVoList);
+        }
+
+        // 主材库存
+        Map<Long, BigDecimal> semiFinishedProductInventoryMap = Collections.emptyMap();
+        List<Long> semiFinishedProductBomSpecIdList = outBomVoList.stream()
+                .filter(item -> WarehouseConstant.SEMI_FINISHED_PRODUCT.equals(item.getWarehouseId()))
+                .map(OutBomVo::getBomSpecId)
+                .collect(Collectors.toList());
+        if (!semiFinishedProductBomSpecIdList.isEmpty()) {
+            List<Inventory> tempList = inventoryService.list(q -> q.eq(Inventory::getWarehouseId, WarehouseConstant.SEMI_FINISHED_PRODUCT)
+                    .eq(Inventory::getDepartmentId, DepartmentConstant.SD_SPORTS)
+                    .in(Inventory::getBomSpecId, semiFinishedProductBomSpecIdList));
+            semiFinishedProductInventoryMap = tempList.stream().collect(Collectors.toMap(Inventory::getBomSpecId,
+                    item -> item.getQuantity().add(item.getLockQuantity()), (v1, v2) -> v2));
+
+        }
+
+        // 包材库存
+        Map<Long, BigDecimal> packagingMaterialInventoryMap = Collections.emptyMap();
+        List<Long> packagingMaterialBomSpecIdList = outBomVoList.stream()
+                .filter(item -> WarehouseConstant.PACKAGING_MATERIAL.equals(item.getWarehouseId()))
+                .map(OutBomVo::getBomSpecId)
+                .collect(Collectors.toList());
+        if (!packagingMaterialBomSpecIdList.isEmpty()) {
+            List<Inventory> tempList = inventoryService.list(q -> q
+                    .eq(Inventory::getWarehouseId, WarehouseConstant.PACKAGING_MATERIAL)
+                    .eq(Inventory::getDepartmentId, DepartmentConstant.SD_SPORTS)
+                    .in(Inventory::getBomSpecId, packagingMaterialBomSpecIdList)
+            );
+            packagingMaterialInventoryMap = tempList.stream().collect(Collectors.toMap(Inventory::getBomSpecId,
+                    item -> item.getQuantity().add(item.getLockQuantity()), (v1, v2) -> v2));
+        }
+
+        // 赋值库存
+        for (OutBomVo outBomVo : outBomVoList) {
+            if (WarehouseConstant.SEMI_FINISHED_PRODUCT.equals(outBomVo.getWarehouseId())) {
+                outBomVo.setInventoryQuantity(semiFinishedProductInventoryMap.getOrDefault(outBomVo.getBomSpecId(), BigDecimal.ZERO));
+            } else {
+                outBomVo.setInventoryQuantity(packagingMaterialInventoryMap.getOrDefault(outBomVo.getBomSpecId(), BigDecimal.ZERO));
+            }
+        }
+
+        return outBomVoList.stream()
+                .sorted(Comparator.comparing(OutBomVo::getWarehouseId, Comparator.reverseOrder()).thenComparing(OutBomVo::getBomSpecCode))
+                .collect(Collectors.toList());
+    }
+
 }

+ 21 - 0
sd-business/src/main/resources/mapper/production/ProductionExceedReceiveMapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sd.business.mapper.production.ProductionExceedReceiveMapper">
+
+    <select id="getPage" resultType="com.sd.business.entity.production.vo.ProductionExceedReceiveVo">
+        select
+            per.id,
+            per.type,
+            per.order_id,
+            per.responsible,
+            per.create_user,
+            per.create_time,
+            per.update_user,
+            per.update_time,
+            oi.code     orderCode,
+            oi.wln_code orderWlnCode
+        from production_exceed_receive per
+            inner join order_info oi on per.order_id = oi.id
+            ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 32 - 0
sd-business/src/main/resources/mapper/production/ProductionExceedReceiveSkuMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sd.business.mapper.production.ProductionExceedReceiveSkuMapper">
+
+    <select id="getPage" resultType="com.sd.business.entity.production.vo.ProductionExceedReceiveSkuVo">
+        select
+            pers.id,
+            pers.production_exceed_receive_id,
+            pers.order_id,
+            pers.order_sku_id,
+            pers.sku_spec_id,
+            pers.exception_sku_spec_id,
+            pers.quantity,
+            pers.warehouse_id,
+            pers.create_user,
+            pers.create_time,
+            pers.update_user,
+            pers.update_time,
+            per.type,
+            per.responsible,
+            oi.code     orderCode,
+            oi.wln_code orderWlnCode,
+            ss.code     skuSpecCode,
+            ss.name     skuSpecName,
+            w.name      warehouseName
+        from production_exceed_receive_sku pers
+            inner join production_exceed_receive per on pers.production_exceed_receive_id = per.id
+            inner join order_info oi on pers.order_id = oi.id
+            inner join sku_spec ss on pers.sku_spec_id = ss.id
+            inner join warehouse w on pers.warehouse_id = w.id
+    </select>
+</mapper>