Browse Source

Merge remote-tracking branch 'origin/master_liushuang'

# Conflicts:
#	src/main/java/com/jsh/erp/datasource/mappers/MaterialMapperEx.java
#	src/main/java/com/jsh/erp/service/MaterialService.java
#	src/main/java/com/jsh/erp/service/impl/MaterialServiceImpl.java
13660505945 1 tháng trước cách đây
mục cha
commit
7d0519fdae

+ 2 - 2
jshERP-web/src/views/bill/modules/AssembleModal.vue

@@ -171,8 +171,8 @@ export default {
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
           {
-            title: '条码',
-            key: 'barCode',
+            title: '批次号',
+            key: 'batchNumber',
             width: '12%',
             type: FormTypes.popupJsh,
             kind: 'material',

+ 2 - 2
jshERP-web/src/views/bill/modules/DisassembleModal.vue

@@ -171,8 +171,8 @@ export default {
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
           {
-            title: '条码',
-            key: 'barCode',
+            title: '批次号',
+            key: 'batchNumber',
             width: '12%',
             type: FormTypes.popupJsh,
             kind: 'material',

+ 24 - 3
jshERP-web/src/views/bill/modules/SaleOrderModal.vue

@@ -282,8 +282,26 @@
               />
             </a-form-item>
           </a-col>
-          <a-col :lg="6" :md="12" :sm="24"> </a-col>
-          <a-col :lg="6" :md="12" :sm="24"> </a-col>
+          <a-col :lg="6" :md="12" :sm="24">
+            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="收货人" data-step="10">
+              <a-input placeholder="请输入收货人" v-decorator.trim="['receiverName']" :readOnly="true" />
+            </a-form-item>
+          </a-col>
+          <a-col :lg="6" :md="12" :sm="24">
+            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="收货人电话" data-step="10">
+              <a-input placeholder="请输入收货人电话" v-decorator.trim="['receiverPhone']" :readOnly="true" />
+            </a-form-item>
+          </a-col>
+          <a-col :lg="6" :md="12" :sm="24">
+            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="收货地址" data-step="8">
+              <a-input
+                style="width: 80%"
+                placeholder="请输入收货地址"
+                v-decorator.trim="['receiverAddress']"
+                :readOnly="true"
+              />
+            </a-form-item>
+          </a-col>
         </a-row>
         <a-row class="form-row" :gutter="24">
           <a-col :lg="6" :md="12" :sm="24">
@@ -513,7 +531,10 @@ export default {
               'discountLastMoney',
               'accountId',
               'changeAmount',
-              'salesMan'
+              'salesMan',
+              'receiverName',
+              'receiverPhone',
+              'receiverAddress'
             )
           )
         })

+ 26 - 5
jshERP-web/src/views/bill/modules/SaleOutModal.vue

@@ -339,9 +339,21 @@
               />
             </a-form-item>
           </a-col>
-          <a-col :lg="6" :md="12" :sm="24"> </a-col>
-          <a-col :lg="6" :md="12" :sm="24"> </a-col>
-          <a-col :lg="6" :md="12" :sm="24"> </a-col>
+          <a-col :lg="6" :md="12" :sm="24">
+            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="收货人" data-step="10">
+              <a-input placeholder="请输入收货人" v-decorator="['receiverName']" :readOnly="true" />
+            </a-form-item>
+          </a-col>
+          <a-col :lg="6" :md="12" :sm="24">
+            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="收货人电话" data-step="10">
+              <a-input placeholder="请输入收货人电话" v-decorator="['receiverPhone']" :readOnly="true" />
+            </a-form-item>
+          </a-col>
+          <a-col :lg="6" :md="12" :sm="24">
+            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="收货地址" data-step="10">
+              <a-input placeholder="请输入收货地址" v-decorator="['receiverAddress']" :readOnly="true" />
+            </a-form-item>
+          </a-col>
         </a-row>
         <a-row class="form-row" :gutter="24">
           <a-col :lg="6" :md="12" :sm="24">
@@ -640,7 +652,10 @@ export default {
               'deposit',
               'changeAmount',
               'debt',
-              'salesMan'
+              'salesMan',
+              'receiverName',
+              'receiverPhone',
+              'receiverAddress'
             )
           )
         })
@@ -721,7 +736,10 @@ export default {
       remark,
       depotId,
       accountId,
-      salesMan
+      salesMan,
+      receiverName,
+      receiverPhone,
+      receiverAddress
     ) {
       let that = this
       this.rowCanEdit = false
@@ -769,6 +787,9 @@ export default {
             changeAmount: changeAmount,
             accountId: accountId,
             remark: remark,
+            receiverName,
+            receiverPhone,
+            receiverAddress,
           })
           this.personList.value = salesMan
         })

+ 13 - 1
jshERP-web/src/views/system/UserList.vue

@@ -53,6 +53,10 @@
               <a v-if="btnEnableList.indexOf(1) > -1 && customerFlag === '1'" @click="btnSetCustomer(record)"
                 >分配客户</a
               >
+              <a-divider v-if="btnEnableList.indexOf(1) > -1 && depotFlag === '1'" type="vertical" />
+              <a v-if="btnEnableList.indexOf(1) > -1 && customerFlag === '1'" @click="btnSetSupplier(record)"
+                >分配供应商</a
+              >
               <a-divider v-if="btnEnableList.indexOf(1) > -1 && customerFlag === '1'" type="vertical" />
               <a @click="handleEdit(record)">编辑</a>
               <a-divider v-if="btnEnableList.indexOf(1) > -1" type="vertical" />
