Bläddra i källkod

集采订单同步销售订单

ms-blue 1 månad sedan
förälder
incheckning
060d86ab2e

+ 5 - 0
src/main/java/com/jsh/erp/constants/ExceptionConstants.java

@@ -369,6 +369,10 @@ public class ExceptionConstants {
     public static final int MATERIAL_DEPOT_NOT_DECIMAL_CODE = 8000031;
     public static final String MATERIAL_DEPOT_NOT_DECIMAL_MSG = "第%s行仓库不存在";
 
+    //erp_sku 不存在
+    public static final int MATERIAL_ERP_SKU_NOT_DECIMAL_CODE = 8000032;
+    public static final String MATERIAL_ERP_SKU_NOT_DECIMAL_MSG = "商品erp_sku[%s]不存在";
+
     /**
      *  单据信息
      * type = 85
@@ -461,6 +465,7 @@ public class ExceptionConstants {
     public static final int DEPOT_HEAD_NOT_EXIST_CODE = 8500031;
     public static final String DEPOT_HEAD_NOT_EXIST_MSG = "抱歉,单据不存在";
 
+
     /**
      *  单据明细信息
      * type = 90

+ 4 - 3
src/main/java/com/jsh/erp/controller/OpenController.java

@@ -10,6 +10,7 @@ import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 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;
 
@@ -39,15 +40,15 @@ public class OpenController {
      */
     @ApiOperation(value = "获取商品系统sku,返回信息集采系统")
     @PostMapping(value = "/sync-system-sku")
-    public String syncSystemSku(String param) {
+    public String syncSystemSku(@RequestBody String param) {
         return syncTescoSystemService.syncSystemSku(param);
     }
 
 
     @ApiOperation(value = "同步集采订单-》销售订单")
     @PostMapping(value = "/sync-order")
-    public String syncOrder(String param){
-        return null;
+    public String syncOrder(@RequestBody String param){
+        return syncTescoSystemService.syncOrder(param);
     }
 
 

+ 2 - 0
src/main/java/com/jsh/erp/datasource/entities/Supplier.java

@@ -1,6 +1,7 @@
 package com.jsh.erp.datasource.entities;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
 
 import java.math.BigDecimal;
 
@@ -8,6 +9,7 @@ import java.math.BigDecimal;
  * 供应商/客户信息表实体类
  *
  */
+@Data
 @TableName("jsh_supplier")
 public class Supplier {
 

+ 1 - 0
src/main/java/com/jsh/erp/datasource/mappers/MaterialMapperEx.java

@@ -6,6 +6,7 @@ import org.apache.ibatis.annotations.Param;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Description

+ 87 - 0
src/main/java/com/jsh/erp/datasource/tesco/request/ErpXsddReqVO.java

@@ -0,0 +1,87 @@
+package com.jsh.erp.datasource.tesco.request;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Description TODO
+ * @Author MS.BLUE
+ * @Date 2025-04-14
+ */
+@Data
+public class ErpXsddReqVO {
+
+    /**
+     * 订单编号
+     */
+    private String orderSn;
+
+    /**
+     * 订单总额
+     */
+    private BigDecimal totalPrice ;
+
+    /**
+     * 客户信息
+     */
+    private Customer customer;
+
+    /**
+     * 订单商品列表
+     */
+    private List<OrderItem> items;
+
+    @Data
+    public static class Customer {
+        /**
+         * 客户名称
+         */
+        private String name;
+
+        /**
+         * 客户账号
+         */
+        private String account;
+
+        /**
+         * 收货人姓名
+         */
+        private String receiverName;
+
+        /**
+         * 收货人电话
+         */
+        private String receiverPhone;
+
+        /**
+         * 收货人地址
+         */
+        private String receiverAddress;
+    }
+
+    @Data
+    public static class OrderItem {
+        /**
+         * ERP SKU编号
+         */
+        private String erpSku;
+
+        /**
+         * 商品单价
+         */
+        private BigDecimal unitPrice;
+
+        /**
+         * 商品下单数量
+         */
+        private Integer quantity;
+
+        /**
+         * 商品实付价格
+         */
+        private BigDecimal price;
+    }
+}

+ 56 - 0
src/main/java/com/jsh/erp/datasource/vo/Material4UnitPrice.java

@@ -0,0 +1,56 @@
+package com.jsh.erp.datasource.vo;
+
+import com.jsh.erp.datasource.entities.Unit;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @Description TODO
+ * @Author MS.BLUE
+ * @Date 2025-04-15
+ */
+@Data
+public class Material4UnitPrice extends Unit {
+
+    /**
+     *基础单位 销售价格
+     */
+    private BigDecimal basicUnitPrice;
+
+    /**
+     *其他单位 销售价格
+     */
+    private BigDecimal otherUnitPrice;
+
+    /**
+     *其他单位2 销售价格
+     */
+    private BigDecimal otherUnitTwoPrice;
+
+    /**
+     *其他单位3 销售价格
+     */
+    private BigDecimal otherUnitThreePrice;
+
+    /**
+     *基础单位 基础数量
+     */
+    private BigDecimal basicUnitNumber;
+
+    /**
+     *其他单位 基础数量
+     */
+    private BigDecimal otherUnitNumber;
+
+    /**
+     *其他单位2 基础数量
+     */
+    private BigDecimal otherUnitTwoNumber;
+
+    /**
+     *其他单位3 基础数量
+     */
+    private BigDecimal otherUnitThreeNumber;
+
+}

+ 2 - 1
src/main/java/com/jsh/erp/filter/LogCostFilter.java

@@ -56,7 +56,8 @@ public class LogCostFilter implements Filter {
         }
         if (requestUrl != null && (requestUrl.contains("/doc.html") ||
             requestUrl.contains("/user/pdaLogin") ||
-            requestUrl.contains("/user/login") || requestUrl.contains("/user/register") || requestUrl.contains("/user/randomImage"))) {
+            requestUrl.contains("/user/login") || requestUrl.contains("/user/register") || requestUrl.contains("/user/randomImage")
+            ||requestUrl.contains("/open-api"))) {
             chain.doFilter(request, response);
             return;
         }

+ 13 - 0
src/main/java/com/jsh/erp/service/SupplierService.java

@@ -89,4 +89,17 @@ public interface SupplierService extends IService<Supplier> {
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     int batchSetAdvanceIn(String ids) throws Exception;
+
+    /**
+     * 根据类型 和 电话号码查询供应商/客户信息
+     * @param type
+     * @param telephone
+     * @return
+     */
+    Supplier getSupplierByPhone(String type,String telephone );
+
+    Supplier getCustomerByPhone(String telephone );
+
+    // 创建新客户
+    Supplier createCustomer(Supplier supplier);
 }

+ 431 - 76
src/main/java/com/jsh/erp/service/SyncTescoSystemService.java

@@ -1,14 +1,25 @@
 package com.jsh.erp.service;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.jsh.erp.constants.ExceptionConstants;
 import com.jsh.erp.datasource.entities.DepotHeadVo4Body;
 import com.jsh.erp.datasource.entities.MaterialVo4Unit;
+import com.jsh.erp.datasource.entities.Supplier;
+import com.jsh.erp.datasource.entities.Unit;
+import com.jsh.erp.datasource.tesco.request.ErpXsddReqVO;
 import com.jsh.erp.datasource.vo.DepotHeadXsddRequestVO;
 import com.jsh.erp.datasource.vo.DepotItemXsddRequestVO;
+import com.jsh.erp.datasource.vo.Material4UnitPrice;
+import com.jsh.erp.exception.BusinessRunTimeException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
@@ -38,6 +49,9 @@ public class SyncTescoSystemService {
     @Resource
     private SequenceService sequenceService;
 
+    @Resource
+    private SupplierService supplierService;
+
     public String syncSystemSku(String param) {
         logger.info("获取商品系统sku,返回信息集采系统 param:{}", param);
         JSONObject result = new JSONObject();
@@ -52,7 +66,7 @@ public class SyncTescoSystemService {
             }
 
             // 解析传入的JSON参数
-            JSONArray barCodeArray = JSONArray.parseArray(param);
+            JSONArray barCodeArray = JSON.parseArray(param);
             if (barCodeArray == null || barCodeArray.isEmpty()) {
                 result.put("code", 1);
                 result.put("msg", "参数格式错误");
@@ -82,13 +96,14 @@ public class SyncTescoSystemService {
                 result.put("msg", "未找到对应商品信息");
             }
         } catch (Exception e) {
+            e.printStackTrace();
             result.put("code", 1);
             result.put("msg", "系统异常,请稍后重试");
         }
 
         // 将数据数组放入返回结果
         result.put("data", dataArray);
-        logger.info("  result:{}", param);
+        logger.info("  result:{}", result);
         return result.toJSONString();
     }
 
@@ -118,39 +133,37 @@ public class SyncTescoSystemService {
         logger.info("同步集采订单-》销售订单 param:{}", param);
         JSONObject result = new JSONObject();
         try {
-            // 解析传入的JSON参数
-            JSONObject paramJson = JSONObject.parseObject(param);
-            if (paramJson == null || paramJson.isEmpty()) {
+            // 解析传入的JSON参数为 ErpXsddReqVO
+            ErpXsddReqVO erpXsddReqVO = JSON.parseObject(param, ErpXsddReqVO.class);
+            if (erpXsddReqVO == null) {
                 result.put("code", 1);
                 result.put("msg", "参数不能为空");
                 return result.toJSONString();
             }
 
             // 校验订单编号
-            String orderSn = paramJson.getString("orderSn");
-            if (orderSn == null || orderSn.isEmpty()) {
+            if (erpXsddReqVO.getOrderSn() == null || erpXsddReqVO.getOrderSn().isEmpty()) {
                 result.put("code", 1);
                 result.put("msg", "订单编号不能为空");
                 return result.toJSONString();
             }
 
             // 校验客户信息
-            JSONObject customer = paramJson.getJSONObject("customer");
-            if (customer == null || customer.isEmpty()) {
+            if (erpXsddReqVO.getCustomer() == null) {
                 result.put("code", 1);
                 result.put("msg", "客户信息不能为空");
                 return result.toJSONString();
             }
 
             // 校验订单商品信息
-            JSONArray itemArray = paramJson.getJSONArray("item");
-            if (itemArray == null || itemArray.isEmpty()) {
+            if (erpXsddReqVO.getItems() == null || erpXsddReqVO.getItems().isEmpty()) {
                 result.put("code", 1);
                 result.put("msg", "订单商品信息不能为空");
                 return result.toJSONString();
             }
 
-            buildOrderAndItem(paramJson, itemArray);
+            // 构建订单和商品信息
+            buildOrderAndItem(erpXsddReqVO);
 
             // 返回成功结果
             result.put("code", 0);
@@ -163,107 +176,449 @@ public class SyncTescoSystemService {
         return result.toJSONString();
     }
 
-    private void buildOrderAndItem(JSONObject orderJson, JSONArray itemJsonArray) throws Exception {
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    private void buildOrderAndItem(ErpXsddReqVO erpXsddReqVO) throws Exception {
+        // 1. 初始化订单基本信息
+        DepotHeadXsddRequestVO order = initSalesOrder(erpXsddReqVO);
+
+        // 2. 处理订单商品项
+        List<DepotItemXsddRequestVO> itemList = processOrderItems(erpXsddReqVO, order);
+
+        // 3. 提交订单
+        depotHeadService.syncOrderToXsdd(order, itemList);
+    }
+
+    private DepotHeadXsddRequestVO initSalesOrder(ErpXsddReqVO erpXsddReqVO) throws Exception {
         DepotHeadXsddRequestVO order = new DepotHeadXsddRequestVO();
         order.setType("其他");
         order.setSubType("销售订单");
-        String orderSn = orderJson.getString("orderSn");
+        order.setLinkTesco(erpXsddReqVO.getOrderSn());
+
+        ErpXsddReqVO.Customer customer = erpXsddReqVO.getCustomer();
+        // 根据手机号查询客户
+        Supplier supplier = supplierService.getCustomerByPhone(customer.getAccount());
+        if (supplier == null) {
+            // 如果客户不存在,创建新客户
+            supplier = new Supplier();
+            supplier.setSupplier(customer.getName());
+            supplier.setTelephone(customer.getAccount());
+            supplier.setContacts(customer.getReceiverName());
+            supplier.setPhoneNum(customer.getReceiverPhone());
+            supplier.setAddress(customer.getReceiverAddress());
+            supplier = supplierService.createCustomer(supplier);
+        }
 
+        // 绑定客户 ID
+        order.setOrganId(supplier.getId());
+        order.setReceiverName(customer.getReceiverName());
+        order.setReceiverPhone(customer.getReceiverPhone());
+        order.setReceiverAddress(customer.getReceiverAddress());
+        order.setRemark("集采同步订单");
         String number = sequenceService.buildOnlyNumber();
         String defaultNumber = "XSDD" + number;
         order.setDefaultNumber(defaultNumber);
         order.setNumber(defaultNumber);
         order.setCreateTime(new Date());
         order.setOperTime(new Date());
-        order.setOrganId(1L);// 供应商
-        order.setCreator(1L);// 创建人
-        order.setAccountId(1L);// 账户
+        order.setCreator(1L); // 创建人ID
+        order.setAccountId(1L); // 账户ID
         order.setChangeAmount(BigDecimal.ZERO);
         order.setBackAmount(BigDecimal.ZERO);
-        order.setTotalPrice(orderJson.getBigDecimal("totalPrice"));
+        order.setTotalPrice(erpXsddReqVO.getTotalPrice());
         order.setPayType("现付");
         order.setDiscount(BigDecimal.ZERO);
         order.setDiscountMoney(BigDecimal.ZERO);
-        order.setDiscountLastMoney(orderJson.getBigDecimal("totalPrice"));
+        order.setDiscountLastMoney(erpXsddReqVO.getTotalPrice());
         order.setStatus("0");
         order.setPurchaseStatus("0");
-        order.setSource("2");// 来源集采商城
+        order.setSource("2"); // 来源集采商城
         order.setTenantId(null);
         order.setDeleteFlag("0");
+        return order;
+    }
+
+    /**
+     * 处理订单商品项
+     */
+    private List<DepotItemXsddRequestVO> processOrderItems(ErpXsddReqVO erpXsddReqVO, DepotHeadXsddRequestVO order) throws Exception {
 
         List<DepotItemXsddRequestVO> itemList = new ArrayList<>();
+        List<ErpXsddReqVO.OrderItem> reqVOItems = erpXsddReqVO.getItems();
 
-        List<String> systemSkuList = itemJsonArray.stream().map(JSONObject.class::cast).map(json -> json.getString("erp_sku")).collect(Collectors.toList());
+        // 1. 获取所有商品信息
+        List<String> systemSkuList = reqVOItems.stream().map(ErpXsddReqVO.OrderItem::getErpSku).collect(Collectors.toList());
+        List<MaterialVo4Unit> materialList = materialService.getMaterialBySystemSku(systemSkuList);
+        Map<String, List<MaterialVo4Unit>> skuToMaterialMap = materialList.stream().collect(Collectors.groupingBy(MaterialVo4Unit::getSystemSku));
 
-        Map<String, JSONObject> skuToJsonMap = itemJsonArray.stream().map(JSONObject.class::cast).collect(Collectors.toMap(json -> json.getString("erp_sku"), json -> json));
+        // 2. 处理每个订单项
+        for (ErpXsddReqVO.OrderItem reqVOItem : reqVOItems) {
+            try {
+                processSingleOrderItem(reqVOItem, order, itemList, skuToMaterialMap);
+            } catch (Exception e) {
+                logger.error("处理订单项失败 erp_sku: {}: {}", reqVOItem.getErpSku(), e.getMessage());
+                throw e;
+            }
+        }
 
-        List<MaterialVo4Unit> materialList = materialService.getMaterialBySystemSku(systemSkuList);
+        return itemList;
+    }
 
-        Map<String, List<MaterialVo4Unit>> skuToMaterialMap = materialList.stream().collect(Collectors.groupingBy(MaterialVo4Unit::getSystemSku));
 
-        for (Map.Entry<String, JSONObject> entry : skuToJsonMap.entrySet()) {
-            String erpSku = entry.getKey(); // 获取 erp_sku
-            JSONObject itemJson = entry.getValue(); // 获取对应的 JSONObject
+    /**
+     * 处理单个订单项
+     */
+    private void processSingleOrderItem(ErpXsddReqVO.OrderItem reqVOItem, DepotHeadXsddRequestVO order, List<DepotItemXsddRequestVO> itemList, Map<String, List<MaterialVo4Unit>> skuToMaterialMap) throws Exception {
 
-            Integer quantity = itemJson.getInteger("quantity");
-            BigDecimal unitPrice = itemJson.getBigDecimal("unitPrice");
-            BigDecimal price = itemJson.getBigDecimal("price");
+        // 1. 参数校验
+        validateOrderItem(reqVOItem);
 
-            if (quantity == null || unitPrice == null || price == null) {
-                logger.warn("商品信息不完整,erp_sku: {}", erpSku);
+        // 2. 获取商品信息
+        List<MaterialVo4Unit> materials = skuToMaterialMap.get(reqVOItem.getErpSku());
+        if (CollectionUtils.isEmpty(materials)) {
+            throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ERP_SKU_NOT_DECIMAL_CODE, String.format(ExceptionConstants.MATERIAL_ERP_SKU_NOT_DECIMAL_MSG, reqVOItem.getErpSku()));
+        }
+
+        // 3. 获取单位信息
+        MaterialVo4Unit primaryMaterial = materials.get(0);
+        Material4UnitPrice material4UnitPrice = getMaterial4UnitPrice(primaryMaterial);
+
+        // 4. 匹配销售单位
+        UnitMatchResult matchResult = matchUnitAndCalculateBaseQuantity(reqVOItem.getUnitPrice(), BigDecimal.valueOf(reqVOItem.getQuantity()), material4UnitPrice);
+
+        // 5. 根据单位类型分配库存
+        if (matchResult.isLargeUnit()) {
+            allocateLargeUnitStock(reqVOItem, order, itemList, materials, matchResult, material4UnitPrice);
+        } else {
+            allocateBasicUnitStock(reqVOItem, order, itemList, materials, matchResult);
+        }
+    }
+
+    /**
+     * 分配大单位库存(不拆分配)
+     */
+    private void allocateLargeUnitStock(ErpXsddReqVO.OrderItem reqVOItem, DepotHeadXsddRequestVO order, List<DepotItemXsddRequestVO> itemList, List<MaterialVo4Unit> materials,
+        UnitMatchResult matchResult, Material4UnitPrice material4UnitPrice) throws Exception {
+
+        String orderUnit = matchResult.getMatchedUnit();
+        BigDecimal unitRatio = getUnitRatio(orderUnit, material4UnitPrice);
+        BigDecimal remainingOrderQty = matchResult.getOrderUnitQuantity();
+
+        // 分配库存
+        for (MaterialVo4Unit m : materials) {
+            if (remainingOrderQty.compareTo(BigDecimal.ZERO) <= 0)
+                break;
+
+            BigDecimal inventory = m.getInventory();
+            if (inventory.compareTo(unitRatio) < 0)
                 continue;
+
+            // 计算可分配数量(向下取整)
+            BigDecimal allocatableUnits = inventory.divideToIntegralValue(unitRatio).min(remainingOrderQty);
+
+            if (allocatableUnits.compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal allocBaseQty = allocatableUnits.multiply(unitRatio);
+
+                // 创建订单项
+                DepotItemXsddRequestVO item = createOrderItem(order, m, orderUnit, allocatableUnits, allocBaseQty, reqVOItem.getUnitPrice());
+                itemList.add(item);
+
+                // 更新库存
+                m.setInventory(inventory.subtract(allocBaseQty));
+
+                // 更新剩余需求
+                remainingOrderQty = remainingOrderQty.subtract(allocatableUnits);
+
+                logger.info("分配库存:批次[{}] 分配 {} {} (剩余需求: {})", m.getBatchNumber(), allocatableUnits.toPlainString(), orderUnit, remainingOrderQty.toPlainString());
             }
+        }
 
-            List<MaterialVo4Unit> materials = skuToMaterialMap.get(erpSku);
-
-            if (materials != null && !materials.isEmpty()) {
-                BigDecimal remainingQuantity = itemJson.getBigDecimal("quantity"); // 剩余数量
-                for (MaterialVo4Unit material : materials) {
-                    BigDecimal inventory = material.getInventory(); // 当前商品库存
-                    if (inventory.compareTo(BigDecimal.ZERO) <= 0) {
-                        continue; // 如果库存为0,跳过
-                    }
-
-                    DepotItemXsddRequestVO item = new DepotItemXsddRequestVO();
-                    item.setHeaderId(order.getId());
-                    item.setMaterialId(material.getId());
-                    item.setMaterialExtendId(material.getMeId());
-                    item.setMaterialUnit(material.getUnit());
-                    item.setSku(material.getSku());
-                    item.setDepotId(material.getDepotId());
-                    item.setTaxRate(BigDecimal.ONE);
-                    item.setTaxMoney(BigDecimal.ZERO);
-                    item.setBatchNumber("");
-                    item.setUnitPrice(unitPrice); // 设置单价
-                    if (inventory.compareTo(remainingQuantity) >= 0) {
-                        // 如果当前商品库存大于等于剩余数量,直接使用剩余数量
-                        item.setOperNumber(remainingQuantity);
-                        // 计算实付价格:单价 × 剩余数量
-                        BigDecimal taxLastMoney = itemJson.getBigDecimal("unitPrice").multiply(remainingQuantity);
-                        item.setTaxLastMoney(taxLastMoney);
-                        item.setAllPrice(taxLastMoney);
-                        itemList.add(item);
-                        break; // 结束循环
-                    } else {
-                        // 如果当前商品库存小于剩余数量,使用当前商品库存
-                        item.setOperNumber(inventory);
-                        // 计算实付价格:单价 × 剩余数量
-                        BigDecimal taxLastMoney = itemJson.getBigDecimal("unitPrice").multiply(remainingQuantity);
-                        item.setTaxLastMoney(taxLastMoney);
-                        item.setAllPrice(taxLastMoney);
-                        itemList.add(item);
-                        remainingQuantity = remainingQuantity.subtract(inventory); // 减少剩余数量
-                    }
-                }
+        // 检查是否完全分配
+        if (remainingOrderQty.compareTo(BigDecimal.ZERO) > 0) {
+            throw new RuntimeException(buildStockShortageMessage(reqVOItem.getErpSku(), matchResult.getOrderUnitQuantity(), remainingOrderQty, orderUnit, materials, true, // 是大单位
+                material4UnitPrice));
+        }
+    }
+
+    /**
+     * 分配基本单位库存
+     */
+    private void allocateBasicUnitStock(ErpXsddReqVO.OrderItem reqVOItem, DepotHeadXsddRequestVO order, List<DepotItemXsddRequestVO> itemList, List<MaterialVo4Unit> materials, UnitMatchResult matchResult) throws Exception {
+
+        // 获取基本参数
+        BigDecimal remainingQty = matchResult.getBaseQuantity(); // 剩余需求数量(基本单位)
+        String basicUnit = matchResult.getMatchedUnit(); // 基本单位名称
+        String erpSku = reqVOItem.getErpSku();
+        BigDecimal unitPrice = reqVOItem.getUnitPrice();
+
+        // 记录原始需求用于错误提示
+        BigDecimal originalQty = remainingQty;
+
+        // 遍历库存批次进行分配
+        for (MaterialVo4Unit m : materials) {
+            if (remainingQty.compareTo(BigDecimal.ZERO) <= 0) {
+                break; // 需求已满足
+            }
+
+            BigDecimal inventory = m.getInventory();
+            if (inventory.compareTo(BigDecimal.ZERO) <= 0) {
+                continue; // 跳过无库存批次
+            }
+
+            // 计算当前批次可分配数量
+            BigDecimal allocateQty = inventory.min(remainingQty);
+
+            // 创建订单明细项
+            DepotItemXsddRequestVO item = createOrderItem(order, m, basicUnit, allocateQty, allocateQty, unitPrice);
+            itemList.add(item);
+
+            // 更新库存
+            m.setInventory(inventory.subtract(allocateQty));
+
+            // 更新剩余需求
+            remainingQty = remainingQty.subtract(allocateQty);
+
+            logger.info("分配基本单位库存:批次[{}]  分配 {} {} (剩余需求: {})", m.getBatchNumber(), allocateQty.toPlainString(), basicUnit, remainingQty.toPlainString());
+        }
+
+        // 检查是否完全分配
+        if (remainingQty.compareTo(BigDecimal.ZERO) > 0) {
+            // 在allocateBasicUnitStock方法中调用
+            throw new RuntimeException(buildStockShortageMessage(erpSku, originalQty, remainingQty, basicUnit, materials, false, null));
+        }
+    }
+
+
+    /**
+     * 构建库存不足提示信息(通用方法,支持基本单位和大单位)
+     *
+     * @param erpSku 商品SKU
+     * @param totalQty 总需求数量
+     * @param remainingQty 剩余未分配数量
+     * @param orderUnit 订单单位
+     * @param materials 库存列表
+     * @param isLargeUnit 是否为大单位
+     * @param material4UnitPrice 单位价格信息(大单位时需要)
+     * @return 完整的库存不足提示信息
+     */
+    private String buildStockShortageMessage(String erpSku, BigDecimal totalQty, BigDecimal remainingQty, String orderUnit, List<MaterialVo4Unit> materials, boolean isLargeUnit, Material4UnitPrice material4UnitPrice) {
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("商品[").append(erpSku).append("]库存不足!\n");
+        sb.append("需求: ").append(totalQty.toPlainString()).append(" ").append(orderUnit).append("\n");
+        sb.append("未分配: ").append(remainingQty.toPlainString()).append(" ").append(orderUnit).append("\n");
+        sb.append("当前库存:\n");
+
+        // 获取基本单位名称
+        String basicUnit = isLargeUnit ? material4UnitPrice.getBasicUnit() : orderUnit;
+
+        materials.forEach(m -> {
+            // 计算当前批次的显示库存量
+            String stockDisplay;
+            if (isLargeUnit) {
+                BigDecimal unitRatio = getUnitRatio(orderUnit, material4UnitPrice);
+                BigDecimal stockInOrderUnit = m.getInventory().divideToIntegralValue(unitRatio);
+                stockDisplay = String.format("%s %s (%s %s)", stockInOrderUnit.toPlainString(), orderUnit, m.getInventory().toPlainString(), basicUnit);
             } else {
-                // 如果未找到对应的 MaterialVo4Unit,可以记录日志或处理异常
-                logger.warn("未找到 erp_sku: {} 对应的商品信息", erpSku);
+                stockDisplay = m.getInventory().toPlainString() + " " + basicUnit;
             }
+
+            sb.append(String.format("批次[%s] 生产日期[%s] - 库存: %s\n", m.getBatchNumber(), m.getProductionDate(), stockDisplay));
+        });
+
+        // 添加建议提示
+        if (isLargeUnit) {
+            sb.append("\n提示:").append(orderUnit).append("与").append(basicUnit).append("的换算比例为: 1").append(orderUnit).append("=").append(getUnitRatio(orderUnit, material4UnitPrice).toPlainString()).append(basicUnit);
         }
-        depotHeadService.syncOrderToXsdd(order, itemList);
+
+        return sb.toString();
+    }
+
+
+    /**
+     * 订单项参数校验
+     */
+    private void validateOrderItem(ErpXsddReqVO.OrderItem item) throws Exception {
+        if (item.getQuantity() == null || item.getQuantity() <= 0) {
+            throw new RuntimeException("商品数量必须大于0");
+        }
+        if (item.getUnitPrice() == null || item.getUnitPrice().compareTo(BigDecimal.ZERO) <= 0) {
+            throw new RuntimeException("商品单价必须大于0");
+        }
+        if (StringUtils.isBlank(item.getErpSku())) {
+            throw new RuntimeException("商品SKU不能为空");
+        }
+    }
+
+
+
+    
+
+    /**
+     * 创建订单明细项
+     */
+    private DepotItemXsddRequestVO createOrderItem(DepotHeadXsddRequestVO order, MaterialVo4Unit material, String unit, BigDecimal operNumber, BigDecimal basicNumber, BigDecimal unitPrice) {
+        DepotItemXsddRequestVO item = new DepotItemXsddRequestVO();
+        item.setHeaderId(order.getId());
+        item.setMaterialId(material.getId());
+        item.setMaterialExtendId(material.getMeId());
+        item.setMaterialUnit(unit);
+        item.setSku(material.getSku());
+        item.setDepotId(material.getDepotId());
+        item.setOperNumber(operNumber);
+        item.setBasicNumber(basicNumber);
+        item.setUnitPrice(unitPrice);
+        item.setTaxRate(BigDecimal.ONE);
+        item.setTaxMoney(BigDecimal.ZERO);
+        item.setBatchNumber("");
+        item.setTaxLastMoney(unitPrice.multiply(operNumber));
+        item.setAllPrice(unitPrice.multiply(operNumber));
+        return item;
+    }
+
+
+    private Material4UnitPrice getMaterial4UnitPrice(MaterialVo4Unit material) throws Exception {
+        Material4UnitPrice material4UnitPrice = new Material4UnitPrice();
+        Unit unitInfo = new Unit(); // 查询多单位信息
+        unitInfo.setBasicUnit(material.getCommodityUnit());
+        if(material.getUnitId() != null){
+            unitInfo = materialService.findUnit(material.getId());
+        }
+
+        BeanUtils.copyProperties(unitInfo, material4UnitPrice);
+
+        // 设置基础单位价格、基础数量
+        material4UnitPrice.setBasicUnitPrice(material.getWholesaleDecimal());
+        material4UnitPrice.setBasicUnitNumber(BigDecimal.ONE);
+
+        // 设置其他单位价格、其他数量
+        if (StringUtils.isNotEmpty(material4UnitPrice.getOtherUnit())) {
+            material4UnitPrice.setOtherUnitPrice(material.getWholesaleDecimal().multiply(material4UnitPrice.getRatio()));
+            material4UnitPrice.setOtherUnitNumber(material4UnitPrice.getRatio());
+        }
+
+        // 设置其他单位2价格、其他数量2
+        if (StringUtils.isNotEmpty(material4UnitPrice.getOtherUnitTwo())) {
+            material4UnitPrice.setOtherUnitTwoPrice(material.getWholesaleDecimal().multiply(material4UnitPrice.getRatioTwo()));
+            material4UnitPrice.setOtherUnitTwoNumber(material4UnitPrice.getRatioTwo());
+        }
+
+        // 设置其他单位3价格、其他数量3
+        if (StringUtils.isNotEmpty(material4UnitPrice.getOtherUnitThree())) {
+            material4UnitPrice.setOtherUnitThreePrice(material.getWholesaleDecimal().multiply(material4UnitPrice.getRatioThree()));
+            material4UnitPrice.setOtherUnitThreeNumber(material4UnitPrice.getRatioThree());
+        }
+        return material4UnitPrice;
+    }
+
+
+
+    /**
+     * 根据单价匹配单位并计算基本单位数量<br>
+     * 如果订单商品单价和商品最小单位单价相等,则使用最小单位, remainingQuantity = quantity<br>
+     * 如果订单商品单价和商品其他单位单价相等,则使用其他单位, remainingQuantity = quantity * material4UnitPrice.getRatio()<br>
+     * 如果订单商品单价和商品其他单位2单价相等,则使用其他单位2, remainingQuantity = quantity * material4UnitPrice.getRatioTwo()<br>
+     * 如果订单商品单价和商品其他单位3单价相等,则使用其他单位3, remainingQuantity = quantity * material4UnitPrice.getRatioThree()<br>
+     */
+    private UnitMatchResult matchUnitAndCalculateBaseQuantity(BigDecimal orderUnitPrice, BigDecimal orderQuantity, Material4UnitPrice material4UnitPrice) {
+        // 允许的价格误差范围
+        final BigDecimal PRICE_TOLERANCE = new BigDecimal("0.001");
+
+        // 1. 检查是否匹配基本单位价格
+        if (material4UnitPrice.getBasicUnitPrice() != null && orderUnitPrice.subtract(material4UnitPrice.getBasicUnitPrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
+            return new UnitMatchResult(material4UnitPrice.getBasicUnit(), orderQuantity, orderQuantity, false);
+        }
+
+        // 2. 检查是否匹配副单位价格
+        if (material4UnitPrice.getOtherUnitPrice() != null && orderUnitPrice.subtract(material4UnitPrice.getOtherUnitPrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
+            BigDecimal baseQuantity = orderQuantity.multiply(material4UnitPrice.getRatio());
+            return new UnitMatchResult(material4UnitPrice.getOtherUnit(), orderQuantity, baseQuantity, true);
+        }
+
+        // 3. 检查是否匹配副单位2价格
+        if (material4UnitPrice.getOtherUnitTwoPrice() != null && orderUnitPrice.subtract(material4UnitPrice.getOtherUnitTwoPrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
+            BigDecimal baseQuantity = orderQuantity.multiply(material4UnitPrice.getRatioTwo());
+            return new UnitMatchResult(material4UnitPrice.getOtherUnitTwo(), orderQuantity, baseQuantity, true);
+        }
+
+        // 4. 检查是否匹配副单位3价格
+        if (material4UnitPrice.getOtherUnitThreePrice() != null && orderUnitPrice.subtract(material4UnitPrice.getOtherUnitThreePrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
+            BigDecimal baseQuantity = orderQuantity.multiply(material4UnitPrice.getRatioThree());
+            return new UnitMatchResult(material4UnitPrice.getOtherUnitThree(), orderQuantity, baseQuantity, true);
+        }
+
+        // 5. 默认返回基本单位(如果无法匹配)
+        return new UnitMatchResult(material4UnitPrice.getBasicUnit(), orderQuantity, orderQuantity, false);
+    }
+
+
+
+    /**
+     * 将基本单位数量转换为订单单位数量
+     */
+    private BigDecimal convertToOrderUnitQuantity(BigDecimal baseQuantity, String orderUnit, Material4UnitPrice material4UnitPrice) {
+        if (orderUnit.equals(material4UnitPrice.getBasicUnit())) {
+            return baseQuantity;
+        } else if (orderUnit.equals(material4UnitPrice.getOtherUnit())) {
+            return baseQuantity.divide(material4UnitPrice.getRatio());
+        } else if (orderUnit.equals(material4UnitPrice.getOtherUnitTwo())) {
+            return baseQuantity.divide(material4UnitPrice.getRatioTwo());
+        } else if (orderUnit.equals(material4UnitPrice.getOtherUnitThree())) {
+            return baseQuantity.divide(material4UnitPrice.getRatioThree());
+        }
+        return baseQuantity;
     }
 
+    /**
+     * 获取单位的换算比例
+     */
+    private BigDecimal getUnitRatio(String unit, Material4UnitPrice material4UnitPrice) {
+        if (unit.equals(material4UnitPrice.getBasicUnit())) {
+            return BigDecimal.ONE;
+        } else if (unit.equals(material4UnitPrice.getOtherUnit())) {
+            return material4UnitPrice.getRatio();
+        } else if (unit.equals(material4UnitPrice.getOtherUnitTwo())) {
+            return material4UnitPrice.getRatioTwo();
+        } else if (unit.equals(material4UnitPrice.getOtherUnitThree())) {
+            return material4UnitPrice.getRatioThree();
+        }
+        return BigDecimal.ONE;
+    }
 
+    /**
+     * 单位匹配结果类
+     */
+    private static class UnitMatchResult {
+        private String matchedUnit;          // 匹配到的单位
+        private BigDecimal orderUnitQuantity; // 订单单位数量
+        private BigDecimal baseQuantity;     // 基本单位数量
+        private boolean isLargeUnit;         // 是否是大单位
+
+        public UnitMatchResult(String matchedUnit, BigDecimal orderUnitQuantity,
+                               BigDecimal baseQuantity, boolean isLargeUnit) {
+            this.matchedUnit = matchedUnit;
+            this.orderUnitQuantity = orderUnitQuantity;
+            this.baseQuantity = baseQuantity;
+            this.isLargeUnit = isLargeUnit;
+        }
+
+        // getter方法
+        public String getMatchedUnit() {
+            return matchedUnit;
+        }
+
+        public BigDecimal getBaseQuantity() {
+            return baseQuantity;
+        }
+
+        public boolean isLargeUnit() {
+            return isLargeUnit;
+        }
+
+        public BigDecimal getOrderUnitQuantity() {
+            return orderUnitQuantity;
+        }
+
+    }
 
 
 }

+ 8 - 0
src/main/java/com/jsh/erp/service/UserBusinessService.java

@@ -138,6 +138,14 @@ public class UserBusinessService {
         return ubValue;
     }
 
+    public String[] getUBValuByTypeAndKeyIdToArray(String type, String keyId) throws Exception {
+        String ubValue = getUBValueByTypeAndKeyId(type, keyId);
+        if (ubValue == null || ubValue.length() <= 2) { // "[x]"最小长度3
+            return new String[0];
+        }
+        return ubValue.substring(1, ubValue.length()-1).split("\\]\\[");
+    }
+
     public Long checkIsValueExist(String type, String keyId)throws Exception {
         UserBusinessExample example = new UserBusinessExample();
         example.createCriteria().andTypeEqualTo(type).andKeyIdEqualTo(keyId)

+ 10 - 1
src/main/java/com/jsh/erp/service/impl/DepotHeadServiceImpl.java

@@ -134,13 +134,17 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         try{
             HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
             Long userId = userService.getUserId(request);
-            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
+            Role role = userService.getRoleTypeByUserId(userId);
+            String priceLimit = role.getPriceLimit();
             String billCategory = getBillCategory(subType);
             String [] depotArray = getDepotArray(subType);
             String [] creatorArray = getCreatorArray();
             String [] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
             String [] purchaseStatusArray = StringUtil.isNotEmpty(purchaseStatus) ? purchaseStatus.split(",") : null;
             String [] organArray = getOrganArray(subType, purchaseStatus);
+            if ("采购订单".equals(subType) && "供应商".equals(role.getName())) {
+                organArray = getOrganArrayByCurrentUser(userId);
+            }
             //以销定购,查看全部数据
             creatorArray = StringUtil.isNotEmpty(purchaseStatus) ? null: creatorArray;
             Map<Long,String> personMap = personService.getPersonMap();
@@ -329,6 +333,11 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         return organArray;
     }
 
+    public String [] getOrganArrayByCurrentUser(Long userId) throws Exception {
+        String[] organArray = userBusinessService.getUBValuByTypeAndKeyIdToArray("UserSupplier", userId.toString());
+        return organArray;
+    }
+
     /**
      * 根据角色类型获取操作员
      * @return

+ 0 - 23
src/main/java/com/jsh/erp/service/impl/DepotItemServiceImpl.java

@@ -802,29 +802,6 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                 DepotItem depotItem = new DepotItem();
                 BeanUtils.copyProperties(item, depotItem);
 
-                // 以下进行单位换算
-                Unit unitInfo = materialService.findUnit(depotItem.getMaterialId()); // 查询多单位信息
-                if (depotItem.getOperNumber() != null) {
-                    // 获取子表单商品单位
-                    String unit = depotItem.getMaterialUnit() == null ? "" : depotItem.getMaterialUnit();
-                    BigDecimal oNumber = depotItem.getOperNumber();
-                    if (StringUtil.isNotEmpty(unitInfo.getName())) {
-                        String basicUnit = unitInfo.getBasicUnit(); // 基本单位
-                        if (unit.equals(basicUnit)) { // 如果等于基本单位
-                            depotItem.setBasicNumber(oNumber); // 数量一致
-                        } else if (unit.equals(unitInfo.getOtherUnit())) { // 如果等于副单位
-                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatio())); // 数量乘以比例
-                        } else if (unit.equals(unitInfo.getOtherUnitTwo())) { // 如果等于副单位2
-                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioTwo())); // 数量乘以比例
-                        } else if (unit.equals(unitInfo.getOtherUnitThree())) { // 如果等于副单位3
-                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioThree())); // 数量乘以比例
-                        } else {
-                            depotItem.setBasicNumber(oNumber); // 数量一致
-                        }
-                    } else {
-                        depotItem.setBasicNumber(oNumber); // 其他情况
-                    }
-                }
                 this.insertDepotItemWithObj(depotItem);
                 // 更新当前库存
                 updateCurrentStock(depotItem);

+ 23 - 0
src/main/java/com/jsh/erp/service/impl/SupplierServiceImpl.java

@@ -9,6 +9,7 @@ import com.jsh.erp.datasource.mappers.*;
 import com.jsh.erp.datasource.vo.DepotHeadVo4StatementAccount;
 import com.jsh.erp.exception.BusinessRunTimeException;
 import com.jsh.erp.exception.JshException;
+import com.jsh.erp.query.LambdaQueryWrapperX;
 import com.jsh.erp.service.*;
 import com.jsh.erp.utils.*;
 import jxl.Sheet;
@@ -17,6 +18,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.multipart.MultipartFile;
@@ -748,4 +750,25 @@ public class SupplierServiceImpl extends ServiceImpl<SupplierMapper, Supplier> i
         }
         return res;
     }
+
+    @Override
+    public Supplier getSupplierByPhone(String type, String telephone) {
+        List<Supplier> supplierList = supplierMapper.selectList(new LambdaQueryWrapperX<Supplier>().eq(Supplier::getType, type).eq(Supplier::getTelephone, telephone));
+        if(CollectionUtils.isEmpty(supplierList)){
+            return null;
+        }
+        return supplierList.get(0);
+    }
+
+    @Override
+    public Supplier getCustomerByPhone(String telephone) {
+        return getSupplierByPhone("客户", telephone);
+    }
+
+    @Override
+    public Supplier createCustomer(Supplier supplier) {
+        supplier.setType("客户");
+        supplierMapper.insertSelective(supplier);
+        return supplier;
+    }
 }

+ 1 - 1
src/main/resources/mapper_xml/DepotHeadMapper.xml

@@ -157,7 +157,7 @@
       #{source,jdbcType=VARCHAR}, #{linkNumber,jdbcType=VARCHAR}, #{linkApply,jdbcType=VARCHAR}, 
       #{tenantId,jdbcType=BIGINT}, #{deleteFlag,jdbcType=VARCHAR})
   </insert>
-  <insert id="insertSelective" parameterType="com.jsh.erp.datasource.entities.DepotHead">
+  <insert id="insertSelective" parameterType="com.jsh.erp.datasource.entities.DepotHead" useGeneratedKeys="true" keyProperty="id">
     insert into jsh_depot_head
     <trim prefix="(" suffix=")" suffixOverrides=",">
       <if test="id != null">

+ 35 - 12
src/main/resources/mapper_xml/MaterialMapperEx.xml

@@ -811,19 +811,42 @@
 
 
     <select id="getMaterialBySystemSku" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.entities.MaterialVo4Unit">
-        select m.*,u.name unit_name, me.id meId,me.bar_code m_bar_code, me.commodity_unit, me.purchase_decimal, me.commodity_decimal,me.inventory
-        me.wholesale_decimal, me.low_decimal, me.sku, me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.depot_id, me.position
-        from jsh_material m
-        left join jsh_material_extend me on m.id=me.material_id and ifnull(me.delete_Flag,'0') !='1'
-        left join jsh_unit u on m.unit_id=u.id and ifnull(u.delete_Flag,'0') !='1'
-        where
-        me.system_sku in (
-        <foreach collection="systemSkuArray" item="systemSku" separator=",">
-            #{systemSku}
-        </foreach>
+        WITH RankedExtend AS (
+            SELECT
+                me.*,
+                ROW_NUMBER() OVER (PARTITION BY me.material_id ORDER BY me.batch_number DESC) AS rn
+            FROM jsh_material_extend me
+            LEFT JOIN jsh_material m ON m.id = me.material_id
+            WHERE ifnull(me.delete_Flag, '0') != '1'
+              AND m.system_sku IN (
+                <foreach collection="systemSkuArray" item="systemSku" separator=",">
+                    #{systemSku}
+                </foreach>
+            )
         )
-        and ifnull(m.delete_flag,'0') !='1'
-        order by m.id desc, me.default_flag desc,me.production_date asc, me.batch_number asc
+        SELECT
+            m.*,
+            re.id AS meId,
+            re.bar_code AS m_bar_code,
+            re.commodity_unit,
+            re.purchase_decimal,
+            re.commodity_decimal,
+            re.wholesale_decimal,
+            re.low_decimal,
+            me.sku,
+            me.production_date,
+            me.expiry_num,
+            me.supplier_id,
+            me.bar_code,
+            me.batch_number,
+            me.inventory,
+            me.depot_id,
+            me.POSITION
+        FROM jsh_material m
+        LEFT JOIN RankedExtend re ON m.id = re.material_id AND re.rn = 1
+        LEFT JOIN jsh_material_extend me ON re.bar_code = me.bar_code
+        WHERE ifnull(m.delete_flag, '0') != '1' AND re.id IS NOT NULL
+        ORDER BY m.id DESC, me.default_flag DESC, me.production_date,me.batch_number ASC
     </select>
 
 </mapper>

+ 12 - 12
src/main/resources/mapper_xml/SupplierMapper.xml

@@ -31,7 +31,7 @@
     <result column="settlement_method" jdbcType="VARCHAR" property="settlementMethod" />
     <result column="billing_cycle_days" jdbcType="INTEGER" property="billingCycleDays" />
     <result column="procurement_contact" jdbcType="VARCHAR" property="procurementContact" />
-    <result column="delivery_days" jdbcType="INTEGER" property="deliverydays" />
+    <result column="delivery_days" jdbcType="INTEGER" property="deliveryDays" />
     <result column="invoice_type" jdbcType="VARCHAR" property="invoiceType" />
     <result column="contract_upload" jdbcType="VARCHAR" property="contractUpload" />
   </resultMap>
@@ -146,10 +146,10 @@
             #{bankName,jdbcType=VARCHAR}, #{accountNumber,jdbcType=VARCHAR}, #{taxRate,jdbcType=DECIMAL},
             #{sort,jdbcType=VARCHAR}, #{creator,jdbcType=BIGINT}, #{tenantId,jdbcType=BIGINT},
             #{deleteFlag,jdbcType=VARCHAR}, #{supplierLevel,jdbcType=VARCHAR}, #{settlementMethod,jdbcType=VARCHAR},
-            #{billingCycleDays,jdbcType=INTEGER}, #{procurementContact,jdbcType=VARCHAR}, #{deliverydays,jdbcType=INTEGER},
+            #{billingCycleDays,jdbcType=INTEGER}, #{procurementContact,jdbcType=VARCHAR}, #{deliveryDays,jdbcType=INTEGER},
             #{invoiceType,jdbcType=VARCHAR}, #{contractUpload,jdbcType=VARCHAR})
   </insert>
-  <insert id="insertSelective" parameterType="com.jsh.erp.datasource.entities.Supplier">
+  <insert id="insertSelective" parameterType="com.jsh.erp.datasource.entities.Supplier" useGeneratedKeys="true" keyProperty="id">
     insert into jsh_supplier
     <trim prefix="(" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -239,7 +239,7 @@
       <if test="procurementContact != null">
         procurement_contact,
       </if>
-      <if test="deliverydays != null">
+      <if test="deliveryDays != null">
         delivery_days,
       </if>
       <if test="invoiceType != null">
@@ -337,8 +337,8 @@
       <if test="procurementContact != null">
         #{procurementContact,jdbcType=VARCHAR},
       </if>
-      <if test="deliverydays != null">
-        #{deliverydays,jdbcType=INTEGER},
+      <if test="deliveryDays != null">
+        #{deliveryDays,jdbcType=INTEGER},
       </if>
       <if test="invoiceType != null">
         #{invoiceType,jdbcType=VARCHAR},
@@ -444,8 +444,8 @@
       <if test="record.procurementContact != null">
         procurement_contact = #{record.procurementContact,jdbcType=VARCHAR},
       </if>
-      <if test="record.deliverydays != null">
-        delivery_days = #{record.deliverydays,jdbcType=INTEGER},
+      <if test="record.deliveryDays != null">
+        delivery_days = #{record.deliveryDays,jdbcType=INTEGER},
       </if>
       <if test="record.invoiceType != null">
         invoice_type = #{record.invoiceType,jdbcType=VARCHAR},
@@ -489,7 +489,7 @@
       settlement_method = #{record.settlementMethod,jdbcType=VARCHAR},
       billing_cycle_days = #{record.billingCycleDays,jdbcType=INTEGER},
       procurement_contact = #{record.procurementContact,jdbcType=VARCHAR},
-      delivery_days = #{record.deliverydays,jdbcType=INTEGER},
+      delivery_days = #{record.deliveryDays,jdbcType=INTEGER},
       invoice_type = #{record.invoiceType,jdbcType=VARCHAR},
       contract_upload = #{record.contractUpload,jdbcType=VARCHAR}
     <if test="_parameter != null">
@@ -583,8 +583,8 @@
       <if test="procurementContact != null">
         procurement_contact = #{procurementContact,jdbcType=VARCHAR},
       </if>
-      <if test="deliverydays != null">
-        delivery_days = #{deliverydays,jdbcType=INTEGER},
+      <if test="deliveryDays != null">
+        delivery_days = #{deliveryDays,jdbcType=INTEGER},
       </if>
       <if test="invoiceType != null">
         invoice_type = #{invoiceType,jdbcType=VARCHAR},
@@ -625,7 +625,7 @@
       settlement_method = #{settlementMethod,jdbcType=VARCHAR},
       billing_cycle_days = #{billingCycleDays,jdbcType=INTEGER},
       procurement_contact = #{procurementContact,jdbcType=VARCHAR},
-      delivery_days = #{deliverydays,jdbcType=INTEGER},
+      delivery_days = #{deliveryDays,jdbcType=INTEGER},
       invoice_type = #{invoiceType,jdbcType=VARCHAR},
       contract_upload = #{contractUpload,jdbcType=VARCHAR}
     where id = #{id,jdbcType=BIGINT}