Browse Source

订单同步表

24282 1 year ago
parent
commit
ce8cd2ce8d
31 changed files with 2095 additions and 267 deletions
  1. 0 47
      sd-business/src/main/java/com/sd/business/controller/order/OrderSkuBomController.java
  2. 0 47
      sd-business/src/main/java/com/sd/business/controller/order/OrderSkuController.java
  3. 67 0
      sd-business/src/main/java/com/sd/business/entity/bom/bo/BomSpecBo.java
  4. 10 0
      sd-business/src/main/java/com/sd/business/entity/department/constant/DepartmentConstant.java
  5. 44 0
      sd-business/src/main/java/com/sd/business/entity/in/emums/InDetailTypeEnum.java
  6. 36 0
      sd-business/src/main/java/com/sd/business/entity/in/emums/InOutTypeEnum.java
  7. 43 0
      sd-business/src/main/java/com/sd/business/entity/in/emums/OutDetailTypeEnum.java
  8. 17 0
      sd-business/src/main/java/com/sd/business/entity/inventory/enums/FinishedOperationTypeEnum.java
  9. 44 0
      sd-business/src/main/java/com/sd/business/entity/order/enums/OrderClassifyEnum.java
  10. 72 0
      sd-business/src/main/java/com/sd/business/entity/order/enums/OrderExceptionTypeEnum.java
  11. 49 0
      sd-business/src/main/java/com/sd/business/entity/order/enums/OrderStatusEnum.java
  12. 7 2
      sd-business/src/main/java/com/sd/business/entity/order/po/OrderInfo.java
  13. 28 0
      sd-business/src/main/java/com/sd/business/entity/warehouse/constant/WarehouseConstant.java
  14. 14 0
      sd-business/src/main/java/com/sd/business/service/bom/BomSpecService.java
  15. 54 0
      sd-business/src/main/java/com/sd/business/service/bom/impl/BomSpecServiceImpl.java
  16. 5 0
      sd-business/src/main/java/com/sd/business/service/department/DepartmentService.java
  17. 11 0
      sd-business/src/main/java/com/sd/business/service/department/impl/DepartmentServiceImpl.java
  18. 21 0
      sd-business/src/main/java/com/sd/business/service/inventory/InventoryService.java
  19. 71 0
      sd-business/src/main/java/com/sd/business/service/inventory/impl/InventoryServiceImpl.java
  20. 5 0
      sd-business/src/main/java/com/sd/business/service/order/OrderInfoService.java
  21. 0 29
      sd-business/src/main/java/com/sd/business/service/order/OrderSkuBomService.java
  22. 0 29
      sd-business/src/main/java/com/sd/business/service/order/OrderSkuService.java
  23. 218 1
      sd-business/src/main/java/com/sd/business/service/order/impl/OrderInfoServiceImpl.java
  24. 0 47
      sd-business/src/main/java/com/sd/business/service/order/impl/OrderSkuBomServiceImpl.java
  25. 0 47
      sd-business/src/main/java/com/sd/business/service/order/impl/OrderSkuServiceImpl.java
  26. 17 18
      sd-business/src/main/java/com/sd/business/util/CodeEnum.java
  27. 30 0
      sd-framework/src/main/java/com/sd/framework/util/TransactionUtil.java
  28. 320 0
      sd-wln/src/main/java/com/sd/wln/context/OrderContext.java
  29. 14 0
      sd-wln/src/main/java/com/sd/wln/scheduled/WlnSyncTask.java
  30. 44 0
      sd-wln/src/main/java/com/sd/wln/service/WlnOrderService.java
  31. 854 0
      sd-wln/src/main/java/com/sd/wln/service/impl/WlnOrderServiceImpl.java

+ 0 - 47
sd-business/src/main/java/com/sd/business/controller/order/OrderSkuBomController.java

@@ -1,14 +1,7 @@
 package com.sd.business.controller.order;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.domain.BaseSelectDto;
-import com.sd.business.entity.order.dto.OrderSkuBomDto;
-import com.sd.business.entity.order.dto.OrderSkuBomSelectDto;
-import com.sd.business.entity.order.vo.OrderSkuBomVo;
 import com.sd.business.service.order.OrderSkuBomService;
 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;
 
@@ -28,44 +21,4 @@ public class OrderSkuBomController {
     @Autowired
     private OrderSkuBomService orderSkuBomService;
 
-    /**
-     * 订单sku bom 关联分页
-     */
-    @PostMapping("/page")
-    public Page<OrderSkuBomVo> page(@RequestBody OrderSkuBomSelectDto dto) {
-        return orderSkuBomService.getPage(dto);
-    }
-
-    /**
-     * 订单sku bom 关联明细
-     */
-    @PostMapping("/detail")
-    public OrderSkuBomVo detail(@RequestBody BaseSelectDto dto) {
-        return orderSkuBomService.detail(dto.getId());
-    }
-
-    /**
-     * 订单sku bom 关联新增
-     */
-    @PostMapping("/add")
-    public void add(@RequestBody OrderSkuBomDto dto) {
-        orderSkuBomService.add(dto);
-    }
-
-    /**
-     * 订单sku bom 关联编辑
-     */
-    @PostMapping("/edit")
-    public void edit(@RequestBody OrderSkuBomDto dto) {
-        orderSkuBomService.edit(dto);
-    }
-
-    /**
-     * 订单sku bom 关联删除
-     */
-    @PostMapping("/delete")
-    public void delete(@RequestBody BaseSelectDto dto) {
-        orderSkuBomService.delete(dto.getId());
-    }
-
 }

+ 0 - 47
sd-business/src/main/java/com/sd/business/controller/order/OrderSkuController.java

@@ -1,14 +1,7 @@
 package com.sd.business.controller.order;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.domain.BaseSelectDto;
-import com.sd.business.entity.order.dto.OrderSkuDto;
-import com.sd.business.entity.order.dto.OrderSkuSelectDto;
-import com.sd.business.entity.order.vo.OrderSkuVo;
 import com.sd.business.service.order.OrderSkuService;
 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;
 
@@ -28,44 +21,4 @@ public class OrderSkuController {
     @Autowired
     private OrderSkuService orderSkuService;
 
-    /**
-     * 订单sku分页
-     */
-    @PostMapping("/page")
-    public Page<OrderSkuVo> page(@RequestBody OrderSkuSelectDto dto) {
-        return orderSkuService.getPage(dto);
-    }
-
-    /**
-     * 订单sku明细
-     */
-    @PostMapping("/detail")
-    public OrderSkuVo detail(@RequestBody BaseSelectDto dto) {
-        return orderSkuService.detail(dto.getId());
-    }
-
-    /**
-     * 订单sku新增
-     */
-    @PostMapping("/add")
-    public void add(@RequestBody OrderSkuDto dto) {
-        orderSkuService.add(dto);
-    }
-
-    /**
-     * 订单sku编辑
-     */
-    @PostMapping("/edit")
-    public void edit(@RequestBody OrderSkuDto dto) {
-        orderSkuService.edit(dto);
-    }
-
-    /**
-     * 订单sku删除
-     */
-    @PostMapping("/delete")
-    public void delete(@RequestBody BaseSelectDto dto) {
-        orderSkuService.delete(dto.getId());
-    }
-
 }

+ 67 - 0
sd-business/src/main/java/com/sd/business/entity/bom/bo/BomSpecBo.java

@@ -0,0 +1,67 @@
+package com.sd.business.entity.bom.bo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+@Getter
+@Setter
+public class BomSpecBo {
+
+    /**
+     * bom规格id
+     */
+    private Long bomSpecId;
+
+    /**
+     * bom规格编码
+     */
+    private String bomSpecCode;
+
+    /**
+     * bom规格名称
+     */
+    private String bomSpecName;
+
+    /**
+     * 成本价
+     */
+    private BigDecimal costPrice;
+
+    /**
+     * 对内销售价(含税)
+     */
+    private BigDecimal internalSellingPrice;
+
+    /**
+     * 对外销售价(含税)
+     */
+    private BigDecimal externalSellingPrice;
+
+    /**
+     * 种类 字典:bom_species
+     */
+    private String bomSpecies;
+
+    /**
+     * 单位
+     */
+    private String unit;
+
+    /**
+     * 分类id
+     */
+    private Long classifyId;
+
+    /**
+     * 分类父id
+     */
+    private Long classifyParentId;
+
+    /**
+     * 分类名称
+     */
+    private String classifyName;
+
+}

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

@@ -0,0 +1,10 @@
+package com.sd.business.entity.department.constant;
+
+public interface DepartmentConstant {
+
+    /**
+     * 胜德体育
+     */
+    Long SD_SPORTS = 0L;
+
+}

+ 44 - 0
sd-business/src/main/java/com/sd/business/entity/in/emums/InDetailTypeEnum.java

@@ -0,0 +1,44 @@
+package com.sd.business.entity.in.emums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum InDetailTypeEnum {
+
+    PURCHASE(1, "采购入库"),
+    PRODUCTION(2, "生产入库"),
+    RETURN_GOODS(3, "退货入库"),
+    GIVE_BACK(4, "归还入库"),
+    ALLOT(5, "调拨入库"),
+    OTHER(6, "其他入库"),
+    ABANDON(7, "废弃入库"),
+    CHECK(8, "盘点修正"),
+    GIFT(9, "赠品入库"),
+    ;
+
+    private static final Map<Integer, InDetailTypeEnum> map = new HashMap<>();
+
+    static {
+        for (InDetailTypeEnum inDetailTypeEnum : InDetailTypeEnum.values()) {
+            map.put(inDetailTypeEnum.getKey(), inDetailTypeEnum);
+        }
+    }
+
+    private final Integer key;
+    private final String value;
+
+    public static InDetailTypeEnum getInDetailType(Integer key) {
+        InDetailTypeEnum inDetailTypeEnum = map.get(key);
+        if (inDetailTypeEnum == null) {
+            throw new ServiceException("未知入库类型");
+        }
+        return inDetailTypeEnum;
+    }
+
+}

+ 36 - 0
sd-business/src/main/java/com/sd/business/entity/in/emums/InOutTypeEnum.java

@@ -0,0 +1,36 @@
+package com.sd.business.entity.in.emums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum InOutTypeEnum {
+
+    IN(1, "入库"),
+    OUT(0, "出库");
+
+    private static final Map<Integer, InOutTypeEnum> map = new HashMap<>();
+
+    static {
+        for (InOutTypeEnum inOutTypeEnum : InOutTypeEnum.values()) {
+            map.put(inOutTypeEnum.getKey(), inOutTypeEnum);
+        }
+    }
+
+    private final Integer key;
+    private final String value;
+
+    public static InOutTypeEnum getInOutType(Integer key) {
+        InOutTypeEnum inOutTypeEnum = map.get(key);
+        if (inOutTypeEnum == null) {
+            throw new ServiceException("未知出入库类型");
+        }
+        return inOutTypeEnum;
+    }
+
+}

+ 43 - 0
sd-business/src/main/java/com/sd/business/entity/in/emums/OutDetailTypeEnum.java

@@ -0,0 +1,43 @@
+package com.sd.business.entity.in.emums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum OutDetailTypeEnum {
+
+    PRODUCTION(1, "生产出库"),
+    SELL(2, "销售出库"),
+    ALLOT(3, "调拨出库"),
+    INVENTORY_LOSS(4, "盘亏出库"),
+    HELP_ONESELF(5, "自用出库"),
+    OTHER(6, "其他出库"),
+    CHECK(7, "盘点修正"),
+    PURCHASE(8, "采购退货"),
+    ;
+
+    private static final Map<Integer, OutDetailTypeEnum> map = new HashMap<>();
+
+    static {
+        for (OutDetailTypeEnum outDetailTypeEnum : OutDetailTypeEnum.values()) {
+            map.put(outDetailTypeEnum.getKey(), outDetailTypeEnum);
+        }
+    }
+
+    private final Integer key;
+    private final String value;
+
+    public static OutDetailTypeEnum getOutDetailType(Integer key) {
+        OutDetailTypeEnum outDetailTypeEnum = map.get(key);
+        if (outDetailTypeEnum == null) {
+            throw new ServiceException("未知出库类型");
+        }
+        return outDetailTypeEnum;
+    }
+
+}

+ 17 - 0
sd-business/src/main/java/com/sd/business/entity/inventory/enums/FinishedOperationTypeEnum.java

@@ -0,0 +1,17 @@
+package com.sd.business.entity.inventory.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum FinishedOperationTypeEnum {
+
+    PRODUCTION_WAREHOUSING(1, "生产完成入库"),
+    SALE_OUT_OF_WAREHOUSE(2, "销售出库"),
+    ;
+
+    private final Integer type;
+    private final String explain;
+
+}

+ 44 - 0
sd-business/src/main/java/com/sd/business/entity/order/enums/OrderClassifyEnum.java

