Browse Source

Merge remote-tracking branch 'origin/master'

24282 1 năm trước cách đây
mục cha
commit
b8c6bb716c
35 tập tin đã thay đổi với 1383 bổ sung151 xóa
  1. 8 0
      sd-business/src/main/java/com/sd/business/controller/apply/ApplyBuyController.java
  2. 33 4
      sd-business/src/main/java/com/sd/business/controller/production/ProductionExceedReceiveController.java
  3. 12 0
      sd-business/src/main/java/com/sd/business/controller/sku/SkuSpecController.java
  4. 26 0
      sd-business/src/main/java/com/sd/business/entity/order/dto/SkuSpecPackageBomDto.java
  5. 46 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/OutBomDto.java
  6. 13 14
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveDto.java
  7. 31 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSelectDto.java
  8. 18 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSkuDto.java
  9. 41 0
      sd-business/src/main/java/com/sd/business/entity/production/dto/ProductionExceedReceiveSkuSelectDto.java
  10. 40 0
      sd-business/src/main/java/com/sd/business/entity/production/po/ProductionExceedReceive.java
  11. 61 0
      sd-business/src/main/java/com/sd/business/entity/production/po/ProductionExceedReceiveSku.java
  12. 41 0
      sd-business/src/main/java/com/sd/business/entity/production/vo/ProductionExceedReceiveSkuVo.java
  13. 25 0
      sd-business/src/main/java/com/sd/business/entity/production/vo/ProductionExceedReceiveVo.java
  14. 56 0
      sd-business/src/main/java/com/sd/business/entity/sku/dto/SkuSpecImportDataDto.java
  15. 1 1
      sd-business/src/main/java/com/sd/business/entity/warehouse/constant/WarehouseConstant.java
  16. 0 1
      sd-business/src/main/java/com/sd/business/flow/ApplyBuyFlow.java
  17. 27 0
      sd-business/src/main/java/com/sd/business/mapper/production/ProductionExceedReceiveMapper.java
  18. 27 0
      sd-business/src/main/java/com/sd/business/mapper/production/ProductionExceedReceiveSkuMapper.java
  19. 1 1
      sd-business/src/main/java/com/sd/business/service/apply/ApplyBuyService.java
  20. 4 3
      sd-business/src/main/java/com/sd/business/service/apply/impl/ApplyBuyServiceImpl.java
  21. 2 3
      sd-business/src/main/java/com/sd/business/service/in/impl/InOutStorageBomServiceImpl.java
  22. 4 0
      sd-business/src/main/java/com/sd/business/service/inventory/InventoryFinishedService.java
  23. 2 1
      sd-business/src/main/java/com/sd/business/service/inventory/impl/InventoryFinishedServiceImpl.java
  24. 48 1
      sd-business/src/main/java/com/sd/business/service/order/impl/OrderServiceImpl.java
  25. 42 0
      sd-business/src/main/java/com/sd/business/service/production/ProductionExceedReceiveService.java
  26. 22 0
      sd-business/src/main/java/com/sd/business/service/production/ProductionExceedReceiveSkuService.java
  27. 0 7
      sd-business/src/main/java/com/sd/business/service/production/ProductionOrderService.java
  28. 417 0
      sd-business/src/main/java/com/sd/business/service/production/impl/ProductionExceedReceiveServiceImpl.java
  29. 40 0
      sd-business/src/main/java/com/sd/business/service/production/impl/ProductionExceedReceiveSkuServiceImpl.java
  30. 0 114
      sd-business/src/main/java/com/sd/business/service/production/impl/ProductionOrderServiceImpl.java
  31. 16 0
      sd-business/src/main/java/com/sd/business/service/sku/SkuSpecService.java
  32. 225 0
      sd-business/src/main/java/com/sd/business/service/sku/impl/SkuSpecServiceImpl.java
  33. 21 0
      sd-business/src/main/resources/mapper/production/ProductionExceedReceiveMapper.xml
  34. 32 0
      sd-business/src/main/resources/mapper/production/ProductionExceedReceiveSkuMapper.xml
  35. 1 1
      sd-business/src/main/resources/mapper/purchase/PurchasePendingStorageMapper.xml

+ 8 - 0
sd-business/src/main/java/com/sd/business/controller/apply/ApplyBuyController.java

