heshaofeng
2025-12-11 cd44f1223ccf40a2b6f0788dbcd24ff7cd8f0eef
Merge branch 'master' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu
已添加1个文件
已修改6个文件
568 ■■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/config/buttons.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/EmptyTrayInbound.vue 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js 340 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/EmptyTrayOutbound.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/config/buttons.js
@@ -235,6 +235,14 @@
    onClick: function () {
    }
},
{
    name: "空托入库",
    class: '',
    value: 'EmptyTrayInbound',
    type: 'primary',
    onClick: function () {
    }
},
]
export default buttons
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/extend/EmptyTrayInbound.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
<template>
    <vol-box v-model="show" title="空托入库" :width="800" :height="1200">
        <template #content>
            <el-form ref="form" :model="form" label-width="90px">
                <el-form-item label="入库区域:">
                    <el-select v-model="form.locationType" placeholder="请选择入库区域">
                        <el-option v-for="item in locationTypes" :key="item.locationType" :label="item.locationTypeDesc"
                            :value="item.locationType" />
                    </el-select>
                </el-form-item>
                <el-form-item label="托盘条码:">
                    <el-input v-model="form.palletCode" placeholder="请扫描/输入托盘条码" @keyup.enter="submit" @keyup.13="submit"
                        clearable maxlength="50" @paste="handlePaste" @input="handleInput" />
                </el-form-item>
            </el-form>
        </template>
        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="submit">确认</el-button>
                <el-button @click="show = false">关闭</el-button>
            </div>
        </template>
    </vol-box>