@@ -0,0 +1,44 @@
+package com.sd.business.entity.order.enums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 订单类型
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderClassifyEnum {
+    WLN_ORDER(1, "万里牛订单"),
+    PURCHASE_ORDER(2, "采购订单"),
+    OUTSOURCE_ORDER(3, "委外订单"),
+    AFTER_SALE_ORDER(4, "售后订单"),
+    NO_REASON_ORDER(5, "无理由订单");
+
+    private static final Map<Integer, OrderClassifyEnum> map = new HashMap<>();
+
+    static {
+        for (OrderClassifyEnum orderClassifyEnum : values()) {
+            map.put(orderClassifyEnum.getKey(), orderClassifyEnum);
+        }
+    }
+
+    private final Integer key;
+    private final String value;
+
+    /**
+     * 通过key获取名称
+     */
+    public static OrderClassifyEnum getEnum(Integer key) {
+        OrderClassifyEnum orderClassifyEnum = map.get(key);
+        if (orderClassifyEnum == null) {
+            throw new ServiceException("未知订单类型:" + key);
+        }
+        return orderClassifyEnum;
+    }
+
+}

+ 72 - 0
sd-business/src/main/java/com/sd/business/entity/order/enums/OrderExceptionTypeEnum.java

@@ -0,0 +1,72 @@
+package com.sd.business.entity.order.enums;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Getter
+@AllArgsConstructor
+public enum OrderExceptionTypeEnum {
+
+    NORMAL(0, "正常订单"),
+    ORDER_CLOSURE(1, "万里牛状态异常:订单关闭"),
+    ORDER_ABORT(2, "万里牛状态异常:订单异常结束"),
+    ORDER_EXCEPTION_HANDLING(3, "万里牛状态异常:订单异常处理"),
+    UNKNOWN_WAREHOUSE(4, "无法通过仓库编码找到事业部"),
+    UNKNOWN_SKU_SPEC(5, "订单存在未知sku规格"),
+    UNKNOWN_BOM_SPEC(6, "订单sku规格未绑定bom规格"),
+    SKU_UPDATE(7, "订单商品被更改"),
+    NO_DESIGN_DOCUMENT(8, "未绑定图稿"),
+    UNDERSTOCK(9, "主材库存不足"),
+    ORDER_CHECK(10, "万里牛状态异常:订单打回审核"),
+    ;
+
+    private static final Map<Integer, OrderExceptionTypeEnum> map = new HashMap<>();
+
+    static {
+        for (OrderExceptionTypeEnum orderExceptionTypeEnum : values()) {
+            map.put(orderExceptionTypeEnum.getKey(), orderExceptionTypeEnum);
+        }
+    }
+
+    private final Integer key;
+    private final String value;
+
+    /**
+     * 通过key获取名称
+     */
+    public static OrderExceptionTypeEnum getEnum(Integer key) {
+        OrderExceptionTypeEnum orderExceptionTypeEnum = map.get(key);
+        if (orderExceptionTypeEnum == null) {
+            throw new ServiceException("未知订单异常类型:" + key);
+        }
+        return orderExceptionTypeEnum;
+    }
+
+    public static List<Map<String, Object>> getMapList() {
+        return Arrays.stream(values())
+                .filter(item -> ObjectUtil.notEqual(NORMAL, item))
+                .map(item -> {
+                    Map<String, Object> tempMap = new HashMap<>();
+                    tempMap.put("key", item.getKey());
+                    tempMap.put("value", item.getValue());
+                    return tempMap;
+                })
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 通过key获取名称
+     */
+    public static String getEnumValue(Integer key) {
+        return getEnum(key).getValue();
+    }
+
+}

+ 49 - 0
sd-business/src/main/java/com/sd/business/entity/order/enums/OrderStatusEnum.java

@@ -0,0 +1,49 @@
+package com.sd.business.entity.order.enums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 订单状态
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderStatusEnum {
+    DRAFT(0, "草稿"),
+    UNDER_REVIEW(10, "订单待确认"),
+    STOCK_PREPARATION(20, "备料中"),
+    IN_PRODUCTION(30, "生产中"),
+    COMPLETION_PRODUCTION(40, "生产完成"),
+    HAVE_BEEN_SHIPPED(50, "已发货"),
+    SUSPEND(60, "挂起"),
+    EXCHANGE(90, "已售后"),
+
+    ;
+
+    private static final Map<Integer, OrderStatusEnum> map = new HashMap<>();
+
+    static {
+        for (OrderStatusEnum orderStatusEnum : values()) {
+            map.put(orderStatusEnum.getKey(), orderStatusEnum);
+        }
+    }
+
+    private final Integer key;
+    private final String value;
+
+    /**
+     * 通过key获取名称
+     */
+    public static OrderStatusEnum getEnum(Integer key) {
+        OrderStatusEnum orderStatusEnum = map.get(key);
+        if (orderStatusEnum == null) {
+            throw new ServiceException("未知订单状态:" + key);
+        }
+        return orderStatusEnum;
+    }
+
+}

+ 7 - 2
sd-business/src/main/java/com/sd/business/entity/order/po/OrderInfo.java

@@ -34,7 +34,7 @@ public class OrderInfo extends BasePo {
     /**
      * 订单分类 1万里牛订单,2采购订单,3委外订单,4售后订单,5无理由订单
      */
-    private Boolean classify;
+    private Integer classify;
 
     /**
      * 事业部id
@@ -264,11 +264,16 @@ public class OrderInfo extends BasePo {
     /**
      * 备料类型 0半成品,1成品
      */
-    private Boolean stockType;
+    private Integer stockType;
 
     /**
      * 备注
      */
     private String remark;
 
+    /**
+     * 订单删除标记
+     */
+    private Integer delFlag;
+
 }

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

@@ -0,0 +1,28 @@
+package com.sd.business.entity.warehouse.constant;
+
+/**
+ * 仓库id
+ */
+public interface WarehouseConstant {
+
+    /**
+     * 半成品仓
+     */
+    Long SEMI_FINISHED_PRODUCT = 1684037244354052098L;
+
+    /**
+     * 包材仓
+     */
+    Long PACKAGING_MATERIAL = 1684037201379213314L;
+
+    /**
+     * 采购次品仓(供退仓)
+     */
+    Long PURCHASE_DEFECTIVE = 1684037092708990977L;
+
+    /**
+     * 生产次品仓
+     */
+    Long PRODUCTION_DEFECTIVE = 1684037357424099330L;
+
+}

+ 14 - 0
sd-business/src/main/java/com/sd/business/service/bom/BomSpecService.java

@@ -1,8 +1,12 @@
 package com.sd.business.service.bom;
 
 import com.ruoyi.common.core.service.BaseService;
+import com.sd.business.entity.bom.bo.BomSpecBo;
 import com.sd.business.entity.bom.po.BomSpec;
 
+import java.util.Collection;
+import java.util.Map;
+
 
 /**
  * <p>
@@ -14,4 +18,14 @@ import com.sd.business.entity.bom.po.BomSpec;
  */
 public interface BomSpecService extends BaseService<BomSpec> {
 
+    /**
+     * 获取sku规格明细map
+     */
+    Map<Long, BomSpecBo> getBomSpecBo(Collection<Long> bomSpecIdList);
+
+    /**
+     * 获取sku规格明细
+     */
+    BomSpecBo getBomSpecBo(Long bomSpecId);
+
 }

+ 54 - 0
sd-business/src/main/java/com/sd/business/service/bom/impl/BomSpecServiceImpl.java

@@ -1,11 +1,18 @@
 package com.sd.business.service.bom.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sd.business.entity.bom.bo.BomSpecBo;
+import com.sd.business.entity.bom.po.Bom;
+import com.sd.business.entity.bom.po.BomClassify;
 import com.sd.business.entity.bom.po.BomSpec;
 import com.sd.business.mapper.bom.BomSpecMapper;
 import com.sd.business.service.bom.BomSpecService;
+import com.sd.framework.util.sql.Sql;
 import org.springframework.stereotype.Service;
 
+import java.util.Collection;
+import java.util.Map;
+
 
 /**
  * <p>
@@ -18,4 +25,51 @@ import org.springframework.stereotype.Service;
 @Service
 public class BomSpecServiceImpl extends ServiceImpl<BomSpecMapper, BomSpec> implements BomSpecService {
 
+    @Override
+    public Map<Long, BomSpecBo> getBomSpecBo(Collection<Long> bomSpecIdList) {
+
+        return Sql.create(BomSpecBo.class)
+                .selectAs(BomSpec::getId, BomSpecBo::getBomSpecId)
+                .selectAs(BomSpec::getCode, BomSpecBo::getBomSpecCode)
+                .selectAs(BomSpec::getName, BomSpecBo::getBomSpecName)
+                .selectAs(BomSpec::getCostPrice, BomSpecBo::getCostPrice)
+                .selectAs(BomSpec::getInternalSellingPrice, BomSpecBo::getInternalSellingPrice)
+                .selectAs(BomSpec::getExternalSellingPrice, BomSpecBo::getExternalSellingPrice)
+                .selectAs(Bom::getSpecies, BomSpecBo::getBomSpecies)
+                .selectAs(Bom::getUnit, BomSpecBo::getUnit)
+                .selectAs(BomClassify::getId, BomSpecBo::getClassifyId)
+                .selectAs(BomClassify::getParentId, BomSpecBo::getClassifyParentId)
+                .selectAs(BomClassify::getName, BomSpecBo::getClassifyName)
+
+                .from(BomSpec.class)
+                .leftJoin(Bom.class, Bom::getId, BomSpec::getBomId)
+                .leftJoin(BomClassify.class, BomClassify::getId, Bom::getBomClassifyId)
+
+                .in(BomSpec::getId, bomSpecIdList)
+                .mapKEntity(BomSpecBo::getBomSpecId);
+    }
+
+    @Override
+    public BomSpecBo getBomSpecBo(Long bomSpecId) {
+
+        return Sql.create(BomSpecBo.class)
+                .selectAs(BomSpec::getId, BomSpecBo::getBomSpecId)
+                .selectAs(BomSpec::getCode, BomSpecBo::getBomSpecCode)
+                .selectAs(BomSpec::getName, BomSpecBo::getBomSpecName)
+                .selectAs(BomSpec::getCostPrice, BomSpecBo::getCostPrice)
+                .selectAs(BomSpec::getInternalSellingPrice, BomSpecBo::getInternalSellingPrice)
+                .selectAs(BomSpec::getExternalSellingPrice, BomSpecBo::getExternalSellingPrice)
+                .selectAs(Bom::getSpecies, BomSpecBo::getBomSpecies)
+                .selectAs(Bom::getUnit, BomSpecBo::getUnit)
+                .selectAs(BomClassify::getId, BomSpecBo::getClassifyId)
+                .selectAs(BomClassify::getParentId, BomSpecBo::getClassifyParentId)
+                .selectAs(BomClassify::getName, BomSpecBo::getClassifyName)
+
+                .from(BomSpec.class)
+                .leftJoin(Bom.class, Bom::getId, BomSpec::getBomId)
+                .leftJoin(BomClassify.class, BomClassify::getId, Bom::getBomClassifyId)
+
+                .eq(BomSpec::getId, bomSpecId)
+                .one();
+    }
 }

+ 5 - 0
sd-business/src/main/java/com/sd/business/service/department/DepartmentService.java

@@ -43,4 +43,9 @@ public interface DepartmentService extends BaseService<Department> {
      */
     void delete(Long id);
 
+    /**
+     * 根据仓库编码获取事业部
+     */
+    Department getDepartmentByWarehouseCode(String warehouseCode);
+
 }

+ 11 - 0
sd-business/src/main/java/com/sd/business/service/department/impl/DepartmentServiceImpl.java

@@ -159,4 +159,15 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
         removeById(id);
     }
 
+    @Override
+    public Department getDepartmentByWarehouseCode(String warehouseCode) {
+        Sql.create(Department.class)
+                .selectAll(Department.class)
+                .from(Department.class)
+                .findInSet(Department::getWlnWarehouseCode, warehouseCode)
+                .last("limit 1")
+                .one();
+        return null;
+    }
+
 }

+ 21 - 0
sd-business/src/main/java/com/sd/business/service/inventory/InventoryService.java

@@ -10,6 +10,7 @@ import com.sd.business.entity.inventory.po.Inventory;
 import com.sd.business.entity.inventory.vo.InventoryVo;
 import com.sd.business.entity.inventory.vo.QuantityByDepartmentVo;
 import com.sd.business.entity.inventory.vo.QuantityByWarehouseVo;
+import com.sd.business.entity.order.po.OrderSku;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -51,4 +52,24 @@ public interface InventoryService extends BaseService<Inventory> {
      */
     List<QuantityByDepartmentVo> getQuantityByDepartment(QuantityByDepartmentDto dto);
 
+    /**
+     * 锁定库存
+     */
+    boolean lockStorage(Map<Long, BigDecimal> map, Long warehouseId);
+
+    /**
+     * 锁定库存
+     */
+    boolean lockStorage(List<OrderSku> orderSkuList);
+
+    /**
+     * 解锁库存
+     */
+    void unlockStorage(Map<Long, BigDecimal> map, Long warehouseId);
+
+    /**
+     * 解锁库存
+     */
+    void unlockStorage(List<OrderSku> orderSkuList);
+
 }

+ 71 - 0
sd-business/src/main/java/com/sd/business/service/inventory/impl/InventoryServiceImpl.java

