diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/api/api.js b/jeecg-boot-master/ant-design-vue-jeecg/src/api/api.js
index 315d182..c3f09c4 100644
--- a/jeecg-boot-master/ant-design-vue-jeecg/src/api/api.js
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/api/api.js
@@ -106,9 +106,11 @@ export const getReceiptTypeList = (params)=>getAction('/config/receiptType/getRe
 export const getShipmentTypeList = (params)=>getAction('/config/shipmentType/getShipmentTypeList', params);
 export const searchMaterialByCode = (params)=>postAction('/config/material/searchMaterialByCode', params);
 export const listReceiveByReceiptId = (params)=>postAction('/receipt/receiveHeader/listReceiveByReceiptId', params);
-export const createTask = (params)=>postAction('/receipt/receiptContainerHeader/createTask', params);
+export const createReceiptTask = (params)=>postAction('/receipt/receiptContainerHeader/createReceiptTask', params);
 export const completeTaskByWMS = (params)=>postAction('/task/taskHeader/completeTaskByWMS', params);
 export const execute = (params)=>postAction('/task/taskHeader/execute', params);
+export const autoCombination = (params)=>postAction('/shipment/shipmentCombination/autoCombination', params);
+export const createShipmentTask = (params)=>postAction('/shipment/shipmentCombination/createShipmentTask', params);
 
 // 中转HTTP请求
 export const transitRESTful = {
diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptContainerHeaderList.vue b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptContainerHeaderList.vue
index a4285ca..5ed02e3 100644
--- a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptContainerHeaderList.vue
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptContainerHeaderList.vue
@@ -149,7 +149,7 @@
   import ReceiptContainerDetailList from './ReceiptContainerDetailList'
   import {initDictOptions,filterMultiDictText} from '@/components/dict/JDictSelectUtil'
   import '@/assets/less/TableExpand.less'
-  import {createTask} from '@/api/api'
+  import {createReceiptTask} from '@/api/api'
 
   export default {
     name: "ReceiptContainerHeaderList",
@@ -290,7 +290,7 @@
         const that = this;
         this.model = Object.assign({}, record);
         that.querySource.id = record.id;
-        createTask(that.querySource).then((res) => {
+        createReceiptTask(that.querySource).then((res) => {
           this.loading = false;
           if (res.success) {
             this.$message.success(res.message);
diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue
index f82b90f..229fb2e 100644
--- a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue
@@ -390,7 +390,7 @@
             this.dataSource = res.result.records;
             this.ipagination.total = res.result.total;
           }
-          if(res.code===510){
+          if(res.code===510) {
             this.$message.warning(res.message)
           }
           this.loading = false;
diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue
index 993f996..9dc9be8 100644
--- a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue
@@ -62,7 +62,7 @@
       </a-form>
     </div>
     <!-- 查询区域-END -->
-    
+
     <!-- 操作按钮区域 -->
     <div class="table-operator">
       <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
@@ -118,7 +118,8 @@
 
         <span slot="action" slot-scope="text, record">
           <a @click="handleEdit(record)">编辑</a>
-
+          <a-divider type="vertical" />
+          <a v-if="record.status == 0" @click="createTask(record)">生成任务</a>
           <a-divider type="vertical" />
           <a-dropdown>
             <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
@@ -153,6 +154,7 @@
   import ShipmentContainerDetailList from './ShipmentContainerDetailList'
   import {initDictOptions,filterMultiDictText} from '@/components/dict/JDictSelectUtil'
   import '@/assets/less/TableExpand.less'
+  import {createShipmentTask} from '@/api/api'
 
   export default {
     name: "ShipmentContainerHeaderList",
@@ -164,6 +166,7 @@
     data () {
       return {
         description: '出库组盘管理页面',
+        querySource:{},
         // 表头
         columns: [
           {
@@ -282,6 +285,22 @@
         this.selectedRowKeys = selectedRowKeys;
         this.selectionRows = selectionRows;
       },
+      createTask(record) {
+        this.loading = true;
+        const that = this;
+        this.model = Object.assign({}, record);
+        that.querySource.id = record.id;
+        createShipmentTask(that.querySource).then((res) => {
+          this.loading = false;
+          if (res.success) {
+            this.$message.success(res.message);
+          }
+          else {
+            this.$message.error(res.message);
+          }
+          this.searchQuery();
+        });
+      },
       loadData(arg) {
         if(!this.url.list){
           this.$message.error("请设置url.list属性!")
diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue
index c36ad1e..2385221 100644
--- a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue
@@ -112,14 +112,9 @@
         // 表头
         columns: [
           {
-            title: '#',
-            dataIndex: '',
-            key:'rowIndex',
-            width:60,
+            title:'单据详情ID',
             align:"center",
-            customRender:function (t,r,index) {
-              return parseInt(index)+1;
-            }
+            dataIndex: 'id'
           },
           {
             title:'物料编码',
@@ -164,7 +159,7 @@
           {
             title:'单据状态',
             align:"center",
-            dataIndex: 'status'
+            dataIndex: 'status_dictText',
           },
           {
             title:'创建人',
diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentHeaderList.vue b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentHeaderList.vue
index f7212fe..2d30760 100644
--- a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentHeaderList.vue
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentHeaderList.vue
@@ -166,6 +166,8 @@
         </template>
 
         <span slot="action" slot-scope="text, record">
+          <a @click="autoShipmentCombine(record)">自动配盘</a>
+          <a-divider type="vertical" />
           <a @click="handleEdit(record)">编辑</a>
 
           <a-divider type="vertical" />
@@ -205,6 +207,7 @@
   import {getCompanyList} from '@/api/api'
   import {getShipmentTypeList} from '@/api/api'
   import {getCustomerList} from '@/api/api'
+  import {autoCombination} from '@/api/api'
 
   export default {
     name: "ShipmentHeaderList",
@@ -416,6 +419,18 @@
         })
         return actions.join('')
       },
+      autoShipmentCombine(record) {
+        this.loading = true;
+        autoCombination(record).then((res) => {
+          if (res.success) {
+            this.$message.success(res.message);
+          } else {
+            this.$message.warning(res.message)
+          }
+          this.loading = false;
+          this.searchQuery();
+        });
+      },
       loadData(arg) {
         if(!this.url.list){
           this.$message.error("请设置url.list属性!")
diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/TaskHeaderList.vue b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/ReceiptTaskHeaderList.vue
index 3ec5ba4..248bfaf 100644
--- a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/TaskHeaderList.vue
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/ReceiptTaskHeaderList.vue
@@ -341,6 +341,7 @@
         }
         this.onClearSelected()
         var params = this.getQueryParams();//查询条件
+        params.innernalTaskType = 100;
         this.loading = true;
         getAction(this.url.list, params).then((res) => {
           if (res.success) {
diff --git a/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/ShipmentTaskHeaderList.vue b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/ShipmentTaskHeaderList.vue
new file mode 100644
index 0000000..4ae548f
--- /dev/null
+++ b/jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/ShipmentTaskHeaderList.vue
@@ -0,0 +1,408 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="任务类型">
+              <j-dict-select-tag placeholder="请选择任务类型" v-model="queryParam.taskType" dictCode="task_type"/>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="容器号">
+              <a-input placeholder="请输入容器号" v-model="queryParam.containerCode"></a-input>
+            </a-form-item>
+          </a-col>
+          <template v-if="toggleSearchStatus">
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="起始库位">
+                <a-input placeholder="请输入起始库位" v-model="queryParam.fromLocationCode"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="目标库位">
+                <a-input placeholder="请输入目标库位" v-model="queryParam.toLocationCode"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="是否空出">
+                <j-dict-select-tag placeholder="请选择是否空出" v-model="queryParam.isEmptyOut" dictCode="is_or_not"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="是否重入">
+                <j-dict-select-tag placeholder="请选择是否重入" v-model="queryParam.isDoubleIn" dictCode="is_or_not"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="重入库位号">
+                <a-input placeholder="请输入重入库位号" v-model="queryParam.originLocationCode"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="任务状态">
+                <j-dict-select-tag placeholder="请选择任务状态" v-model="queryParam.status" dictCode="task_header_status"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="起始出入口">
+                <a-input placeholder="请输入起始出入口" v-model="queryParam.fromPort"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="目标出入口">
+                <a-input placeholder="请输入目标出入口" v-model="queryParam.toPort"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="10" :lg="11" :md="12" :sm="24">
+              <a-form-item label="创建日期">
+                <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" class="query-group-cust" v-model="queryParam.createTime_begin"></j-date>
+                <span class="query-group-split-cust"></span>
+                <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" class="query-group-cust" v-model="queryParam.createTime_end"></j-date>
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+<!--    <div class="table-operator">-->
+<!--      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>-->
+<!--      <a-button type="primary" icon="download" @click="handleExportXls('任务表')">导出</a-button>-->
+<!--      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">-->
+<!--        <a-button type="primary" icon="import">导入</a-button>-->
+<!--      </a-upload>-->
+<!--      &lt;!&ndash; 高级查询区域 &ndash;&gt;-->
+<!--      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
+<!--    </div>-->
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        class="j-table-force-nowrap"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'radio'}"
+        :customRow="clickThenSelect"
+        @change="handleTableChange">
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a v-if="record.status == 1" @click="executeTask(record)">执行</a>
+          <a-divider type="vertical" />
+          <a v-if="record.status < 100" @click="completeTask(record)">完成</a>
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+               <a-menu-item>
+                <a @click="handleEdit(record)">编辑</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+
+    <a-tabs defaultActiveKey="1">
+      <a-tab-pane tab="任务详情" key="1" >
+        <TaskDetailList :mainId="selectedMainId" />
+      </a-tab-pane>
+    </a-tabs>
+
+    <taskHeader-modal ref="modalForm" @ok="modalFormOk"></taskHeader-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import TaskHeaderModal from './modules/TaskHeaderModal'
+  import { getAction } from '@/api/manage'
+  import TaskDetailList from './TaskDetailList'
+  import {initDictOptions,filterMultiDictText} from '@/components/dict/JDictSelectUtil'
+  import '@/assets/less/TableExpand.less'
+  import {completeTaskByWMS} from '@/api/api'
+  import {execute} from '@/api/api'
+
+  export default {
+    name: "TaskHeaderList",
+    mixins:[JeecgListMixin],
+    components: {
+      TaskDetailList,
+      TaskHeaderModal
+    },
+    data () {
+      return {
+        description: '任务表管理页面',
+        // 表头
+        columns: [
+          {
+            title:'任务ID',
+            align:"center",
+            dataIndex: 'id',
+          },
+          {
+            title:'任务类型',
+            align:"center",
+            dataIndex: 'taskType_dictText',
+          },
+          {
+            title:'容器号',
+            align:"center",
+            dataIndex: 'containerCode'
+          },
+          {
+            title:'起始库位',
+            align:"center",
+            dataIndex: 'fromLocationCode'
+          },
+          {
+            title:'目标库位',
+            align:"center",
+            dataIndex: 'toLocationCode'
+          },
+          // {
+          //   title:'是否空出',
+          //   align:"center",
+          //   dataIndex: 'isEmptyOut_dictText',
+          // },
+          {
+            title:'是否重入',
+            align:"center",
+            dataIndex: 'isDoubleIn_dictText',
+          },
+          {
+            title:'重入库位号',
+            align:"center",
+            dataIndex: 'originLocationCode'
+          },
+          {
+            title:'任务状态',
+            align:"center",
+            dataIndex: 'status_dictText',
+          },
+          {
+            title:'起始出入口',
+            align:"center",
+            dataIndex: 'fromPort'
+          },
+          {
+            title:'目标出入口',
+            align:"center",
+            dataIndex: 'toPort'
+          },
+          {
+            title:'创建人',
+            align:"center",
+            dataIndex: 'createBy'
+          },
+          {
+            title:'创建日期',
+            align:"center",
+            dataIndex: 'createTime'
+          },
+          {
+            title:'更新人',
+            align:"center",
+            dataIndex: 'updateBy'
+          },
+          {
+            title:'更新日期',
+            align:"center",
+            dataIndex: 'updateTime'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' },
+          }
+        ],
+        url: {
+          list: "/task/taskHeader/list",
+          delete: "/task/taskHeader/delete",
+          deleteBatch: "/task/taskHeader/deleteBatch",
+          exportXlsUrl: "/task/taskHeader/exportXls",
+          importExcelUrl: "task/taskHeader/importExcel",
+        },
+        dictOptions:{
+         taskType:[],
+         isEmptyOut:[],
+         isDoubleIn:[],
+         status:[],
+        },
+        /* 分页参数 */
+        ipagination:{
+          current: 1,
+          pageSize: 5,
+          pageSizeOptions: ['5', '10', '50'],
+          showTotal: (total, range) => {
+            return range[0] + "-" + range[1] + " 共" + total + "条"
+          },
+          showQuickJumper: true,
+          showSizeChanger: true,
+          total: 0
+        },
+        selectedMainId:'',
+        superFieldList:[],
+      }
+    },
+    created() {
+      this.getSuperFieldList();
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      }
+    },
+    methods: {
+      initDictConfig(){
+      },
+      clickThenSelect(record) {
+        return {
+          on: {
+            click: () => {
+              this.onSelectChange(record.id.split(","), [record]);
+            }
+          }
+        }
+      },
+      onClearSelected() {
+        this.selectedRowKeys = [];
+        this.selectionRows = [];
+        this.selectedMainId=''
+      },
+      onSelectChange(selectedRowKeys, selectionRows) {
+        this.selectedMainId=selectedRowKeys[0]
+        this.selectedRowKeys = selectedRowKeys;
+        this.selectionRows = selectionRows;
+      },
+      loadData(arg) {
+        if(!this.url.list){
+          this.$message.error("请设置url.list属性!")
+          return
+        }
+        //加载数据 若传入参数1则加载第一页的内容
+        if (arg === 1) {
+          this.ipagination.current = 1;
+        }
+        this.onClearSelected()
+        var params = this.getQueryParams();//查询条件
+        params.innernalTaskType = 200; //只差出库任务
+        this.loading = true;
+        getAction(this.url.list, params).then((res) => {
+          if (res.success) {
+            this.dataSource = res.result.records;
+            this.ipagination.total = res.result.total;
+          }
+          if(res.code===510){
+            this.$message.warning(res.message)
+          }
+          this.loading = false;
+        })
+      },
+      completeTask(record) {
+        this.loading = true;
+        this.model = Object.assign({}, record);
+        completeTaskByWMS(this.model).then((res) => {
+          this.loading = false;
+          if (res.success) {
+            this.$message.success(res.message);
+          }
+          else {
+            this.$message.error(res.message);
+          }
+          this.searchQuery();
+        });
+      },
+      executeTask(record) {
+        this.loading = true;
+        this.model = Object.assign({}, record);
+        execute(this.model).then((res) => {
+          this.loading = false;
+          if (res.success) {
+            this.$message.success(res.message);
+          }
+          else {
+            this.$message.error(res.message);
+          }
+          this.searchQuery();
+        });
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'int',value:'taskType',text:'任务类型',dictCode:'task_type'})
+        fieldList.push({type:'string',value:'containerCode',text:'容器号',dictCode:''})
+        fieldList.push({type:'string',value:'fromLocationCode',text:'起始库位',dictCode:''})
+        fieldList.push({type:'string',value:'toLocationCode',text:'目标库位',dictCode:''})
+        fieldList.push({type:'string',value:'isEmptyOut',text:'是否空出',dictCode:'is_or_not'})
+        fieldList.push({type:'int',value:'isDoubleIn',text:'是否重入',dictCode:'is_or_not'})
+        fieldList.push({type:'string',value:'originLocationCode',text:'重入库位号',dictCode:''})
+        fieldList.push({type:'int',value:'status',text:'任务状态',dictCode:'task_header_status'})
+        fieldList.push({type:'string',value:'fromPort',text:'起始出入口',dictCode:''})
+        fieldList.push({type:'string',value:'toPort',text:'目标出入口',dictCode:''})
+        fieldList.push({type:'string',value:'createBy',text:'创建人',dictCode:''})
+        fieldList.push({type:'datetime',value:'createTime',text:'创建日期'})
+        fieldList.push({type:'string',value:'updateBy',text:'更新人',dictCode:''})
+        fieldList.push({type:'datetime',value:'updateTime',text:'更新日期'})
+        this.superFieldList = fieldList
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less'
+</style>
\ No newline at end of file
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/IContainerService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/IContainerService.java
index 31ffed9..054f64f 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/IContainerService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/IContainerService.java
@@ -20,4 +20,6 @@ public interface IContainerService extends IService<Container> {
 
     boolean updateLocationCodeAndStatus(String containerCode, String locationCode,
                                      String status, String warehouseCode);
+    //创建零时容器
+    Container createLSContainer(String warehouseCode);
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java
index facedc6..7f7cfe8 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java
@@ -1,5 +1,6 @@
 package org.jeecg.modules.wms.config.container.service.impl;
 
+import com.aliyun.oss.ServiceException;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.jeecg.common.api.vo.Result;
@@ -7,12 +8,15 @@ import org.jeecg.modules.wms.config.container.entity.Container;
 import org.jeecg.modules.wms.config.container.mapper.ContainerMapper;
 import org.jeecg.modules.wms.config.container.service.IContainerService;
 import org.jeecg.modules.wms.config.containerType.service.IContainerTypeService;
+import org.jeecg.utils.constant.QuantityConstant;
 import org.springframework.stereotype.Service;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
 import javax.annotation.Resource;
+import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 
@@ -84,6 +88,21 @@ public class ContainerServiceImpl extends ServiceImpl<ContainerMapper, Container
         return result;
     }
 
+    @Override
+    public Container createLSContainer(String warehouseCode) {
+        String code = MessageFormat.format("{0}{1}",
+                "LS",
+                String.format("%d", Calendar.getInstance().getTimeInMillis()));
+        Container container = new Container();
+        container.setCode(code);
+        container.setWarehouseCode(warehouseCode);
+        container.setStatus(QuantityConstant.STATUS_CONTAINER_EMPTY);
+        if (!save(container)){
+            throw new ServiceException("新增容器失败");
+        }
+        return container;
+    }
+
 
     private int getStartNumber(String containerTypeCode, String warehouseCode) {
         LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery();
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryDetailService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryDetailService.java
index b8f63cd..74eb349 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryDetailService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryDetailService.java
@@ -16,4 +16,6 @@ public interface IInventoryDetailService extends IService<InventoryDetail> {
 	public List<InventoryDetail> selectByMainId(String mainId);
 
 	List<InventoryDetail> getInventoryDetailListByInventoryHeaderId(Integer inventoryHeaderId);
+
+	List<InventoryDetail> getInventoryDetailListByContainerCode(String containerCode, String warehouseCode);
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
index 37c88d3..012d6d5 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
@@ -36,4 +36,13 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe
 		List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
 		return inventoryDetailList;
 	}
+
+	@Override
+	public List<InventoryDetail> getInventoryDetailListByContainerCode(String containerCode, String warehouseCode) {
+		LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+		inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getContainerCode, containerCode)
+										.eq(InventoryDetail::getWarehouseCode, warehouseCode);
+		List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
+		return inventoryDetailList;
+	}
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/controller/ReceiptContainerHeaderController.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/controller/ReceiptContainerHeaderController.java
index df5b14d..df618e5 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/controller/ReceiptContainerHeaderController.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/controller/ReceiptContainerHeaderController.java
@@ -296,11 +296,11 @@ public class ReceiptContainerHeaderController extends JeecgController<ReceiptCon
 	  * @return
 	  */
 	 @ApiOperation(value="入库组盘-创建任务", notes="入库组盘-创建任务")
-	 @PostMapping("/createTask")
+	 @PostMapping("/createReceiptTask")
 	 @ResponseBody
-	 public Result createTask(@RequestBody ReceiptContainerHeader receiptContainerHeader, HttpServletRequest req) {
+	 public Result createReceiptTask(@RequestBody ReceiptContainerHeader receiptContainerHeader, HttpServletRequest req) {
 		 String warehouseCode = JwtUtil.getWarehouseCodeByToken(req);
-		 return receiptContainerHeaderService.createTask(receiptContainerHeader, warehouseCode);
+		 return receiptContainerHeaderService.createReceiptTask(receiptContainerHeader, warehouseCode);
 	 }
 
 
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerDetailService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerDetailService.java
index c11206f..64411b1 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerDetailService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerDetailService.java
@@ -14,4 +14,6 @@ import java.util.List;
 public interface IReceiptContainerDetailService extends IService<ReceiptContainerDetail> {
 
 	public List<ReceiptContainerDetail> selectByMainId(String mainId);
+
+	public List<ReceiptContainerDetail> getReceiptContainerDetailListByHeaderId(int receiptContainerHeaderId);
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerHeaderService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerHeaderService.java
index 157a5ea..02a84d0 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerHeaderService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerHeaderService.java
@@ -30,7 +30,12 @@ public interface IReceiptContainerHeaderService extends IService<ReceiptContaine
 
 	ReceiptContainerHeader getUnCompleteReceiptContainerByCode(String containerCode, String warehouseCode);
 
-	public Result createTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode);
+	public Result createReceiptTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode);
 
 	boolean updateStatusById(int status, int id);
+
+	// 获取没有完成的入库组盘
+	List<ReceiptContainerHeader> getUnCompleteCombineList();
+
+	boolean havaUnCompleteCombine(String containerCode, String warehouseCode);
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerDetailServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerDetailServiceImpl.java
index ebc0b4d..33e55ef 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerDetailServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerDetailServiceImpl.java
@@ -1,5 +1,7 @@
 package org.jeecg.modules.wms.receipt.receiptContainerHeader.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerDetail;
 import org.jeecg.modules.wms.receipt.receiptContainerHeader.mapper.ReceiptContainerDetailMapper;
 import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptContainerDetailService;
@@ -24,4 +26,12 @@ public class ReceiptContainerDetailServiceImpl extends ServiceImpl<ReceiptContai
 	public List<ReceiptContainerDetail> selectByMainId(String mainId) {
 		return receiptContainerDetailMapper.selectByMainId(mainId);
 	}
+
+	@Override
+	public List<ReceiptContainerDetail> getReceiptContainerDetailListByHeaderId(int receiptContainerHeaderId) {
+		LambdaQueryWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+		receiptContainerDetailLambdaQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeaderId);
+		List<ReceiptContainerDetail> receiptContainerDetailList = list(receiptContainerDetailLambdaQueryWrapper);
+		return receiptContainerDetailList;
+	}
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
index 2176053..a229f8c 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
@@ -93,7 +93,7 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl<ReceiptContai
 
 	@Override
 	@Transactional
-	public Result createTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode) {
+	public Result createReceiptTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode) {
 		int id = receiptContainerHeader.getId();
 		receiptContainerHeader = this.getById(id);
 		if (receiptContainerHeader == null) {
@@ -107,11 +107,9 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl<ReceiptContai
 		if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
 			return Result.error("托盘已经锁定,不能生成任务");
 		}
-		LambdaQueryWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
-		receiptContainerDetailLambdaQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId());
 		List<ReceiptContainerDetail> receiptContainerDetailList =
-				receiptContainerDetailService.list(receiptContainerDetailLambdaQueryWrapper);
-		if(receiptContainerDetailList.isEmpty()) {
+				receiptContainerDetailService.getReceiptContainerDetailListByHeaderId(receiptContainerHeader.getId());
+		if(receiptContainerDetailList.size() == 0) {
 			return Result.error("id:" + id + "的入库组盘,没有组盘明细,请先组盘!");
 		}
 		boolean result = containerService.updateStatus(containerCode,
@@ -233,4 +231,26 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl<ReceiptContai
 		return success;
 	}
 
+	@Override
+	public List<ReceiptContainerHeader> getUnCompleteCombineList() {
+		LambdaQueryWrapper<ReceiptContainerHeader> receiptContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+		receiptContainerHeaderLambdaQueryWrapper
+				.lt(ReceiptContainerHeader::getStatus, QuantityConstant.RECEIPT_CONTAINER_FINISHED);
+		List<ReceiptContainerHeader> receiptContainerHeaderList = list(receiptContainerHeaderLambdaQueryWrapper);
+		return receiptContainerHeaderList;
+	}
+
+	@Override
+	public boolean havaUnCompleteCombine(String containerCode, String warehouseCode) {
+		LambdaQueryWrapper<ReceiptContainerHeader> receiptContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+		receiptContainerHeaderLambdaQueryWrapper.eq(ReceiptContainerHeader::getContainerCode, containerCode)
+				.eq(ReceiptContainerHeader::getWarehouseCode, warehouseCode)
+				.lt(ReceiptContainerHeader::getStatus, QuantityConstant.RECEIPT_CONTAINER_FINISHED);
+		ReceiptContainerHeader receiptContainerHeader = getOne(receiptContainerHeaderLambdaQueryWrapper);
+		if(receiptContainerHeader != null)  {
+			return true;
+		}
+		return false;
+	}
+
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java
index 3a87ed9..df13a30 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java
@@ -51,6 +51,10 @@ public class ReceiptHeaderServiceImpl extends ServiceImpl<ReceiptHeaderMapper, R
 	@Override
 	@Transactional
 	public void delMain(String id) {
+		ReceiptHeader receiptHeader = getById(id);
+		if(receiptHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
+			throw new ServiceException("不能删除非新建状态单据");
+		}
 		receiptDetailMapper.deleteByMainId(id);
 		receiptHeaderMapper.deleteById(id);
 	}
@@ -59,6 +63,10 @@ public class ReceiptHeaderServiceImpl extends ServiceImpl<ReceiptHeaderMapper, R
 	@Transactional
 	public void delBatchMain(Collection<? extends Serializable> idList) {
 		for(Serializable id:idList) {
+			ReceiptHeader receiptHeader = getById(id);
+			if(receiptHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
+				throw new ServiceException("不能删除非新建状态单据");
+			}
 			receiptDetailMapper.deleteByMainId(id.toString());
 			receiptHeaderMapper.deleteById(id);
 		}
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/controller/ReceiveController.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/controller/ReceiveController.java
index d343666..d5fbb1c 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/controller/ReceiveController.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/controller/ReceiveController.java
@@ -5,6 +5,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.system.util.JwtUtil;
 import org.jeecg.modules.wms.config.container.entity.Container;
@@ -71,6 +72,7 @@ public class ReceiveController {
      * 收货
      * @return
      */
+    @AutoLog("入库单-收货")
     @ApiOperation(value="入库单-收货", notes="入库单-收货")
     @PostMapping("/receiving")
     @ResponseBody
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/service/impl/ReceiveServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/service/impl/ReceiveServiceImpl.java
index 19f8ef6..3870531 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/service/impl/ReceiveServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/service/impl/ReceiveServiceImpl.java
@@ -64,7 +64,7 @@ public class ReceiveServiceImpl extends ServiceImpl<ReceiveMapper, Receive>  imp
      * 7.更新入库单状态
      */
     @Override
-    @Transactional
+    @Transactional(rollbackFor = ServiceException.class)
     public Result receiving(List<Receive> receiveList, String warehouseCode) {
         boolean result = false;
         if(receiveList == null || receiveList.size() == 0) {
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/controller/shipmentCombinationController.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/controller/shipmentCombinationController.java
new file mode 100644
index 0000000..3d12c08
--- /dev/null
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/controller/shipmentCombinationController.java
@@ -0,0 +1,84 @@
+package org.jeecg.modules.wms.shipment.shipmentCombination.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
+import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
+import org.jeecg.modules.wms.receipt.receiving.domain.Receive;
+import org.jeecg.modules.wms.shipment.shipmentCombination.service.IShipmentCombinationService;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
+import org.jeecg.utils.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * @author 游杰
+ */
+@Api(tags="入库表主表")
+@RestController
+@RequestMapping("/shipment/shipmentCombination")
+@Slf4j
+public class shipmentCombinationController {
+
+    @Resource
+    private IShipmentDetailService shipmentDetailService;
+    @Resource
+    private IShipmentCombinationService shipmentCombinationService;
+
+    /**
+     * 获取单据列表
+     * @param shipmentCode
+     * @return
+     */
+    @GetMapping("/getShipmentDetailListByShipmentCode")
+    @ResponseBody
+    public Result getShipmentDetailListByShipmentCode(String shipmentCode, HttpServletRequest req) {
+        if(StringUtils.isEmpty(shipmentCode)){
+            return null;
+        }
+        String warehouseCode = JwtUtil.getWarehouseCodeByToken(req);
+        LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+        shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getShipmentCode, shipmentCode)
+                .eq(ShipmentDetail::getWarehouseCode, warehouseCode);
+        List<ShipmentDetail> shipmentDetails = shipmentDetailService.list(shipmentDetailLambdaQueryWrapper) ;
+        return Result.ok(shipmentDetails);
+    }
+
+    /**
+     * 自动组盘
+     * @return
+     */
+    @AutoLog("出库单-自动配盘")
+    @ApiOperation(value="出库单-自动配盘", notes="出库单-自动配盘")
+    @PostMapping("/autoCombination")
+    @ResponseBody
+    public Result autoCombination(@RequestBody ShipmentHeader shipmentHeader) {
+        String shipmentCode = shipmentHeader.getCode();
+        String warehouseCode = shipmentHeader.getWarehouseCode();
+        return shipmentCombinationService.autoCombination(shipmentCode, warehouseCode);
+    }
+
+    /**
+     * 创建任务
+     * @return
+     */
+    @ApiOperation(value="入库组盘-创建任务", notes="入库组盘-创建任务")
+    @PostMapping("/createShipmentTask")
+    @ResponseBody
+    public Result createShipmentTask(@RequestBody ShipmentContainerHeader shipmentContainerHeader, HttpServletRequest req) {
+        String warehouseCode = JwtUtil.getWarehouseCodeByToken(req);
+        return shipmentCombinationService.createShipmentTask(shipmentContainerHeader, warehouseCode);
+    }
+}
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/entity/CombinationModel.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/entity/CombinationModel.java
new file mode 100644
index 0000000..cc1425e
--- /dev/null
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/entity/CombinationModel.java
@@ -0,0 +1,19 @@
+package org.jeecg.modules.wms.shipment.shipmentCombination.entity;
+
+import lombok.Data;
+import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
+
+import java.math.BigDecimal;
+
+@Data
+public class CombinationModel {
+
+    //组盘时的出库明细Id
+    private ShipmentDetail shipmentDetail;
+    //组盘时选择的库存
+    private InventoryDetail inventoryDetail;
+    //组盘数量
+    private BigDecimal shipQty;
+
+}
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java
new file mode 100644
index 0000000..afbb188
--- /dev/null
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java
@@ -0,0 +1,27 @@
+package org.jeecg.modules.wms.shipment.shipmentCombination.service;
+
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
+import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
+import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
+
+import java.util.List;
+
+/**
+ * @author 游杰
+ */
+public interface IShipmentCombinationService {
+
+    public List<InventoryDetail> getInventorys(ShipmentDetail shipmentDetail);
+
+    public Result autoCombination(String shipmentCode, String warehouseCode);
+
+    public Result autoCombination(ShipmentDetail shipmentDetail);
+
+    public Result combination(CombinationModel combinationModel);
+
+    public Result createShipmentTask(ShipmentContainerHeader shipmentContainerHeader, String warehouseCode);
+}
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
new file mode 100644
index 0000000..8f625b3
--- /dev/null
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
@@ -0,0 +1,549 @@
+package org.jeecg.modules.wms.shipment.shipmentCombination.service.impl;
+
+import com.aliyun.oss.ServiceException;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.wms.config.container.entity.Container;
+import org.jeecg.modules.wms.config.container.service.IContainerService;
+import org.jeecg.modules.wms.config.location.entity.Location;
+import org.jeecg.modules.wms.config.location.service.ILocationService;
+import org.jeecg.modules.wms.config.material.entity.Material;
+import org.jeecg.modules.wms.config.material.service.IMaterialService;
+import org.jeecg.modules.wms.config.parameterConfiguration.entity.ParameterConfiguration;
+import org.jeecg.modules.wms.config.parameterConfiguration.service.IParameterConfigurationService;
+import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
+import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
+import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
+import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
+import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptContainerHeaderService;
+import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
+import org.jeecg.modules.wms.shipment.shipmentCombination.service.IShipmentCombinationService;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
+import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail;
+import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
+import org.jeecg.modules.wms.task.taskHeader.service.ITaskDetailService;
+import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
+import org.jeecg.utils.StringUtils;
+import org.jeecg.utils.constant.QuantityConstant;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 游杰
+ */
+@Service
+public class ShipmentCombinationServiceImpl implements IShipmentCombinationService {
+
+    @Resource
+    private IInventoryDetailService inventoryDetailService;
+    @Resource
+    private IShipmentHeaderService shipmentHeaderService;
+    @Resource
+    private IShipmentDetailService shipmentDetailService;
+    @Resource
+    private IReceiptContainerHeaderService receiptContainerHeaderService;
+    @Resource
+    private IShipmentContainerHeaderService shipmentContainerHeaderService;
+    @Resource
+    private IContainerService containerService;
+    @Resource
+    private ILocationService locationService;
+    @Resource
+    private IShipmentContainerDetailService shipmentContainerDetailService;
+    @Resource
+    private IMaterialService materialService;
+    @Resource
+    private IParameterConfigurationService parameterConfigurationService;
+    @Resource
+    private ITaskHeaderService taskHeaderService;
+    @Resource
+    private ITaskDetailService taskDetailService;
+
+    /**
+     * 根据出库单详情,匹配到可用出库的库存详情
+     * 默认匹配条件是 仓库,货主,物料编码,库存状态,批次 是一致的就可以出库
+     * @param shipmentDetail
+     * @return
+     */
+    @Override
+    public List<InventoryDetail> getInventorys(ShipmentDetail shipmentDetail) {
+        String warehouseCode = shipmentDetail.getWarehouseCode();
+        String companyCode = shipmentDetail.getCompanyCode();
+        String materialCode = shipmentDetail.getMaterialCode();
+        String inventoryStatus = shipmentDetail.getInventoryStatus();
+        String batch = shipmentDetail.getBatch();
+        int shipmentId = shipmentDetail.getShipmentId();
+        if(StringUtils.isEmpty(warehouseCode)) {
+            throw new ServiceException("寻找库存详情时,出库详情没有仓库编码");
+        }
+        if(StringUtils.isEmpty(companyCode)) {
+            throw new ServiceException("寻找库存详情时,出库详情没有货主编码");
+        }
+        if(StringUtils.isEmpty(materialCode)) {
+            throw new ServiceException("寻找库存详情时, 出库详情没有物料编码");
+        }
+        if(StringUtils.isEmpty(inventoryStatus)) {
+            throw new ServiceException("寻找库存详情时, 出库详情没有物料品质");
+        }
+        LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+        inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getWarehouseCode, warehouseCode)
+                                        .eq(InventoryDetail::getCompanyCode, companyCode)
+                                        .eq(InventoryDetail::getMaterialCode, materialCode)
+                                        .eq(InventoryDetail::getInventoryStatus, inventoryStatus);
+        List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper);
+        return inventoryDetailList;
+    }
+
+    @Override
+    @Transactional(rollbackFor = ServiceException.class)
+    public Result autoCombination(String shipmentCode, String warehouseCode) {
+        LambdaQueryWrapper<ShipmentHeader> shipmentHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+        shipmentHeaderLambdaQueryWrapper.eq(ShipmentHeader::getWarehouseCode, warehouseCode)
+                .eq(ShipmentHeader::getCode, shipmentCode);
+        ShipmentHeader shipmentHeader = shipmentHeaderService.getOne(shipmentHeaderLambdaQueryWrapper);
+        if(shipmentHeader == null) {
+            throw new ServiceException("系统没有此单据");
+        }
+        if(shipmentHeader.getLastStatus() >= QuantityConstant.SHIPMENT_HEADER_COMPLETED) {
+            return Result.OK("出库单已经作业完毕");
+        }
+        LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+        shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getShipmentCode, shipmentCode)
+                .eq(ShipmentDetail::getWarehouseCode, warehouseCode);
+        List<ShipmentDetail> shipmentDetailList = shipmentDetailService.list(shipmentDetailLambdaQueryWrapper);
+        boolean over = true;
+        for(ShipmentDetail shipmentDetail : shipmentDetailList) {
+            if(shipmentDetail.getTaskQty().compareTo(shipmentDetail.getQty()) < 0) {
+                over = false;
+            }
+            Result result = autoCombination(shipmentDetail);
+            if(!result.isSuccess()) {
+                throw new ServiceException(result.getMessage());
+            }
+        }
+        if(over) {
+            return Result.OK("出库单已经配盘");
+        }
+        return Result.OK("自动组盘成功");
+    }
+
+    @Override
+    @Transactional(rollbackFor = ServiceException.class)
+    public Result autoCombination(ShipmentDetail shipmentDetail) {
+        //出库数量
+        BigDecimal shipmentQty = shipmentDetail.getQty().subtract(shipmentDetail.getTaskQty());
+        //判断是否还有需要出库的物料,如果没有就跳过该物料
+        if (shipmentQty.compareTo(BigDecimal.ZERO) <= 0) {
+             return Result.OK("出库数量必须大于0");
+        }
+        List<InventoryDetail> inventoryList = getInventorys(shipmentDetail);
+        //去除已锁的库存
+        ArrayList<InventoryDetail> removeInventoryList = new ArrayList<>();
+        List<ReceiptContainerHeader> receiptContainerHeaderList =
+                receiptContainerHeaderService.getUnCompleteCombineList();
+        List<ShipmentContainerHeader> shipmentContainerHeaderList =
+                shipmentContainerHeaderService.getUnCompleteCombineList();
+        for (InventoryDetail inventoryDetail : inventoryList) {
+            String containerCode = inventoryDetail.getContainerCode();
+            String warehouseCode = inventoryDetail.getWarehouseCode();
+            Container container = containerService.getContainerByCode(
+                    containerCode, warehouseCode);
+            if(container == null) {
+                return Result.error("自动配盘时,没有找到容器:" + containerCode);
+            }
+            if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
+                removeInventoryList.add(inventoryDetail);
+                continue;
+            }
+            for(ReceiptContainerHeader receiptContainerHeader : receiptContainerHeaderList) {
+                if(receiptContainerHeader.getContainerCode().equals(containerCode)) {
+                    removeInventoryList.add(inventoryDetail);
+                    continue;
+                }
+            }
+            for(ShipmentContainerHeader shipmentContainerHeader : shipmentContainerHeaderList) {
+                if(shipmentContainerHeader.getContainerCode().equals(containerCode)) {
+                    removeInventoryList.add(inventoryDetail);
+                    continue;
+                }
+            }
+        }
+        inventoryList.removeAll(removeInventoryList);
+        if (inventoryList.size() < 1){
+            return Result.error(shipmentDetail.getMaterialName()+"' 没有符合出库条件的库存");
+        }
+
+        for (InventoryDetail inventoryDetail : inventoryList) {
+            //判断需要配盘数量是否等于0,等于0代表配盘完毕,完毕就退出内循环
+            if (shipmentQty.compareTo(BigDecimal.ZERO) == 0) {
+                break;
+            }
+            if (shipmentQty.compareTo(BigDecimal.ZERO) < 0) {
+               throw new ServiceException("配盘时,出库数量不能小于0");
+            }
+            CombinationModel combinationModel = new CombinationModel();
+            combinationModel.setShipmentDetail(shipmentDetail);
+            combinationModel.setInventoryDetail(inventoryDetail);
+            BigDecimal inventoryQty = inventoryDetail.getQty().subtract(inventoryDetail.getTaskQty());
+            if (inventoryQty.compareTo(shipmentQty) >= 0) {
+                combinationModel.setShipQty(shipmentQty);
+                shipmentQty = BigDecimal.ZERO;
+            } else {
+                combinationModel.setShipQty(inventoryQty);
+                shipmentQty = shipmentQty.subtract(inventoryQty);
+            }
+            Result result = combination(combinationModel);
+            if(!result.isSuccess()) {
+                throw new ServiceException(result.getMessage());
+            }
+        }
+        return Result.OK("自动组盘成功");
+    }
+
+    @Override
+    @Transactional(rollbackFor = ServiceException.class)
+    public Result combination(CombinationModel combinationModel) {
+        BigDecimal shipmentQty = combinationModel.getShipQty();
+        ShipmentDetail shipmentDetail = combinationModel.getShipmentDetail();
+        InventoryDetail inventoryDetail = combinationModel.getInventoryDetail();
+        if(shipmentQty.compareTo(BigDecimal.ZERO) <= 0) {
+            return Result.error("配盘时,出库数量必须大于0");
+        }
+        if(shipmentDetail == null){
+            return Result.error("配盘时,出库明细未找到");
+        }
+        if(inventoryDetail == null){
+            return Result.error("配盘时,库存未找到");
+        }
+        String containerCode = inventoryDetail.getContainerCode();
+        String warehouseCode = inventoryDetail.getWarehouseCode();
+        String locationCode = inventoryDetail.getLocationCode();
+        if(!warehouseCode.equals(shipmentDetail.getWarehouseCode())) {
+            return Result.error("配盘时,库存仓库编码和出库单仓库编码不一致");
+        }
+        boolean success = receiptContainerHeaderService.havaUnCompleteCombine(containerCode, warehouseCode);
+        if(success) {
+            return Result.error("配盘时, 容器:" + containerCode + " 已经用于入库组盘");
+        }
+        Location location = locationService.getLocationByCode(locationCode, warehouseCode);
+        if(location == null) {
+            return Result.error("配盘时, 没有找到库位, 编码" + locationCode);
+        }
+        Container container = containerService.getContainerByCode(containerCode, warehouseCode);
+        if(container == null) {
+            return Result.error("配盘时, 没有找到容器, 编码" + containerCode);
+        }
+        if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
+            return Result.error("配盘时, 托盘已经锁定,不能再组盘");
+        }
+        BigDecimal shipmentDetailQty = shipmentDetail.getQty();
+        BigDecimal shipmentDetailTaskQty = shipmentDetail.getTaskQty();
+        //可出数量
+        BigDecimal shipmentDetailAvailableQty = shipmentDetailQty.subtract(shipmentDetailTaskQty);
+        if(shipmentDetailAvailableQty.compareTo(shipmentQty) < 0) {
+            return Result.error("配盘时, 录入数量超出出库单明细待出数量");
+        }
+        BigDecimal inventoryDetailQty = inventoryDetail.getQty();
+        BigDecimal inventoryDetailTaskQty = inventoryDetail.getTaskQty();
+        BigDecimal inventoryDetailAvailableQty = inventoryDetailQty.subtract(inventoryDetailTaskQty);
+        if(inventoryDetailAvailableQty.compareTo(shipmentQty) < 0) {
+            return Result.error("配盘时, 录入数量超出库存详情待出数量");
+        }
+        if(!shipmentDetail.getMaterialCode().equals(inventoryDetail.getMaterialCode())){
+            return Result.error("配盘时, 配盘物料不一致");
+        }
+        inventoryDetailTaskQty = inventoryDetailTaskQty.add(shipmentQty);
+        if(inventoryDetailTaskQty.compareTo(BigDecimal.ZERO) <= 0) {
+            return Result.error("配盘时, 库存详情的任务数量必须大于0");
+        }
+        if(inventoryDetailTaskQty.compareTo(inventoryDetailQty) > 0) {
+            return Result.error("配盘时, 库存详情的任务数量不能超过库存数量");
+        }
+        inventoryDetail.setTaskQty(inventoryDetailTaskQty);
+        success = inventoryDetailService.updateById(inventoryDetail);
+        if(!success) {
+            throw new ServiceException("配盘时, 更新库存详情失败");
+        }
+        shipmentDetailTaskQty = shipmentDetailTaskQty.add(shipmentQty);
+        if(shipmentDetailTaskQty.compareTo(BigDecimal.ZERO) <= 0) {
+            return Result.error("配盘时, 出库详情的任务数量必须大于0");
+        }
+        if(shipmentDetailTaskQty.compareTo(shipmentDetailQty) > 0) {
+            return Result.error("配盘时, 出库详情的任务数量不能超过单据数量");
+        } else if(inventoryDetailTaskQty.compareTo(inventoryDetailQty) == 0) {
+            shipmentDetail.setStatus(QuantityConstant.SHIPMENT_HEADER_COMPLETED);
+        } else if(inventoryDetailTaskQty.compareTo(inventoryDetailQty) < 0) {
+            shipmentDetail.setStatus(QuantityConstant.SHIPMENT_HEADER_OFF_SHELF);
+        }
+        shipmentDetail.setTaskQty(shipmentDetailTaskQty);
+        success = shipmentDetailService.updateById(shipmentDetail);
+        if(!success) {
+            throw new ServiceException("配盘时, 更新出库详情失败");
+        }
+        ShipmentContainerHeader shipmentContainerHeader = addShipmentContainerHeader(inventoryDetail, shipmentDetail);
+        if(shipmentContainerHeader == null) {
+            throw new ServiceException("配盘时, 新增出库组盘头失败");
+        }
+        ShipmentContainerDetail shipmentContainerDetail = addShipmentContainerDetail(shipmentContainerHeader, combinationModel);
+        if(shipmentContainerDetail == null) {
+            throw new ServiceException("配盘时, 新增出库组盘详情失败");
+        }
+        success = shipmentHeaderService.updateShipmentHeaderStatus(shipmentDetail.getShipmentId());
+        if(!success) {
+            throw new ServiceException("配盘时, 更新出库单失败");
+        }
+        return Result.ok("配盘成功");
+    }
+
+    @Transactional(rollbackFor = ServiceException.class)
+    public ShipmentContainerHeader addShipmentContainerHeader(InventoryDetail inventoryDetail,
+                                                               ShipmentDetail shipmentDetail) {
+        String containerCode = inventoryDetail.getContainerCode();
+        String warehouseCode = inventoryDetail.getWarehouseCode();
+        String locationCode = inventoryDetail.getLocationCode();
+        Container container = containerService.getContainerByCode(containerCode, warehouseCode);
+        LambdaQueryWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+        shipmentContainerHeaderLambdaQueryWrapper.eq(ShipmentContainerHeader::getContainerCode, containerCode)
+                                                .eq(ShipmentContainerHeader::getFromLocationCode, locationCode)
+                                                .eq(ShipmentContainerHeader::getWarehouseCode, warehouseCode)
+                                                .lt(ShipmentContainerHeader::getStatus,QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
+        ShipmentContainerHeader shipmentContainerHeader = shipmentContainerHeaderService.getOne(shipmentContainerHeaderLambdaQueryWrapper);
+        if(shipmentContainerHeader != null)  {
+            return shipmentContainerHeader;
+        } else {
+            List<InventoryDetail> inventoryDetailList = inventoryDetailService.getInventoryDetailListByContainerCode(containerCode, warehouseCode);
+            int taskType = QuantityConstant.TASK_TYPE_WHOLESHIPMENT;
+            // 如果库存还有剩余,那么就是分拣出库
+            if(inventoryDetailList != null && inventoryDetailList.size() > 0) {
+                for(InventoryDetail inventoryDetail1 : inventoryDetailList) {
+                    if(inventoryDetail1.getQty().subtract(inventoryDetail1.getTaskQty()).
+                            compareTo(BigDecimal.ZERO) > 0) {
+                        taskType = QuantityConstant.TASK_TYPE_SORTINGSHIPMENT;
+                    }
+                }
+            }
+            shipmentContainerHeader = new ShipmentContainerHeader();
+            shipmentContainerHeader.setContainerCode(containerCode);
+            shipmentContainerHeader.setFromLocationCode(locationCode);
+            shipmentContainerHeader.setWarehouseCode(warehouseCode);
+            shipmentContainerHeader.setCompanyCode(shipmentDetail.getCompanyCode());
+            shipmentContainerHeader.setContainerTypeCode(container.getContainerTypeCode());
+            shipmentContainerHeader.setToPort(shipmentDetail.getToPort());
+            shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_BUILD);
+            shipmentContainerHeader.setTaskType(taskType);
+            boolean success = shipmentContainerHeaderService.save(shipmentContainerHeader);
+            if (!success) {
+                 throw new ServiceException("新增出库组盘头失败");
+            }
+            return shipmentContainerHeader;
+        }
+    }
+
+    @Transactional(rollbackFor = ServiceException.class)
+    public ShipmentContainerDetail addShipmentContainerDetail(ShipmentContainerHeader shipmentContainerHeader,
+                                                              CombinationModel combinationModel) {
+        boolean success = false;
+        BigDecimal shipmentQty = combinationModel.getShipQty();
+        ShipmentDetail shipmentDetail = combinationModel.getShipmentDetail();
+        InventoryDetail inventoryDetail = combinationModel.getInventoryDetail();
+        String containerCode = inventoryDetail.getContainerCode();
+        String warehouseCode = inventoryDetail.getWarehouseCode();
+        String locationCode = inventoryDetail.getLocationCode();
+        String materialCode = inventoryDetail.getMaterialCode();
+        LambdaQueryWrapper<ShipmentContainerDetail> shipmentContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+        shipmentContainerDetailLambdaQueryWrapper.eq(ShipmentContainerDetail::getShipmentContainerId, shipmentContainerHeader.getId())
+                .eq(ShipmentContainerDetail::getShipmentDetailId, shipmentDetail.getId())
+                .eq(ShipmentContainerDetail::getInventoryDetailId, inventoryDetail.getId())
+                .eq(ShipmentContainerDetail::getWarehouseCode, warehouseCode);
+        ShipmentContainerDetail shipmentContainerDetail = shipmentContainerDetailService.getOne(shipmentContainerDetailLambdaQueryWrapper);
+        if(shipmentContainerDetail != null) {
+            shipmentContainerDetail.setQty(shipmentContainerDetail.getQty().add(combinationModel.getShipQty()));
+            success = shipmentContainerDetailService.updateById(shipmentContainerDetail);
+            if(!success) {
+                throw new ServiceException("更新出库组盘详情失败");
+            }
+        } else {
+            Material material = materialService.getMaterialByCode(materialCode);
+            if (material == null) {
+                throw new ServiceException("出库单(" + shipmentDetail.getShipmentCode() + ")的物料(" + materialCode + ")不存在!");
+            }
+            shipmentContainerDetail = new ShipmentContainerDetail();
+            shipmentContainerDetail.setWarehouseCode(shipmentContainerHeader.getWarehouseCode());
+            shipmentContainerDetail.setCompanyCode(shipmentDetail.getCompanyCode());
+            shipmentContainerDetail.setContainerCode(shipmentContainerHeader.getContainerCode());
+            shipmentContainerDetail.setFromLocationCode(shipmentContainerHeader.getFromLocationCode());
+            shipmentContainerDetail.setToLocationCode(shipmentContainerHeader.getToLocationCode());
+            shipmentContainerDetail.setInventoryDetailId(inventoryDetail.getId());
+            shipmentContainerDetail.setInventoryStatus(shipmentDetail.getInventoryStatus());
+            shipmentContainerDetail.setShipmentCode(shipmentDetail.getShipmentCode());
+            shipmentContainerDetail.setShipmentId(shipmentDetail.getShipmentId());
+            shipmentContainerDetail.setShipmentDetailId(shipmentDetail.getId());
+            shipmentContainerDetail.setShipmentContainerId(shipmentContainerHeader.getId());
+            shipmentContainerDetail.setMaterialCode(shipmentDetail.getMaterialCode());
+            shipmentContainerDetail.setMaterialName(shipmentDetail.getMaterialName());
+            shipmentContainerDetail.setMaterialSpec(shipmentDetail.getMaterialSpec());
+            shipmentContainerDetail.setMaterialUnit(shipmentDetail.getMaterialUnit());
+            shipmentContainerDetail.setQty(shipmentQty);
+            shipmentContainerDetail.setBatch(shipmentDetail.getBatch());
+            shipmentContainerDetail.setLot(shipmentDetail.getLot());
+            shipmentContainerDetail.setProject(shipmentDetail.getProject());
+            success = shipmentContainerDetailService.save(shipmentContainerDetail);
+            if(!success){
+                throw new ServiceException("新建组盘明细失败,sql错误");
+            }
+        }
+        return shipmentContainerDetail;
+    }
+
+    @Override
+    @Transactional(rollbackFor = ServiceException.class)
+    public Result createShipmentTask(ShipmentContainerHeader shipmentContainerHeader, String warehouseCode) {
+        Integer preTaskNo = 0;
+        if (shipmentContainerHeader == null) {
+            return Result.error("生成出库任务时, 出库组盘头"  + "未找到,操作中止");
+        }
+        shipmentContainerHeader = shipmentContainerHeaderService.getById(shipmentContainerHeader.getId());
+        if (shipmentContainerHeader.getStatus() >= QuantityConstant.SHIPMENT_CONTAINER_TASK) {
+            return Result.error("生成出库任务时, 出库组盘头" + shipmentContainerHeader.getId() + "已经生成任务,请不要重复生成,操作中止");
+        }
+        List<ShipmentContainerDetail> shipmentContainerDetailList = shipmentContainerDetailService.getShipmentContainerDetailListByHeaderId(shipmentContainerHeader.getId());
+        if (shipmentContainerDetailList.size() == 0) {
+            return Result.error("生成出库任务时, 出库组盘头" + shipmentContainerHeader.getId() + "没有子任务,操作中止");
+        }
+        if(!shipmentContainerHeader.getWarehouseCode().equals(warehouseCode)) {
+            return Result.error("生成出库任务时, 出库组盘头" + shipmentContainerHeader.getId() + "仓库编码和登录的仓库编码不一致");
+        }
+        String fromLocationCode = shipmentContainerHeader.getFromLocationCode();
+        String toLocationCode = shipmentContainerHeader.getToLocationCode();
+        String containerCode = shipmentContainerHeader.getContainerCode();
+        if(StringUtils.isEmpty(fromLocationCode)) {
+            return Result.error("生成出库任务时, 出库组盘头没有起始库位号为空");
+        }
+        Location location = locationService.getLocationByCode(fromLocationCode, warehouseCode);
+        if(location == null) {
+            return Result.error("生成出库任务时, 库位号" + fromLocationCode +  "没有找到库位");
+        }
+        if(location.getRowFlag() == QuantityConstant.ROW_OUT) {
+            Location location1 = locationService.getNear(location);
+            if(location1 != null) {
+                String locationCode = location1.getCode();
+                TaskHeader taskHeader = taskHeaderService
+                        .getUnCompleteTaskByToLocationCode(locationCode, warehouseCode);
+                preTaskNo = taskHeader.getPreTaskNo();
+            }
+        }
+        Container container = containerService.getContainerByCode(containerCode, warehouseCode);
+        if(container == null) {
+            return Result.error("生成出库任务时, 托盘不存在" + containerCode);
+        }
+        if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
+            return Result.error("生成出库任务时, 托盘已经锁定" + containerCode);
+        }
+        container.setStatus(QuantityConstant.STATUS_CONTAINER_LOCK);
+        boolean success = containerService.updateById(container);
+        if(!success) {
+            throw new ServiceException("生成出库任务时, 更新容器失败" + containerCode);
+        }
+        success = locationService.updateStatus(fromLocationCode,
+                QuantityConstant.STATUS_LOCATION_LOCK, warehouseCode);
+        if(!success) {
+            throw new ServiceException("生成出库任务时, 更新库位失败" + fromLocationCode);
+        }
+        List<InventoryDetail> inventoryDetailList = inventoryDetailService
+                .getInventoryDetailListByContainerCode(containerCode, warehouseCode);
+        BigDecimal inventoryTotal = BigDecimal.ZERO;
+        for (InventoryDetail inventoryDetail : inventoryDetailList) {
+            inventoryTotal = inventoryTotal.add(inventoryDetail.getQty());
+        }
+        BigDecimal shipmentTotal = BigDecimal.ZERO;
+        for (ShipmentContainerDetail shipmentContainerDetail : shipmentContainerDetailList) {
+            shipmentTotal = shipmentTotal.add(shipmentContainerDetail.getQty());
+        }
+        int taskType = QuantityConstant.TASK_TYPE_WHOLESHIPMENT;
+        if (inventoryTotal.compareTo(shipmentTotal) == 0) {
+            taskType = QuantityConstant.TASK_TYPE_WHOLESHIPMENT;
+        } else if(inventoryTotal.compareTo(shipmentTotal) < 0) {
+            return Result.error("生成出库任务时, 库存数量少于出库数量");
+        } else if(inventoryTotal.compareTo(shipmentTotal) > 0) {
+            taskType = QuantityConstant.TASK_TYPE_SORTINGSHIPMENT;
+        }
+        String value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_SHIPMENT_TASK);
+        int shipmentTaskRule = Integer.parseInt(value);
+        if(shipmentTaskRule == QuantityConstant.RULE_TASK_PICK_SHIPMENT) {
+            taskType = QuantityConstant.TASK_TYPE_SORTINGSHIPMENT;
+        }
+        value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_TASK_LOCATION);
+        int taskLocationRule = Integer.parseInt(value);
+        if (taskLocationRule == QuantityConstant.RULE_TASK_SET_LOCATION) {
+            toLocationCode = fromLocationCode;
+            shipmentContainerHeader.setToLocationCode(toLocationCode);
+        }
+        shipmentContainerHeader.setTaskType(taskType);
+        String zoneCode = location.getZoneCode();
+        TaskHeader taskHeader = new TaskHeader();
+        taskHeader.setPreTaskNo(preTaskNo);
+        taskHeader.setTaskType(taskType);
+        taskHeader.setInnernalTaskType(QuantityConstant.TASK_INTENERTYPE_SHIPMENT);
+        taskHeader.setZoneCode(zoneCode);
+        taskHeader.setWarehouseCode(warehouseCode);
+        taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD);
+        taskHeader.setContainerCode(containerCode);
+        taskHeader.setToPort(shipmentContainerHeader.getToPort());
+        taskHeader.setFromLocationCode(fromLocationCode);
+        if(taskType == QuantityConstant.TASK_TYPE_SORTINGSHIPMENT) {
+            taskHeader.setToLocationCode(toLocationCode);
+        }
+        taskHeader.setShipmentContainerHeaderId(shipmentContainerHeader.getId());
+        success = taskHeaderService.save(taskHeader);
+        if(!success) {
+            throw new ServiceException("生成出库任务时, 创建任务失败");
+        }
+        int taskHeaderId = taskHeader.getId();
+        List<TaskDetail> taskDetailList = new ArrayList<>();
+        for (ShipmentContainerDetail shipmentContainerDetail : shipmentContainerDetailList) {
+            TaskDetail taskDetail = new TaskDetail();
+            taskDetail.setTaskHeaderId(taskHeaderId);
+            taskDetail.setWarehouseCode(warehouseCode);
+            taskDetail.setCompanyCode(shipmentContainerDetail.getCompanyCode());
+            taskDetail.setFromInventoryDetailId(shipmentContainerDetail.getInventoryDetailId());
+            taskDetail.setShipmentId(shipmentContainerDetail.getShipmentId());
+            taskDetail.setShipmentDetailId(shipmentContainerDetail.getShipmentDetailId());
+            taskDetail.setShipmentContainerDetailId(shipmentContainerDetail.getId());
+            taskDetail.setTaskType(taskType);
+            taskDetail.setBatch(shipmentContainerDetail.getBatch());
+            taskDetail.setLot(shipmentContainerDetail.getLot());
+            taskDetail.setProject(shipmentContainerDetail.getProject());
+            taskDetail.setInventoryStatus(shipmentContainerDetail.getInventoryStatus());
+            taskDetail.setMaterialCode(shipmentContainerDetail.getMaterialCode());
+            taskDetail.setMaterialSpec(shipmentContainerDetail.getMaterialSpec());
+            taskDetail.setMaterialName(shipmentContainerDetail.getMaterialName());
+            taskDetail.setMaterialUnit(shipmentContainerDetail.getMaterialUnit());
+            taskDetail.setQty(shipmentContainerDetail.getQty());
+            taskDetailList.add(taskDetail);
+        }
+        success = taskDetailService.saveBatch(taskDetailList);
+        if(!success) {
+            throw new ServiceException("生成出库任务时, 创建任务详情失败");
+        }
+        shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_TASK);
+        success = shipmentContainerHeaderService.updateById(shipmentContainerHeader);
+        if(!success) {
+            throw new ServiceException("生成出库任务时, 更新出库组盘头失败");
+        }
+
+        return Result.OK("生成出库任务成功");
+    }
+}
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerDetail.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerDetail.java
index d17cdd6..a6af706 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerDetail.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerDetail.java
@@ -53,6 +53,18 @@ public class ShipmentContainerDetail implements Serializable {
 	@Excel(name = "货主编码", width = 15)
     @ApiModelProperty(value = "货主编码")
     private String companyCode;
+    /**容器号*/
+    @Excel(name = "容器号", width = 15)
+    @ApiModelProperty(value = "容器号")
+    private String containerCode;
+    /**起始库位*/
+    @Excel(name = "起始库位", width = 15)
+    @ApiModelProperty(value = "起始库位")
+    private String fromLocationCode;
+    /**目标库位*/
+    @Excel(name = "目标库位", width = 15)
+    @ApiModelProperty(value = "目标库位")
+    private String toLocationCode;
 	/**物料编码*/
 	@Excel(name = "物料编码", width = 15)
     @ApiModelProperty(value = "物料编码")
@@ -69,10 +81,14 @@ public class ShipmentContainerDetail implements Serializable {
 	@Excel(name = "物料单位", width = 15)
     @ApiModelProperty(value = "物料单位")
     private String materialUnit;
-	/**数量*/
-	@Excel(name = "数量", width = 15)
+    /**数量*/
+    @Excel(name = "数量", width = 15)
     @ApiModelProperty(value = "数量")
-    private Integer qty;
+    private java.math.BigDecimal qty;
+    /**库存详情ID*/
+    @Excel(name = "库存详情ID", width = 15)
+    @ApiModelProperty(value = "库存详情ID")
+    private Integer inventoryDetailId;
 	/**库存状态*/
 	@Excel(name = "库存状态", width = 15)
     @ApiModelProperty(value = "库存状态")
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerDetailService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerDetailService.java
index 9424120..7e27919 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerDetailService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerDetailService.java
@@ -13,4 +13,6 @@ import java.util.List;
 public interface IShipmentContainerDetailService extends IService<ShipmentContainerDetail> {
 
 	public List<ShipmentContainerDetail> selectByMainId(String mainId);
+
+	public List<ShipmentContainerDetail> getShipmentContainerDetailListByHeaderId(int shipmentContainerHeaderId);
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerHeaderService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerHeaderService.java
index fcc7141..acff6a2 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerHeaderService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerHeaderService.java
@@ -26,5 +26,8 @@ public interface IShipmentContainerHeaderService extends IService<ShipmentContai
 	 */
 	public void delBatchMain (Collection<? extends Serializable> idList);
 
+	public List<ShipmentContainerHeader> getUnCompleteCombineList();
+
+	boolean havaUnCompleteCombine(String containerCode, String warehouseCode);
 
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerDetailServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerDetailServiceImpl.java
index 0b1655c..4078667 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerDetailServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerDetailServiceImpl.java
@@ -1,5 +1,7 @@
 package org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.mapper.ShipmentContainerDetailMapper;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
@@ -24,4 +26,12 @@ public class ShipmentContainerDetailServiceImpl extends ServiceImpl<ShipmentCont
 	public List<ShipmentContainerDetail> selectByMainId(String mainId) {
 		return shipmentContainerDetailMapper.selectByMainId(mainId);
 	}
+
+	@Override
+	public List<ShipmentContainerDetail> getShipmentContainerDetailListByHeaderId(int shipmentContainerHeaderId) {
+		LambdaQueryWrapper<ShipmentContainerDetail> shipmentContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+		shipmentContainerDetailLambdaQueryWrapper.eq(ShipmentContainerDetail::getShipmentContainerId, shipmentContainerHeaderId);
+		List<ShipmentContainerDetail> shipmentContainerDetailList = list(shipmentContainerDetailLambdaQueryWrapper);
+		return shipmentContainerDetailList;
+	}
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerHeaderServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerHeaderServiceImpl.java
index 776b2d1..f2c1287 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerHeaderServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerHeaderServiceImpl.java
@@ -1,14 +1,25 @@
 package org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptDetail;
+import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.mapper.ShipmentContainerDetailMapper;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.mapper.ShipmentContainerHeaderMapper;
 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
+import org.jeecg.utils.constant.QuantityConstant;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
 import java.io.Serializable;
 import java.util.List;
 import java.util.Collection;
@@ -26,6 +37,10 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont
 	private ShipmentContainerHeaderMapper shipmentContainerHeaderMapper;
 	@Autowired
 	private ShipmentContainerDetailMapper shipmentContainerDetailMapper;
+	@Resource
+	private IShipmentDetailService shipmentDetailService;
+	@Resource
+	private IShipmentHeaderService shipmentHeaderService;
 
 	@Override
 	@Transactional
@@ -43,4 +58,29 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont
 		}
 	}
 
+	@Override
+	public List<ShipmentContainerHeader> getUnCompleteCombineList() {
+		LambdaQueryWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+		shipmentContainerHeaderLambdaQueryWrapper
+				.lt(ShipmentContainerHeader::getStatus, QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
+		List<ShipmentContainerHeader> shipmentContainerHeaderList = list(shipmentContainerHeaderLambdaQueryWrapper);
+		return shipmentContainerHeaderList;
+	}
+
+	@Override
+	public boolean havaUnCompleteCombine(String containerCode, String warehouseCode) {
+		LambdaQueryWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+		shipmentContainerHeaderLambdaQueryWrapper
+				.eq(ShipmentContainerHeader::getContainerCode, containerCode)
+				.eq(ShipmentContainerHeader::getWarehouseCode, warehouseCode)
+				.lt(ShipmentContainerHeader::getStatus, QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
+		ShipmentContainerHeader shipmentContainerHeader = getOne(shipmentContainerHeaderLambdaQueryWrapper);
+		if(shipmentContainerHeader != null)  {
+			return true;
+		}
+		return false;
+	}
+
+
+
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/entity/ShipmentDetail.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/entity/ShipmentDetail.java
index 39a2e55..b301f34 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/entity/ShipmentDetail.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/entity/ShipmentDetail.java
@@ -88,12 +88,17 @@ public class ShipmentDetail implements Serializable {
     private String project;
 	/**单据状态*/
 	@Excel(name = "单据状态", width = 15)
+    @Dict(dicCode = "shipment_status")
     @ApiModelProperty(value = "单据状态")
     private Integer status;
 	/**上游单号*/
 	@Excel(name = "上游单号", width = 15)
     @ApiModelProperty(value = "上游单号")
     private String referCode;
+    /**目标出入口*/
+    @Excel(name = "目标出入口", width = 15)
+    @ApiModelProperty(value = "目标出入口")
+    private String toPort;
 	/**上游行号*/
 	@Excel(name = "上游行号", width = 15)
     @ApiModelProperty(value = "上游行号")
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/IShipmentHeaderService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/IShipmentHeaderService.java
index f986c66..bcc8a0b 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/IShipmentHeaderService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/IShipmentHeaderService.java
@@ -1,6 +1,8 @@
 package org.jeecg.modules.wms.shipment.shipmentHeader.service;
 
 import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -30,4 +32,7 @@ public interface IShipmentHeaderService extends IService<ShipmentHeader> {
 	public Result saveShipmentHeader(ShipmentHeader shipmentHeader);
 
 	public String createCode(String shipmentType);
+
+	public boolean updateShipmentHeaderStatus(Integer id);
+
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/impl/ShipmentHeaderServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/impl/ShipmentHeaderServiceImpl.java
index a5b16a1..5040145 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/impl/ShipmentHeaderServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/impl/ShipmentHeaderServiceImpl.java
@@ -4,15 +4,29 @@ import com.aliyun.oss.ServiceException;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.wms.config.container.entity.Container;
+import org.jeecg.modules.wms.config.container.service.IContainerService;
+import org.jeecg.modules.wms.config.location.entity.Location;
+import org.jeecg.modules.wms.config.location.service.ILocationService;
+import org.jeecg.modules.wms.config.parameterConfiguration.service.IParameterConfigurationService;
 import org.jeecg.modules.wms.config.receiptType.entity.ReceiptType;
 import org.jeecg.modules.wms.config.shipmentType.entity.ShipmentType;
 import org.jeecg.modules.wms.config.shipmentType.service.IShipmentTypeService;
+import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
+import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
+import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
 import org.jeecg.modules.wms.shipment.shipmentHeader.mapper.ShipmentDetailMapper;
 import org.jeecg.modules.wms.shipment.shipmentHeader.mapper.ShipmentHeaderMapper;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
 import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
+import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
+import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
 import org.jeecg.utils.StringUtils;
 import org.jeecg.utils.constant.QuantityConstant;
 import org.springframework.stereotype.Service;
@@ -22,6 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
@@ -42,10 +57,30 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper,
 	private ShipmentDetailMapper shipmentDetailMapper;
 	@Resource
 	private IShipmentTypeService shipmentTypeService;
+	@Resource
+	private IShipmentHeaderService shipmentHeaderService;
+	@Resource
+	private IShipmentDetailService shipmentDetailService;
+	@Resource
+	private IShipmentContainerDetailService shipmentContainerDetailService;
+	@Resource
+	private ILocationService locationService;
+	@Resource
+	private IContainerService containerService;
+	@Resource
+	private ITaskHeaderService taskHeaderService;
+	@Resource
+	private IInventoryDetailService inventoryDetailService;
+	@Resource
+	private IParameterConfigurationService parameterConfigurationService;
 
 	@Override
 	@Transactional
 	public void delMain(String id) {
+		ShipmentHeader shipmentHeader = getById(id);
+		if(shipmentHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
+			throw new ServiceException("不能删除非新建状态单据");
+		}
 		shipmentDetailMapper.deleteByMainId(id);
 		shipmentHeaderMapper.deleteById(id);
 	}
@@ -54,6 +89,10 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper,
 	@Transactional
 	public void delBatchMain(Collection<? extends Serializable> idList) {
 		for(Serializable id:idList) {
+			ShipmentHeader shipmentHeader = getById(id);
+			if(shipmentHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
+				throw new ServiceException("不能删除非新建状态单据");
+			}
 			shipmentDetailMapper.deleteByMainId(id.toString());
 			shipmentHeaderMapper.deleteById(id);
 		}
@@ -111,4 +150,39 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper,
 		}
 		return code;
 	}
+
+	@Override
+	public boolean updateShipmentHeaderStatus(Integer id) {
+		LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+		shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getShipmentId, id);
+		List<ShipmentDetail> shipmentDetailList = shipmentDetailService.list(shipmentDetailLambdaQueryWrapper);
+		ShipmentHeader shipmentHeader = shipmentHeaderService.getById(id);
+		if(shipmentHeader == null) {
+			return false;
+		}
+		int minStatus;
+		int maxStatus;
+		if(shipmentDetailList.size() == 0) {
+			minStatus = QuantityConstant.RECEIPT_HEADER_BUILD;
+			maxStatus = QuantityConstant.RECEIPT_HEADER_BUILD;
+		} else {
+			minStatus = shipmentDetailList.get(0).getStatus();
+			maxStatus = shipmentDetailList.get(0).getStatus();
+			for(ShipmentDetail shipmentDetail : shipmentDetailList) {
+				int status = shipmentDetail.getStatus();
+				if (minStatus > status) {
+					minStatus = status;
+				}
+				if (maxStatus < status) {
+					maxStatus = status;
+				}
+			}
+		}
+
+		shipmentHeader.setFirstStatus(maxStatus);
+		shipmentHeader.setLastStatus(minStatus);
+		boolean result = shipmentHeaderService.updateById(shipmentHeader);
+		return result;
+	}
+
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java
index 07e4b5c..3593dcd 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java
@@ -34,10 +34,14 @@ public class TaskHeader implements Serializable {
     @Excel(name = "前置任务号", width = 15)
     @ApiModelProperty(value = "前置任务号")
     private Integer preTaskNo;
-    /**前置任务号*/
+    /**入库组盘ID*/
     @Excel(name = "入库组盘ID", width = 15)
     @ApiModelProperty(value = "入库组盘ID")
     private Integer receiptContainerHeaderId;
+    /**出库组盘ID*/
+    @Excel(name = "出库组盘ID", width = 15)
+    @ApiModelProperty(value = "出库组盘ID")
+    private Integer shipmentContainerHeaderId;
 	/**仓库*/
     @Excel(name = "仓库", width = 15)
     @ApiModelProperty(value = "仓库")
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
index 26aabd7..9a929d7 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
@@ -31,6 +31,7 @@ public interface ITaskHeaderService extends IService<TaskHeader> {
 
 	Result createTransferTask(String fromLocationCode, String toLocationCode, String warehouseCode);
 
+
 	TaskHeader getUnCompleteTaskByFromLocationCode(String fromLocationCode, String warehouseCode);
 
 	TaskHeader getUnCompleteTaskByToLocationCode(String toLocationCode, String warehouseCode);
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
index 2878f4b..e7bd245 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
@@ -22,6 +22,11 @@ import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptCont
 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptDetail;
 import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptDetailService;
 import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptHeaderService;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
+import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
 import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail;
 import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
 import org.jeecg.modules.wms.task.taskHeader.mapper.TaskDetailMapper;
@@ -78,6 +83,12 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
 	@Resource
 	private IReceiptContainerHeaderService receiptContainerHeaderService;
 	@Resource
+	private IShipmentContainerDetailService shipmentContainerDetailService;
+	@Resource
+	private IShipmentContainerHeaderService shipmentContainerHeaderService;
+	@Resource
+	private IShipmentHeaderService shipmentHeaderService;
+	@Resource
 	private IMaterialService materialService;
 	@Resource
 	private WcsService wcsService;
@@ -316,6 +327,10 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
 			case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
 				result = completeReceiptTask(taskHeader);
 				break;
+			case QuantityConstant.TASK_TYPE_WHOLESHIPMENT:
+			case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:
+				result = completeShipmentTask(taskHeader);
+				break;
 			default:
 				throw new ServiceException("不支持的任务类型" + taskType);
 		}
@@ -349,7 +364,6 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
 		boolean success = false;
 		String warehouseCode = taskHeader.getWarehouseCode();
 		String containerCode = taskHeader.getContainerCode();
-		String toLocationCode = taskHeader.getToLocationCode();
 
 		InventoryHeader inventoryHeader = inventoryHeaderService.
 				getInventoryHeaderByContainerCode(containerCode, warehouseCode);
@@ -361,9 +375,9 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
 		if(inventoryDetailList.size() == 0) {
 			throw new ServiceException("合并库存时, 没有找到库存详情");
 		}
-		if(inventoryDetailList.size() == 1) {
-			return true;
-		}
+//		if(inventoryDetailList.size() == 1) {
+//			return true;
+//		}
 		for (int i = 0; i < inventoryDetailList.size() - 1; i++) {
 			for (int j = inventoryDetailList.size() - 1; j > i; j--) {
 				InventoryDetail inventoryDetail1 = inventoryDetailList.get(i);
@@ -378,7 +392,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
 					if(!success) {
 						throw new ServiceException("合并库存时, 更新库存详情失败:" + inventoryDetail1.getId());
 					}
-					success = inventoryDetailService.removeById(inventoryDetail2);
+					success = inventoryDetailService.removeById(inventoryDetail2.getId());
 					if(!success) {
 						throw new ServiceException("合并库存时, 删除库存详情失败:" + inventoryDetail2.getId());
 					}
@@ -417,6 +431,12 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
 		int taskType = taskHeader.getTaskType();
 		List<TaskDetail> taskDetailList = taskDetailService.getTaskDetailListByTaskId(taskHeader.getId());
 		boolean success = false;
+		if(taskHeader == null) {
+			return Result.error("任务未找到,执行中止");
+		}
+		if (taskHeader.getStatus().equals(QuantityConstant.TASK_STATUS_COMPLETED)) {
+			return Result.ok("任务(" +taskHeader.getId() + ")任务已经是完成的!");
+		}
 		if (taskDetailList.isEmpty()) {
 			throw new ServiceException("任务明细为空");
 		}
@@ -560,4 +580,170 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
 		return Result.ok("完成入库任务");
 	}
 
+	/**
+	 * 完成出库任务
+	 * @param taskHeader 任务
+	 * @return result 完成出库任务
+	 */
+	@Transactional(rollbackFor = Exception.class)
+	public Result completeShipmentTask(TaskHeader taskHeader) {
+		String warehouseCode = taskHeader.getWarehouseCode();
+		String fromLocationCode = taskHeader.getFromLocationCode();
+		String toLocationCode = taskHeader.getToLocationCode();
+		String zoneCode = taskHeader.getZoneCode();
+		String containerCode = taskHeader.getContainerCode();
+		int taskType = taskHeader.getTaskType();
+		List<TaskDetail> taskDetailList = taskDetailService.getTaskDetailListByTaskId(taskHeader.getId());
+		boolean success = false;
+		if(taskHeader == null) {
+			return Result.error("完成出库任务未找到,执行中止");
+		}
+		if (taskHeader.getStatus().equals(QuantityConstant.TASK_STATUS_COMPLETED)) {
+			return Result.ok("完成出库任务,(" + taskHeader.getId() + ")任务已经是完成的!");
+		}
+		if (taskDetailList.isEmpty()) {
+			throw new ServiceException("完成出库任务,任务明细为空");
+		}
+		if (StringUtils.isEmpty(fromLocationCode)) {
+			throw new ServiceException("完成出库任务" + taskHeader.getId() + "没有起始库位,执行中止");
+		}
+		if (StringUtils.isEmpty(toLocationCode)
+				&& taskType == QuantityConstant.TASK_TYPE_SORTINGSHIPMENT) {
+			throw new ServiceException("完成出库任务,任务" + taskHeader.getId() + "没有目的库位,执行中止");
+		}
+		InventoryHeader inventoryHeader = inventoryHeaderService
+				.getInventoryHeaderByContainerCode(containerCode, warehouseCode);
+		if(inventoryHeader == null) {
+			throw new ServiceException("完成出库任务,出库任务" + taskHeader.getId() + "没有找到库存头");
+		}
+		List<InventoryTransaction> inventoryTransactionList = new ArrayList<>();
+		List<Integer> shipmentIdList = new ArrayList<>();
+		for(TaskDetail taskDetail : taskDetailList) {
+			ShipmentContainerDetail shipmentContainerDetail =
+					shipmentContainerDetailService.getById(taskDetail.getShipmentContainerDetailId());
+			if(shipmentContainerDetail == null) {
+				throw new ServiceException("完成出库任务, 出库任务没有找到出库组盘详情" + taskDetail.getShipmentContainerDetailId());
+			}
+			InventoryDetail inventoryDetail =
+					inventoryDetailService.getById(taskDetail.getFromInventoryDetailId());
+			if(inventoryDetail == null) {
+				throw new ServiceException("完成出库任务,出库任务没有找到库存详情" + taskDetail.getFromInventoryDetailId());
+			}
+			inventoryDetail.setTaskQty(inventoryDetail.getTaskQty().subtract(taskDetail.getQty()));
+			inventoryDetail.setQty(inventoryDetail.getQty().subtract(taskDetail.getQty()));
+			inventoryDetail.setLocationCode(toLocationCode);
+			//扣减后的库存不能小于0
+			if (inventoryDetail.getQty().compareTo(BigDecimal.ZERO) < 0) {
+				throw new ServiceException("完成出库任务,扣减库存大于wms库存");
+			}
+			if (inventoryDetail.getQty().compareTo(BigDecimal.ZERO) == 0) {
+				if(inventoryDetail.getTaskQty().compareTo(BigDecimal.ZERO) != 0) {
+					throw new ServiceException("完成出库任务,扣减库存的库存详情任务数量不为0");
+				}
+				success = inventoryDetailService.removeById(inventoryDetail.getId());
+				if(!success) {
+					throw new ServiceException("完成出库任务,删除库存详情失败");
+				}
+			} else {
+				success = inventoryDetailService.updateById(inventoryDetail);
+				if(!success) {
+					throw new ServiceException("完成出库任务,更新库存详情失败");
+				}
+			}
+
+			InventoryTransaction inventoryTransaction = new InventoryTransaction();
+			inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_SHIPMENT);
+			inventoryTransaction.setWarehouseCode(warehouseCode);
+			inventoryTransaction.setCompanyCode(inventoryDetail.getCompanyCode());
+			inventoryTransaction.setContainerCode(containerCode);
+			inventoryTransaction.setLocationCode(fromLocationCode);
+			inventoryTransaction.setMaterialCode(inventoryDetail.getMaterialCode());
+			inventoryTransaction.setMaterialName(inventoryDetail.getMaterialName());
+			inventoryTransaction.setMaterialSpec(inventoryDetail.getMaterialSpec());
+			inventoryTransaction.setMaterialUnit(inventoryDetail.getMaterialUnit());
+			inventoryTransaction.setInventoryStatus(inventoryDetail.getInventoryStatus());
+			inventoryTransaction.setShipmentId(taskDetail.getShipmentId());
+			inventoryTransaction.setShipmentDetailId(taskDetail.getShipmentDetailId());
+			inventoryTransaction.setShipmentContainerDetailId(taskDetail.getShipmentContainerDetailId());
+			inventoryTransaction.setBatch(inventoryDetail.getBatch());
+			inventoryTransaction.setLot(inventoryDetail.getLot());
+			inventoryTransaction.setProject(inventoryDetail.getProject());
+			inventoryTransaction.setQty(taskDetail.getQty());
+			inventoryTransactionList.add(inventoryTransaction);
+			shipmentIdList.add(taskDetail.getShipmentId());
+		}
+		String containerStatus = QuantityConstant.STATUS_CONTAINER_SOME;
+		List<InventoryDetail> inventoryDetailList = inventoryDetailService
+				.getInventoryDetailListByInventoryHeaderId(inventoryHeader.getId());
+		if(inventoryDetailList.size() == 0) {
+			success = inventoryHeaderService.removeById(inventoryHeader.getId());
+			if(!success) {
+				throw new ServiceException("完成出库任务,删除库存头失败");
+			}
+			containerStatus = QuantityConstant.STATUS_CONTAINER_EMPTY;
+		} else {
+			if(taskType == QuantityConstant.TASK_TYPE_WHOLESHIPMENT) {
+				throw new ServiceException("完成整盘出库任务,不能还剩库存详情");
+			}
+			containerStatus = QuantityConstant.STATUS_CONTAINER_SOME;
+		}
+
+		success = inventoryTransactionService.saveBatch(inventoryTransactionList);
+		if(!success) {
+			throw new ServiceException("完成出库任务,保存库存详情失败");
+		}
+		taskHeader.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
+		success = taskHeaderService.updateById(taskHeader);
+		if(!success) {
+			throw new ServiceException("完成出库任务,保存任务头失败");
+		}
+		if(taskType == QuantityConstant.TASK_TYPE_WHOLESHIPMENT) {
+			success = locationService.updateContainerCodeAndStatus(
+					fromLocationCode, QuantityConstant.EMPTY_STRING, QuantityConstant.STATUS_LOCATION_EMPTY, warehouseCode);
+			if(!success) {
+				throw new ServiceException("完成整盘出库任务,更新源库位失败");
+			}
+			containerService.updateLocationCodeAndStatus(containerCode, QuantityConstant.EMPTY_STRING,
+					QuantityConstant.STATUS_CONTAINER_EMPTY, warehouseCode);
+			if(!success) {
+				throw new ServiceException("完成整盘出库任务,更新容器失败");
+			}
+		} else if(taskType == QuantityConstant.TASK_TYPE_SORTINGSHIPMENT) {
+			success = locationService.updateContainerCodeAndStatus(
+					fromLocationCode, QuantityConstant.EMPTY_STRING, QuantityConstant.STATUS_LOCATION_EMPTY, warehouseCode);
+			if(!success) {
+				throw new ServiceException("完成分拣出库任务,更新源库位失败");
+			}
+			success = locationService.updateContainerCodeAndStatus(
+					toLocationCode, containerCode, QuantityConstant.STATUS_LOCATION_EMPTY, warehouseCode);
+			if(!success) {
+				throw new ServiceException("完成分拣出库任务,更新目标库位失败");
+			}
+			success = containerService.updateLocationCodeAndStatus(
+					containerCode, toLocationCode, containerStatus, warehouseCode);
+			if(!success) {
+				throw new ServiceException("完成分拣出库任务,更新容器失败");
+			}
+		}
+		ShipmentContainerHeader shipmentContainerHeader = shipmentContainerHeaderService
+				.getById(taskHeader.getShipmentContainerHeaderId());
+		if(shipmentContainerHeader == null) {
+			throw new ServiceException("完成出库任务,获取出库组盘头失败");
+		}
+		shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
+		success = shipmentContainerHeaderService.updateById(shipmentContainerHeader);
+		if(!success) {
+			throw new ServiceException("完成出库任务,更新出库组盘头失败");
+		}
+		if(inventoryDetailList.size() != 0) {
+			if(!combineInventoryDetail(taskHeader)) {
+				throw new ServiceException("合并入库库存失败");
+			}
+		}
+		shipmentIdList = shipmentIdList.stream().distinct().collect(Collectors.toList());
+		for(Integer shipmentId : shipmentIdList) {
+			shipmentHeaderService.updateShipmentHeaderStatus(shipmentId);
+		}
+		return Result.ok("完成出库任务");
+	}
 }
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/resources/application.yml b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/resources/application.yml
index 8054cf9..8329076 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/resources/application.yml
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/resources/application.yml
@@ -2,4 +2,4 @@ spring:
   application:
     name: jeecg-system
   profiles:
-    active: @profile.name@
\ No newline at end of file
+    active: dev