@@ -79,6 +83,7 @@
         <user-modal ref="modalForm" @ok="modalFormOk"></user-modal>
         <user-depot-modal ref="userDepotModal" @ok="modalFormOk"></user-depot-modal>
         <user-customer-modal ref="userCustomerModal" @ok="modalFormOk"></user-customer-modal>
+        <user-supplier-modal ref="userSupplierModal" @ok="modalFormOk"></user-supplier-modal>
       </a-card>
     </a-col>
   </a-row>
@@ -92,6 +97,7 @@ import { postAction } from '@/api/manage'
 import { getCurrentSystemConfig } from '@/api/api'
 import { JeecgListMixin } from '@/mixins/JeecgListMixin'
 import JInput from '@/components/jeecg/JInput'
+import UserSupplierModal from './modules/userSupplierModal.vue'
 export default {
   name: 'UserList',
   mixins: [JeecgListMixin],
@@ -100,6 +106,7 @@ export default {
     UserDepotModal,
     UserCustomerModal,
     JInput,
+    UserSupplierModal,
   },
   data() {
     return {
@@ -129,7 +136,7 @@ export default {
           dataIndex: 'action',
           scopedSlots: { customRender: 'action' },
           align: 'center',
-          width: 200,
+          width: 260,
         },
         { title: '登录名称', dataIndex: 'loginName', width: 100, align: 'left' },
         { title: '用户姓名', dataIndex: 'username', width: 100, align: 'left' },
@@ -206,6 +213,11 @@ export default {
       this.$refs.userCustomerModal.title = '分配客户给:' + record.username
       this.$refs.userCustomerModal.disableSubmit = false
     },
+    btnSetSupplier(record) {
+      this.$refs.userSupplierModal.edit(record)
+      this.$refs.userSupplierModal.title = '分配供应商给:' + record.username
+      this.$refs.userSupplierModal.disableSubmit = false
+    },
   },
 }
 </script>

+ 4 - 1
jshERP-web/src/views/system/modules/CustomerModal.vue

@@ -36,7 +36,7 @@
           <a-row class="form-row" :gutter="24">
             <a-col :span="24 / 2">
               <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="手机号码">
-                <a-input placeholder="请输入手机号码" v-decorator.trim="['telephone']" />
+                <a-input placeholder="请输入手机号码" v-decorator.trim="['telephone', validatorRules.telephone]" />
               </a-form-item>
             </a-col>
             <a-col :span="24 / 2">
@@ -130,6 +130,9 @@ export default {
       confirmLoading: false,
       form: this.$form.createForm(this),
       validatorRules: {
+        telephone: {
+          rules: [{ required: true, message: '请输入手机号!' }],
+        },
         supplier: {
           rules: [
             { required: true, message: '请输入名称!' },

+ 217 - 0
jshERP-web/src/views/system/modules/userSupplierModal.vue

@@ -0,0 +1,217 @@
+<template>
+  <div ref="container">
+    <a-modal
+      :title="title"
+      :width="800"
+      :visible="visible"
+      :confirmLoading="confirmLoading"
+      :getContainer="() => $refs.container"
+      :maskStyle="{ top: '93px', left: '154px' }"
+      :wrapClassName="wrapClassNameInfo()"
+      :mask="isDesktop()"
+      :maskClosable="false"
+      @ok="handleOk"
+      @cancel="handleCancel"
+      cancelText="取消"
+      okText="保存"
+      style="top: 5%; height: 95%"
+    >
+      <a-spin :spinning="confirmLoading">
+        <div class="drawer-bootom-button">
+          <a-dropdown :trigger="['click']" placement="topCenter">
+            <a-menu slot="overlay">
+              <a-menu-item key="1" @click="switchCheckStrictly(1)">父子关联</a-menu-item>
+              <a-menu-item key="2" @click="switchCheckStrictly(2)">取消关联</a-menu-item>
+              <a-menu-item key="3" @click="checkALL">全部勾选</a-menu-item>
+              <a-menu-item key="4" @click="cancelCheckALL">取消全选</a-menu-item>
+              <a-menu-item key="5" @click="expandAll">展开所有</a-menu-item>
+              <a-menu-item key="6" @click="closeAll">合并所有</a-menu-item>
+            </a-menu>
+            <a-button> 树操作 <a-icon type="up" /> </a-button>
+          </a-dropdown>
+        </div>
+        <a-col :md="10" :sm="24">
+          <template>
+            <a-tree
+              checkable
+              multiple
+              @check="onCheck"
+              :selectedKeys="selectedKeys"
+              :checkedKeys="checkedKeys"
+              :treeData="roleFunctionTree"
+              :checkStrictly="checkStrictly"
+              :expandedKeys="iExpandedKeys"
+              :autoExpandParent="true"
+              @expand="onExpand"
+            />
+          </template>
+        </a-col>
+      </a-spin>
+    </a-modal>
+  </div>
+</template>
+<script>
+import pick from 'lodash.pick'
+import { mixinDevice } from '@/utils/mixin'
+import { addUserBusiness, editUserBusiness, checkUserBusiness } from '@/api/api'
+import { getAction } from '../../../api/manage'
+export default {
+  name: 'UserSupplierModal',
+  mixins: [mixinDevice],
+  data() {
+    return {
+      title: '操作',
+      visible: false,
+      model: {},
+      roleId: 0,
+      iExpandedKeys: [],
+      roleFunctionTree: [],
+      checkedKeys: [],
+      selectedKeys: [],
+      checkStrictly: false,
+      hiding: true,
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      form: this.$form.createForm(this),
+    }
+  },
+  created() {},
+  methods: {
+    edit(record) {
+      this.form.resetFields()
+      this.model = Object.assign({}, {})
+      this.visible = true
+      this.$nextTick(() => {
+        this.form.setFieldsValue(pick(this.model, 'name', 'type', 'description'))
+      })
+      this.roleId = record.id
+      this.checkedKeys = []
+      this.loadTree(record.id)
+    },
+    close() {
+      this.$emit('close')
+      this.visible = false
+    },
+    handleOk() {
+      const that = this
+      // 触发表单验证
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          that.confirmLoading = true
+          let formData = Object.assign(this.model, values)
+          formData.type = 'UserSupplier'
+          formData.keyId = this.roleId
+          formData.value = this.checkedKeys
+          let obj
+          checkUserBusiness({ type: 'UserSupplier', keyId: this.roleId }).then((res) => {
+            if (res.data && res.data.id) {
+              formData.id = res.data.id
+              obj = editUserBusiness(formData)
+            } else {
+              obj = addUserBusiness(formData)
+            }
+            obj
+              .then((res) => {
+                if (res.code === 200) {
+                  that.$emit('ok')
+                } else {
+                  that.$message.warning(res.data.message)
+                }
+              })
+              .finally(() => {
+                that.confirmLoading = false
+                that.close()
+              })
+          })
+        }
+      })
+    },
+    handleCancel() {
+      this.close()
+    },
+    loadTree(id) {
+      let that = this
+      that.treeData = []
+      that.roleFunctionTree = []
+      let params = {}
+      params.id = ''
+      getAction('/supplier/findUserSupplier?UBType=UserSupplier&UBKeyId=' + id).then((res) => {
+        if (res) {
+          //机构全选后,再添加机构,选中数量增多
+          this.allTreeKeys = []
+          for (let i = 0; i < res.length; i++) {
+            let temp = res[i]
+            that.treeData.push(temp)
+            that.roleFunctionTree.push(temp)
+            that.setThisExpandedKeys(temp)
+            that.getAllKeys(temp)
+          }
+          console.log(JSON.stringify(this.checkedKeys))
+          this.loading = false
+        }
+      })
+    },
+    onCheck(checkedKeys, info) {
+      console.log('onCheck', checkedKeys, info)
+      this.hiding = false
+      if (this.checkStrictly) {
+        this.checkedKeys = checkedKeys.checked
+      } else {
+        this.checkedKeys = checkedKeys
+      }
+    },
+    setThisExpandedKeys(node) {
+      if (node.checked == true) {
+        this.checkedKeys.push(node.key)
+      }
+      if (node.children && node.children.length > 0) {
+        this.iExpandedKeys.push(node.key)
+        for (let a = 0; a < node.children.length; a++) {
+          this.setThisExpandedKeys(node.children[a])
+        }
+      }
+    },
+    getAllKeys(node) {
+      // console.log('node',node);
+      this.allTreeKeys.push(node.key)
+      if (node.children && node.children.length > 0) {
+        for (let a = 0; a < node.children.length; a++) {
+          this.getAllKeys(node.children[a])
+        }
+      }
+    },
+    expandAll() {
+      this.iExpandedKeys = this.allTreeKeys
+    },
+    closeAll() {
+      this.iExpandedKeys = []
+    },
+    checkALL() {
+      this.checkStriccheckStrictlytly = false
+      this.checkedKeys = this.allTreeKeys
+    },
+    cancelCheckALL() {
+      this.checkedKeys = []
+    },
+    switchCheckStrictly(v) {
+      if (v == 1) {
+        this.checkStrictly = false
+      } else if (v == 2) {
+        this.checkStrictly = true
+      }
+    },
+    onExpand(expandedKeys) {
+      console.log('onExpand', expandedKeys)
+      this.iExpandedKeys = expandedKeys
+    },
+  },
+}
+</script>
+<style scoped></style>

+ 11 - 0
src/main/java/com/jsh/erp/controller/OpenController.java

@@ -51,6 +51,17 @@ public class OpenController {
         return syncTescoSystemService.syncOrder(param);
     }
 
+    @ApiOperation(value = "同步集采库存")
+    @PostMapping(value = "/sync-tesco-stock")
+    public String sycnTescoStock(@RequestBody List<Long> mIdList){
+        return syncTescoSystemService.sycnTescoStock(mIdList);
+    }
+
+    @PostMapping(value = "/sync-tesco-saleprice")
+    public String sycnTescoSalePrice(@RequestBody List<Long> mIdList){
+        return syncTescoSystemService.sycnTescoSalePrice(mIdList);
+    }
+
 
 
 }

+ 3 - 0
src/main/java/com/jsh/erp/datasource/mappers/MaterialCurrentStockMapperEx.java

@@ -1,6 +1,7 @@
 package com.jsh.erp.datasource.mappers;
 
 import com.jsh.erp.datasource.entities.MaterialCurrentStock;
+import com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku;
 import org.apache.ibatis.annotations.Param;
 
 import java.math.BigDecimal;
@@ -20,4 +21,6 @@ public interface MaterialCurrentStockMapperEx {
     BigDecimal getCurrentUnitPriceByMId(@Param("materialId") Long materialId);
 
     void batchDeleteByDepots(@Param("ids") String ids[]);
+
+    List<MaterialCurrentStock4SystemSku> getCurrentStockMapByMdIdList(@Param("materialIdList") List<Long> materialIdList);
 }

+ 143 - 0
src/main/java/com/jsh/erp/datasource/vo/MaterialCurrentStock4SystemSku.java

@@ -0,0 +1,143 @@
+package com.jsh.erp.datasource.vo;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @Description TODO
+ * @Author MS.BLUE
+ * @Date 2025-04-16
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL) // 序列化时忽略null
+@JsonIgnoreProperties(ignoreUnknown = true)// 反序列化时忽略未知属性
+public class MaterialCurrentStock4SystemSku {
+
+    /**
+     * 商品id
+     */
+    private Long mId;
+
+    /**
+     * 商品名称
+     */
+    private String mName;
+
+    /**
+     * 商品单位-单个单位
+     */
+    private String unit;
+
+    /**
+     * 多单位商品
+     */
+
+    private Long unitId;
+
+    /**
+     * 是否是多单位商品
+     */
+    private boolean isLargeUnit;
+
+    /**
+     * 系统商品编码
+     */
+    private String systemSku;
+
+    /**
+     * 基础单位
+     */
+    private String basicUnit;
+
+    /**
+     * 其他单位
+     */
+    private String otherUnit;
+
+    /**
+     * 其他单位2
+     */
+    private String otherUnitTwo;
+
+    /**
+     * 其他单位3
+     */
+    private String otherUnitThree;
+
+    /**
+     * 基础单位-总库存
+     */
+    private BigDecimal basicUnitTotalStock;
+
+    /**
+     * 其他单位-总库存
+     * =
+     * {@link #basicUnitTotalStock}
+     * ÷{@link #ratio}
+     */
+    private BigDecimal otherUnitTotalStock;
+
+    /**
+     * 其他单位2-总库存
+     * =
+     * {@link #basicUnitTotalStock}
+     * ÷{@link #ratioTwo}
+     */
+    private BigDecimal otherUnitTwoTotalStock;
+
+    /**
+     * 其他单位3-总库存
+     * =
+     * {@link #basicUnitTotalStock}
+     * ÷{@link #ratioThree}
+     */
+    private BigDecimal otherUnitThreeTotalStock;
+
+    /**
+     * 其他单位-比率
+     */
+    private BigDecimal ratio;
+
+    /**
+     * 其他单位2-比率
+     */
+    private BigDecimal ratioTwo;
+
+    /**
+     * 其他单位3-比率
+     */
+    private BigDecimal ratioThree;
+
+
+    /**
+     * 基础单位-销售价格
+     */
+    private BigDecimal basicUnitSalePrice;
+
+    /**
+     * 其他单位-销售价格
+     * =
+     * {@link #basicUnitSalePrice}
+     * * {@link #ratio}
+     */
+    private BigDecimal otherUnitSalePrice;
+
+    /**
+     * 其他单位2-销售价格
+     * =
+     * {@link #basicUnitSalePrice}
+     * * {@link #ratioTwo}
+     */
+    private BigDecimal otherUnitTwoSalePrice;
+
+    /**
+     * 其他单位3-销售价格
+     * =
+     * {@link #basicUnitSalePrice}
+     * * {@link #ratioThree}
+     */
+    private BigDecimal otherUnitThreeSalePrice;
+}