@@ -1,10 +1,12 @@
 package com.sd.business.service.inventory.impl;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 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.dto.InventorySelectDto;
 import com.sd.business.entity.inventory.dto.QuantityByDepartmentDto;
@@ -14,6 +16,8 @@ import com.sd.business.entity.inventory.po.Inventory;
 import com.sd.business.entity.inventory.vo.InventoryVo;
 import com.sd.business.entity.inventory.vo.QuantityByDepartmentVo;
 import com.sd.business.entity.inventory.vo.QuantityByWarehouseVo;
+import com.sd.business.entity.order.po.OrderSku;
+import com.sd.business.entity.warehouse.constant.WarehouseConstant;
 import com.sd.business.entity.warehouse.po.Warehouse;
 import com.sd.business.mapper.inventory.InventoryMapper;
 import com.sd.business.service.inventory.InventoryService;
@@ -27,6 +31,7 @@ import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 
 /**
@@ -129,4 +134,70 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
                 .list();
     }
 
+    @Override
+    public boolean lockStorage(Map<Long, BigDecimal> map, Long warehouseId) {
+        if (ObjectUtil.isEmpty(map)) {
+            return true;
+        }
+        synchronized (this) {
+            List<Inventory> list = list(q -> q
+                    .in(Inventory::getBomSpecId, map.keySet())
+                    .eq(Inventory::getWarehouseId, warehouseId)
+                    .eq(Inventory::getDepartmentId, DepartmentConstant.SD_SPORTS)
+            );
+            if (map.size() != list.size()) {
+                return false;
+            }
+            for (Inventory inventory : list) {
+                BigDecimal lockQuantity = map.get(inventory.getBomSpecId());
+                if (inventory.getQuantity().compareTo(lockQuantity) >= 0) {
+                    inventory.setQuantity(inventory.getQuantity().subtract(lockQuantity));
+                    inventory.setLockQuantity(inventory.getLockQuantity().add(lockQuantity));
+                } else {
+                    return false;
+                }
+            }
+            this.updateBatchById(list);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean lockStorage(List<OrderSku> orderSkuList) {
+        Map<Long, BigDecimal> map = orderSkuList.stream()
+                .collect(Collectors.toMap(OrderSku::getBomSpecId, OrderSku::getQuantity, BigDecimal::add));
+        return lockStorage(map, WarehouseConstant.SEMI_FINISHED_PRODUCT);
+    }
+
+    @Override
+    public void unlockStorage(Map<Long, BigDecimal> map, Long warehouseId) {
+        if (ObjectUtil.isEmpty(map)) {
+            return;
+        }
+        synchronized (this) {
+            List<Inventory> list = list(q -> q
+                    .in(Inventory::getBomSpecId, map.keySet())
+                    .eq(Inventory::getWarehouseId, warehouseId)
+                    .eq(Inventory::getDepartmentId, DepartmentConstant.SD_SPORTS)
+            );
+            for (Inventory inventory : list) {
+                BigDecimal lockQuantity = map.get(inventory.getBomSpecId());
+                inventory.setQuantity(inventory.getQuantity().add(lockQuantity));
+                inventory.setLockQuantity(inventory.getLockQuantity().subtract(lockQuantity));
+            }
+            updateBatchById(list);
+        }
+    }
+
+    @Override
+    public void unlockStorage(List<OrderSku> orderSkuList) {
+        if (orderSkuList.isEmpty()) {
+            return;
+        }
+        Map<Long, BigDecimal> map = orderSkuList.stream()
+                .collect(Collectors.toMap(OrderSku::getBomSpecId, OrderSku::getQuantity, BigDecimal::add));
+        unlockStorage(map, WarehouseConstant.SEMI_FINISHED_PRODUCT);
+    }
+
+
 }

+ 5 - 0
sd-business/src/main/java/com/sd/business/service/order/OrderInfoService.java

@@ -43,4 +43,9 @@ public interface OrderInfoService extends BaseService<OrderInfo> {
      */
     void delete(Long id);
 
+    /**
+     * 删除订单并回滚库存
+     */
+    void deleteAndStore(Long id);
+
 }

+ 0 - 29
sd-business/src/main/java/com/sd/business/service/order/OrderSkuBomService.java

@@ -1,11 +1,7 @@
 package com.sd.business.service.order;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.service.BaseService;
-import com.sd.business.entity.order.dto.OrderSkuBomDto;
-import com.sd.business.entity.order.dto.OrderSkuBomSelectDto;
 import com.sd.business.entity.order.po.OrderSkuBom;
-import com.sd.business.entity.order.vo.OrderSkuBomVo;
 
 
 /**
@@ -18,29 +14,4 @@ import com.sd.business.entity.order.vo.OrderSkuBomVo;
  */
 public interface OrderSkuBomService extends BaseService<OrderSkuBom> {
 
-    /**
-     * 订单sku bom 关联分页
-     */
-    Page<OrderSkuBomVo> getPage(OrderSkuBomSelectDto dto);
-
-    /**
-     * 订单sku bom 关联明细
-     */
-    OrderSkuBomVo detail(Long id);
-
-    /**
-     * 订单sku bom 关联新增
-     */
-    void add(OrderSkuBomDto dto);
-
-    /**
-     * 订单sku bom 关联编辑
-     */
-    void edit(OrderSkuBomDto dto);
-
-    /**
-     * 订单sku bom 关联删除
-     */
-    void delete(Long id);
-
 }

+ 0 - 29
sd-business/src/main/java/com/sd/business/service/order/OrderSkuService.java

@@ -1,11 +1,7 @@
 package com.sd.business.service.order;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.service.BaseService;
-import com.sd.business.entity.order.dto.OrderSkuDto;
-import com.sd.business.entity.order.dto.OrderSkuSelectDto;
 import com.sd.business.entity.order.po.OrderSku;
-import com.sd.business.entity.order.vo.OrderSkuVo;
 
 
 /**
@@ -18,29 +14,4 @@ import com.sd.business.entity.order.vo.OrderSkuVo;
  */
 public interface OrderSkuService extends BaseService<OrderSku> {
 
-    /**
-     * 订单sku分页
-     */
-    Page<OrderSkuVo> getPage(OrderSkuSelectDto dto);
-
-    /**
-     * 订单sku明细
-     */
-    OrderSkuVo detail(Long id);
-
-    /**
-     * 订单sku新增
-     */
-    void add(OrderSkuDto dto);
-
-    /**
-     * 订单sku编辑
-     */
-    void edit(OrderSkuDto dto);
-
-    /**
-     * 订单sku删除
-     */
-    void delete(Long id);
-
 }

+ 218 - 1
sd-business/src/main/java/com/sd/business/service/order/impl/OrderInfoServiceImpl.java

@@ -1,17 +1,54 @@
 package com.sd.business.service.order.impl;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+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.fjhx.file.utils.ObsFileUtil;
+import com.ruoyi.common.constant.StatusConstant;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.sd.business.entity.bom.bo.BomSpecBo;
+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.po.InOutStorageBom;
 import com.sd.business.entity.order.dto.OrderInfoDto;
 import com.sd.business.entity.order.dto.OrderInfoSelectDto;
+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.OrderSkuBom;
+import com.sd.business.entity.order.po.OrderSkuProductionCost;
 import com.sd.business.entity.order.vo.OrderInfoVo;
+import com.sd.business.entity.production.po.ProductionWorkOrder;
+import com.sd.business.entity.warehouse.constant.WarehouseConstant;
 import com.sd.business.mapper.order.OrderInfoMapper;
+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.OrderInfoService;
+import com.sd.business.service.order.OrderPackageBomService;
+import com.sd.business.service.order.OrderSkuBomService;
+import com.sd.business.service.order.OrderSkuProductionCostService;
+import com.sd.business.service.order.OrderSkuService;
+import com.sd.business.service.production.ProductionWorkOrderService;
 import com.sd.framework.util.Assert;
 import com.sd.framework.util.sql.Sql;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
 
 /**
  * <p>
@@ -24,6 +61,33 @@ import org.springframework.stereotype.Service;
 @Service
 public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
 
+    @Autowired
+    private BomSpecService bomSpecService;
+
+    @Autowired
+    private OrderSkuService orderSkuService;
+
+    @Autowired
+    private OrderSkuBomService orderSkuBomService;
+
+    @Autowired
+    private OrderPackageBomService orderPackageBomService;
+
+    @Autowired
+    private OrderSkuProductionCostService orderSkuProductionCostService;
+
+    @Autowired
+    private ProductionWorkOrderService productionWorkOrderService;
+
+    @Autowired
+    private InventoryService inventoryService;
+
+    @Autowired
+    private InOutStorageService inOutStorageService;
+
+    @Autowired
+    private InventoryFinishedService inventoryFinishedService;
+
     @Override
     public Page<OrderInfoVo> getPage(OrderInfoSelectDto dto) {
 
@@ -62,7 +126,160 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
 
     @Override
     public void delete(Long id) {
-        removeById(id);
+        this.removeById(id);
+        orderSkuService.remove(q -> q.eq(OrderSku::getOrderId, id));
+        orderSkuBomService.remove(q -> q.eq(OrderSkuBom::getOrderId, id));
+        orderPackageBomService.remove(q -> q.eq(OrderPackageBom::getOrderId, id));
+        orderSkuProductionCostService.remove(q -> q.eq(OrderSkuProductionCost::getOrderId, id));
+        productionWorkOrderService.remove(q -> q.eq(ProductionWorkOrder::getOrderId, id));
+
+        ObsFileUtil.removeFile(id);
+    }
+
+    @DSTransactional
+    @Override
+    public synchronized void deleteAndStore(Long id) {
+        OrderInfo orderInfo = getById(id);
+
+        if (orderInfo == null) {
+            throw new ServiceException("未找到订单");
+        }
+
+        // 解锁库存
+        unLockStorage(orderInfo);
+
+        if (orderInfo.getStatus() <= OrderStatusEnum.STOCK_PREPARATION.getKey()) {
+            delete(id);
+            return;
+        }
+
+        // 获取订单商品主材和包材
+        List<OrderSku> orderSkuList = orderSkuService.list(q -> q.eq(OrderSku::getOrderId, id));
+        List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.eq(OrderSkuBom::getOrderId, id));
+
+        Map<Long, OrderSku> orderSkuMap = orderSkuList.stream().collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
+
+        // 合并主材和包材
+        List<InOutStorageBom> inOutStorageBomList = orderSkuList.stream().map(item -> {
+            InOutStorageBom inOutStorageBom = new InOutStorageBom();
+            inOutStorageBom.setBomSpecId(item.getBomSpecId());
+            inOutStorageBom.setQuantity(item.getQuantity());
+            return inOutStorageBom;
+        }).collect(Collectors.toList());
+
+        for (OrderSkuBom orderSkuBom : orderSkuBomList) {
+            OrderSku orderSku = orderSkuMap.get(orderSkuBom.getOrderSkuId());
+            InOutStorageBom inOutStorageBom = new InOutStorageBom();
+            inOutStorageBom.setBomSpecId(orderSkuBom.getBomSpecId());
+            inOutStorageBom.setQuantity(orderSkuBom.getQuantity().multiply(orderSku.getQuantity()));
+            inOutStorageBomList.add(inOutStorageBom);
+        }
+
+        // 合并数量
+        Map<Long, InOutStorageBom> map = inOutStorageBomList.stream().collect(Collectors.toMap(
+                InOutStorageBom::getBomSpecId,
+                Function.identity(),
+                (v1, v2) -> {
+                    v1.setQuantity(v1.getQuantity().add(v2.getQuantity()));
+                    return v1;
+                }
+        ));
+        inOutStorageBomList = new ArrayList<>(map.values());
+
+        // 区分半成品仓和包材仓库
+        Map<Long, BomSpecBo> bomSpecBoMap = bomSpecService.getBomSpecBo(map.keySet());
+
+        // 主材从半成品仓入库
+        semiFinishedProductOutStorage(inOutStorageBomList, bomSpecBoMap, orderInfo);
+
+        // 包材从包材仓出库
+        packagingMaterialOutStorage(inOutStorageBomList, bomSpecBoMap, orderInfo);
+
+        // 删除订单回滚成品仓库存
+        inventoryFinishedService.removeOrder(id);
+
+        delete(id);
+    }
+
+    /**
+     * 解锁库存
+     */
+    private void unLockStorage(OrderInfo orderInfo) {
+
+        // 未锁定库存跳过
+        if (ObjectUtil.notEqual(orderInfo.getLockStorage(), StatusConstant.YES)) {
+            return;
+        }
+
+        // 修改订单库存锁定状态为否
+        orderInfo.setLockStorage(StatusConstant.NO);
+        update(q -> q.eq(BaseIdPo::getId, orderInfo.getId()).set(OrderInfo::getLockStorage, StatusConstant.NO));
+
+        // 订单sku列表
+        List<OrderSku> orderSkuList = orderSkuService.list(q -> q.eq(OrderSku::getOrderId, orderInfo.getId()));
+
+        // 过滤订单
+        List<Long> bomSpecIdList = orderSkuList.stream().map(OrderSku::getBomSpecId).collect(Collectors.toList());
+        Map<Long, BomSpecBo> bomSpecBoMap = bomSpecService.getBomSpecBo(bomSpecIdList);
+        orderSkuList = orderSkuList.stream()
+                .filter(item -> bomSpecBoMap.get(item.getBomSpecId()).getClassifyParentId().equals(1L))
+                .collect(Collectors.toList());
+
+        inventoryService.unlockStorage(orderSkuList);
+    }
+
+    /**
+     * 主材出库
+     */
+    private void semiFinishedProductOutStorage(List<InOutStorageBom> inOutStorageBomList, Map<Long, BomSpecBo> bomSpecBoMap, OrderInfo orderInfo) {
+        List<InOutStorageBom> semiFinishedProductInOutStorageBomList = inOutStorageBomList
+                .stream()
+                .filter(item -> {
+                    BomSpecBo tempBomSpecBo = bomSpecBoMap.get(item.getBomSpecId());
+                    if (tempBomSpecBo == null) {
+                        return false;
+                    }
+                    return ObjectUtil.equal(tempBomSpecBo.getClassifyParentId(), 1L);
+                })
+                .collect(Collectors.toList());
+        InOutStorageDto semiFinishedProductInOutStorageDto = new InOutStorageDto();
+        semiFinishedProductInOutStorageDto.setType(InOutTypeEnum.IN.getKey());
+        semiFinishedProductInOutStorageDto.setDetailType(InDetailTypeEnum.RETURN_GOODS.getKey());
+        semiFinishedProductInOutStorageDto.setWarehouseId(WarehouseConstant.SEMI_FINISHED_PRODUCT);
+        semiFinishedProductInOutStorageDto.setDepartmentId(orderInfo.getOutDepartmentId());
+        semiFinishedProductInOutStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
+        semiFinishedProductInOutStorageDto.setRemark("删除订单:" + orderInfo.getCode()
+                + (StrUtil.isBlank(orderInfo.getWlnCode()) ? StringPool.EMPTY : "(" + orderInfo.getWlnCode() + ")")
+                + " 主材退料入库");
+        semiFinishedProductInOutStorageDto.setInOutStorageBomList(semiFinishedProductInOutStorageBomList);
+        inOutStorageService.add(semiFinishedProductInOutStorageDto);
+    }
+
+    /**
+     * 包材出库
+     */
+    private void packagingMaterialOutStorage(List<InOutStorageBom> inOutStorageBomList, Map<Long, BomSpecBo> bomSpecBoMap, OrderInfo orderInfo) {
+        List<InOutStorageBom> packagingMaterialInOutStorageBomList = inOutStorageBomList
+                .stream()
+                .filter(item -> {
+                    BomSpecBo tempBomSpecBo = bomSpecBoMap.get(item.getBomSpecId());
+                    if (tempBomSpecBo == null) {
+                        return true;
+                    }
+                    return ObjectUtil.notEqual(tempBomSpecBo.getClassifyParentId(), 1L);
+                })
+                .collect(Collectors.toList());
+        InOutStorageDto packagingMaterialInOutStorageDto = new InOutStorageDto();
+        packagingMaterialInOutStorageDto.setType(InOutTypeEnum.IN.getKey());
+        packagingMaterialInOutStorageDto.setDetailType(InDetailTypeEnum.RETURN_GOODS.getKey());
+        packagingMaterialInOutStorageDto.setWarehouseId(WarehouseConstant.PACKAGING_MATERIAL);
+        packagingMaterialInOutStorageDto.setDepartmentId(orderInfo.getOutDepartmentId());
+        packagingMaterialInOutStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
+        packagingMaterialInOutStorageDto.setRemark("删除订单:" + orderInfo.getCode()
+                + (StrUtil.isBlank(orderInfo.getWlnCode()) ? StringPool.EMPTY : "(" + orderInfo.getWlnCode() + ")")
+                + " 包材退料入库");
+        packagingMaterialInOutStorageDto.setInOutStorageBomList(packagingMaterialInOutStorageBomList);
+        inOutStorageService.add(packagingMaterialInOutStorageDto);
     }
 
 }