@@ -63,4 +63,12 @@ public class ApplyBuyController {
         applyBuyService.edit(dto);
     }
 
+    /**
+     * 更新申购单附件
+     */
+    @PostMapping("/updateApplyBuyAccessory")
+    public void updateApplyBuyAccessory(@RequestBody BaseSelectDto dto) {
+        applyBuyService.addApplyBuyAccessory(dto.getId());
+    }
+
 }

+ 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);
+    }
 }

+ 12 - 0
sd-business/src/main/java/com/sd/business/controller/sku/SkuSpecController.java

@@ -3,16 +3,20 @@ package com.sd.business.controller.sku;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.BaseSelectDto;
 import com.sd.business.entity.sku.dto.SkuSpecDto;
+import com.sd.business.entity.sku.dto.SkuSpecImportDataDto;
 import com.sd.business.entity.sku.dto.SkuSpecSelectDto;
 import com.sd.business.entity.sku.vo.SkuSpecVo;
 import com.sd.business.service.sku.SkuSpecService;
+import com.sd.framework.util.excel.util.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * <p>
@@ -79,4 +83,12 @@ public class SkuSpecController {
         return skuSpecService.getSkuInventoryQuantity(dto.getId());
     }
 
+    /**
+     * sku规格导入
+     */
+    @PostMapping("/skuSpecImport")
+    public void skuSpecImport(MultipartFile file) {
+        List<SkuSpecImportDataDto> list = ExcelUtil.read(file, SkuSpecImportDataDto.class);
+        skuSpecService.skuSpecImport(list);
+    }
 }

+ 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;
+}

+ 56 - 0
sd-business/src/main/java/com/sd/business/entity/sku/dto/SkuSpecImportDataDto.java

@@ -0,0 +1,56 @@
+package com.sd.business.entity.sku.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * sku规格导入入参实体
+ */
+@Getter
+@Setter
+public class SkuSpecImportDataDto {
+
+    /**
+     * sku规格品号
+     */
+    @ExcelProperty("SKU")
+    private String skuSpecCode;
+
+    /**
+     * sku规格
+     */
+    @ExcelProperty("规格")
+    private String spec;
+
+    @ExcelProperty("图稿类型")
+    private String machinedPanelStr;
+
+    @ExcelProperty("图稿文件")
+    private String machinedPanelFileStr;
+
+    @ExcelProperty("裸垫品号")
+    private String bomSpecCode;
+    @ExcelProperty("opp膜品号")
+    private String packagingBomSpecCode_1;
+    @ExcelProperty("彩纸品号")
+    private String packagingBomSpecCode_2;
+    @ExcelProperty("松紧圈品号")
+    private String packagingBomSpecCode_3;
+    @ExcelProperty("松紧圈背带")
+    private String packagingBomSpecCode_4;
+    @ExcelProperty("热收缩膜")
+    private String packagingBomSpecCode_5;
+    @ExcelProperty("气泡袋")
+    private String packagingBomSpecCode_6;
+    @ExcelProperty("网包品号")
+    private String packagingBomSpecCode_7;
+    @ExcelProperty("吊牌品号")
+    private String packagingBomSpecCode_8;
+    @ExcelProperty("纸箱")
+    private String packagingBomSpecCode_9;
+    @ExcelProperty("不干胶品号")
+    private String packagingBomSpecCode_10;
+    @ExcelProperty("快递袋")
+    private String deliveryMaterialsBomSpecCode;
+}

+ 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;
 

+ 0 - 1
sd-business/src/main/java/com/sd/business/flow/ApplyBuyFlow.java

@@ -58,7 +58,6 @@ public class ApplyBuyFlow extends FlowDelegate {
                 .set(BasePo::getUpdateTime, new Date())
                 .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
         );
-        applyBuyService.addBomAccessory(businessId);
     }
 
     /**

+ 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);
+}

+ 1 - 1
sd-business/src/main/java/com/sd/business/service/apply/ApplyBuyService.java

@@ -42,5 +42,5 @@ public interface ApplyBuyService extends BaseService<ApplyBuy> {
      * 新增备货需求附件
      * @param id
      */
-    void addBomAccessory(Long id);
+    void addApplyBuyAccessory(Long id);
 }

+ 4 - 3
sd-business/src/main/java/com/sd/business/service/apply/impl/ApplyBuyServiceImpl.java