+ 130 - 3
src/main/java/com/jsh/erp/service/SyncTescoSystemService.java

@@ -4,31 +4,36 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
 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.mappers.MaterialCurrentStockMapperEx;
 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.datasource.vo.MaterialCurrentStock4SystemSku;
 import com.jsh.erp.exception.BusinessRunTimeException;
+import com.jsh.erp.utils.HttpClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * @Description TODO
@@ -52,6 +57,15 @@ public class SyncTescoSystemService {
     @Resource
     private SupplierService supplierService;
 
+    @Resource
+    private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
+
+    @Value("${tesco.sycnErpMaterialStockUrl}")
+    private String sycnErpMaterialStockUrl;
+
+    @Value("${tesco.sycnErpMaterialPriceUrl}")
+    private String sycnErpMaterialPriceUrl;
+
     public String syncSystemSku(String param) {
         logger.info("获取商品系统sku,返回信息集采系统 param:{}", param);
         JSONObject result = new JSONObject();
@@ -176,6 +190,118 @@ public class SyncTescoSystemService {
         return result.toJSONString();
     }
 
+    public String sycnTescoStock(Long mId){
+        return sycnTescoStock(Arrays.asList(mId));
+    }
+
+    public String sycnTescoStock(List<Long> mIdList) {
+        List<MaterialCurrentStock4SystemSku> stockList = materialCurrentStockMapperEx.getCurrentStockMapByMdIdList(mIdList);
+        if (!CollectionUtils.isEmpty(stockList)) {
+            try {
+                for (MaterialCurrentStock4SystemSku stock : stockList) {
+                    Unit unitInfo = new Unit(); // 查询多单位信息
+                    stock.setBasicUnit(stock.getUnit());
+                    stock.setBasicUnitTotalStock(stock.getBasicUnitTotalStock().setScale(0, RoundingMode.DOWN));
+                    if (stock.getUnitId() != null) {
+                        unitInfo = materialService.findUnit(stock.getMId());
+                        stock.setBasicUnit(unitInfo.getBasicUnit());
+                        stock.setLargeUnit(true);
+                        processOtherUnitStock(stock, unitInfo);
+                    }
+                }
+                String jsonParam = new ObjectMapper().writeValueAsString(stockList);
+                logger.info("同步集采库存请求参数:{}", jsonParam);
+                String response = HttpClient.httpPost(sycnErpMaterialStockUrl, jsonParam);
+                logger.info("同步集采库存响应:{}", response);
+                return jsonParam;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+        }
+        return null;
+    }
+
+    private void processOtherUnitStock(MaterialCurrentStock4SystemSku stock, Unit unitInfo) {
+        if (StringUtils.isNotEmpty(unitInfo.getOtherUnit())) {
+            BigDecimal otherUnitTotalStock = stock.getBasicUnitTotalStock().divide(unitInfo.getRatio(), 0, RoundingMode.DOWN);
+            String otherUnitStr = "1" + unitInfo.getOtherUnit() + "=" + unitInfo.getRatio().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
+            stock.setOtherUnit(otherUnitStr);
+            stock.setRatio(unitInfo.getRatio().setScale(0, RoundingMode.DOWN));
+            stock.setOtherUnitTotalStock(otherUnitTotalStock);
+
+            if (StringUtils.isNotEmpty(unitInfo.getOtherUnitTwo())) {
+                BigDecimal otherUnitTwoTotalStock = stock.getBasicUnitTotalStock().divide(unitInfo.getRatioTwo(), 0, RoundingMode.DOWN);
+                String otherUnitTwoStr = "1" + unitInfo.getOtherUnitTwo() + "=" + unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
+                stock.setOtherUnitTwo(otherUnitTwoStr);
+                stock.setRatioTwo(unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN));
+                stock.setOtherUnitTwoTotalStock(otherUnitTwoTotalStock);
+
+                if (StringUtils.isNotEmpty(unitInfo.getOtherUnitThree())) {
+                    BigDecimal otherUnitThreeTotalStock = stock.getBasicUnitTotalStock().divide(unitInfo.getRatioThree(), 0, RoundingMode.DOWN);
+                    String otherUnitThreeStr = "1" + unitInfo.getOtherUnitThree() + "=" + unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
+                    stock.setOtherUnitTwo(otherUnitThreeStr);
+                    stock.setRatioThree(unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN));
+                    stock.setOtherUnitThreeTotalStock(otherUnitThreeTotalStock);
+                }
+            }
+        }
+    }
+
+    public String sycnTescoSalePrice(List<Long> mIdList) {
+        try {
+            List<MaterialCurrentStock4SystemSku> mList = materialService.getMaterialCurrentPriceByIdList(mIdList);
+            if (!CollectionUtils.isEmpty(mList)) {
+                for (MaterialCurrentStock4SystemSku material : mList){
+                    Unit unitInfo = new Unit(); // 查询多单位信息
+                    material.setBasicUnit(material.getUnit());
+                    if (material.getUnitId() != null) {
+                        unitInfo = materialService.findUnit(material.getMId());
+                        material.setBasicUnit(unitInfo.getBasicUnit());
+                        material.setLargeUnit(true);
+
+                        processOtherUnitSalePrice(material, unitInfo);
+                    }
+                }
+
+                String jsonParam = new ObjectMapper().writeValueAsString(mList);
+                logger.info("同步集采销售价格请求参数:{}", jsonParam);
+                String response = HttpClient.httpPost(sycnErpMaterialPriceUrl, jsonParam);
+                logger.info("同步集采销售价格响应:{}", response);
+                return jsonParam;
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return null;
+    }
+
+    private void processOtherUnitSalePrice(MaterialCurrentStock4SystemSku stock, Unit unitInfo) {
+        if (StringUtils.isNotEmpty(unitInfo.getOtherUnit())) {
+            BigDecimal otherUnitSalePrice = stock.getBasicUnitSalePrice().multiply(unitInfo.getRatio());
+            String otherUnitStr = "1" + unitInfo.getOtherUnit() + "=" + unitInfo.getRatio().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
+            stock.setOtherUnit(otherUnitStr);
+            stock.setRatio(unitInfo.getRatio().setScale(0, RoundingMode.DOWN));
+            stock.setOtherUnitSalePrice(otherUnitSalePrice);
+
+            if (StringUtils.isNotEmpty(unitInfo.getOtherUnitTwo())) {
+                BigDecimal otherUnitTwoSalePrice = stock.getBasicUnitSalePrice().multiply(unitInfo.getRatioTwo());
+                String otherUnitTwoStr = "1" + unitInfo.getOtherUnitTwo() + "=" + unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
+                stock.setOtherUnitTwo(otherUnitTwoStr);
+                stock.setRatioTwo(unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN));
+                stock.setOtherUnitTwoSalePrice(otherUnitTwoSalePrice);
+
+                if (StringUtils.isNotEmpty(unitInfo.getOtherUnitThree())) {
+                    BigDecimal otherUnitThreeSalePrice = stock.getBasicUnitSalePrice().multiply(unitInfo.getRatioThree());
+                    String otherUnitThreeStr = "1" + unitInfo.getOtherUnitThree() + "=" + unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
+                    stock.setOtherUnitTwo(otherUnitThreeStr);
+                    stock.setRatioThree(unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN));
+                    stock.setOtherUnitThreeSalePrice(otherUnitThreeSalePrice);
+                }
+            }
+        }
+    }
+
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     private void buildOrderAndItem(ErpXsddReqVO erpXsddReqVO) throws Exception {
         // 1. 初始化订单基本信息
@@ -200,6 +326,7 @@ public class SyncTescoSystemService {
         if (supplier == null) {
             // 如果客户不存在,创建新客户
             supplier = new Supplier();
+            supplier.setEnabled(true);
             supplier.setSupplier(customer.getName());
             supplier.setTelephone(customer.getAccount());
             supplier.setContacts(customer.getReceiverName());
@@ -469,7 +596,7 @@ public class SyncTescoSystemService {
         item.setUnitPrice(unitPrice);
         item.setTaxRate(BigDecimal.ONE);
         item.setTaxMoney(BigDecimal.ZERO);
-        item.setBatchNumber("");
+        item.setBatchNumber(material.getBatchNumber());
         item.setTaxLastMoney(unitPrice.multiply(operNumber));
         item.setAllPrice(unitPrice.multiply(operNumber));
         return item;

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

@@ -5,12 +5,16 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jsh.erp.constants.BusinessConstants;
 import com.jsh.erp.constants.ExceptionConstants;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.mappers.DepotHeadMapper;
 import com.jsh.erp.datasource.mappers.DepotHeadMapperEx;
 import com.jsh.erp.datasource.mappers.DepotItemMapperEx;
+import com.jsh.erp.datasource.mappers.MaterialCurrentStockMapper;
+import com.jsh.erp.datasource.mappers.MaterialCurrentStockMapperEx;
 import com.jsh.erp.datasource.pda.dto.PDADepotHeadDTO;
 import com.jsh.erp.datasource.pda.dto.PDADepotMaterialDto;
 import com.jsh.erp.datasource.pda.vo.PDADepotHeadVO;
@@ -22,6 +26,7 @@ import com.jsh.erp.query.QueryWrapperX;
 import com.jsh.erp.service.*;
 import com.jsh.erp.util.QRCodeGenerator;
 import com.jsh.erp.utils.ExcelUtils;
+import com.jsh.erp.utils.HttpClient;
 import com.jsh.erp.utils.PageUtils;
 import com.jsh.erp.utils.StringUtil;
 import com.jsh.erp.utils.Tools;
@@ -92,6 +97,8 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
     private MaterialService materialService;
     @Resource
     private MaterialExtendService materialExtendService;
+    @Resource
+    private SyncTescoSystemService syncTescoSystemService;
 
     /**
      * PDA查询订单
@@ -1006,7 +1013,10 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
                 if(materialsListMap!=null) {
                     dh.setMaterialsList(materialsListMap.get(dh.getId()));
                 }
-                dh.setCreatorName(userService.getUser(dh.getCreator()).getUsername());
+                User creatorUser = userService.getUser(dh.getCreator());
+                if(creatorUser != null){
+                    dh.setCreatorName(creatorUser.getUsername());
+                }
                 resList.add(dh);
             }
         }catch(Exception e){
@@ -1841,11 +1851,17 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
             Long headId = list.get(0).getId();
             /** 销售订单 单据子表信息 */
             depotItemService.saveOrderItem(depotHead, depotItemList);
+            List<Long> mIdList = depotItemList.stream().map(DepotItemXsddRequestVO::getMaterialId).collect(Collectors.toList());
+            //同步集采库存
+            syncTescoSystemService.sycnTescoStock(mIdList);
         }
+
         logService.insertLog("销售订单", new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(depotHead.getNumber()).toString(), ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest());
         return "";
     }
 
+
+
     /**
      * 根据商品id获取最后一条销售订单
      * @param mid 商品id

+ 4 - 1
src/main/java/com/jsh/erp/service/impl/DepotItemServiceImpl.java

@@ -18,6 +18,7 @@ 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.HttpClient;
 import com.jsh.erp.utils.StringUtil;
 import com.jsh.erp.utils.Tools;
 import org.slf4j.Logger;
@@ -846,7 +847,6 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                         depotItem.setBasicNumber(oNumber); // 其他情况
                     }
                 }
-                this.insertDepotItemWithObj(depotItem);
                 depotItem.setHeaderId(depotHead.getId());
                 this.insertDepotItem(depotItem);
                 // 更新当前库存
@@ -1331,6 +1331,9 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
         }
     }
 
+
+
+
     @Override
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     public BigDecimal getFinishNumber(Long meId, Long id, Long headerId, Unit unitInfo, String materialUnit, String linkType) {

+ 4 - 1
src/main/resources/application-dev.yml

@@ -1,6 +1,6 @@
 server:
   #端口号
-  port: 8080
+  port: 9080
   tomcat:
     basedir: F:/kaifa/temp #文件上传临时路径
 
@@ -30,3 +30,6 @@ aliyun:
     bucketName: xiangli-erp
     miniProgramAppId: wxd716cb744e32271a
     linkUrl: https://xiangli-erp.oss-cn-hangzhou.aliyuncs.com
+tesco:
+  sycnErpMaterialStockUrl: http://localhost:8088/no-auth/erp/sync-stock
+  sycnErpMaterialPriceUrl: http://localhost:8088/no-auth/erp/sync-saleprice

+ 4 - 0
src/main/resources/application-pro.yml

@@ -30,3 +30,7 @@ aliyun:
     bucketName: xiangli-erp
     miniProgramAppId: wxd716cb744e32271a
     linkUrl: https://xiangli-erp.oss-cn-hangzhou.aliyuncs.com
+
+tesco:
+  sycnErpMaterialStockUrl: https://tesco.xianglitech.com.cn/prod-api/no-auth/erp/sync-stock
+  sycnErpMaterialPriceUrl: https://tesco.xianglitech.com.cn/prod-api/no-auth/erp/sync-saleprice

+ 4 - 0
src/main/resources/application-test.yml

@@ -30,3 +30,7 @@ aliyun:
     bucketName: xiangli-erp
     miniProgramAppId: wxd716cb744e32271a
     linkUrl: https://xiangli-erp.oss-cn-hangzhou.aliyuncs.com
+
+tesco:
+  sycnErpMaterialStockUrl: https://test.xianglitech.com.cn/stage-api/no-auth/erp/sync-stock
+  sycnErpMaterialPriceUrl: https://test.xianglitech.com.cn/stage-api/no-auth/erp/sync-saleprice

+ 46 - 9
src/main/resources/mapper_xml/DepotHeadMapper.xml

@@ -101,7 +101,7 @@
     account_id, change_amount, back_amount, total_price, pay_type, bill_type, remark, 
     file_name, sales_man, account_id_list, account_money_list, discount, discount_money, 
     discount_last_money, other_money, deposit, status, purchase_status, source, link_number, 
-    link_apply, tenant_id, delete_flag
+    link_apply, tenant_id, delete_flag,goods_quantity, goods_type_count, link_tesco, receiver_name, receiver_phone, receiver_address
   </sql>
   <select id="selectByExample" parameterType="com.jsh.erp.datasource.entities.DepotHeadExample" resultMap="BaseResultMap">
     select
@@ -144,7 +144,7 @@
       discount_money, discount_last_money, other_money, 
       deposit, status, purchase_status, 
       source, link_number, link_apply, 
-      tenant_id, delete_flag)
+      tenant_id, delete_flag,goods_quantity, goods_type_count, link_tesco, receiver_name, receiver_phone, receiver_address)
     values (#{id,jdbcType=BIGINT}, #{type,jdbcType=VARCHAR}, #{subType,jdbcType=VARCHAR}, 
       #{defaultNumber,jdbcType=VARCHAR}, #{number,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 
       #{operTime,jdbcType=TIMESTAMP}, #{organId,jdbcType=BIGINT}, #{creator,jdbcType=BIGINT}, 
@@ -155,7 +155,9 @@
       #{discountMoney,jdbcType=DECIMAL}, #{discountLastMoney,jdbcType=DECIMAL}, #{otherMoney,jdbcType=DECIMAL}, 
       #{deposit,jdbcType=DECIMAL}, #{status,jdbcType=VARCHAR}, #{purchaseStatus,jdbcType=VARCHAR}, 
       #{source,jdbcType=VARCHAR}, #{linkNumber,jdbcType=VARCHAR}, #{linkApply,jdbcType=VARCHAR}, 
-      #{tenantId,jdbcType=BIGINT}, #{deleteFlag,jdbcType=VARCHAR})
+      #{tenantId,jdbcType=BIGINT}, #{deleteFlag,jdbcType=VARCHAR},#{goodsQuantity,jdbcType=INTEGER},
+      #{goodsTypeCount,jdbcType=INTEGER}, #{linkTesco,jdbcType=VARCHAR}, #{receiverName,jdbcType=VARCHAR},
+      #{receiverPhone,jdbcType=VARCHAR}, #{receiverAddress,jdbcType=VARCHAR})
   </insert>
   <insert id="insertSelective" parameterType="com.jsh.erp.datasource.entities.DepotHead" useGeneratedKeys="true" keyProperty="id">
     insert into jsh_depot_head
@@ -394,7 +396,7 @@
         #{receiverPhone,jdbcType=VARCHAR},
       </if>
       <if test="receiverAddress != null">
-        #{receiverAddress,jdbcType=VARCHAR}
+        #{receiverAddress,jdbcType=VARCHAR},
       </if>
     </trim>
   </insert>
@@ -503,6 +505,27 @@
       <if test="record.deleteFlag != null">
         delete_flag = #{record.deleteFlag,jdbcType=VARCHAR},
       </if>
+      <if test="record.voucherPicture != null">
+        voucher_picture = #{record.voucherPicture,jdbcType=VARCHAR},
+      </if>
+      <if test="record.goodsQuantity != null">
+        goods_quantity = #{record.goodsQuantity,jdbcType=INTEGER},
+      </if>
+      <if test="record.goodsTypeCount != null">
+        goods_type_count = #{record.goodsTypeCount,jdbcType=INTEGER},
+      </if>
+      <if test="record.linkTesco != null">
+        link_tesco = #{record.linkTesco,jdbcType=VARCHAR},
+      </if>
+      <if test="record.receiverName != null">
+        receiver_name = #{record.receiverName,jdbcType=VARCHAR},
+      </if>
+      <if test="record.receiverPhone != null">
+        receiver_phone = #{record.receiverPhone,jdbcType=VARCHAR},
+      </if>
+      <if test="record.receiverAddress != null">
+        receiver_address = #{record.receiverAddress,jdbcType=VARCHAR},
+      </if>
     </set>
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
@@ -541,7 +564,14 @@
       link_number = #{record.linkNumber,jdbcType=VARCHAR},
       link_apply = #{record.linkApply,jdbcType=VARCHAR},
       tenant_id = #{record.tenantId,jdbcType=BIGINT},
-      delete_flag = #{record.deleteFlag,jdbcType=VARCHAR}
+      delete_flag = #{record.deleteFlag,jdbcType=VARCHAR},
+      voucher_picture = #{record.voucherPicture,jdbcType=VARCHAR},
+      goods_quantity = #{record.goodsQuantity,jdbcType=INTEGER},
+      goods_type_count = #{record.goodsTypeCount,jdbcType=INTEGER},
+      link_tesco = #{record.linkTesco,jdbcType=VARCHAR},
+      receiver_name = #{record.receiverName,jdbcType=VARCHAR},
+      receiver_phone = #{record.receiverPhone,jdbcType=VARCHAR},
+      receiver_address = #{record.receiverAddress,jdbcType=VARCHAR}
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
     </if>
@@ -655,13 +685,13 @@
         link_tesco =#{linkTesco,jdbcType=VARCHAR},
       </if>
       <if test="receiverName != null">
-        receiver_name = #{receiverName,jdbcType=VARCHAR}
+        receiver_name = #{receiverName,jdbcType=VARCHAR},
       </if>
       <if test="receiverPhone != null">
-        receiver_phone = #{receiverPhone,jdbcType=VARCHAR}
+        receiver_phone = #{receiverPhone,jdbcType=VARCHAR},
       </if>
       <if test="receiverAddress != null">
-        receiver_address = #{receiverAddress,jdbcType=VARCHAR}
+        receiver_address = #{receiverAddress,jdbcType=VARCHAR},
       </if>
     </set>
     where id = #{id,jdbcType=BIGINT}
@@ -698,7 +728,14 @@
       link_number = #{linkNumber,jdbcType=VARCHAR},
       link_apply = #{linkApply,jdbcType=VARCHAR},
       tenant_id = #{tenantId,jdbcType=BIGINT},
-      delete_flag = #{deleteFlag,jdbcType=VARCHAR}
+      delete_flag = #{deleteFlag,jdbcType=VARCHAR},
+      voucher_picture = #{voucherPicture,jdbcType=VARCHAR},
+      goods_quantity = #{goodsQuantity,jdbcType=INTEGER},
+      goods_type_count = #{goodsTypeCount,jdbcType=INTEGER},
+      link_tesco = #{linkTesco,jdbcType=VARCHAR},
+      receiver_name = #{receiverName,jdbcType=VARCHAR},
+      receiver_phone = #{receiverPhone,jdbcType=VARCHAR},
+      receiver_address = #{receiverAddress,jdbcType=VARCHAR}
     where id = #{id,jdbcType=BIGINT}
   </update>
 

+ 20 - 0
src/main/resources/mapper_xml/MaterialCurrentStockMapperEx.xml

@@ -31,6 +31,26 @@
         select ifnull(mcs.current_unit_price,0) as current_unit_price from jsh_material_current_stock mcs where mcs.material_id=#{materialId} limit 1
     </select>
 
+    <select id="getCurrentStockMapByMdIdList" resultType="com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku">
+        SELECT m.id                                             AS mId,
+               m.name                                           AS mName,
+               m.unit                                           AS unit,
+               m.unit_id                                        AS unitId,
+               m.system_sku                                     AS systemSku,
+               SUM(mcs.current_number)                          AS basicUnitTotalStock,
+               MIN(mcs.current_unit_price)                      AS basicUnitSalePrice
+        FROM jsh_material_current_stock mcs
+        LEFT JOIN jsh_material m ON m.id = mcs.material_id
+        WHERE m.id IN
+        <foreach collection="materialIdList" item="materialId" index="index" separator="," open="(" close=")">
+            #{materialId}
+        </foreach>
+        AND ifnull(mcs.delete_flag,'0') !='1'
+        AND ifnull(m.delete_flag,'0') !='1'
+        GROUP BY m.id, m.system_sku
+    </select>
+
+
     <update id="batchDeleteByDepots">
         update jsh_material_current_stock
         set delete_flag='1'

+ 27 - 0
src/main/resources/mapper_xml/MaterialMapperEx.xml

@@ -880,4 +880,31 @@
         and ifnull(me.delete_flag,'0') !='1'
     </select>
 
+    <select id="getMaterialCurrentPriceByIdList" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku">
+        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.id IN (
+                <foreach collection="idList" item="systemSku" separator=",">
+                    #{systemSku}
+                </foreach>
+            )
+        )
+        SELECT
+            m.id                                             AS mId,
+            m.name                                           AS mName,
+            m.unit                                           AS unit,
+            m.unit_id                                        AS unitId,
+            m.system_sku                                     AS systemSku,
+            re.wholesale_decimal                             AS basicUnitSalePrice
+        FROM jsh_material m
+        LEFT JOIN RankedExtend re ON m.id = re.material_id AND re.rn = 1
+        WHERE ifnull(m.delete_flag, '0') != '1' AND re.id IS NOT NULL
+        ORDER BY m.id DESC
+    </select>
+
 </mapper>