+ 0 - 47
sd-business/src/main/java/com/sd/business/service/order/impl/OrderSkuBomServiceImpl.java

@@ -1,15 +1,9 @@
 package com.sd.business.service.order.impl;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.sd.business.entity.order.dto.OrderSkuBomDto;
-import com.sd.business.entity.order.dto.OrderSkuBomSelectDto;
 import com.sd.business.entity.order.po.OrderSkuBom;
-import com.sd.business.entity.order.vo.OrderSkuBomVo;
 import com.sd.business.mapper.order.OrderSkuBomMapper;
 import com.sd.business.service.order.OrderSkuBomService;
-import com.sd.framework.util.Assert;
-import com.sd.framework.util.sql.Sql;
 import org.springframework.stereotype.Service;
 
 
@@ -24,45 +18,4 @@ import org.springframework.stereotype.Service;
 @Service
 public class OrderSkuBomServiceImpl extends ServiceImpl<OrderSkuBomMapper, OrderSkuBom> implements OrderSkuBomService {
 
-    @Override
-    public Page<OrderSkuBomVo> getPage(OrderSkuBomSelectDto dto) {
-
-        Page<OrderSkuBomVo> page = Sql.create(OrderSkuBomVo.class)
-                .selectAll(OrderSkuBom.class)
-                .from(OrderSkuBom.class)
-                .orderByDesc(OrderSkuBom::getId)
-                .page(dto);
-
-        return page;
-    }
-
-    @Override
-    public OrderSkuBomVo detail(Long id) {
-
-        OrderSkuBomVo vo = Sql.create(OrderSkuBomVo.class)
-                .selectAll(OrderSkuBom.class)
-                .from(OrderSkuBom.class)
-                .eq(OrderSkuBom::getId, id)
-                .one();
-
-        Assert.notNull(vo, "未知数据");
-
-        return vo;
-    }
-
-    @Override
-    public void add(OrderSkuBomDto dto) {
-        save(dto);
-    }
-
-    @Override
-    public void edit(OrderSkuBomDto dto) {
-        updateById(dto);
-    }
-
-    @Override
-    public void delete(Long id) {
-        removeById(id);
-    }
-
 }

+ 0 - 47
sd-business/src/main/java/com/sd/business/service/order/impl/OrderSkuServiceImpl.java

@@ -1,15 +1,9 @@
 package com.sd.business.service.order.impl;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.sd.business.entity.order.dto.OrderSkuDto;
-import com.sd.business.entity.order.dto.OrderSkuSelectDto;
 import com.sd.business.entity.order.po.OrderSku;
-import com.sd.business.entity.order.vo.OrderSkuVo;
 import com.sd.business.mapper.order.OrderSkuMapper;
 import com.sd.business.service.order.OrderSkuService;
-import com.sd.framework.util.Assert;
-import com.sd.framework.util.sql.Sql;
 import org.springframework.stereotype.Service;
 
 
@@ -24,45 +18,4 @@ import org.springframework.stereotype.Service;
 @Service
 public class OrderSkuServiceImpl extends ServiceImpl<OrderSkuMapper, OrderSku> implements OrderSkuService {
 
-    @Override
-    public Page<OrderSkuVo> getPage(OrderSkuSelectDto dto) {
-
-        Page<OrderSkuVo> page = Sql.create(OrderSkuVo.class)
-                .selectAll(OrderSku.class)
-                .from(OrderSku.class)
-                .orderByDesc(OrderSku::getId)
-                .page(dto);
-
-        return page;
-    }
-
-    @Override
-    public OrderSkuVo detail(Long id) {
-
-        OrderSkuVo vo = Sql.create(OrderSkuVo.class)
-                .selectAll(OrderSku.class)
-                .from(OrderSku.class)
-                .eq(OrderSku::getId, id)
-                .one();
-
-        Assert.notNull(vo, "未知数据");
-
-        return vo;
-    }
-
-    @Override
-    public void add(OrderSkuDto dto) {
-        save(dto);
-    }
-
-    @Override
-    public void edit(OrderSkuDto dto) {
-        updateById(dto);
-    }
-
-    @Override
-    public void delete(Long id) {
-        removeById(id);
-    }
-
 }

+ 17 - 18
sd-business/src/main/java/com/sd/business/util/CodeEnum.java

@@ -4,18 +4,24 @@ import cn.hutool.core.convert.Convert;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.extra.spring.SpringUtil;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.common.exception.ServiceException;
-import lombok.AllArgsConstructor;
+import com.sd.business.service.inventory.InventoryFinishedOrderDetailService;
+import com.sd.business.service.statement.StatementOfAccountService;
 import lombok.Getter;
 
 import java.util.Date;
 import java.util.Map;
 
 @Getter