@@ -152,6 +152,7 @@ public class ApplyBuyServiceImpl extends ServiceImpl<ApplyBuyMapper, ApplyBuy> i
 
         save(dto);
         applyBuyBomService.saveBatch(applyBuyBomList);
+        this.addApplyBuyAccessory(dto.getId());
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -168,7 +169,7 @@ public class ApplyBuyServiceImpl extends ServiceImpl<ApplyBuyMapper, ApplyBuy> i
 
     @DSTransactional
     @Override
-    public void addBomAccessory(Long id) {
+    public void addApplyBuyAccessory(Long id) {
         // 新增备货需求附件
         List<ApplyBuyBomAccessoryVo> applyData = this.getApplyData(id);
         // 修改表头
@@ -197,7 +198,7 @@ public class ApplyBuyServiceImpl extends ServiceImpl<ApplyBuyMapper, ApplyBuy> i
         obsFile.setId(fileInfo.getId());
         obsFile.setFileName(fileName);
         obsFile.setFileUrl(fileUrl);
-        ObsFileUtil.saveFile(obsFile, id);
+        ObsFileUtil.editFile(obsFile, id);
     }
 
 
@@ -300,7 +301,7 @@ public class ApplyBuyServiceImpl extends ServiceImpl<ApplyBuyMapper, ApplyBuy> i
             vo.setActualSalesDays(actualSalesDays);
             vo.setShortageQuantity(shortageQuantity);
             vo.setApplyBuyQuantity(applyBuyBom.getQuantity());
-            vo.setTurnoverRate(turnoverRateMap.get(applyBuyBom.getBomSpecId()));
+            vo.setTurnoverRate(turnoverRateMap.getOrDefault(applyBuyBom.getBomSpecId(), BigDecimal.ZERO));
             accessoryList.add(vo);
         }
 

+ 2 - 3
sd-business/src/main/java/com/sd/business/service/in/impl/InOutStorageBomServiceImpl.java

@@ -122,7 +122,6 @@ public class InOutStorageBomServiceImpl extends ServiceImpl<InOutStorageBomMappe
                 .orderByAsc(InOutStorage::getInOutStorageTime));
 
         List<InOutStorageErpExportVo> inOutStorageErpExportVoList = new ArrayList<>();
-        int codeNum = 1;
         String dateFormat = "";
         for (InOutStorage inOutStorage : inOutStorageList) {
             InOutStorageErpExportVo inOutStorageErpExportVo = new InOutStorageErpExportVo();
@@ -139,9 +138,9 @@ public class InOutStorageBomServiceImpl extends ServiceImpl<InOutStorageBomMappe
             String format = "-20" + substring;
             if (!Objects.equals(dateFormat, format)) {
                 dateFormat = format;
-                // 后四位生成规则,取系统单号 dd01
-                codeNum = Integer.parseInt(codes[1].substring(codes[1].length() - 2) + codes[2].substring(codes[2].length() - 2));
             }
+            // 后四位生成规则,取系统单号 dd01
+            int codeNum = Integer.parseInt(codes[1].substring(codes[1].length() - 2) + codes[2].substring(codes[2].length() - 2));
             String code = inOutStorageErpExportVo.getDocCode() + format + String.format("%04d", codeNum);
             inOutStorageErpExportVo.setCode(code);
             inOutStorageErpExportVo.setCreateTime(DateUtil.format(inOutStorage.getInOutStorageTime(), "yyyy/MM/dd HH:mm:ss"));

+ 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;

+ 48 - 1
sd-business/src/main/java/com/sd/business/service/order/impl/OrderServiceImpl.java

@@ -303,12 +303,37 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderInfo> implem
                 orderDto.setClassify(OrderClassifyEnum.PURCHASE_ORDER.getKey());
             }
         }