</template>
<script>
import VolBox from '@/components/basic/VolBox.vue'
export default {
    components: { VolBox },
    props: {
        value: { type: Boolean, default: false }
    },
    data() {
        return {
            show: false,
            form: {
                palletCode: '',
                locationType: ''
            },
            locationTypes: []
        }
    },
    methods: {
        open() {
            this.show = true
            this.getData();
        },
        async getData() {
            try {
                const { data } = await this.http.post("api/LocationInfo/GetLocationTypes")
                this.locationTypes = data
            } catch (e) {
                this.$message.error('获取区域类型失败')
            }
        },
        async submit() {
            if (!this.form.palletCode) {
                this.$message.warning('请输入托盘条码')
                return
            }
            if (!this.form.locationType) {
                this.$message.warning('请选择入库区域')
                return
            }
            try {
                let param = {
                    WarehouseCode: this.form.locationType,
                    PalletCode: this.form.palletCode
                }
                const { status, message } = await this.http.post(
                    `/api/InboundOrder/EmptyMaterielGroup`,
                    param
                )
                if (status) {
                    this.$message.success("组盘成功")
                    this.show = false
                    this.$emit('refresh')
                } else {
                    this.$message.error(message || '操作失败')
                }
            } catch (error) {
                this.$message.error('请求异常')
            }
        },
        // æ‰«ææžªä¼˜åŒ–处理
        handleInput(value) {
            // è¿‡æ»¤éžæ•°å­—和条码常用字符
            this.form.palletCode = value.replace(/[^a-zA-Z0-9\-]/g, '')
        },
        handlePaste(e) {
            // ç²˜è´´æ—¶è‡ªåŠ¨æäº¤
            setTimeout(this.submit, 100)
        }
    }
}
</script>
<style scoped>
.dialog-footer {
    text-align: right;
}
</style>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js
@@ -2,11 +2,11 @@
import http from '@/api/http.js'
import { h, createVNode, render, reactive, ref } from 'vue';
import { ElDialog, ElForm, ElFormItem, ElInput, ElButton, ElMessage, ElSelect, ElOption } from 'element-plus'; // å¼•å…¥ElMessage,解决提示无反应
import gridHeader from './extend/EmptyTrayInbound.vue'
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridHeader: gridHeader,
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
@@ -245,186 +245,194 @@
          }
        }
      },
      {
        name: '空托盘入库',
        type: 'primary',
        value: '空托盘入库',
      // {
      //   name: '空托盘入库',
      //   type: 'primary',
      //   value: '空托盘入库',
        onClick: function () {
          const mountNode = document.createElement('div');
          document.body.appendChild(mountNode);
      //   onClick: function () {
      //     const mountNode = document.createElement('div');
      //     document.body.appendChild(mountNode);
          // å“åº”式表单数据:料箱码(必填,扫码枪/手动输入)
          const formData = reactive({
            boxCode: '',
            warehouseCode: ''
          });
      //     // å“åº”式表单数据:料箱码(必填,扫码枪/手动输入)
      //     const formData = reactive({
      //       boxCode: '',
      //       warehouseCode: ''
      //     });
          const warehouses = ref([]);
          const isLoadingWarehouses = ref(false);
      //     const warehouses = ref([]);
      //     const isLoadingWarehouses = ref(false);
          const getWarehouseList = async () => {
            isLoadingWarehouses.value = true;
            try {
              const { data, status } = await http.post('/api/LocationInfo/GetLocationTypes');
              if (status && Array.isArray(data)) {
                // æ ¼å¼åŒ–仓库选项:适配ElSelect的label-value格式
                warehouses.value = data.map(item => ({
                  label: item.locationTypeDesc,
                  value: item.locationType
                }));
              } else {
                ElMessage.error('获取区域列表失败');
                warehouses.value = [];
              }
            } catch (err) {
              ElMessage.error('区域数据请求异常,请稍后重试');
              warehouses.value = [];
            } finally {
              isLoadingWarehouses.value = false;
            }
          };
      //     const getWarehouseList = async () => {
      //       isLoadingWarehouses.value = true;
      //       try {
      //         const { data, status } = await http.post('/api/LocationInfo/GetLocationTypes');
      //         if (status && Array.isArray(data)) {
      //           // æ ¼å¼åŒ–仓库选项:适配ElSelect的label-value格式
      //           warehouses.value = data.map(item => ({
      //             label: item.locationTypeDesc,
      //             value: item.locationType
      //           }));
      //         } else {
      //           ElMessage.error('获取区域列表失败');
      //           warehouses.value = [];
      //         }
      //       } catch (err) {
      //         ElMessage.error('区域数据请求异常,请稍后重试');
      //         warehouses.value = [];
      //       } finally {
      //         isLoadingWarehouses.value = false;
      //       }
      //     };
          // æäº¤è¡¨å•的统一逻辑(供回车触发和按钮点击共用)
          const submitForm = async () => {
            const formRef = vnode.component.refs.batchInForm;
            try {
              // æ‰§è¡Œè¡¨å•校验(料箱码必填)
              await formRef.validate();
            } catch (err) {
              ElMessage.warning('请输入有效的料箱码');
              return;
            }
      //     // æäº¤è¡¨å•的统一逻辑(供回车触发和按钮点击共用)
      //     const submitForm = async () => {
      //       const formRef = vnode.component.refs.batchInForm;
      //       try {
      //         // æ‰§è¡Œè¡¨å•校验(料箱码必填)
      //         await formRef.validate();
      //       } catch (err) {
      //         ElMessage.warning('请输入有效的料箱码');
      //         return;
      //       }
            http.post('/api/InboundOrder/EmptyMaterielGroup', {
              palletCode: formData.boxCode.trim(),
              warehouseCode: formData.warehouseCode
            }).then(({ data, status, message }) => {
              if (status) {
                ElMessage.success(`入库成功,料箱码:${formData.boxCode.trim()}`);
                this.refresh();
                formData.boxCode = '';
      //       http.post('/api/InboundOrder/EmptyMaterielGroup', {
      //         palletCode: formData.boxCode.trim(),
      //         warehouseCode: formData.warehouseCode
      //       }).then(({ data, status, message }) => {
      //         if (status) {
      //           ElMessage.success(`入库成功,料箱码:${formData.boxCode.trim()}`);
      //           this.refresh();
      //           formData.boxCode = '';
                setTimeout(() => {
                  const inputRef = vnode.component.refs.boxCodeInput;
                  inputRef?.focus();
                }, 100);
              } else {
                ElMessage.error(message || data?.message || '入库失败');
                selectBoxCodeInput();
              }
            }).catch(() => {
              ElMessage.error('请求失败,请稍后重试');
              selectBoxCodeInput();
            });
          };
      //           setTimeout(() => {
      //             const inputRef = vnode.component.refs.boxCodeInput;
      //             inputRef?.focus();
      //           }, 100);
      //         } else {
      //           ElMessage.error(message || data?.message || '入库失败');
      //           selectBoxCodeInput();
      //         }
      //       }).catch(() => {
      //         ElMessage.error('请求失败,请稍后重试');
      //         selectBoxCodeInput();
      //       });
      //     };
          const selectBoxCodeInput = () => {
            setTimeout(() => {
              const inputRef = vnode.component.refs.boxCodeInput;
              if (inputRef) {
                const targetInput = inputRef.$el?.querySelector('input') || inputRef;
                targetInput?.focus();
                targetInput?.select();
              }
            }, 100);
          }
          const vnode = createVNode(ElDialog, {
            title: '空托盘入库',
            width: '400px',
            modelValue: true,
            appendToBody: true,
      //     const selectBoxCodeInput = () => {
      //       setTimeout(() => {
      //         const inputRef = vnode.component.refs.boxCodeInput;
      //         if (inputRef) {
      //           const targetInput = inputRef.$el?.querySelector('input') || inputRef;
      //           targetInput?.focus();
      //           targetInput?.select();
      //         }
      //       }, 100);
      //     }
      //     const vnode = createVNode(ElDialog, {
      //       title: '空托盘入库',
      //       width: '400px',
      //       modelValue: true,
      //       appendToBody: true,
            onOpened: async () => {
              await getWarehouseList();
              const inputRef = vnode.component.refs.boxCodeInput;
              inputRef?.focus();
            },
            'onUpdate:modelValue': (isVisible) => {
              if (!isVisible) {
                render(null, mountNode);
                document.body.removeChild(mountNode);
              }
            }
          }, {
            default: () => h(ElForm, {
              model: formData,
              rules: {
                boxCode: [
                  { required: true, message: '请输入料箱码', trigger: ['blur', 'enter'] }
                ],
                warehouseCode: [
                  { required: true, message: '请选择区域', trigger: ['change', 'blur'] }
                ]
              },
              ref: 'batchInForm'
            }, [
              //仓库数据
              h(ElFormItem, { label: '区域', prop: 'warehouseCode', required: true }, [
                h(ElSelect, {
                  modelValue: formData.warehouseCode,
                  'onUpdate:modelValue': (val) => {
                    formData.warehouseCode = val;
                  },
                  placeholder: '请选择入库区域',
                  filterable: true, // æ”¯æŒæœç´¢ä»“库
                  loading: isLoadingWarehouses.value, // åŠ è½½çŠ¶æ€
                  style: { width: '100%' }
                }, [
                  // æ¸²æŸ“仓库下拉选项
                  warehouses.value.map(item => h(ElOption, {
                    label: item.label,
                    value: item.value
                  }))
                ])
              ]),
              // æ–™ç®±ç è¾“入项(支持聚焦、回车提交)
              h(ElFormItem, { label: '料箱码', prop: 'boxCode', required: true }, [
                h(ElInput, {
                  type: 'text',
                  modelValue: formData.boxCode,
                  'onUpdate:modelValue': (val) => {
                    formData.boxCode = val;
                  },
                  ref: 'boxCodeInput',
                  placeholder: '扫码输入或手动输入料箱码',
                  // ç›‘听回车事件(扫码枪默认会发送回车)
                  onKeydown: (e) => {
                    if (e.key === 'Enter') {
                      e.preventDefault();
                      submitForm();
                    }
                  }
                })
              ]),
              // åº•部按钮区
              h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [
                h(ElButton, {
                  type: 'text',
                  onClick: () => {
                    render(null, mountNode);
                    document.body.removeChild(mountNode);
                    ElMessage.info('取消入库任务');
                  }
                }, '取消'),
                h(ElButton, {
                  type: 'primary',
                  onClick: submitForm
                }, '确定')
              ])
            ])
          });
      //       onOpened: async () => {
      //         await getWarehouseList();
      //         const inputRef = vnode.component.refs.boxCodeInput;
      //         inputRef?.focus();
      //       },
      //       'onUpdate:modelValue': (isVisible) => {
      //         if (!isVisible) {
      //           render(null, mountNode);
      //           document.body.removeChild(mountNode);
      //         }
      //       }
      //     }, {
      //       default: () => h(ElForm, {
      //         model: formData,
      //         rules: {
      //           boxCode: [
      //             { required: true, message: '请输入料箱码', trigger: ['blur', 'enter'] }
      //           ],
      //           warehouseCode: [
      //             { required: true, message: '请选择区域', trigger: ['change', 'blur'] }
      //           ]
      //         },
      //         ref: 'batchInForm'
      //       }, [
      //         //仓库数据
      //         h(ElFormItem, { label: '区域', prop: 'warehouseCode', required: true }, [
      //           h(ElSelect, {
      //             modelValue: formData.warehouseCode,
      //             'onUpdate:modelValue': (val) => {
      //               formData.warehouseCode = val;
      //             },
      //             placeholder: '请选择入库区域',
      //             filterable: true, // æ”¯æŒæœç´¢ä»“库
      //             loading: isLoadingWarehouses.value, // åŠ è½½çŠ¶æ€
      //             style: { width: '100%' }
      //           }, [
      //             // æ¸²æŸ“仓库下拉选项
      //             warehouses.value.map(item => h(ElOption, {
      //               label: item.label,
      //               value: item.value
      //             }))
      //           ])
      //         ]),
      //         // æ–™ç®±ç è¾“入项(支持聚焦、回车提交)
      //         h(ElFormItem, { label: '料箱码', prop: 'boxCode', required: true }, [
      //           h(ElInput, {
      //             type: 'text',
      //             modelValue: formData.boxCode,
      //             'onUpdate:modelValue': (val) => {
      //               formData.boxCode = val;
      //             },
      //             ref: 'boxCodeInput',
      //             placeholder: '扫码输入或手动输入料箱码',
      //             // ç›‘听回车事件(扫码枪默认会发送回车)
      //             onKeydown: (e) => {
      //               if (e.key === 'Enter') {
      //                 e.preventDefault();
      //                 submitForm();
      //               }
      //             }
      //           })
      //         ]),
      //         // åº•部按钮区
      //         h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [
      //           h(ElButton, {
      //             type: 'text',
      //             onClick: () => {
      //               render(null, mountNode);
      //               document.body.removeChild(mountNode);
      //               ElMessage.info('取消入库任务');
      //             }
      //           }, '取消'),
      //           h(ElButton, {
      //             type: 'primary',
      //             onClick: submitForm
      //           }, '确定')
      //         ])
      //       ])
      //     });
          vnode.appContext = this.$.appContext;
          render(vnode, mountNode);
        }
      }
      //     vnode.appContext = this.$.appContext;
      //     render(vnode, mountNode);
      //   }
      // }
    ], box: [], detail: []
  },
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      var EmptyTrayInboundBtn = this.buttons.find(x => x.value == "EmptyTrayInbound");
        if (EmptyTrayInboundBtn != null) {
          EmptyTrayInboundBtn.onClick = () => {
               this.$refs.gridHeader.open();
            }
        }
      this.columns.forEach(column => {
        if (column.field === 'orderStatistics') {
          column.formatter = (row) => {
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/extend/EmptyTrayOutbound.vue
@@ -1,17 +1,19 @@
<template>
  <vol-box v-model="show" title="空托出库" :width="400" :height="600">
  <vol-box v-model="show" title="空托出库" :width="800" :height="1200">
    <template #content>
      <el-form ref="form" :model="form" label-width="90px">
        <el-form-item label="出库区域:">
          <el-select v-model="locationType" placeholder="请选择出库区域">
            <el-option v-for="item in locationTypes" :key="item.locationType" :label="item.locationTypeDesc.toString()" :value="item.locationType">
            <el-option v-for="item in locationTypes" :key="item.locationType" :label="item.locationTypeDesc.toString()"
              :value="item.locationType">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <el-form ref="form" :model="form" label-width="90px">
        <el-form-item label="出库数量:">
          <el-input-number v-model="num" :min="1" :max="999" :controls="true" placeholder="请选择出库数量" style="width: 100%;"></el-input-number>
          <el-input-number v-model="num" :min="1" :max="999" :controls="true" placeholder="请选择出库数量"
            style="width: 100%;"></el-input-number>
        </el-form-item>
      </el-form>
    </template>
@@ -39,7 +41,7 @@
      num: 1,
      show: false,
      locationTypes: [],
      locationType:"",
      locationType: "",
    }
  },
  methods: {
@@ -63,7 +65,7 @@
    },
    getData() {
      this.http.post("api/LocationInfo/GetLocationTypes",null, "查询中")
      this.http.post("api/LocationInfo/GetLocationTypes", null, "查询中")
        .then((x) => {
          this.locationTypes = x.data;
        })
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs
@@ -943,7 +943,7 @@
        /// <summary>
        /// æ‰§è¡Œæ‰‹åŠ¨æ‹†åŒ…é€»è¾‘ - ä¿®å¤ç‰ˆæœ¬
        /// æ‰§è¡Œæ‰‹åŠ¨æ‹†åŒ…é€»è¾‘
        /// </summary>
        private async Task<List<SplitResult>> ExecuteManualSplitLogic(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
            decimal splitQuantity, string palletCode)
@@ -1001,8 +1001,8 @@
                    MaterielCode = stockDetail.MaterielCode,
                    OrderNo = stockDetail.OrderNo,
                    BatchNo = stockDetail.BatchNo,
                    StockQuantity = newStockQuantity,  // ä¿®å¤ï¼šä½¿ç”¨æ­£ç¡®çš„æ‹†åŒ…数量
                    OutboundQuantity = 0,  // æ–°æ¡ç åˆå§‹å‡ºåº“数量为0
                    StockQuantity = newStockQuantity,
                    OutboundQuantity = 0,
                    Barcode = newBarcode,
                    Status = (int)StockStatusEmun.出库锁定,
                    SupplyCode = stockDetail.SupplyCode,
@@ -3158,17 +3158,7 @@
            _logger.LogInformation($"需要自动拆包 - åº“å­˜: {stockDetail.StockQuantity}, åˆ†é…: {lockInfo.AssignQuantity}, æ‹†åŒ…数量: {splitQuantity}");
            // æ‰§è¡Œè‡ªåŠ¨æ‹†åŒ…
            var splitResult = await ExecuteAutoSplitLogic(lockInfo, stockDetail, splitQuantity, palletCode);
            // å°†æ‹†åŒ…数量传递给调用方,用于验证
            if (splitResult != null && splitResult.Any())
            {
                // åœ¨è¿”回结果中携带拆包数量信息
                foreach (var result in splitResult)
                {
                    result.quantityTotal = splitQuantity.ToString("F2");
                }
            }
            var splitResult = await ExecuteAutoSplitLogic(lockInfo, stockDetail, splitQuantity,  palletCode);
            return splitResult;
        }
@@ -3178,7 +3168,7 @@
        /// åŽŸåˆ™ï¼šåªåˆ†ç¦»ç‰©ç†åº“å­˜ï¼Œä¸æ”¹å˜åŽŸè®¢å•çš„ä»»ä½•åˆ†é…å’Œå‡ºåº“æ•°é‡
        /// </summary>
        private async Task<List<SplitResult>> ExecuteAutoSplitLogic(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
            decimal splitQuantity, string palletCode)
            decimal splitQuantity,string palletCode)
        {
            _logger.LogInformation($"开始执行自动拆包逻辑 - åŽŸæ¡ç : {stockDetail.Barcode}, æ‹†åŒ…数量: {splitQuantity}");
@@ -3269,7 +3259,7 @@
                await RecordSplitHistory(lockInfo, stockDetail, splitQuantity, newBarcode, true, originalStockQty);
                // åˆ›å»ºæ‹†åŒ…结果列表
                var splitResults = CreateSplitResults(lockInfo, splitQuantity, lockInfo.AssignQuantity, newBarcode, stockDetail.Barcode);
                var splitResults = CreateSplitResults(lockInfo, splitQuantity, stockDetail.StockQuantity, newBarcode, stockDetail.Barcode);
                _logger.LogInformation($"自动拆包逻辑执行完成 - åˆ›å»ºäº†æœªåˆ†é…çš„库存和锁定记录");
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -303,11 +303,11 @@
                _recordService.StockQuantityChangeRecordService.AddStockChangeRecord(stockInfo, stockInfo.Details, beforeQuantity, stockInfo.Details.Sum(x => x.StockQuantity) + beforeQuantity, WIDESEA_Common.StockEnum.StockChangeType.MaterielGroup);
            }
            catch(Exception ex)
            catch (Exception ex)
            {
                _logger.LogInformation($"InboundTaskCompleted AddLocationStatusChangeRecord : {ex.Message} " );
                _logger.LogInformation($"InboundTaskCompleted AddLocationStatusChangeRecord : {ex.Message} ");
            }
                try
            try
            {
                foreach (var inboundOrder in inboundOrders)
                {
@@ -579,7 +579,7 @@
                {
                    _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforelocationStatus, StockChangeType.Inbound.ObjToInt(), "", task.TaskNum);
                }
                catch(Exception ex)
                catch (Exception ex)
                {
                    _logger.LogInformation($"InEmptyTaskCompleted AddLocationStatusChangeRecord : {ex.Message} ");
                }
@@ -696,7 +696,7 @@
                {
                    await Db.Deleteable(task).ExecuteCommandAsync();
                }
                await RecalculateOrderStatus(task.OrderNo);
                try
                {
@@ -757,8 +757,8 @@
        {
            try
            {
                // èŽ·å–å—å½±å“çš„è®¢å•æ˜Žç»†ID(去重)
                //var affectedDetailIds = returnLocks
                //    .Select(x => x.OrderDetailId)
@@ -999,7 +999,7 @@
                    _logger.LogInformation($"更新订单状态 - OrderNo: {orderNo}, æ—§çŠ¶æ€: {outboundOrder.OrderStatus}, æ–°çŠ¶æ€: {newStatus}");
                }
            }
            catch (Exception ex)
            {
@@ -1136,8 +1136,33 @@
                                allocatefeedmodel.Details.Add(detailModel);
                            }
                            var groupedResult = allocatefeedmodel.Details.GroupBy(item => new
                            {
                                item.WarehouseCode,
                                item.MaterialCode,
                                item.Unit,
                                item.LineNo
                            }).Select(group => new AllocateDtoDetail
                            {
                                 WarehouseCode = group.Key.WarehouseCode,
                                 MaterialCode = group.Key.MaterialCode,
                                 LineNo = group.Key.LineNo,
                                 Qty = group.Sum(x => x.Qty),
                                 Unit = group.Key.Unit,
                                 Barcodes = group.SelectMany(x => x.Barcodes)
                                                       .GroupBy(b => b.Barcode)
                                                       .Select(b => new BarcodeInfo
                                                       {
                                                           Barcode = b.Key,
                                                           BatchNo = b.First().BatchNo,
                                                           SupplyCode = b.First().SupplyCode,
                                                           Qty = b.Max(x => x.Qty),
                                                           Unit = b.First().Unit
                                                       }) .ToList()
                             }) .ToList();
                            allocatefeedmodel.Details = groupedResult;
                            var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
                          var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
                            if (result != null && result.code == 200)
                            {
                                await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
@@ -1222,6 +1247,31 @@
                                }
                                feedmodel.details.Add(detailModel);
                            }
                            var groupedResult = feedmodel.details.GroupBy(item => new
                            {
                                item.warehouseCode,
                                item.materialCode,
                                item.unit,
                                item.lineNo
                            }).Select(group => new FeedbackOutboundDetailsModel
                            {
                                warehouseCode = group.Key.warehouseCode,
                                materialCode = group.Key.materialCode,
                                lineNo = group.Key.lineNo,
                                qty = group.Sum(x => x.qty),
                                unit = group.Key.unit,
                                barcodes = group.SelectMany(x => x.barcodes)
                                                       .GroupBy(b => b.barcode)
                                                       .Select(b => new WIDESEA_DTO.Outbound.BarcodesModel
                                                       {
                                                           barcode = b.Key,
                                                           batchNo = b.First().batchNo,
                                                           supplyCode = b.First().supplyCode,
                                                           qty = b.Max(x => x.qty),
                                                           unit = b.First().unit
                                                       }).ToList()
                            }).ToList();
                            feedmodel.details = groupedResult;
                            var result = await _invokeMESService.FeedbackOutbound(feedmodel);
                            if (result != null && result.code == 200)
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs
@@ -66,8 +66,7 @@
        [HttpPost, Route("Test"), AllowAnonymous, MethodParamsValidate]
        public async Task<WebResponseContent> Test()
        {
        {
            //var originalTask = _taskRepository.Db.Queryable<Dt_Task>().First();
            //var result = _task_HtyService.DeleteAndMoveIntoHty(originalTask, OperateTypeEnum.人工删除);
@@ -91,7 +90,7 @@
            //var  ddddssss = "WSLOT" + DateTime.Now.ToString("yyyyMMddHHmmss") + ssss.ToString().PadLeft(5, '0');
            //erpApiService.GetSuppliersAsync();
            erpApiService.GetMaterialUnitAsync();
           // erpApiService.GetMaterialUnitAsync();
            //var sss = await _invokeMESService.NewMaterielToMes(new WIDESEA_DTO.Basic.MaterielToMesDTO
            //{