-@AllArgsConstructor
 public enum CodeEnum {
-
+    // 对账单号
+    STATEMENT_OF_ACCOUNT_CODE("SOA", "-yyMMdd-", "code", 6, StatementOfAccountService.class),
+    // 成品仓入库
+    FINISHED_IN("POS", "-yyMMdd-", "code", 6, InventoryFinishedOrderDetailService.class),
+    // 成品仓出库
+    FINISHED_OUT("PWS", "-yyMMdd-", "code", 6, InventoryFinishedOrderDetailService.class),
     ;
 
     // 编码前缀
@@ -29,6 +35,14 @@ public enum CodeEnum {
     // service
     private final IService<?> service;
 
+    CodeEnum(String prefix, String dateFormat, String codeFieldName, Integer length, Class<? extends IService<?>> serviceCls) {
+        this.prefix = prefix;
+        this.dateFormat = dateFormat;
+        this.length = length;
+        this.codeFieldName = codeFieldName;
+        this.service = SpringUtil.getBean(serviceCls);
+    }
+
     /**
      * 不够位数的在前面补0,保留num的长度位数字
      */
@@ -36,21 +50,6 @@ public enum CodeEnum {
         return String.format("%0" + length + "d", codeNum + 1);
     }
 
-    // /**
-    //  * 获取键值对
-    //  */
-    // public String getCode(String code) {
-    //     if (ObjectUtil.isNotEmpty(code)) {
-    //         Long count = service.query().eq(codeFieldName, code).count();
-    //         if (count != 0) {
-    //             throw new ServiceException("编码已存在");
-    //         }
-    //         return code;
-    //     } else {
-    //         return getCode();
-    //     }
-    // }
-
     /**
      * 获取键值对
      */

+ 30 - 0
sd-framework/src/main/java/com/sd/framework/util/TransactionUtil.java

@@ -1,6 +1,8 @@
 package com.sd.framework.util;
 
 import cn.hutool.extra.spring.SpringUtil;
+import com.ruoyi.common.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
 import org.jetbrains.annotations.NotNull;
 import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.support.TransactionCallbackWithoutResult;
@@ -8,6 +10,7 @@ import org.springframework.transaction.support.TransactionTemplate;
 
 import java.util.function.Supplier;
 
+@Slf4j
 public class TransactionUtil {
 
     private final static TransactionTemplate transactionTemplate = SpringUtil.getBean(TransactionTemplate.class);
@@ -26,6 +29,21 @@ public class TransactionUtil {
         });
     }
 
+    public static void execute(Runnable runnable, String errorStr) {
+        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
+            @Override
+            protected void doInTransactionWithoutResult(@NotNull TransactionStatus status) {
+                try {
+                    runnable.run();
+                } catch (Exception e) {
+                    status.setRollbackOnly();
+                    log.error(errorStr, e);
+                    throw new ServiceException(errorStr);
+                }
+            }
+        });
+    }
+
     public static <T> T execute(Supplier<T> supplier) {
         return transactionTemplate.execute(status -> {
             try {
@@ -37,4 +55,16 @@ public class TransactionUtil {
         });
     }
 
+    public static <T> T execute(Supplier<T> supplier, String errorStr) {
+        return transactionTemplate.execute(status -> {
+            try {
+                return supplier.get();
+            } catch (Exception e) {
+                status.setRollbackOnly();
+                log.error(errorStr, e);
+                throw new ServiceException(errorStr);
+            }
+        });
+    }
+
 }

+ 320 - 0
sd-wln/src/main/java/com/sd/wln/context/OrderContext.java

@@ -0,0 +1,320 @@
+package com.sd.wln.context;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import com.ruoyi.framework.mybatis.holder.LogicHolder;
+import com.sd.business.entity.artwork.po.ArtworkLibrary;
+import com.sd.business.entity.bom.bo.BomSpecBo;
+import com.sd.business.entity.department.po.Department;
+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.OrderSkuBom;
+import com.sd.business.entity.order.po.OrderSkuProductionCost;
+import com.sd.business.entity.price.po.PriceBillingStandard;
+import com.sd.business.entity.price.po.PriceBillingStandardDetail;
+import com.sd.business.entity.sku.po.SkuSpec;
+import com.sd.business.entity.sku.po.SkuSpecLink;
+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.order.OrderInfoService;
+import com.sd.business.service.order.OrderSkuService;
+import com.sd.business.service.price.PriceBillingStandardDetailService;
+import com.sd.business.service.price.PriceBillingStandardService;
+import com.sd.business.service.sku.SkuSpecLinkService;
+import com.sd.business.service.sku.SkuSpecService;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Slf4j
+public class OrderContext {
+
+    private static final OrderInfoService orderInfoService = SpringUtil.getBean(OrderInfoService.class);
+    private static final OrderSkuService orderSkuService = SpringUtil.getBean(OrderSkuService.class);
+    private static final DepartmentService departmentService = SpringUtil.getBean(DepartmentService.class);
+    private static final SkuSpecService skuSpecService = SpringUtil.getBean(SkuSpecService.class);
+    private static final SkuSpecLinkService skuSpecLinkService = SpringUtil.getBean(SkuSpecLinkService.class);
+    private static final BomSpecService bomSpecService = SpringUtil.getBean(BomSpecService.class);
+    private static final ArtworkLibraryService artworkLibraryService = SpringUtil.getBean(ArtworkLibraryService.class);
+    private static final PriceBillingStandardService priceBillingStandardService = SpringUtil.getBean(PriceBillingStandardService.class);
+    private static final PriceBillingStandardDetailService priceBillingStandardDetailService = SpringUtil.getBean(PriceBillingStandardDetailService.class);
+
+    /**
+     * 保存订单列表
+     */
+    @Getter
+    private final List<OrderInfo> saveOrderList = new ArrayList<>();
+
+    /**
+     * 更新订单列表
+     */
+    @Getter
+    private final List<OrderInfo> updateOrderList = new ArrayList<>();
+
+    /**
+     * 需要保存对账单的订单列表
+     */
+    @Getter
+    private final List<OrderInfo> saveStatementOrderList = new ArrayList<>();
+
+    /**
+     * 保存订单明细列表
+     */
+    @Getter
+    private final List<OrderSku> saveOrderSkuList = new ArrayList<>();
+
+    /**
+     * 保存订单包材
+     */
+    @Getter
+    private final List<OrderSkuBom> saveOrderSkuBomList = new ArrayList<>();
+
+    /**
+     * 保存订单包装
+     */
+    @Getter
+    private final List<OrderPackageBom> orderPackageBomList = new ArrayList<>();
+
+    /**
+     * 保存订单产品生产成本
+     */
+    @Getter
+    private final List<OrderSkuProductionCost> saveOrderSkuProductionCostList = new ArrayList<>();
+
+    /**
+     * 万里牛订单列表
+     */
+    @Getter
+    private final List<JSONObject> wlnOrderList;
+
+    /**
+     * 事业部
+     */
+    @Getter
+    private final Department department;
+
+    /**
+     * 已存在数据库中的订单map
+     * key:万里牛订单uid
+     * value:订单实体
+     */
+    private Map<String, OrderInfo> existOrderMap;
+
+    /**
+     * 已存在数据库中的订单sku map
+     * key:订单id
+     * value:订单sku实体列表
+     */
+    private Map<Long, List<OrderSku>> existOrderSkuMap;
+
+    /**
+     * sku规格map
+     * key:万里牛sku规格uid
+     * value:sku规格实体
+     */
+    private Map<String, SkuSpec> skuSpecMap;
+
+    /**
+     * sku规格关联bom
+     * key:sku规格id
+     * value: key:类型 1包材 2快递包装 value:sku规格实体
+     */
+    private Map<Long, Map<Integer, List<SkuSpecLink>>> skuSpecLinkBomSpecMap;
+
+    /**
+     * bom规格明细
+     * key:bom规格id
+     * value:bom规格明细
+     */
+    private Map<Long, BomSpecBo> bomSpecBoMap;
+
+    /**
+     * 生产文件
+     */
+    private Map<Long, ArtworkLibrary> artworkLibraryMap;
+
+    /**
+     * 加工计费标准明细列表
+     */
+    private Map<String, List<PriceBillingStandardDetail>> priceBillingStandardMap;
+
+    /**
+     * 实例化
+     */
+    public OrderContext(String warehouseCode, List<JSONObject> wlnOrderList) {
+        this.wlnOrderList = wlnOrderList;
+        this.department = departmentService.getDepartmentByWarehouseCode(warehouseCode);
+    }
+
+    /**
+     * 获取已存在数据库中的订单map
+     */
+    public Map<String, OrderInfo> getExistOrderMap() {
+        if (existOrderMap == null) {
+            List<String> uidList = wlnOrderList.stream().map(item -> item.getString("uid")).collect(Collectors.toList());
+            LogicHolder.setLogicHolder(true);
+            existOrderMap = orderInfoService.mapKEntity(OrderInfo::getWlnUid, q -> q.in(OrderInfo::getWlnUid, uidList));
+            LogicHolder.clear();
+        }
+        return existOrderMap;
+    }
+
+    /**
+     * 已存在数据库中的订单sku map
+     */
+    public Map<Long, List<OrderSku>> getExistOrderSkuMap() {
+        if (existOrderSkuMap == null) {
+            List<Long> orderIdList = getExistOrderMap().values().stream().map(BaseIdPo::getId).collect(Collectors.toList());
+            if (orderIdList.isEmpty()) {
+                existOrderSkuMap = Collections.emptyMap();
+            } else {
+                existOrderSkuMap = orderSkuService.mapKGroup(OrderSku::getOrderId, q -> q.in(OrderSku::getOrderId, orderIdList));
+            }
+        }
+        return existOrderSkuMap;
+    }
+
+    /**
+     * 获取sku规格map
+     */
+    public Map<String, SkuSpec> getSkuSpecMap() {
+        if (skuSpecMap == null) {
+            List<String> wlnSkuSpecUidList = wlnOrderList.stream()
+                    .flatMap(item -> item.getJSONArray("orders").toJavaList(JSONObject.class).stream())
+                    .map(item -> item.getString("sys_spec_uid"))
+                    .filter(ObjectUtil::isNotNull)
+                    .distinct()
+                    .collect(Collectors.toList());
+
+            if (wlnSkuSpecUidList.isEmpty()) {
+                skuSpecMap = Collections.emptyMap();
+            } else {
+                skuSpecMap = skuSpecService.mapKEntity(SkuSpec::getWlnSkuSpecId, q -> q.in(SkuSpec::getWlnSkuSpecId, wlnSkuSpecUidList));
+            }
+        }
+        return skuSpecMap;
+    }
+
+    /**
+     * 获取sku规格关联bom
+     */
+    public Map<Long, Map<Integer, List<SkuSpecLink>>> getSkuSpecLinkBomSpecMap() {
+
+        if (skuSpecLinkBomSpecMap == null) {
+
+            if (department == null) {
+                skuSpecLinkBomSpecMap = Collections.emptyMap();
+                return skuSpecLinkBomSpecMap;
+            }
+
+            Collection<SkuSpec> values = getSkuSpecMap().values();
+            if (values.isEmpty()) {
+                skuSpecLinkBomSpecMap = Collections.emptyMap();
+                return skuSpecLinkBomSpecMap;
+            }
+
+            List<Long> skuSpecIdList = values.stream().map(SkuSpec::getId).distinct().collect(Collectors.toList());
+            List<SkuSpecLink> list = skuSpecLinkService.list(q -> q.in(SkuSpecLink::getSkuSpecId, skuSpecIdList));
+
+            skuSpecLinkBomSpecMap = list.stream().collect(Collectors.groupingBy(
+                    SkuSpecLink::getSkuSpecId, Collectors.groupingBy(SkuSpecLink::getType)));
+        }
+
+        return skuSpecLinkBomSpecMap;
+    }
+
+    /**
+     * 获取bom规格明细
+     */
+    public Map<Long, BomSpecBo> getBomSpecBoMap() {
+        if (bomSpecBoMap == null) {
+            List<Long> bomSpecIdList = Stream.concat(
+                            getSkuSpecMap().values().stream().map(SkuSpec::getBomSpecId),
+                            getSkuSpecLinkBomSpecMap().values().stream().flatMap(item -> Stream.concat(
+                                    item.getOrDefault(1, Collections.emptyList()).stream(),
+                                    item.getOrDefault(2, Collections.emptyList()).stream()
+                            )).map(SkuSpecLink::getBomSpecId))
+                    .distinct().collect(Collectors.toList());
+            bomSpecBoMap = bomSpecService.getBomSpecBo(bomSpecIdList);
+        }
+        return bomSpecBoMap;
+    }
+
+    /**
+     * 获取加工计费标准明细列表
+     */
+    public List<PriceBillingStandardDetail> getPriceBillingStandardMap(String species) {
+        if (StrUtil.isEmpty(species)) {
+            return Collections.emptyList();
+        }
+
+        if (priceBillingStandardMap == null) {
+            if (department == null || department.getPriceBillingStandardId() == null) {
+                priceBillingStandardMap = Collections.emptyMap();
+            } else {
+                String priceBillingStandardId = department.getPriceBillingStandardId();
+                if (StrUtil.isEmpty(priceBillingStandardId)) {
+                    priceBillingStandardMap = Collections.emptyMap();
+                } else {
+                    priceBillingStandardMap = new HashMap<>();
+                    List<Long> idList = Arrays.stream(priceBillingStandardId.split(",")).map(Convert::toLong).collect(Collectors.toList());
+                    List<PriceBillingStandard> priceBillingStandardList = priceBillingStandardService.listByIds(idList);
+
+                    Map<Long, List<PriceBillingStandardDetail>> map = priceBillingStandardDetailService.mapKGroup(
+                            PriceBillingStandardDetail::getPriceBillingStandardId,
+                            q -> q.in(PriceBillingStandardDetail::getPriceBillingStandardId, idList));
+
+                    for (PriceBillingStandard priceBillingStandard : priceBillingStandardList) {
+                        priceBillingStandardMap.put(priceBillingStandard.getSpecies(),
+                                map.getOrDefault(priceBillingStandard.getId(), Collections.emptyList()));
+                    }
+
+                }
+            }
+        }
+        return priceBillingStandardMap.getOrDefault(species, Collections.emptyList());
+    }
+
+    /**
+     * 获取生产文件
+     */
+    public Map<Long, ArtworkLibrary> getArtworkLibraryMap() {
+        if (artworkLibraryMap != null) {
+            return artworkLibraryMap;
+        }
+
+        Map<String, SkuSpec> tempSkuSpecMap = getSkuSpecMap();
+        if (tempSkuSpecMap.isEmpty()) {
+            artworkLibraryMap = Collections.emptyMap();
+            return artworkLibraryMap;
+        }
+
+        List<Long> artworkLibraryId = tempSkuSpecMap.values().stream().map(SkuSpec::getArtworkLibraryId).collect(Collectors.toList());
+        if (artworkLibraryId.isEmpty()) {
+            artworkLibraryMap = Collections.emptyMap();
+            return artworkLibraryMap;
+        }
+
+        List<ArtworkLibrary> artworkLibraryList = artworkLibraryService.listByIds(artworkLibraryId);
+        artworkLibraryMap = artworkLibraryList.stream().collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
+
+        return artworkLibraryMap;
+    }
+
+}

+ 14 - 0
sd-wln/src/main/java/com/sd/wln/scheduled/WlnSyncTask.java

@@ -1,5 +1,6 @@
 package com.sd.wln.scheduled;
 
+import com.sd.wln.service.WlnOrderService;
 import com.sd.wln.service.WlnSkuService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Profile;
@@ -16,6 +17,10 @@ public class WlnSyncTask {
     @Autowired
     private WlnSkuService wlnSkuService;
 
+    @Autowired
+    private WlnOrderService wlnOrderService;
+
+
     /**
      * 同步sku信息
      */
@@ -24,4 +29,13 @@ public class WlnSyncTask {
         wlnSkuService.sync();
     }
 
+    /**
+     * 同步订单数据
+     */
+    @Scheduled(fixedDelay = 3 * 60 * 1000)
+    private void syncOrder() {
+        wlnOrderService.syncOrder();
+    }
+
+
 }

+ 44 - 0
sd-wln/src/main/java/com/sd/wln/service/WlnOrderService.java

@@ -0,0 +1,44 @@
+package com.sd.wln.service;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.sd.business.entity.order.po.OrderInfo;
+import com.sd.wln.context.OrderContext;
+
+public interface WlnOrderService {
+
+    /**
+     * 同步订单
+     */
+    void syncOrder();
+
+    /**
+     * 创建订单
+     */
+    OrderInfo createOrder(OrderContext context, JSONObject wlnOrder);
+
+    /**
+     * 更新订单
+     */
+    void updateOrder(OrderContext context, JSONObject wlnOrder, OrderInfo orderInfo);
+
+    /**
+     * 添加订单
+     */
+    void addOrder(OrderContext context, JSONObject wlnOrder, OrderInfo orderInfo);
+
+    /**
+     * 新增或编辑订单
+     */
+    void saveOrUpdateOrder(OrderContext context);
+
+    /**
+     * 锁定库存
+     */
+    void lockStorage(OrderContext context);
+
+    /**
+     * 解锁库存
+     */
+    void unlockStorage(OrderContext context);
+
+}

+ 854 - 0
sd-wln/src/main/java/com/sd/wln/service/impl/WlnOrderServiceImpl.java

@@ -0,0 +1,854 @@
+package com.sd.wln.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.fjhx.tenant.entity.dict.po.DictCommonData;
+import com.fjhx.tenant.service.dict.DictCommonDataService;
+import com.ruoyi.common.constant.StatusConstant;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.framework.mybatis.holder.LogicHolder;
+import com.sd.business.entity.artwork.po.ArtworkLibrary;
+import com.sd.business.entity.bom.bo.BomSpecBo;
+import com.sd.business.entity.department.po.Department;
+import com.sd.business.entity.order.enums.OrderClassifyEnum;
+import com.sd.business.entity.order.enums.OrderExceptionTypeEnum;
+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.OrderSkuBom;
+import com.sd.business.entity.order.po.OrderSkuProductionCost;
+import com.sd.business.entity.price.po.PriceBillingStandardDetail;
+import com.sd.business.entity.sku.po.SkuSpec;
+import com.sd.business.entity.sku.po.SkuSpecLink;
+import com.sd.business.entity.statement.dto.StatementOfAccountDto;
+import com.sd.business.service.bom.BomSpecService;
+import com.sd.business.service.inventory.InventoryFinishedService;
+import com.sd.business.service.inventory.InventoryService;
+import com.sd.business.service.order.OrderInfoService;
+import com.sd.business.service.order.OrderPackageBomService;
+import com.sd.business.service.order.OrderSkuBomService;
+import com.sd.business.service.order.OrderSkuProductionCostService;
+import com.sd.business.service.order.OrderSkuService;
+import com.sd.business.service.statement.StatementOfAccountService;
+import com.sd.framework.util.TransactionUtil;
+import com.sd.wln.context.OrderContext;
+import com.sd.wln.service.WlnOrderService;
+import com.sd.wln.util.WlnUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Slf4j
+@Service
+public class WlnOrderServiceImpl implements WlnOrderService {
+
+    @Autowired
+    private DictCommonDataService dictCommonDataService;
+
+    @Autowired
+    private OrderInfoService orderInfoService;
+
+    @Autowired
+    private OrderSkuService orderSkuService;
+
+    @Autowired
+    private OrderSkuBomService orderSkuBomService;
+
+    @Autowired
+    private InventoryService inventoryService;
+
+    @Autowired
+    private BomSpecService bomSpecService;
+
+    @Autowired
+    private OrderPackageBomService orderPackageBomService;
+
+    @Autowired
+    private StatementOfAccountService statementOfAccountService;
+
+    @Autowired
+    private OrderSkuProductionCostService orderSkuProductionCostService;
+
+    @Autowired
+    private InventoryFinishedService inventoryFinishedService;
+
+    @Override
+    public void syncOrder() {
+
+        List<DictCommonData> warehouseCodeList = dictCommonDataService.list(q -> q.eq(DictCommonData::getDictCode, "warehouse_code"));
+
+        for (DictCommonData dictCommonData : warehouseCodeList) {
+
+            // 获取事业部编号
+            String warehouseCode = dictCommonData.getDictValue();
+
+            // 查询事业部万里牛订单
+            List<JSONObject> wlnOrderList = getWlnOrderList(warehouseCode);
+
+            // 万里牛订单数量若为0,结束同步任务
+            if (ObjectUtil.isEmpty(wlnOrderList)) {
+                continue;
+            }
+
+            // 初始化订单上下文
+            OrderContext context = new OrderContext(warehouseCode, wlnOrderList);
+
+            // 获取已存在订单
+            Map<String, OrderInfo> existOrderMap = context.getExistOrderMap();
+
+            // 循环万里牛订单
+            for (JSONObject wlnOrder : wlnOrderList) {
+
+                // 数据库中是否存在订单
+                OrderInfo orderInfo = existOrderMap.get(wlnOrder.getString("uid"));
+
+                // 不存在新增
+                if (orderInfo == null) {
+
+                    // 9月1号之前的订单不同步
+                    Date printTime = wlnOrder.getDate("print_time");
+                    if (printTime != null && printTime.before(DateUtil.parse("2023-09-01 00:00:00"))) {
+                        continue;
+                    }
+
+                    // 审核通过之前或预售状态的订单不同步
+                    Integer processStatus = wlnOrder.getInteger("process_status");
+                    if (processStatus < 1 || processStatus == 14) {
+                        continue;
+                    }
+
+                    // 创建订单
+                    orderInfo = createOrder(context, wlnOrder);
+
+                    // 添加订单到上下文
+                    addOrder(context, wlnOrder, orderInfo);
+
+                }
+                // 存在修改
+                else {
+                    updateOrder(context, wlnOrder, orderInfo);
+                }
+
+            }
+
+            // 保存新增、修改的订单
+            try {
+                TransactionUtil.execute(() -> {
+                    // 保存或更新数据
+                    saveOrUpdateOrder(context);
+                });
+            } catch (Exception e) {
+                log.error("同步订单失败");
+            }
+
+        }
+
+    }
+
+    /**
+     * 创建订单
+     */
+    @Override
+    public OrderInfo createOrder(OrderContext context, JSONObject wlnOrder) {
+
+        OrderInfo orderInfo = new OrderInfo();
+        orderInfo.setId(IdWorker.getId());
+        orderInfo.setSource(2);
+        orderInfo.setTaxRate(new BigDecimal("10.00"));
+        orderInfo.setTag("0");
+        orderInfo.setSettlementStatus(1);
+
+        orderInfo.setWlnStorageCode(wlnOrder.getString("storage_code"));
+        orderInfo.setWlnUid(wlnOrder.getString("uid"));
+        orderInfo.setCode(wlnOrder.getString("tp_tid"));
+        orderInfo.setWlnCode(wlnOrder.getString("trade_no"));
+        orderInfo.setWlnStatus(wlnOrder.getInteger("process_status"));
+        orderInfo.setWlnCreateTime(wlnOrder.getDate("create_time"));
+        orderInfo.setWlnModifyTime(wlnOrder.getDate("modify_time"));
+        orderInfo.setWlnModifyTimestamp(wlnOrder.getLong("modify_time"));
+        orderInfo.setWlnApproveTime(wlnOrder.getDate("approve_time"));
+        orderInfo.setWlnPrintTime(wlnOrder.getDate("print_time"));
+        orderInfo.setSourcePlatform(wlnOrder.getString("source_platform"));
+        orderInfo.setShopName(wlnOrder.getString("shop_name"));
+        orderInfo.setProvince(wlnOrder.getString("province"));
+        orderInfo.setCity(wlnOrder.getString("city"));
+        orderInfo.setCounty(wlnOrder.getString("district"));
+        orderInfo.setDetailedAddress(wlnOrder.getString("address"));
+        orderInfo.setPostcode(wlnOrder.getString("zip"));
+        orderInfo.setDeliveryTime(DateUtil.offsetDay(orderInfo.getWlnCreateTime(), 1));
+        orderInfo.setRemark(wlnOrder.getString("remark"));
+
+        orderInfo.setTotalAmount(BigDecimal.ZERO);
+        orderInfo.setProductTotalAmount(BigDecimal.ZERO);
+        orderInfo.setCustomProcessingFee(BigDecimal.ZERO);
+        orderInfo.setLssueFee(BigDecimal.ZERO);
+        orderInfo.setDeliveryMaterialsFee(BigDecimal.ZERO);
+        orderInfo.setPackingLabor(BigDecimal.ZERO);
+        orderInfo.setManagementFee(BigDecimal.ZERO);
+        orderInfo.setPackagingMaterialCost(BigDecimal.ZERO);
+
+        // 赋值订单异常类型
+        orderInfo.setExceptionType(OrderExceptionTypeEnum.NORMAL.getKey().toString());
+        if (orderInfo.getWlnStatus() == 10) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.ORDER_CLOSURE);
+        }
+        if (orderInfo.getWlnStatus() == 11) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.ORDER_ABORT);
+        }
+        if (orderInfo.getWlnStatus() == 12) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.ORDER_EXCEPTION_HANDLING);
+        }
+
+        // 事业部id
+        Department department = context.getDepartment();
+        if (department == null) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.UNKNOWN_WAREHOUSE);
+        } else {
+            orderInfo.setDepartmentId(department.getId());
+        }
+
+        // 订单进度
+        if (department != null && Objects.equals(department.getOrderMode(), "2") && orderInfo.getWlnStatus() != 1) {
+            orderInfo.setStatus(OrderStatusEnum.STOCK_PREPARATION.getKey());
+        } else {
+            orderInfo.setStatus(OrderStatusEnum.UNDER_REVIEW.getKey());
+        }
+
+        orderInfo.setLockStorage(StatusConstant.NO);
+
+        return orderInfo;
+    }
+
+    /**
+     * 修改订单
+     */
+    public void updateOrder(OrderContext context, JSONObject wlnOrder, OrderInfo orderInfo) {
+
+        // 已删除、生产中、生产完成、已发货的订单跳过修改
+        if (Objects.equals(orderInfo.getDelFlag(), StatusConstant.DELETED)
+                || Objects.equals(orderInfo.getStatus(), OrderStatusEnum.IN_PRODUCTION.getKey())
+                || Objects.equals(orderInfo.getStatus(), OrderStatusEnum.COMPLETION_PRODUCTION.getKey())
+                || Objects.equals(orderInfo.getStatus(), OrderStatusEnum.HAVE_BEEN_SHIPPED.getKey())) {
+            // 万里牛状态异常:订单关闭的订单类型修改为无理由并生成对账单
+            if (Objects.equals(orderInfo.getStatus(), OrderStatusEnum.IN_PRODUCTION.getKey())
+                    && wlnOrder.getInteger("process_status") == 10
+                    && ObjectUtil.notEqual(orderInfo.getClassify(), OrderClassifyEnum.NO_REASON_ORDER.getKey())) {
+                List<OrderInfo> updateOrderList = context.getUpdateOrderList();
+                List<OrderInfo> saveStatementOrderList = context.getSaveStatementOrderList();
+                orderInfo.setWlnStatus(wlnOrder.getInteger("process_status"));
+                orderInfo.setWlnModifyTime(wlnOrder.getDate("modify_time"));
+                orderInfo.setWlnModifyTimestamp(wlnOrder.getLong("modify_time"));
+                orderInfo.setStatus(OrderStatusEnum.COMPLETION_PRODUCTION.getKey());
+                orderInfo.setClassify(OrderClassifyEnum.NO_REASON_ORDER.getKey());
+                orderInfo.setShippingTime(new Date());
+
+                // 保存对账单列表
+                saveStatementOrderList.add(orderInfo);
+                updateOrderList.add(orderInfo);
+            }
+
+            return;
+        }
+
+        // 打回审核真删订单
+        if (wlnOrder.getInteger("process_status") == 0) {
+            LogicHolder.setLogicHolder(true);
+            orderInfoService.deleteAndStore(orderInfo.getId());
+            LogicHolder.clear();
+            return;
+        }
+
+        Department department = context.getDepartment();
+        Map<Long, List<OrderSku>> existOrderSkuMap = context.getExistOrderSkuMap();
+        List<OrderInfo> updateOrderList = context.getUpdateOrderList();
+
+        orderInfo.setWlnStorageCode(wlnOrder.getString("storage_code"));
+        orderInfo.setWlnUid(wlnOrder.getString("uid"));
+        orderInfo.setCode(wlnOrder.getString("tp_tid"));
+        orderInfo.setWlnCode(wlnOrder.getString("trade_no"));
+        orderInfo.setWlnStatus(wlnOrder.getInteger("process_status"));
+        orderInfo.setWlnCreateTime(wlnOrder.getDate("create_time"));
+        orderInfo.setWlnModifyTime(wlnOrder.getDate("modify_time"));
+        orderInfo.setWlnModifyTimestamp(wlnOrder.getLong("modify_time"));
+        orderInfo.setWlnApproveTime(wlnOrder.getDate("approve_time"));
+        orderInfo.setWlnPrintTime(wlnOrder.getDate("print_time"));
+        orderInfo.setSourcePlatform(wlnOrder.getString("source_platform"));
+        orderInfo.setShopName(wlnOrder.getString("shop_name"));
+        orderInfo.setProvince(wlnOrder.getString("province"));
+        orderInfo.setCity(wlnOrder.getString("city"));
+        orderInfo.setCounty(wlnOrder.getString("district"));
+        orderInfo.setDetailedAddress(wlnOrder.getString("address"));
+        orderInfo.setPostcode(wlnOrder.getString("zip"));
+        orderInfo.setDeliveryTime(DateUtil.offsetDay(orderInfo.getWlnCreateTime(), 1));
+        orderInfo.setRemark(wlnOrder.getString("remark"));
+
+        // 赋值订单异常类型
+        if (orderInfo.getWlnStatus() == 10) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.ORDER_CLOSURE);
+        }
+        if (orderInfo.getWlnStatus() == 11) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.ORDER_ABORT);
+        }
+        if (orderInfo.getWlnStatus() == 12) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.ORDER_EXCEPTION_HANDLING);
+        }
+
+        // 事业部
+        if (department == null) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.UNKNOWN_WAREHOUSE);
+        } else {
+            orderInfo.setDepartmentId(department.getId());
+        }
+
+        List<OrderSku> orderSkuList = new ArrayList<>(existOrderSkuMap.getOrDefault(orderInfo.getId(), Collections.emptyList()));
+        List<JSONObject> wlnOrderSkuList = wlnOrder.getJSONArray("orders").toJavaList(JSONObject.class);
+
+        if (orderSkuList.size() != wlnOrderSkuList.size()) {
+            addExceptionType(orderInfo, OrderExceptionTypeEnum.SKU_UPDATE);
+        } else {
+            for (JSONObject wlnOrderSku : wlnOrderSkuList) {
+                for (OrderSku orderSku : orderSkuList) {
+                    if (Objects.equals(wlnOrderSku.getString("sys_goods_uid"), orderSku.getWlnSkuId())
+                            && Objects.equals(wlnOrderSku.getString("sys_spec_uid"), orderSku.getWlnSkuSpecId())
+                            && Objects.equals(wlnOrderSku.getString("oln_sku_name"), orderSku.getWlnSkuName())
+                            && wlnOrderSku.getBigDecimal("size").compareTo(orderSku.getQuantity()) == 0) {
+                        orderSkuList.remove(orderSku);
+                        break;
+                    }
+                }
+            }
+
+            if (!orderSkuList.isEmpty()) {
+                addExceptionType(orderInfo, OrderExceptionTypeEnum.SKU_UPDATE);
+            }
+        }
+
+        // 万里牛订单状态不为1时,订单状态修改为备料中
+        if (department != null
+                && Objects.equals(department.getOrderMode(), "2")
+                && orderInfo.getWlnStatus() != 1
+                && Objects.equals(orderInfo.getStatus(), OrderStatusEnum.UNDER_REVIEW.getKey())) {
+            orderInfo.setStatus(OrderStatusEnum.STOCK_PREPARATION.getKey());
+        }
+
+        updateOrderList.add(orderInfo);
+    }
+
+    /**
+     * 创建订单包材
+     */
+    private List<OrderSkuBom> createOrderSkuBoom(OrderContext context, OrderSku orderSku) {
+        Map<Long, Map<Integer, List<SkuSpecLink>>> linkBomSpecMap = context.getSkuSpecLinkBomSpecMap();
+        Map<Long, BomSpecBo> bomBoMap = context.getBomSpecBoMap();
+
+        Map<Integer, List<SkuSpecLink>> map = linkBomSpecMap.getOrDefault(orderSku.getSkuSpecId(), Collections.emptyMap());
+        List<SkuSpecLink> skuSpecLinkList = map.getOrDefault(1, Collections.emptyList());
+
+        return skuSpecLinkList.stream().map(item -> {
+            OrderSkuBom orderSkuBom = new OrderSkuBom();
+            orderSkuBom.setId(IdWorker.getId());
+            orderSkuBom.setOrderId(orderSku.getOrderId());
+            orderSkuBom.setOrderSkuId(orderSku.getId());
+            orderSkuBom.setBomSpecId(item.getBomSpecId());
+            orderSkuBom.setQuantity(item.getQuantity());
+            BomSpecBo bomSpecBo = bomBoMap.get(orderSkuBom.getBomSpecId());
+            if (bomSpecBo == null) {
+                orderSkuBom.setUnitPrice(BigDecimal.ZERO);
+            } else {
+                orderSkuBom.setUnitPrice(bomSpecBo.getInternalSellingPrice());
+                orderSku.setPackagingMaterialCost(orderSku.getPackagingMaterialCost()
+                        .add(bomSpecBo.getInternalSellingPrice().multiply(item.getQuantity())));
+            }
+            return orderSkuBom;
+        }).collect(Collectors.toList());
+
+    }
+
+    /**
+     * 创建订单产品成本
+     */
+    private OrderSkuProductionCost createOrderSkuProductionCostList(OrderSku orderSku, List<OrderSkuBom> orderSkuBomList) {
+        OrderSkuProductionCost orderSkuProductionCost = new OrderSkuProductionCost();
+        orderSkuProductionCost.setOrderId(orderSku.getOrderId());
+        orderSkuProductionCost.setOrderSkuId(orderSku.getId());
+
+        // 材料成本
+        orderSkuProductionCost.setMaterialCost(orderSku.getUnitPrice().multiply(orderSku.getQuantity()));
+
+        // 辅料成本暂时没有默认为零
+        orderSkuProductionCost.setAuxiliaryMaterialCost(BigDecimal.ZERO);
+
+        // 产品包材成本
+        if (orderSkuBomList == null) {
+            orderSkuBomList = new ArrayList<>();
+        }
+        BigDecimal productPackagingMaterialCost = orderSkuBomList.stream()
+                .map(orderSkuBom -> orderSkuBom.getQuantity().multiply(orderSkuBom.getUnitPrice()).multiply(orderSku.getQuantity()))
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        orderSkuProductionCost.setProductPackagingMaterialCost(productPackagingMaterialCost);
+
+        // 物流包材成本
+        BigDecimal logisticsPackagingMaterialCost = orderSku.getDeliveryMaterialsFee().multiply(orderSku.getQuantity());
+        orderSkuProductionCost.setLogisticsPackagingMaterialCost(logisticsPackagingMaterialCost);
+
+        // 成本总金额
+        orderSkuProductionCost.setTotalAmount(orderSkuProductionCost.getMaterialCost()
+                .add(orderSkuProductionCost.getAuxiliaryMaterialCost())
+                .add(orderSkuProductionCost.getProductPackagingMaterialCost())
+                .add(orderSkuProductionCost.getLogisticsPackagingMaterialCost()));
+
+        return orderSkuProductionCost;
+    }
+
+    /**
+     * 创建订单包装
+     */
+    private List<OrderPackageBom> createOrderPackageBomList(OrderContext context, OrderSku orderSku) {
+        Map<Long, Map<Integer, List<SkuSpecLink>>> linkBomSpecMap = context.getSkuSpecLinkBomSpecMap();
+        Map<Long, BomSpecBo> bomBoMap = context.getBomSpecBoMap();
+
+        List<OrderPackageBom> orderPackageBomList = new ArrayList<>();
+
+        Map<Integer, List<SkuSpecLink>> map = linkBomSpecMap.getOrDefault(orderSku.getSkuSpecId(), Collections.emptyMap());
+        List<SkuSpecLink> skuSpecLinkList = map.getOrDefault(2, Collections.emptyList());
+
+        for (SkuSpecLink skuSpecLink : skuSpecLinkList) {
+            Long bomSpecId = skuSpecLink.getBomSpecId();
+
+            OrderPackageBom orderPackageBom = new OrderPackageBom();
+            orderPackageBom.setOrderId(orderSku.getOrderId());
+            orderPackageBom.setBomSpecId(bomSpecId);
+            BomSpecBo bomSpecBo = bomBoMap.get(bomSpecId);
+            if (bomSpecBo == null) {
+                orderPackageBom.setCostPrice(BigDecimal.ZERO);
+                orderPackageBom.setInternalSellingPrice(BigDecimal.ZERO);
+            } else {
+                orderPackageBom.setCostPrice(bomSpecBo.getCostPrice());
+                orderPackageBom.setInternalSellingPrice(bomSpecBo.getInternalSellingPrice());
+            }
+            orderPackageBom.setQuantity(orderSku.getQuantity().multiply(skuSpecLink.getQuantity()));
+
+            // 计算订单sku的快递包材费
+            BigDecimal deliveryMaterialsFee = orderPackageBom.getInternalSellingPrice().multiply(skuSpecLink.getQuantity());
+            orderSku.setDeliveryMaterialsFee(orderSku.getDeliveryMaterialsFee().add(deliveryMaterialsFee));
+
+            orderPackageBomList.add(orderPackageBom);
+        }
+
+        return orderPackageBomList;
+    }
+
+    /**
+     * 添加订单到上下文
+     */
+    @Override
+    public void addOrder(OrderContext context, JSONObject wlnOrder, OrderInfo orderInfo) {
+        Map<String, SkuSpec> skuSpecMap = context.getSkuSpecMap();
+
+        List<OrderSku> orderSkuList = new ArrayList<>();
+        List<OrderSkuProductionCost> orderSkuProductionCostList = new ArrayList<>();
+        List<OrderSkuBom> orderSkuBomList = new ArrayList<>();
+        List<OrderPackageBom> orderPackageBomList = new ArrayList<>();
+
+        // 创建订单sku
+        for (JSONObject wlnOrderSku : wlnOrder.getJSONArray("orders").toJavaList(JSONObject.class)) {
+
+            // 通过万里牛sku规格uid找到sku规格
+            SkuSpec skuSpec = skuSpecMap.get(wlnOrderSku.getString("sys_spec_uid"));
+            if (skuSpec == null) {
+                addExceptionType(orderInfo, OrderExceptionTypeEnum.UNKNOWN_SKU_SPEC);
+            } else if (skuSpec.getBomSpecId() == null) {
+                addExceptionType(orderInfo, OrderExceptionTypeEnum.UNKNOWN_BOM_SPEC);
+            }
+
+            // 创建订单sku
+            OrderSku orderSku = createOrderSku(context, wlnOrderSku, orderInfo, skuSpec);
+
+            // 获取订单sku包材
+            List<OrderSkuBom> tempOrderSkuBomList = createOrderSkuBoom(context, orderSku);
+
+            // 获取订单sku快递包材
+            List<OrderPackageBom> tempOrderPackageBomList = createOrderPackageBomList(context, orderSku);
+
+            // 获取订单sku成本
+            OrderSkuProductionCost productionCostList = createOrderSkuProductionCostList(orderSku, tempOrderSkuBomList);
+
+            // 添加订单金额
+            addOrderInfoPrice(orderInfo, orderSku);
+
+            orderSkuList.add(orderSku);
+            orderSkuBomList.addAll(tempOrderSkuBomList);
+            orderPackageBomList.addAll(tempOrderPackageBomList);
+
+            orderSkuProductionCostList.add(productionCostList);
+        }
+        // 合并相同快递包材
+        Map<Long, OrderPackageBom> map = orderPackageBomList.stream().collect(Collectors.toMap(
+                OrderPackageBom::getBomSpecId,
+                Function.identity(),
+                (v1, v2) -> {
+                    v1.setQuantity(v1.getQuantity().add(v2.getQuantity()));
+                    return v1;
+                }
+        ));
+        context.getSaveOrderList().add(orderInfo);
+        context.getSaveOrderSkuList().addAll(orderSkuList);
+        context.getSaveOrderSkuBomList().addAll(orderSkuBomList);
+        context.getSaveOrderSkuProductionCostList().addAll(orderSkuProductionCostList);
+        context.getOrderPackageBomList().addAll(new ArrayList<>(map.values()));
+    }
+
+    /**
+     * 创建订单sku
+     */
+    private OrderSku createOrderSku(OrderContext context, JSONObject wlnOrderSku, OrderInfo orderInfo, SkuSpec skuSpec) {
+
+        OrderSku orderSku = new OrderSku();
+        orderSku.setId(IdWorker.getId());
+        orderSku.setWlnSkuId(wlnOrderSku.getString("sys_goods_uid"));
+        orderSku.setWlnSkuSpecId(wlnOrderSku.getString("sys_spec_uid"));
+        orderSku.setWlnSkuName(wlnOrderSku.getString("oln_sku_name"));
+        orderSku.setOrderId(orderInfo.getId());
+        orderSku.setQuantity(wlnOrderSku.getBigDecimal("size"));
+        orderSku.setPrintType(1);
+        orderSku.setStockPreparationStatus(StatusConstant.NO);
+
+        orderSku.setUnitPrice(BigDecimal.ZERO);
+        orderSku.setCustomProcessingFee(BigDecimal.ZERO);
+        orderSku.setLssueFee(BigDecimal.ZERO);
+        orderSku.setDeliveryMaterialsFee(BigDecimal.ZERO);
+        orderSku.setPackingLabor(BigDecimal.ZERO);
+        orderSku.setManagementFee(BigDecimal.ZERO);
+        orderSku.setPackagingMaterialCost(BigDecimal.ZERO);
+
+        if (skuSpec != null) {
+            orderSku.setSkuId(skuSpec.getSkuId());
+            orderSku.setSkuSpecId(skuSpec.getId());
+            orderSku.setBomSpecId(skuSpec.getBomSpecId());
+
+            Long artworkLibraryId = skuSpec.getArtworkLibraryId();
+
+            if (artworkLibraryId != null) {
+                ArtworkLibrary artworkLibrary = context.getArtworkLibraryMap().get(artworkLibraryId);
+                if (artworkLibrary != null) {
+                    orderSku.setArtworkLibraryId(artworkLibraryId);
+                    orderSku.setBlueprint(artworkLibrary.getImgUrl());
+                    orderSku.setProductionDocument(artworkLibrary.getFileUrl());
+                }
+            }
+
+            assignedOrderSkuPrice(context, orderSku, skuSpec);
+
+            if (OrderStatusEnum.STOCK_PREPARATION.getKey().equals(orderInfo.getStatus())
+                    && orderSku.getArtworkLibraryId() == null) {
+                addExceptionType(orderInfo, OrderExceptionTypeEnum.NO_DESIGN_DOCUMENT);
+            }
+
+        }
+
+        return orderSku;
+    }
+
+    /**
+     * 赋值订单sku价格
+     */
+    private void assignedOrderSkuPrice(OrderContext context, OrderSku orderSku, SkuSpec skuSpec) {
+
+        BomSpecBo bomSpecBo = context.getBomSpecBoMap().get(skuSpec.getBomSpecId());
+
+        // 订单明细sku没绑定bom,不赋值价格
+        if (bomSpecBo == null) {
+            return;
+        }
+
+        // 设置单价
+        orderSku.setUnitPrice(bomSpecBo.getInternalSellingPrice());
+
+        // 如果bom规格不为主材,不赋值价格
+        if (ObjectUtil.notEqual(bomSpecBo.getClassifyParentId(), 1L)) {
+            return;
+        }
+
+        // 获取报价规则列表
+        List<PriceBillingStandardDetail> priceBillingStandardDetailList =
+                context.getPriceBillingStandardMap(bomSpecBo.getBomSpecies());
+
+        // 报价规则列表
+        if (ObjectUtil.isEmpty(priceBillingStandardDetailList)) {
+            return;
+        }
+
+        for (PriceBillingStandardDetail priceBillingStandardDetail : priceBillingStandardDetailList) {
+            String chargeItem = priceBillingStandardDetail.getChargeItem();
+            BigDecimal chargePrice = priceBillingStandardDetail.getChargePrice();
+
+            switch (chargeItem) {
+                case "40":
+                    orderSku.setPackingLabor(chargePrice);
+                    break;
+                case "50":
+                    orderSku.setLssueFee(chargePrice);
+                    break;
+                case "70":
+                    orderSku.setManagementFee(chargePrice);
+                    break;
+                default:
+                    if (Objects.equals(chargeItem, skuSpec.getMachinedPanel())
+                            && orderSku.getQuantity().compareTo(priceBillingStandardDetail.getSectionMin()) >= 0
+                            && orderSku.getQuantity().compareTo(priceBillingStandardDetail.getSectionMax()) < 0) {
+                        orderSku.setCustomProcessingType(chargeItem);
+                        orderSku.setCustomProcessingFee(chargePrice);
+                    }
+            }
+        }
+    }
+
+    /**
+     * 添加订单价格
+     */
+    private void addOrderInfoPrice(OrderInfo orderInfo, OrderSku orderSku) {
+        BigDecimal quantity = orderSku.getQuantity();
+
+        BigDecimal productTotalAmount = quantity.multiply(orderSku.getUnitPrice());
+        BigDecimal customProcessingFee = quantity.multiply(orderSku.getCustomProcessingFee());
+        BigDecimal lssueFee = quantity.multiply(orderSku.getLssueFee());
+        BigDecimal deliveryMaterialsFee = quantity.multiply(orderSku.getDeliveryMaterialsFee());
+        BigDecimal packingLabor = quantity.multiply(orderSku.getPackingLabor());
+        BigDecimal packagingMaterialCost = quantity.multiply(orderSku.getPackagingMaterialCost());
+        BigDecimal managementFee = quantity.multiply(orderSku.getManagementFee());
+        BigDecimal totalAmount = productTotalAmount
+                .add(customProcessingFee)
+                .add(lssueFee)
+                .add(deliveryMaterialsFee)
+                .add(packingLabor)
+                .add(packagingMaterialCost)
+                .add(managementFee);
+
+        orderInfo.setProductTotalAmount(orderInfo.getProductTotalAmount().add(productTotalAmount));
+        orderInfo.setCustomProcessingFee(orderInfo.getCustomProcessingFee().add(customProcessingFee));
+        orderInfo.setLssueFee(orderInfo.getLssueFee().add(lssueFee));
+        orderInfo.setDeliveryMaterialsFee(orderInfo.getDeliveryMaterialsFee().add(deliveryMaterialsFee));
+        orderInfo.setPackingLabor(orderInfo.getPackingLabor().add(packingLabor));
+        orderInfo.setManagementFee(orderInfo.getManagementFee().add(managementFee));
+        orderInfo.setPackagingMaterialCost(orderInfo.getPackagingMaterialCost().add(packagingMaterialCost));
+        orderInfo.setTotalAmount(orderInfo.getTotalAmount().add(totalAmount));
+    }
+
+    /**
+     * 添加订单异常类型
+     */
+    private void addExceptionType(OrderInfo orderInfo, OrderExceptionTypeEnum exceptionTypeEnum) {
+
+        String exceptionType;
+
+        String oldExceptionType = orderInfo.getExceptionType();
+        if (StrUtil.isBlank(oldExceptionType) || oldExceptionType.equals("0")) {
+            exceptionType = exceptionTypeEnum.getKey().toString();
+        } else if (Arrays.asList(oldExceptionType.split(",")).contains(exceptionTypeEnum.getKey().toString())) {
+            exceptionType = oldExceptionType;
+        } else {
+            exceptionType = oldExceptionType + "," + exceptionTypeEnum.getKey();
+        }
+
+        orderInfo.setExceptionType(exceptionType);
+        orderInfo.setExceptionTime(ObjectUtil.defaultIfNull(orderInfo.getExceptionTime(), new Date()));
+    }
+
+    /**
+     * 保存或更新数据
+     */
+    @Override
+    public void saveOrUpdateOrder(OrderContext context) {
+
+        // 新增正常订单锁定库存
+        lockStorage(context);
+
+        // 修改正常订单为异常订单解锁库存
+        unlockStorage(context);
+
+        List<OrderInfo> saveOrderList = context.getSaveOrderList();
+        List<OrderInfo> updateOrderList = context.getUpdateOrderList();
+        List<OrderInfo> saveStatementOrderList = context.getSaveStatementOrderList();
+        List<OrderSku> saveOrderSkuList = context.getSaveOrderSkuList();
+        List<OrderSkuBom> saveOrderSkuBomList = context.getSaveOrderSkuBomList();
+        List<OrderSkuProductionCost> saveOrderSkuProductionCostList = context.getSaveOrderSkuProductionCostList();
+        List<OrderPackageBom> orderPackageBomList = context.getOrderPackageBomList();
+
+        if (!saveOrderList.isEmpty()) {
+            orderInfoService.saveBatch(saveOrderList);
+        }
+        if (!updateOrderList.isEmpty()) {
+            orderInfoService.updateBatchById(updateOrderList);
+        }
+        if (!saveStatementOrderList.isEmpty()) {
+            saveStatementOrderList.forEach(item -> {
+
+                // 生成对账单
+                StatementOfAccountDto statement = new StatementOfAccountDto();
+                statement.setDepartmentId(item.getDepartmentId());
+                statement.setOrderIdList(Collections.singletonList(item.getId()));
+                statementOfAccountService.add(statement);
+
+                // 生产入库
+                inventoryFinishedService.productionWarehousing(Collections.singletonList(item.getId()));
+            });
+        }
+        if (!saveOrderSkuList.isEmpty()) {
+            orderSkuService.saveBatch(saveOrderSkuList);
+        }
+        if (!saveOrderSkuBomList.isEmpty()) {
+            orderSkuBomService.saveBatch(saveOrderSkuBomList);
+        }
+        if (!saveOrderSkuProductionCostList.isEmpty()) {
+            orderSkuProductionCostService.saveBatch(saveOrderSkuProductionCostList);
+        }
+        if (!orderPackageBomList.isEmpty()) {
+            orderPackageBomService.saveBatch(orderPackageBomList);
+        }
+
+    }
+
+    @Override
+    public void lockStorage(OrderContext context) {
+
+        Department department = context.getDepartment();
+
+        if (department == null || ObjectUtil.notEqual(department.getOrderMode(), "2")) {
+            return;
+        }
+
+        List<OrderInfo> saveOrderList = context.getSaveOrderList();
+        List<OrderSku> saveOrderSkuList = context.getSaveOrderSkuList();
+        Map<Long, BomSpecBo> bomSpecBoMap = context.getBomSpecBoMap();
+        List<OrderInfo> updateOrderList = context.getUpdateOrderList();
+        Map<Long, List<OrderSku>> existOrderSkuMap = context.getExistOrderSkuMap();
+
+        Map<Long, OrderInfo> orderMap = Stream.concat(saveOrderList.stream(), updateOrderList.stream()).collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
+
+        Map<Long, List<OrderSku>> orderSkuMap = Stream.concat(
+                        saveOrderSkuList.stream(),
+                        updateOrderList.stream().map(item -> existOrderSkuMap.get(item.getId())).flatMap(Collection::stream)
+                )
+                .filter(item -> orderMap.get(item.getOrderId()).getExceptionType().equals(OrderExceptionTypeEnum.NORMAL.getKey().toString()))
+                .filter(item -> Objects.equals(orderMap.get(item.getOrderId()).getStatus(), OrderStatusEnum.STOCK_PREPARATION.getKey()))
+                .filter(item -> Objects.equals(orderMap.get(item.getOrderId()).getLockStorage(), StatusConstant.NO))
+                .filter(item -> bomSpecBoMap.get(item.getBomSpecId()).getClassifyParentId().equals(1L))
+                .collect(Collectors.groupingBy(OrderSku::getOrderId));
+
+        orderSkuMap.forEach((orderId, orderSkuList) -> {
+            OrderInfo orderInfo = orderMap.get(orderId);
+            boolean lockStorageFlag = inventoryService.lockStorage(orderSkuList);
+
+            if (lockStorageFlag) {
+                orderInfo.setLockStorage(StatusConstant.YES);
+            } else {
+                orderInfo.setLockStorage(StatusConstant.NO);
+                addExceptionType(orderInfo, OrderExceptionTypeEnum.UNDERSTOCK);
+            }
+
+        });
+
+    }
+
+    @Override
+    public void unlockStorage(OrderContext context) {
+        List<OrderInfo> updateOrderList = context.getUpdateOrderList();
+        Map<Long, List<OrderSku>> existOrderSkuMap = context.getExistOrderSkuMap();
+        Map<Long, BomSpecBo> bomSpecBoMap = context.getBomSpecBoMap();
+
+        List<OrderSku> unlockStorageOrderSkuList = new ArrayList<>();
+
+        for (OrderInfo orderInfo : updateOrderList) {
+            if (ObjectUtil.equal(orderInfo.getExceptionType(), OrderExceptionTypeEnum.NORMAL.getKey().toString())
+                    || ObjectUtil.equal(orderInfo.getLockStorage(), StatusConstant.NO)) {
+                continue;
+            }
+
+            List<OrderSku> orderSkuList = existOrderSkuMap.get(orderInfo.getId())
+                    .stream()
+                    .filter(item -> {
+                        Long bomSpecId = item.getBomSpecId();
+                        BomSpecBo bomSpecBo = bomSpecBoMap.get(bomSpecId);
+                        if (bomSpecBo == null) {
+                            bomSpecBo = bomSpecService.getBomSpecBo(bomSpecId);
+                            bomSpecBoMap.put(bomSpecId, bomSpecBo);
+                        }
+                        return Objects.equals(bomSpecBo.getClassifyParentId(), 1L);
+                    })
+                    .collect(Collectors.toList());
+
+            unlockStorageOrderSkuList.addAll(orderSkuList);
+            orderInfo.setLockStorage(StatusConstant.NO);
+        }
+
+        inventoryService.unlockStorage(unlockStorageOrderSkuList);
+    }
+
+    /**
+     * 查询万里牛订单列表
+     */
+    private List<JSONObject> getWlnOrderList(String warehouseCode) {
+        long endTime = new Date().getTime();
+        long startTime;
+
+        OrderInfo orderInfo = orderInfoService.getOne(q -> q
+                .eq(OrderInfo::getWlnStorageCode, warehouseCode)
+                .orderByDesc(OrderInfo::getWlnModifyTimestamp));
+
+        List<JSONObject> list = new ArrayList<>();
+
+        if (orderInfo == null) {
+            int day = 7;
+            startTime = endTime - 1000 * 60 * 60 * 24 * day;
+
+            for (int i = 0; i < day - 1; i++) {
+                getOrderList(startTime, startTime + 1000 * 60 * 60 * 24, warehouseCode, list);
+                startTime += 1000 * 60 * 60 * 24;
+            }
+
+        } else {
+            startTime = orderInfo.getWlnModifyTimestamp() + 1;
+            if (endTime - startTime > 1000 * 60 * 60 * 24 * 7) {
+                startTime = endTime - 1000 * 60 * 60 * 24 * 7;
+            }
+            getOrderList(startTime, endTime, warehouseCode, list);
+        }
+
+        return list;
+    }
+
+    private void getOrderList(Long startTime, Long endTime, String warehouseCode, List<JSONObject> list) {
+        int page = 1;
+        int size;
+        do {
+            try {
+                List<JSONObject> itemList = WlnUtil.getOrderList(page, 200, startTime, endTime, warehouseCode);
+                page++;
+                size = itemList.size();
+                list.addAll(itemList);
+            } catch (Exception e) {
+                log.error("订单同步失败", e);
+                throw new ServiceException("订单同步失败");
+            }
+        } while (size >= 200);
+    }
+
+}