+        // 委外订单修改金额
+        if (ObjectUtil.equals(orderDto.getType(), 2)) {
+            orderDto.setProductTotalAmount(BigDecimal.ZERO);
+            orderDto.setLssueFee(BigDecimal.ZERO);
+            orderDto.setDeliveryMaterialsFee(BigDecimal.ZERO);
+            orderDto.setManagementFee(BigDecimal.ZERO);
+            orderDto.setPackingLabor(orderDto.getPackingLabor().multiply(new BigDecimal(2)));
+            orderDto.setTotalAmount(orderDto.getProductTotalAmount()
+                    .add(orderDto.getCustomProcessingFee())
+                    .add(orderDto.getLssueFee())
+                    .add(orderDto.getDeliveryMaterialsFee())
+                    .add(orderDto.getPackingLabor())
+                    .add(orderDto.getPackagingMaterialCost())
+                    .add(orderDto.getManagementFee()));
+        }
         this.save(orderDto);
 
         // 新增订单产品包材配件
         List<OrderSku> tempOrderSkuList = orderSkuList.stream()
                 .peek(item -> item.setOrderId(orderDto.getId()))
                 .peek(item -> item.setStockPreparationStatus(StatusConstant.NO))
+                .peek(item -> {
+                    // 委外订单修改金额
+                    if (ObjectUtil.equals(orderDto.getType(), 2)) {
+                        item.setUnitPrice(BigDecimal.ZERO);
+                        item.setLssueFee(BigDecimal.ZERO);
+                        item.setDeliveryMaterialsFee(BigDecimal.ZERO);
+                        item.setManagementFee(BigDecimal.ZERO);
+                        item.setPackingLabor(item.getPackingLabor().multiply(new BigDecimal(2)));
+                    }
+                })
                 .map(item -> (OrderSku) item)
                 .collect(Collectors.toList());
         orderSkuService.saveBatch(tempOrderSkuList);
@@ -517,9 +542,21 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderInfo> implem
 
         // 更新订单
         dto.setStatus(OrderStatusEnum.STOCK_PREPARATION.getKey());
-        // 订单为委外订单时,订单分类为委外订单
+        // 订单为委外订单时,订单分类为委外订单,订单费用修改
         if (Objects.equals(dto.getType(), 2)) {
             dto.setClassify(OrderClassifyEnum.OUTSOURCE_ORDER.getKey());
+            dto.setProductTotalAmount(BigDecimal.ZERO);
+            dto.setLssueFee(BigDecimal.ZERO);
+            dto.setDeliveryMaterialsFee(BigDecimal.ZERO);
+            dto.setManagementFee(BigDecimal.ZERO);
+            dto.setPackingLabor(dto.getPackingLabor().multiply(new BigDecimal(2)));
+            dto.setTotalAmount(dto.getProductTotalAmount()
+                    .add(dto.getCustomProcessingFee())
+                    .add(dto.getLssueFee())
+                    .add(dto.getDeliveryMaterialsFee())
+                    .add(dto.getPackingLabor())
+                    .add(dto.getPackagingMaterialCost())
+                    .add(dto.getManagementFee()));
         } else if (Objects.equals(dto.getType(), 1)) {
             // 拥有采购角色的账号创建的自主订单为采购订单
             Long userId = dto.getCreateUser();
@@ -534,6 +571,16 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderInfo> implem
         List<OrderSku> tempOrderSkuList = orderSkuList.stream()
                 .peek(item -> item.setOrderId(dto.getId()))
                 .peek(item -> item.setStockPreparationStatus(StatusConstant.NO))
+                .peek(item -> {
+                    // 委外订单修改金额
+                    if (ObjectUtil.equals(dto.getType(), 2)) {
+                        item.setUnitPrice(BigDecimal.ZERO);
+                        item.setLssueFee(BigDecimal.ZERO);
+                        item.setDeliveryMaterialsFee(BigDecimal.ZERO);
+                        item.setManagementFee(BigDecimal.ZERO);
+                        item.setPackingLabor(item.getPackingLabor().multiply(new BigDecimal(2)));
+                    }
+                })
                 .map(item -> (OrderSku) item)
                 .collect(Collectors.toList());
         orderSkuService.editLinked(tempOrderSkuList, OrderSku::getOrderId, dto.getId());

+ 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规格

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

@@ -5,8 +5,11 @@ 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.SkuSpecImportDataDto;
 import com.sd.business.entity.sku.dto.SkuSpecSelectDto;
 import com.sd.business.entity.sku.po.SkuSpec;
 import com.sd.business.entity.sku.vo.SkuSpecVo;
@@ -78,4 +81,17 @@ public interface SkuSpecService extends BaseService<SkuSpec> {
      * @return
      */
     List<SkuSpecQuotationVo> getSkuSpecQuotationList(SkuSpecQuotationDto dto);
+
+    /**
+     * 获取sku所有材料明细列表
+     * @param dto
+     * @return
+     */
+    List<OutBomVo> getSkuSpecMaterialList(SkuSpecPackageBomDto dto);
+
+    /**
+     * sku规格导入
+     * @param list
+     */
+    void skuSpecImport(List<SkuSpecImportDataDto> list);
 }

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

@@ -11,17 +11,23 @@ import com.fjhx.tenant.service.dict.DictCommonDataService;
 import com.ruoyi.common.core.domain.BaseIdPo;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.sd.business.entity.artwork.po.ArtworkLibrary;
 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.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.SkuSpecImportDataDto;
 import com.sd.business.entity.sku.dto.SkuSpecSelectDto;
 import com.sd.business.entity.sku.po.Sku;
 import com.sd.business.entity.sku.po.SkuSpec;
@@ -29,6 +35,8 @@ import com.sd.business.entity.sku.po.SkuSpecLink;
 import com.sd.business.entity.sku.vo.SkuSpecVo;
 import com.sd.business.entity.warehouse.constant.WarehouseConstant;
 import com.sd.business.mapper.sku.SkuSpecMapper;
+import com.sd.business.service.artwork.ArtworkLibraryService;
+import com.sd.business.service.bom.BomSpecService;
 import com.sd.business.service.department.DepartmentService;
 import com.sd.business.service.inventory.InventoryService;
 import com.sd.business.service.price.PriceBillingStandardDetailService;
@@ -39,6 +47,7 @@ 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.*;
@@ -78,6 +87,12 @@ public class SkuSpecServiceImpl extends ServiceImpl<SkuSpecMapper, SkuSpec> impl
     @Autowired
     private DictCommonDataService dictCommonDataService;
 
+    @Autowired
+    private BomSpecService bomSpecService;
+
+    @Autowired
+    private ArtworkLibraryService artworkLibraryService;
+
     @Override
     public Page<SkuSpecVo> getPage(SkuSpecSelectDto dto) {
         IWrapper<SkuSpec> wrapper = getWrapper();
@@ -179,6 +194,113 @@ public class SkuSpecServiceImpl extends ServiceImpl<SkuSpecMapper, SkuSpec> impl
 
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void skuSpecImport(List<SkuSpecImportDataDto> list) {
+        if (ObjectUtil.isEmpty(list)) {
+            throw new ServiceException("sku规格信息不能为空");
+        }
+        List<String> skuSpecCodes = list.stream().map(SkuSpecImportDataDto::getSkuSpecCode).collect(Collectors.toList());
+        Map<String, SkuSpec> skuSpecMap = this.mapKEntity(SkuSpec::getCode, q -> q.in(SkuSpec::getCode, skuSpecCodes));
+        List<ArtworkLibrary> artworkLibraryList = artworkLibraryService.list();
+        List<BomSpec> bomSpecList = bomSpecService.list();
+        Map<String, BomSpec> bomSpecMap = bomSpecList.stream().collect(Collectors.toMap(BomSpec::getCode, item -> item, (v1, v2) -> v2));
+        List<SkuSpecLink> skuSpecLinkList = new ArrayList<>();
+
+        for (SkuSpecImportDataDto dto : list) {
+            SkuSpec skuSpec = skuSpecMap.get(dto.getSkuSpecCode());
+            if (skuSpec == null) {
+                continue;
+            }
+            // 保存图稿类型
+            String machinedPanelStr = dto.getMachinedPanelStr();
+            if (StrUtil.isNotBlank(machinedPanelStr)) {
+                machinedPanelStr = machinedPanelStr.replace(" ", "");
+                if (machinedPanelStr.startsWith("激光体位线") || machinedPanelStr.startsWith("激光图案")) {
+                    skuSpec.setMachinedPanel("10");
+                } else if (machinedPanelStr.startsWith("激光logo")) {
+                    skuSpec.setMachinedPanel("20");
+                }
+            }
+            // 保存图稿文件
+            String machinedPanelFileStr = dto.getMachinedPanelFileStr();
+            if (StrUtil.isNotBlank(machinedPanelFileStr)) {
+                String spec = dto.getSpec();
+                String sp = "";
+                if (StrUtil.isNotBlank(spec)) {
+                    sp = spec.split("\\*")[1].replace("cm", "").replace(" ", "");
+                }
+                for (ArtworkLibrary artworkLibrary : artworkLibraryList) {
+                    String[] ar = artworkLibrary.getArtworkName().split("_");
+                    String ar0 = ar[0];
+                    String arl = ar[ar.length - 1];
+
+                    if (machinedPanelFileStr.startsWith(ar0) && arl.equals(sp)) {
+                        skuSpec.setArtworkLibraryId(artworkLibrary.getId());
+                        break;
+                    } else if (machinedPanelFileStr.equals(artworkLibrary.getArtworkName())){
+                        skuSpec.setArtworkLibraryId(artworkLibrary.getId());
+                        break;
+                    }
+                }
+            }
+            // 保存裸垫
+            BomSpec bomSpec = bomSpecMap.get(dto.getBomSpecCode());
+            if (bomSpec != null) {
+                skuSpec.setBomSpecId(bomSpec.getId());
+                skuSpec.setLength(bomSpec.getLength());
+                skuSpec.setWidth(bomSpec.getWidth());
+                skuSpec.setHeight(bomSpec.getHeight());
+                skuSpec.setNetWeight(bomSpec.getNetWeight());
+            }
+            // 保存包材
+            List<String> bomSpecCodes = new ArrayList<>();
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_1());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_2());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_3());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_4());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_5());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_6());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_7());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_8());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_9());
+            bomSpecCodes.add(dto.getPackagingBomSpecCode_10());
+            bomSpecCodes.removeAll(Collections.singleton(null));
+            for (String bomSpecCode : bomSpecCodes) {
+                BomSpec packagingBomSpec = bomSpecMap.get(bomSpecCode);
+                if (packagingBomSpec != null) {
+                    SkuSpecLink skuSpecLink = new SkuSpecLink();
+                    skuSpecLink.setSkuId(skuSpec.getSkuId());
+                    skuSpecLink.setSkuSpecId(skuSpec.getId());
+                    skuSpecLink.setBomSpecId(packagingBomSpec.getId());
+                    skuSpecLink.setDepartmentId(0L);
+                    skuSpecLink.setType(1);
+                    skuSpecLink.setQuantity(BigDecimal.ONE);
+                    skuSpecLinkList.add(skuSpecLink);
+                }
+            }
+            // 保存快递包材
+            BomSpec deliveryMaterialsBomSpec = bomSpecMap.get(dto.getDeliveryMaterialsBomSpecCode());
+            if (deliveryMaterialsBomSpec != null) {
+                SkuSpecLink skuSpecLink = new SkuSpecLink();
+                skuSpecLink.setSkuId(skuSpec.getSkuId());
+                skuSpecLink.setSkuSpecId(skuSpec.getId());
+                skuSpecLink.setBomSpecId(deliveryMaterialsBomSpec.getId());
+                skuSpecLink.setDepartmentId(0L);
+                skuSpecLink.setType(2);
+                skuSpecLink.setQuantity(BigDecimal.ONE);
+                skuSpecLinkList.add(skuSpecLink);
+            }
+        }
+
+        this.updateBatchById(skuSpecMap.values());
+        if (!skuSpecLinkList.isEmpty()) {
+            List<Long> skuSpecIds = skuSpecLinkList.stream().map(SkuSpecLink::getSkuSpecId).distinct().collect(Collectors.toList());
+            skuSpecLinkService.remove(q -> q.in(SkuSpecLink::getSkuSpecId, skuSpecIds));
+            skuSpecLinkService.saveBatch(skuSpecLinkList);
+        }
+    }
+
     @Override
     public List<SkuSpecQuotationVo> getSkuSpecQuotationList(SkuSpecQuotationDto dto) {
         Assert.notNull(dto.getDepartmentId(), "事业部id不能为空");
@@ -321,4 +443,107 @@ 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());
+            if (bomSpecBo == null) {
+                throw new ServiceException("sku未绑定bom");
+            }
+            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>

+ 1 - 1
sd-business/src/main/resources/mapper/purchase/PurchasePendingStorageMapper.xml

@@ -12,7 +12,7 @@
             pps.update_user,
             pps.update_time,
             p.code purchaseCode,
-            ifnull(s.name, '福清市胜德塑胶制品有限公司') supplierName
+            ifnull(s.name, '胜德体育') supplierName
         from purchase_pending_storage pps
             left join purchase p on pps.purchase_id = p.id
             left join supplier s on p.supplier_id = s.id