Commit b2e0ce4ae65ba5b12cede5a655fa50890b15a989

Authored by 肖超群
1 parent 27008ab3

开发快速出库功能,在库存界面直接点击就可以出库。

Showing 26 changed files with 507 additions and 85 deletions
ant-design-vue-jeecg/src/api/api.js
... ... @@ -129,6 +129,8 @@ export const searchMaterialByCode = (params) => postAction('/config/material/sea
129 129 export const listReceiveByReceiptId = (params) => postAction('/receipt/receiveHeader/listReceiveByReceiptId', params);
130 130 //创建入库任务
131 131 export const createReceiptTask = (params) => postAction('/receipt/receiptContainerHeader/createReceiptTask', params);
  132 +//批量创建入库任务
  133 +export const createReceiptBatchTask = (params) => postAction('/receipt/receiptContainerHeader/createReceiptBatchTask', params);
132 134 //完成WMS任务
133 135 export const completeTaskByWMS = (params) => postAction('/task/taskHeader/completeTaskByWMS', params);
134 136 //下发任务给WCS
... ... @@ -217,6 +219,8 @@ export const queryWarehouse = (params) => getAction("/config/sysUserWarehouse/qu
217 219 export const getAllWarehouseList = (params) => getAction("/config/warehouse/getAllWarehouseList", params);
218 220 //查询所有库区
219 221 export const getAllZoneList = (params) => getAction("/config/zone/getAllZoneList", params);
  222 +//批量快速出整托
  223 +export const shipmentInventoryHeader = (params) => postAction('/inventory/inventoryHeader/shipmentInventoryHeader', params);
220 224 // 中转HTTP请求
221 225 export const transitRESTful = {
222 226 get: (url, parameter) => getAction(getTransitURL(url), parameter),
... ...
ant-design-vue-jeecg/src/views/system/inventory/InventoryDetailList.vue
... ... @@ -43,9 +43,9 @@
43 43 </a-tag>
44 44 </span>
45 45  
46   - <span slot="controller_dictText" slot-scope="controller_dictText">
47   - <a-tag :key="controller_dictText" :color="getStatusColor(controller_dictText)">
48   - {{ controller_dictText }}
  46 + <span slot="enable_dictText" slot-scope="enable_dictText">
  47 + <a-tag :key="enable_dictText" :color="getStatusColor(enable_dictText)">
  48 + {{ enable_dictText }}
49 49 </a-tag>
50 50 </span>
51 51  
... ... @@ -205,10 +205,10 @@ export default {
205 205 scopedSlots: {customRender: 'inventoryStatus_dictText'}
206 206 },
207 207 {
208   - title: '受控状态',
  208 + title: '可用状态',
209 209 align: 'center',
210   - dataIndex: 'controller_dictText',
211   - scopedSlots: {customRender: 'controller_dictText'}
  210 + dataIndex: 'enable_dictText',
  211 + scopedSlots: {customRender: 'enable_dictText'}
212 212 },
213 213 {
214 214 title: '批次',
... ...
ant-design-vue-jeecg/src/views/system/inventory/InventoryHeaderList.vue
... ... @@ -85,7 +85,7 @@
85 85 :dataSource="dataSource"
86 86 :pagination="ipagination"
87 87 :loading="loading"
88   - :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'radio'}"
  88 + :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'checkbox'}"
89 89 :customRow="clickThenSelect"
90 90 @change="handleTableChange">
91 91  
... ... @@ -146,6 +146,7 @@
146 146 </a-tabs>
147 147  
148 148 <inventoryHeader-modal ref="modalForm" @ok="modalFormOk"></inventoryHeader-modal>
  149 + <QuickShipmentModel ref='quickShipmentModel' @ok='quickShipmentModalFormOk'></QuickShipmentModel>
149 150 </a-card>
150 151 </template>
151 152  
... ... @@ -158,11 +159,13 @@ import InventoryDetailList from &#39;./InventoryDetailList&#39;
158 159 import {initDictOptions, filterMultiDictText} from '@/components/dict/JDictSelectUtil'
159 160 import '@/assets/less/TableExpand.less'
160 161 import { getZoneList } from '@api/api'
  162 +import QuickShipmentModel from "@views/system/shipment/modules/QuickShipmentModal";
161 163  
162 164 export default {
163 165 name: "InventoryHeaderList",
164 166 mixins: [JeecgListMixin],
165 167 components: {
  168 + QuickShipmentModel,
166 169 InventoryDetailList,
167 170 InventoryHeaderModal
168 171 },
... ... @@ -266,6 +269,7 @@ export default {
266 269 },
267 270 selectedMainId: '',
268 271 superFieldList: [],
  272 + selectRecord:[],
269 273 }
270 274 },
271 275 created() {
... ... @@ -321,6 +325,7 @@ export default {
321 325 this.selectedMainId = selectedRowKeys[0].toString();
322 326 this.selectedRowKeys = selectedRowKeys;
323 327 this.selectionRows = selectionRows;
  328 + this.selectRecord = selectionRows;
324 329 },
325 330 loadData(arg) {
326 331 if (!this.url.list) {
... ... @@ -364,13 +369,12 @@ export default {
364 369 if (this.selectedRowKeys.length <= 0) {
365 370 this.$message.warning('请选择一条记录!');
366 371 } else {
367   - let zoneCodes = this.selectRecord.map(row => row.zoneCode)
  372 + let zoneCodes = this.selectRecord.map(row => row.zoneCode);
368 373 if (new Set(zoneCodes).size !== 1) {
369 374 this.$message.warning('所选数据非同库区');
370 375 return;
371 376 }
372   - this.$refs.quickShipmentModel.model.containerCode = this.selectRecord[0].containerCode;
373   - this.$refs.quickShipmentModel.edit();
  377 + this.$refs.quickShipmentModel.edit(this.selectRecord);
374 378 this.$refs.quickShipmentModel.title = '选择出库口';
375 379 }
376 380 },
... ...
ant-design-vue-jeecg/src/views/system/inventory/SimpleInventoryDetailList.vue
... ... @@ -49,11 +49,11 @@
49 49 </a-form-item>
50 50 </a-col>
51 51 <a-col :xl="6" :lg="7" :md="8" :sm="24">
52   - <a-form-item label="受控状态">
  52 + <a-form-item label="可用状态">
53 53 <j-dict-select-tag
54   - placeholder="请选择受控状态"
  54 + placeholder="请选择可用状态"
55 55 v-model="queryParam.controller"
56   - dictCode="inventory_controller"
  56 + dictCode="inventory_enable"
57 57 />
58 58 </a-form-item>
59 59 </a-col>
... ... @@ -136,8 +136,8 @@
136 136 >
137 137 <a-button type="primary" icon="import">导入</a-button>
138 138 </a-upload>
139   - <a-button v-has="'inventoryDetail:controller'" @click='controller()' type='primary'>受控</a-button>
140   - <a-button v-has="'inventoryDetail:releaseController'" @click='releaseController()' type='primary'>释放受控</a-button>
  139 + <a-button v-has="'inventoryDetail:controller'" @click='controller()' type='primary'>冻结</a-button>
  140 + <a-button v-has="'inventoryDetail:releaseController'" @click='releaseController()' type='primary'>释放冻结</a-button>
141 141 <!-- 高级查询区域 -->
142 142 <j-super-query
143 143 :fieldList="superFieldList"
... ... @@ -174,9 +174,9 @@
174 174 class="j-table-force-nowrap"
175 175 @change="handleTableChange"
176 176 >
177   - <span slot="controller_dictText" slot-scope="controller_dictText">
178   - <a-tag :key="controller_dictText" :color="getStatusColor(controller_dictText)">
179   - {{ controller_dictText }}
  177 + <span slot="enable_dictText" slot-scope="enable_dictText">
  178 + <a-tag :key="enable_dictText" :color="getStatusColor(enable_dictText)">
  179 + {{ enable_dictText }}
180 180 </a-tag>
181 181 </span>
182 182  
... ... @@ -327,10 +327,10 @@ export default {
327 327 scopedSlots: {customRender: 'inventoryStatus_dictText'}
328 328 },
329 329 {
330   - title: '受控状态',
  330 + title: '可用状态',
331 331 align: 'center',
332   - dataIndex: 'controller_dictText',
333   - scopedSlots: {customRender: 'controller_dictText'}
  332 + dataIndex: 'enable_dictText',
  333 + scopedSlots: {customRender: 'enable_dictText'}
334 334 },
335 335 {
336 336 title: '批次',
... ... @@ -441,8 +441,8 @@ export default {
441 441 } else {
442 442 let that = this;
443 443 this.$confirm({
444   - title: '确认受控',
445   - content: '是否受控选中数据?',
  444 + title: '确认冻结',
  445 + content: '是否冻结选中数据?',
446 446 onOk: function() {
447 447 that.loading = true;
448 448 postAction(that.url.controller, that.selectedRowKeys).then((res) => {
... ... @@ -469,8 +469,8 @@ export default {
469 469 } else {
470 470 let that = this;
471 471 this.$confirm({
472   - title: '释放受控',
473   - content: '释放受控选中数据?',
  472 + title: '释放冻结',
  473 + content: '释放冻结选中数据?',
474 474 onOk: function() {
475 475 that.loading = true;
476 476 postAction(that.url.releaseController, that.selectedRowKeys).then((res) => {
... ... @@ -544,7 +544,7 @@ export default {
544 544 fieldList.push({type: 'BigDecimal', value: 'qty', text: '数量', dictCode: ''})
545 545 fieldList.push({type: 'BigDecimal', value: 'taskQty', text: '任务锁定数量', dictCode: ''})
546 546 fieldList.push({type: 'string', value: 'inventoryStatus', text: '库存状态', dictCode: 'inventory_status'})
547   - fieldList.push({type: 'int', value: 'controller', text: '受控状态', dictCode: 'inventory_controller'})
  547 + fieldList.push({type: 'int', value: 'enable', text: '可用状态', dictCode: 'inventory_enable'})
548 548 fieldList.push({type: 'string', value: 'batch', text: '批次', dictCode: ''})
549 549 // fieldList.push({type:'string',value:'sn',text:'序列号',dictCode:''})
550 550 fieldList.push({type: 'datetime', value: 'receiptDate', text: '入库日期'})
... ...
ant-design-vue-jeecg/src/views/system/receipt/ReceiptContainerHeaderList.vue
... ... @@ -72,6 +72,8 @@
72 72 <a-upload v-has="'receiptContainerHeader:import'" name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
73 73 <a-button type="primary" icon="import">导入</a-button>
74 74 </a-upload>
  75 + <a-button v-has="'receiptContainerHeader:add'" @click="createBatchTask" type="primary" >批量生成任务</a-button>
  76 + <a-button v-has="'receiptContainerHeader:delete'" @click="cancelBatchTask" type="primary" >批量取消组盘</a-button>
75 77 </div>
76 78  
77 79 <!-- table区域-begin -->
... ... @@ -87,7 +89,7 @@
87 89 :dataSource="dataSource"
88 90 :pagination="ipagination"
89 91 :loading="loading"
90   - :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'radio'}"
  92 + :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'checkbox'}"
91 93 :customRow="clickThenSelect"
92 94 @change="handleTableChange">
93 95  
... ... @@ -117,13 +119,14 @@
117 119 </a-button>
118 120 </template>
119 121 <span slot="action" slot-scope="text, record">
120   - <a v-if="record.status == 0 && record.taskType == 200" @click="selectFillPort(record)" v-has="'receiptContainerHeader:createTask'"><a-button type="primary">生成任务</a-button><a-divider type="vertical"/></a>
  122 + <a v-if="record.status == 0 && record.taskType == 200" @click="selectPort(record)" v-has="'receiptContainerHeader:createTask'"><a-button type="primary">生成任务</a-button><a-divider type="vertical"/></a>
121 123 <a v-else-if="record.status == 0" @click="selectContainerStatus(record)" v-has="'receiptContainerHeader:createTask'"><a-button type="primary">生成任务</a-button><a-divider type="vertical"/></a>
122 124 <!-- <a v-if="record.status == 0 && record.taskType == 200" @click="selectPort(record)" v-has="'receiptContainerHeader:createTask'">生成任务<a-divider type="vertical"/></a>-->
123 125 <!-- <a v-else-if="record.status == 0" @click="createTask(record)" v-has="'receiptContainerHeader:createTask'">生成任务<a-divider type="vertical"/></a>-->
124 126 <a-popconfirm v-if="record.status == 0" v-has="'receiptContainerHeader:delete'" title="确定取消配盘吗?" @confirm="() => handleDelete(record.id)">
125 127 <a><a-button type="danger">取消配盘</a-button> <a-divider type="vertical"/></a>
126 128 </a-popconfirm>
  129 +
127 130 <a v-has="'receiptContainerHeader:edit'" @click="handleEdit(record)"><a-button type="default">编辑</a-button></a>
128 131 </span>
129 132 </a-table>
... ... @@ -146,11 +149,11 @@
146 149  
147 150 import {JeecgListMixin} from '@/mixins/JeecgListMixin'
148 151 import ReceiptContainerHeaderModal from './modules/ReceiptContainerHeaderModal'
149   -import {getAction} from '@/api/manage'
  152 +import {deleteAction, getAction} from '@/api/manage'
150 153 import ReceiptContainerDetailList from './ReceiptContainerDetailList'
151 154 import {initDictOptions, filterMultiDictText} from '@/components/dict/JDictSelectUtil'
152 155 import '@/assets/less/TableExpand.less'
153   -import {createReceiptTask} from '@/api/api'
  156 +import {createReceiptTask, createReceiptBatchTask} from '@/api/api'
154 157 import ReceiptContainerSelectModal from "./modules/ReceiptContainerSelectModal";
155 158 import ReceiptContainerFillSelectModal from "./modules/ReceiptContainerFillSelectModal";
156 159 import ReceiptContainerStatusSelectModal from "./modules/ReceiptContainerStatusSelectModal";
... ... @@ -322,17 +325,92 @@ export default {
322 325 selectPort(record) {
323 326 this.$refs.modalForm2.edit(record);
324 327 this.$refs.modalForm2.title = "选择分拣入库口";
325   - console.log("selectPort");
326 328 },
327 329 selectFillPort(record) {
328 330 this.$refs.modalForm3.edit(record);
329 331 this.$refs.modalForm3.title = "选择分拣入库口";
330   - console.log("selectFillPort");
331 332 },
332 333 selectContainerStatus(record) {
333 334 this.$refs.modalForm4.edit(record);
334 335 this.$refs.modalForm4.title = "选择容器状态";
335   - console.log("selectContainerStatus");
  336 + },
  337 + createBatchTask(){
  338 + if (this.selectedRowKeys.length <= 0) {
  339 + this.$message.warning('请选择一条记录!')
  340 + return
  341 + }else{
  342 + console.log("createBatchTask");
  343 + var receiptContainerHeaderList =[];
  344 + var receiptContainerHeader= null;
  345 + for (var a = 0; a < this.selectedRowKeys.length; a++) {
  346 + if (this.selectionRows[a].status == 0) {
  347 + if (receiptContainerHeader == null)
  348 + {
  349 + receiptContainerHeader = this.selectionRows[a];
  350 + }
  351 + if (receiptContainerHeader.taskType == this.selectionRows[a].taskType)
  352 + {
  353 + receiptContainerHeaderList.push(this.selectionRows[a]);
  354 + }
  355 + }
  356 + }
  357 + if(receiptContainerHeader.taskType == 100) {
  358 + createReceiptBatchTask(receiptContainerHeaderList).then((res) => {
  359 + this.loading = false;
  360 + if (res.success) {
  361 + this.$message.success(res.message);
  362 + } else {
  363 + this.$message.error(res.message);
  364 + }
  365 + this.searchQuery();
  366 + });
  367 + } else {
  368 + this.$refs.modalForm2.batchEdit(receiptContainerHeaderList);
  369 + this.$refs.modalForm2.title = "选择出库口";
  370 + }
  371 + }
  372 + },
  373 + cancelBatchTask() {
  374 + if (!this.url.deleteBatch) {
  375 + this.$message.error("请设置url.deleteBatch属性!")
  376 + return
  377 + }
  378 + if (this.selectedRowKeys.length <= 0) {
  379 + this.$message.warning('请选择一条记录!');
  380 + return;
  381 + } else {
  382 + var ids = "";
  383 + for (var a = 0; a < this.selectedRowKeys.length; a++) {
  384 + if (this.selectionRows[a].status == 0) {
  385 + ids += this.selectedRowKeys[a] + ",";
  386 + }
  387 + }
  388 + if(ids == "") {
  389 + this.$message.warning("没有符合取消条件的组盘");
  390 + return;
  391 + }
  392 + var that = this;
  393 + this.$confirm({
  394 + title: "确认删除",
  395 + content: "是否删除选中数据?",
  396 + onOk: function () {
  397 + that.loading = true;
  398 + deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
  399 + if (res.success) {
  400 + //重新计算分页问题
  401 + that.reCalculatePage(that.selectedRowKeys.length)
  402 + that.$message.success(res.message);
  403 + that.loadData();
  404 + that.onClearSelected();
  405 + } else {
  406 + that.$message.warning(res.message);
  407 + }
  408 + }).finally(() => {
  409 + that.loading = false;
  410 + });
  411 + }
  412 + });
  413 + }
336 414 },
337 415 loadData(arg) {
338 416 if (!this.url.list) {
... ...
ant-design-vue-jeecg/src/views/system/receipt/modules/ReceiptContainerSelectModal.vue
... ... @@ -37,7 +37,7 @@
37 37  
38 38 import {httpAction} from '@/api/manage'
39 39 import {validateDuplicateValue} from '@/utils/util'
40   -import {createReceiptTask} from '@/api/api'
  40 +import {createReceiptTask, createReceiptBatchTask} from '@/api/api'
41 41 import {selectSupplePort} from '@/api/api'
42 42  
43 43 export default {
... ... @@ -54,6 +54,8 @@ export default {
54 54 return {
55 55 title: "操作",
56 56 portList: [],
  57 + flag:'0',
  58 + receiptContainerHeaderList:[],
57 59 width: 500,
58 60 visible: false,
59 61 model: {},
... ... @@ -83,8 +85,15 @@ export default {
83 85 },
84 86 edit(record) {
85 87 console.log("edit");
  88 + this.flag='0';
86 89 this.getPortList(record);
87 90 },
  91 + batchEdit(record) {
  92 + this.visible = true;
  93 + this.flag = '1';
  94 + this.getPortList(record[0]);
  95 + this.receiptContainerHeaderList=record;
  96 + },
88 97 close() {
89 98 this.$emit('close');
90 99 this.visible = false;
... ... @@ -93,24 +102,48 @@ export default {
93 102 handleOk() {
94 103 const that = this;
95 104 // 触发表单验证
96   - this.$refs.form.validate(valid => {
97   - if (valid) {
98   - that.confirmLoading = true;
99   - createReceiptTask(this.model).then((res) => {
100   - if (res.success) {
101   - that.$message.success(res.message);
102   - that.$emit('ok');
103   - } else {
104   - that.$message.warning(res.message);
105   - }
106   - }).finally(() => {
107   - that.confirmLoading = false;
108   - that.close();
109   - });
110   - } else {
111   - return false
112   - }
113   - })
  105 + if (this.flag=='1'){
  106 + this.$refs.form.validate(valid => {
  107 + if (valid) {
  108 + this.receiptContainerHeaderList.forEach(x=>{
  109 + x["toPort"]=that.model.toPort;
  110 + })
  111 + that.confirmLoading = true;
  112 + createReceiptBatchTask(this.receiptContainerHeaderList).then((res) => {
  113 + if (res.success) {
  114 + that.$message.success(res.message);
  115 + that.$emit('ok');
  116 + } else {
  117 + that.$message.warning(res.message);
  118 + }
  119 + }).finally(() => {
  120 + that.confirmLoading = false;
  121 + that.close();
  122 + });
  123 + } else {
  124 + return false
  125 + }
  126 + });
  127 + } else {
  128 + this.$refs.form.validate(valid => {
  129 + if (valid) {
  130 + that.confirmLoading = true;
  131 + createReceiptTask(this.model).then((res) => {
  132 + if (res.success) {
  133 + that.$message.success(res.message);
  134 + that.$emit('ok');
  135 + } else {
  136 + that.$message.warning(res.message);
  137 + }
  138 + }).finally(() => {
  139 + that.confirmLoading = false;
  140 + that.close();
  141 + });
  142 + } else {
  143 + return false
  144 + }
  145 + });
  146 + }
114 147 },
115 148 handleCancel() {
116 149 this.close()
... ...
ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue
... ... @@ -74,7 +74,7 @@
74 74 @change="handleImportExcel">
75 75 <a-button type="primary" icon="import">导入</a-button>
76 76 </a-upload>
77   - <a-button @click="createBatchTask" type="primary" icon="plus">批量生成任务</a-button>
  77 + <a-button @click="createBatchTask" type="primary" >批量生成任务</a-button>
78 78 <a-button @click="cancelBatchTask" type="primary" >批量取消配盘</a-button>
79 79 </div>
80 80  
... ...
ant-design-vue-jeecg/src/views/system/shipment/modules/QuickShipmentModal.vue 0 → 100644
  1 +<template>
  2 + <j-modal
  3 + :title="title"
  4 + :width="width"
  5 + :visible="visible"
  6 + :confirmLoading="confirmLoading"
  7 + switchFullscreen
  8 + @ok="handleOk"
  9 + @cancel="handleCancel"
  10 + cancelText="关闭"
  11 + >
  12 + <a-spin :spinning="confirmLoading">
  13 + <a-form-model ref="form" :model="model" :rules="validatorRules">
  14 + <a-row>
  15 + <a-col :span="24">
  16 + <a-form-model-item label="出库口" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="outPortCode">
  17 + <a-select show-search placeholder="请选择出库口" option-filter-prop="children" v-model="model.outPortCode">
  18 + <a-select-option v-for="item in portList" :key="item.name" :value="item.code">
  19 + {{ item.name }}
  20 + </a-select-option>
  21 + </a-select>
  22 + </a-form-model-item>
  23 + </a-col>
  24 + </a-row>
  25 + </a-form-model>
  26 + </a-spin>
  27 + </j-modal>
  28 +</template>
  29 +
  30 +<script>
  31 +import {getZoneList, selectOutPort, shipmentInventoryHeader} from '@/api/api'
  32 +
  33 +export default {
  34 + name: 'QuickShipmentModel',
  35 + components: { },
  36 + data() {
  37 + return {
  38 + title: '操作',
  39 + width: 400,
  40 + portList: [],
  41 + inventoryHeaderList: [],
  42 + querySource: {},
  43 + visible: false,
  44 + model: {},
  45 + labelCol: {
  46 + xs: { span: 24 },
  47 + sm: { span: 5 }
  48 + },
  49 + wrapperCol: {
  50 + xs: { span: 24 },
  51 + sm: { span: 16 }
  52 + },
  53 + // 选择用户查询条件配置
  54 + selectUserQueryConfig: [],
  55 + confirmLoading: false,
  56 + validatorRules: {
  57 + outPortCode: [{ required: true, message: '请选择出库口!' }]
  58 + }
  59 + }
  60 + },
  61 + created() {
  62 + //备份model原始值
  63 + this.modelDefault = JSON.parse(JSON.stringify(this.model));
  64 + },
  65 + methods: {
  66 + add() {
  67 + this.edit(this.modelDefault)
  68 + },
  69 + edit(record) {
  70 + this.visible = true;
  71 + this.model.containerCode = record[0].containerCode;
  72 + this.inventoryHeaderList = record;
  73 + this.getPortList();
  74 + },
  75 + close() {
  76 + this.$emit('close')
  77 + this.visible = false
  78 + this.$refs.form.clearValidate()
  79 + },
  80 + getPortList() {
  81 + this.querySource.containerCode = this.model.containerCode
  82 + selectOutPort(this.querySource).then(res => {
  83 + if (res.success) {
  84 + this.portList = res.result;
  85 + this.visible = true;
  86 + }
  87 + })
  88 + },
  89 + handleOk() {
  90 + if (this.model.outPortCode === ''){
  91 + this.$message.warning('请选择出库口');
  92 + }
  93 + this.inventoryHeaderList.forEach(x=>{
  94 + x["toPortCode"]=this.model.outPortCode;
  95 + })
  96 + shipmentInventoryHeader(this.inventoryHeaderList).then((res) => {
  97 + if (res.success) {
  98 + this.$message.success(res.message);
  99 + } else {
  100 + this.$message.error(res.message);
  101 + }
  102 + });
  103 + this.$emit("ok", this.model.outPortCode);
  104 + this.close()
  105 + },
  106 + handleCancel() {
  107 + this.close()
  108 + }
  109 + }
  110 +}
  111 +</script>
0 112 \ No newline at end of file
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/controller/LocationController.java
... ... @@ -71,9 +71,9 @@ public class LocationController extends JeecgController&lt;Location, ILocationServi
71 71 QueryWrapper<Location> queryWrapper = QueryGenerator.initQueryWrapper(location, null);
72 72 LambdaQueryWrapper<Location> locationLambdaQueryWrapper = queryWrapper.lambda();
73 73 if (haveContainer != null) {
74   - if (haveContainer == QuantityConstant.STATUS_NOT_CONTAINER) {
  74 + if (haveContainer == QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE) {
75 75 locationLambdaQueryWrapper.eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING);
76   - } else if (haveContainer == QuantityConstant.STATUS_HAVE_CONTAINER) {
  76 + } else if (haveContainer == QuantityConstant.INVENTORY_DETAIL_STATUS_CONTAINER) {
77 77 locationLambdaQueryWrapper.ne(Location::getContainerCode, QuantityConstant.EMPTY_STRING);
78 78 }
79 79 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/entity/Location.java
... ... @@ -153,9 +153,9 @@ public class Location implements Serializable {
153 153  
154 154 public Integer getHaveContainer() {
155 155 if (StringUtils.isNotEmpty(containerCode)) {
156   - return QuantityConstant.STATUS_HAVE_CONTAINER;
  156 + return QuantityConstant.INVENTORY_DETAIL_STATUS_CONTAINER;
157 157 } else {
158   - return QuantityConstant.STATUS_NOT_CONTAINER;
  158 + return QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE;
159 159 }
160 160 }
161 161  
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/service/IHuahengMultiHandlerService.java
... ... @@ -24,8 +24,16 @@ public interface IHuahengMultiHandlerService {
24 24  
25 25 Result combination(CombinationParam combinationParam);
26 26  
  27 + /**
  28 + * 取消配盘
  29 + */
27 30 Result cancelCombine(Integer id);
28 31  
  32 + /**
  33 + * 取消组盘
  34 + */
  35 + Result cancelReceiving(Integer id);
  36 +
29 37 Result autoCombination(String shipmentCode, String warehouseCode);
30 38  
31 39 Result createShipmentTask(ShipmentContainerHeader shipmentContainerHeader, String warehouseCode, long shipmentOrder, int sequence, int sequenceNumber);
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/service/impl/HuahengMultiHandlerServiceImpl.java
... ... @@ -127,6 +127,18 @@ public class HuahengMultiHandlerServiceImpl extends HuahengBaseController implem
127 127 }
128 128  
129 129 @Override
  130 + public Result cancelReceiving(Integer id) {
  131 + Result result = handleMultiProcess("cancelReceiving", new MultiProcessListener() {
  132 + @Override
  133 + public Result<?> doProcess() {
  134 + Result result = receiptContainerHeaderService.cancelReceiving(id);
  135 + return result;
  136 + }
  137 + });
  138 + return result;
  139 + }
  140 +
  141 + @Override
130 142 public Result autoCombination(String shipmentCode, String warehouseCode) {
131 143 Result result = handleMultiProcess("combination", new MultiProcessListener() {
132 144 @Override
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/controller/InventoryHeaderController.java
... ... @@ -347,7 +347,6 @@ public class InventoryHeaderController extends JeecgController&lt;InventoryHeader,
347 347  
348 348 @AutoLog("库存详情-释放受控")
349 349 @ApiOperation(value = "释放受控", notes = "释放受控")
350   - @ApiLogger(apiName = "释放受控")
351 350 @PostMapping(value = "/releaseController")
352 351 @ResponseBody
353 352 public Result releaseController(@RequestBody List<Integer> ids, HttpServletRequest req) {
... ... @@ -359,7 +358,6 @@ public class InventoryHeaderController extends JeecgController&lt;InventoryHeader,
359 358  
360 359 @AutoLog("库存详情-批量受控")
361 360 @ApiOperation(value = "批量受控", notes = "批量受控")
362   - @ApiLogger(apiName = "批量受控")
363 361 @PostMapping("/controller")
364 362 @ResponseBody
365 363 public Result controller(@RequestBody List<Integer> ids) {
... ... @@ -368,4 +366,17 @@ public class InventoryHeaderController extends JeecgController&lt;InventoryHeader,
368 366 }
369 367 return inventoryDetailService.controller(ids);
370 368 }
  369 +
  370 + @AutoLog("库存头-批量出整托库存")
  371 + @ApiOperation(value = "批量出整托库存", notes = "批量出整托库存")
  372 + @ApiLogger(apiName = "批量出整托库存")
  373 + @PostMapping("/shipmentInventoryHeader")
  374 + @ResponseBody
  375 + public Result shipmentInventoryHeader(@RequestBody List<InventoryHeader> inventoryHeaderList, HttpServletRequest req) {
  376 + if (StringUtils.isEmpty(inventoryHeaderList)) {
  377 + return Result.error("库存明细为空");
  378 + }
  379 + String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
  380 + return inventoryHeaderService.shipmentInventoryHeader(inventoryHeaderList, warehouseCode);
  381 + }
371 382 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryDetail.java
... ... @@ -125,11 +125,11 @@ public class InventoryDetail implements Serializable {
125 125 @Excel(name = "库龄(天)", width = 15)
126 126 @ApiModelProperty(value = "库龄(天)")
127 127 private Integer inventoryAge;
128   - /** 受控 */
129   - @Excel(name = "受控", width = 15)
130   - @Dict(dicCode = "inventory_controller")
131   - @ApiModelProperty(value = "受控")
132   - private Integer controller;
  128 + /** 是否可用 */
  129 + @Excel(name = "是否可用", width = 15)
  130 + @Dict(dicCode = "inventory_enable")
  131 + @ApiModelProperty(value = "是否可用")
  132 + private Integer enable;
133 133 /** 备用字段1 */
134 134 @Excel(name = "备用字段1", width = 15)
135 135 @ApiModelProperty(value = "备用字段1")
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryHeader.java
... ... @@ -9,6 +9,7 @@ import org.jeecg.common.exception.JeecgBootException;
9 9 import org.jeecgframework.poi.excel.annotation.Excel;
10 10  
11 11 import com.baomidou.mybatisplus.annotation.IdType;
  12 +import com.baomidou.mybatisplus.annotation.TableField;
12 13 import com.baomidou.mybatisplus.annotation.TableId;
13 14 import com.baomidou.mybatisplus.annotation.TableName;
14 15  
... ... @@ -97,6 +98,8 @@ public class InventoryHeader implements Serializable {
97 98 /** 更新日期 */
98 99 @ApiModelProperty(value = "更新日期")
99 100 private Date updateTime;
  101 + @TableField(exist = false)
  102 + private String toPortCode;
100 103  
101 104 public void setTotalQty(BigDecimal totalQty) {
102 105 if (totalQty.compareTo(BigDecimal.ZERO) < 0) {
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryDetailService.java
... ... @@ -23,6 +23,8 @@ public interface IInventoryDetailService extends IService&lt;InventoryDetail&gt; {
23 23  
24 24 List<InventoryDetail> getInventoryDetailListByInventoryHeaderId(Integer inventoryHeaderId);
25 25  
  26 + List<InventoryDetail> getInventoryDetailListByInventoryHeaderIds(List<Integer> inventoryHeaderIds);
  27 +
26 28 List<InventoryDetail> getInventoryDetailListByContainerCode(String containerCode, String warehouseCode);
27 29  
28 30 // 求一种物料的库存之和
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryHeaderService.java
... ... @@ -2,7 +2,9 @@ package org.jeecg.modules.wms.inventory.inventoryHeader.service;
2 2  
3 3 import java.io.Serializable;
4 4 import java.util.Collection;
  5 +import java.util.List;
5 6  
  7 +import org.jeecg.common.api.vo.Result;
6 8 import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryHeader;
7 9  
8 10 import com.baomidou.mybatisplus.extension.service.IService;
... ... @@ -36,4 +38,6 @@ public interface IInventoryHeaderService extends IService&lt;InventoryHeader&gt; {
36 38 boolean updateContainerStatusAndLocationCode(String containerStatus, String locationCode, Integer id);
37 39  
38 40 boolean updateLocationCodeById(String locationCode, Integer id);
  41 +
  42 + Result shipmentInventoryHeader(List<InventoryHeader> inventoryHeaderList, String warehouseCode);
39 43 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
... ... @@ -17,7 +17,6 @@ import org.jeecg.modules.wms.config.container.service.IContainerService;
17 17 import org.jeecg.modules.wms.config.containerCapacity.entity.ContainerCapacity;
18 18 import org.jeecg.modules.wms.config.containerCapacity.service.IContainerCapacityService;
19 19 import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
20   -import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryHeader;
21 20 import org.jeecg.modules.wms.inventory.inventoryHeader.mapper.InventoryDetailMapper;
22 21 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
23 22 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
... ... @@ -65,7 +64,17 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
65 64 @Override
66 65 public List<InventoryDetail> getInventoryDetailListByInventoryHeaderId(Integer inventoryHeaderId) {
67 66 LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
68   - inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getInventoryHeaderId, inventoryHeaderId);
  67 + inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getInventoryHeaderId, inventoryHeaderId).eq(InventoryDetail::getEnable,
  68 + QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE);
  69 + List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
  70 + return inventoryDetailList;
  71 + }
  72 +
  73 + @Override
  74 + public List<InventoryDetail> getInventoryDetailListByInventoryHeaderIds(List<Integer> inventoryHeaderIds) {
  75 + LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  76 + inventoryDetailLambdaQueryWrapper.in(InventoryDetail::getInventoryHeaderId, inventoryHeaderIds).eq(InventoryDetail::getEnable,
  77 + QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE);
69 78 List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
70 79 return inventoryDetailList;
71 80 }
... ... @@ -73,7 +82,8 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
73 82 @Override
74 83 public List<InventoryDetail> getInventoryDetailListByContainerCode(String containerCode, String warehouseCode) {
75 84 LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
76   - inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getContainerCode, containerCode).eq(InventoryDetail::getWarehouseCode, warehouseCode);
  85 + inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getContainerCode, containerCode).eq(InventoryDetail::getWarehouseCode, warehouseCode)
  86 + .eq(InventoryDetail::getEnable, QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE);
77 87 List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
78 88 return inventoryDetailList;
79 89 }
... ... @@ -105,7 +115,7 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
105 115 .eq(StringUtils.isNotEmpty(inventoryDetail.getBatch()), InventoryDetail::getBatch, inventoryDetail.getBatch())
106 116 .eq(StringUtils.isNotEmpty(inventoryDetail.getLot()), InventoryDetail::getLot, inventoryDetail.getLot())
107 117 .eq(StringUtils.isNotEmpty(inventoryDetail.getProject()), InventoryDetail::getProject, inventoryDetail.getLot())
108   - .eq(InventoryDetail::getController, QuantityConstant.CONTROLLER_NOT_ENABLE)
  118 + .eq(InventoryDetail::getEnable, QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE)
109 119 .eq(InventoryDetail::getContainerStatus, QuantityConstant.STATUS_CONTAINER_EMPTY).eq(InventoryDetail::getCompanyCode, inventoryDetail.getCompanyCode());
110 120 List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
111 121 if (inventoryDetailList.size() == 0) {
... ... @@ -210,11 +220,11 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
210 220 }
211 221 List<InventoryDetail> inventoryDetailUpdateList = new ArrayList<>();
212 222 List<Integer> inventoryHeaderIdList = inventoryDetailList.stream().map(InventoryDetail::getInventoryHeaderId).distinct().collect(Collectors.toList());
213   - List<InventoryHeader> inventoryHeaderList = inventoryHeaderService.listByIds(inventoryHeaderIdList);
  223 +// List<InventoryHeader> inventoryHeaderList = inventoryHeaderService.listByIds(inventoryHeaderIdList);
214 224 for (InventoryDetail inventoryDetail : inventoryDetailList) {
215 225 InventoryDetail inventoryDetail1 = new InventoryDetail();
216 226 inventoryDetail1.setId(inventoryDetail.getId());
217   - inventoryDetail1.setController(QuantityConstant.CONTROLLER_ENABLE);
  227 + inventoryDetail1.setEnable(QuantityConstant.INVENTORY_DETAIL_STATUS_CONTAINER);
218 228 inventoryDetailUpdateList.add(inventoryDetail1);
219 229 }
220 230 boolean success = updateBatchById(inventoryDetailUpdateList);
... ... @@ -234,7 +244,7 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
234 244 for (InventoryDetail inventoryDetail : inventoryDetailList) {
235 245 InventoryDetail inventoryDetail1 = new InventoryDetail();
236 246 inventoryDetail1.setId(inventoryDetail.getId());
237   - inventoryDetail1.setController(QuantityConstant.CONTROLLER_NOT_ENABLE);
  247 + inventoryDetail1.setEnable(QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE);
238 248 inventoryDetailUpdateList.add(inventoryDetail1);
239 249 }
240 250 boolean success = updateBatchById(inventoryDetailUpdateList);
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java
... ... @@ -4,18 +4,33 @@ import java.io.Serializable;
4 4 import java.util.ArrayList;
5 5 import java.util.Collection;
6 6 import java.util.List;
  7 +import java.util.stream.Collectors;
7 8  
8 9 import javax.annotation.Resource;
9 10  
  11 +import org.jeecg.common.api.vo.Result;
10 12 import org.jeecg.common.exception.JeecgBootException;
11 13 import org.jeecg.modules.wms.config.container.entity.Container;
12 14 import org.jeecg.modules.wms.config.container.service.IContainerService;
  15 +import org.jeecg.modules.wms.framework.service.IHuahengMultiHandlerService;
13 16 import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
14 17 import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryHeader;
15 18 import org.jeecg.modules.wms.inventory.inventoryHeader.mapper.InventoryDetailMapper;
16 19 import org.jeecg.modules.wms.inventory.inventoryHeader.mapper.InventoryHeaderMapper;
17 20 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
18 21 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
  22 +import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
  23 +import org.jeecg.modules.wms.shipment.shipmentCombination.service.IShipmentCombinationService;
  24 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
  25 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
  26 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
  27 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
  28 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
  29 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
  30 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
  31 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
  32 +import org.jeecg.utils.StringUtils;
  33 +import org.jeecg.utils.constant.QuantityConstant;
19 34 import org.springframework.beans.factory.annotation.Autowired;
20 35 import org.springframework.stereotype.Service;
21 36 import org.springframework.transaction.annotation.Transactional;
... ... @@ -43,6 +58,18 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
43 58 private IInventoryHeaderService inventoryHeaderService;
44 59 @Resource
45 60 private IInventoryDetailService inventoryDetailService;
  61 + @Resource
  62 + private IShipmentHeaderService shipmentHeaderService;
  63 + @Resource
  64 + private IShipmentDetailService shipmentDetailService;
  65 + @Resource
  66 + private IShipmentContainerHeaderService shipmentContainerHeaderService;
  67 + @Resource
  68 + private IShipmentCombinationService shipmentCombinationService;
  69 + @Resource
  70 + private IShipmentContainerDetailService shipmentContainerDetailService;
  71 + @Resource
  72 + private IHuahengMultiHandlerService huahengMultiHandlerService;
46 73  
47 74 @Override
48 75 @Transactional
... ... @@ -98,7 +125,6 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
98 125 }
99 126  
100 127 @Override
101   - @Transactional
102 128 public boolean updateInventoryLocationAndZoneById(String locationCode, String zoneCode, Integer id) {
103 129 InventoryHeader inventoryHeader = new InventoryHeader();
104 130 inventoryHeader.setId(id);
... ... @@ -108,7 +134,6 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
108 134 }
109 135  
110 136 @Override
111   - @Transactional
112 137 public boolean updateContainerStatusById(String containerStatus, Integer id) {
113 138 InventoryHeader inventoryHeader = new InventoryHeader();
114 139 inventoryHeader.setId(id);
... ... @@ -117,7 +142,6 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
117 142 }
118 143  
119 144 @Override
120   - @Transactional
121 145 public boolean updateContainerStatusAndLocationCode(String containerStatus, String locationCode, Integer id) {
122 146 InventoryHeader inventoryHeader = new InventoryHeader();
123 147 inventoryHeader.setId(id);
... ... @@ -127,7 +151,6 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
127 151 }
128 152  
129 153 @Override
130   - @Transactional
131 154 public boolean updateLocationCodeById(String locationCode, Integer id) {
132 155 InventoryHeader inventoryHeader = new InventoryHeader();
133 156 inventoryHeader.setId(id);
... ... @@ -135,4 +158,90 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
135 158 return inventoryHeaderService.updateById(inventoryHeader);
136 159 }
137 160  
  161 + @Override
  162 + @Transactional(rollbackFor = JeecgBootException.class)
  163 + public Result shipmentInventoryHeader(List<InventoryHeader> inventoryHeaderList, String warehouseCode) {
  164 + if (StringUtils.isEmpty(inventoryHeaderList)) {
  165 + return Result.error("批量快速出库,所选库存头为空");
  166 + }
  167 + String toPortCode = inventoryHeaderList.get(0).getToPortCode();
  168 + if (StringUtils.isEmpty(toPortCode)) {
  169 + return Result.error("批量快速出库,出库站台编码为空");
  170 + }
  171 + List<InventoryHeader> shipmentInventoryHeaderList =
  172 + inventoryHeaderList.stream().filter((item) -> item.getContainerStatus().equals(QuantityConstant.STATUS_CONTAINER_EMPTY)).collect(Collectors.toList());
  173 + if (StringUtils.isEmpty(shipmentInventoryHeaderList)) {
  174 + return Result.error("批量快速出库, 排除锁定库存后没有可出库存头");
  175 + }
  176 + List<Integer> inventoryHeaderIds = shipmentInventoryHeaderList.stream().map(InventoryHeader::getId).collect(Collectors.toList());
  177 + List<InventoryDetail> inventoryDetails = inventoryDetailService.getInventoryDetailListByInventoryHeaderIds(inventoryHeaderIds);
  178 + if (StringUtils.isEmpty(inventoryDetails)) {
  179 + return Result.error("批量快速出库, 排除锁定库存后没有可出库存详情");
  180 + }
  181 +
  182 + ShipmentHeader shipmentHeader = new ShipmentHeader();
  183 + shipmentHeader.setWarehouseCode(warehouseCode);
  184 + shipmentHeader.setType(QuantityConstant.SHIPMENT_BILL_TYPE_QTC);
  185 + shipmentHeader.setRemark("快速出库");
  186 + Result result = shipmentHeaderService.saveShipmentHeader(shipmentHeader);
  187 + if (!result.isSuccess()) {
  188 + throw new JeecgBootException("批量快速出库,创建出库单失败:".concat(result.getMessage()));
  189 + }
  190 + List<ShipmentDetail> shipmentDetailList = new ArrayList<>();
  191 + for (InventoryDetail inventoryDetail : inventoryDetails) {
  192 + ShipmentDetail shipmentDetail = new ShipmentDetail();
  193 + shipmentDetail.setShipmentId(shipmentHeader.getId());
  194 + shipmentDetail.setMaterialCode(inventoryDetail.getMaterialCode());
  195 + shipmentDetail.setInventoryStatus(inventoryDetail.getInventoryStatus());
  196 + shipmentDetail.setQty(inventoryDetail.getQty());
  197 + shipmentDetail.setBatch(inventoryDetail.getBatch());
  198 + result = shipmentDetailService.saveShipmentDetail(shipmentDetail);
  199 + if (!result.isSuccess()) {
  200 + throw new JeecgBootException("批量快速出库,创建出库详情失败:".concat(result.getMessage()));
  201 + }
  202 + shipmentDetail = shipmentDetailService.getById(shipmentDetail.getId());
  203 + shipmentDetailList.add(shipmentDetail);
  204 + }
  205 + for (int i = 0; i < inventoryDetails.size(); i++) {
  206 + InventoryDetail inventoryDetail = inventoryDetails.get(i);
  207 + ShipmentDetail shipmentDetail = shipmentDetailList.get(i);
  208 + CombinationModel combinationModel = new CombinationModel();
  209 + combinationModel.setInventoryDetail(inventoryDetail);
  210 + combinationModel.setShipmentDetail(shipmentDetail);
  211 + combinationModel.setShipQty(inventoryDetail.getQty());
  212 + result = shipmentCombinationService.combination(combinationModel);
  213 + if (!result.isSuccess()) {
  214 + throw new JeecgBootException("批量快速出库,配盘失败:".concat(result.getMessage()));
  215 + }
  216 + }
  217 + List<ShipmentContainerDetail> shipmentContainerDetailList =
  218 + shipmentContainerDetailService.getShipmentContainerDetailListByShipmentCode(shipmentHeader.getCode());
  219 + if (StringUtils.isEmpty(shipmentContainerDetailList)) {
  220 + throw new JeecgBootException("批量快速出库,根据出库单没有找到配盘详情");
  221 + }
  222 + List<Integer> shipmentContainerHeaderIdList =
  223 + shipmentContainerDetailList.stream().map(ShipmentContainerDetail::getShipmentContainerId).collect(Collectors.toList());
  224 + long shipmentOrder = System.currentTimeMillis();
  225 + int sequenceNumber = shipmentContainerHeaderIdList.size();
  226 + int sequence = 0;
  227 + for (int shipmentContainerId : shipmentContainerHeaderIdList) {
  228 + sequence++;
  229 + ShipmentContainerHeader shipmentContainerHeader = shipmentContainerHeaderService.getById(shipmentContainerId);
  230 + if (shipmentContainerHeader == null) {
  231 + throw new JeecgBootException("批量快速出库,没有找到出库表头:" + shipmentContainerId);
  232 + }
  233 + shipmentContainerHeader.setToPort(toPortCode);
  234 + boolean success = shipmentContainerHeaderService.updateById(shipmentContainerHeader);
  235 + if (!success) {
  236 + throw new JeecgBootException("批量快速出库,更新出库组盘头失败");
  237 + }
  238 + result = huahengMultiHandlerService.createShipmentTask(shipmentContainerHeader, warehouseCode, shipmentOrder, sequence, sequenceNumber);
  239 + if (!result.isSuccess()) {
  240 + throw new JeecgBootException(result.getMessage());
  241 + }
  242 + }
  243 +
  244 + return Result.OK("批量快速出库成功");
  245 + }
  246 +
138 247 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/controller/ReceiptContainerHeaderController.java
... ... @@ -143,7 +143,7 @@ public class ReceiptContainerHeaderController extends JeecgController&lt;ReceiptCon
143 143 @DeleteMapping(value = "/delete")
144 144 @RequiresPermissions("receiptContainerHeader:delete")
145 145 public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
146   - return receiptContainerHeaderService.cancelReceiving(Integer.parseInt(id));
  146 + return huahengMultiHandlerService.cancelReceiving(Integer.parseInt(id));
147 147 }
148 148  
149 149 /**
... ... @@ -154,11 +154,18 @@ public class ReceiptContainerHeaderController extends JeecgController&lt;ReceiptCon
154 154 @AutoLog(value = "入库组盘-批量删除")
155 155 @ApiOperation(value = "入库组盘-批量删除", notes = "入库组盘-批量删除")
156 156 @DeleteMapping(value = "/deleteBatch")
157   - @RequiresPermissions("receiptContainerHeader:deleteBatch")
  157 + @RequiresPermissions("receiptContainerHeader:delete")
158 158 public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
159 159 List<String> idList = Arrays.asList(ids.split(","));
160 160 List<Integer> idInterList = idList.stream().map(Integer::parseInt).collect(Collectors.toList());
161   - return receiptContainerHeaderService.cancelReceiving(idInterList);
  161 + Result result = null;
  162 + for (Integer id : idInterList) {
  163 + result = huahengMultiHandlerService.cancelReceiving(id);
  164 + if (!result.isSuccess()) {
  165 + return result;
  166 + }
  167 + }
  168 + return result;
162 169 }
163 170  
164 171 /**
... ... @@ -342,6 +349,24 @@ public class ReceiptContainerHeaderController extends JeecgController&lt;ReceiptCon
342 349 }
343 350  
344 351 /**
  352 + * 创建任务
  353 + * @return
  354 + */
  355 + @ApiOperation(value = "入库组盘-创建任务", notes = "入库组盘-创建任务")
  356 + @PostMapping("/createReceiptBatchTask")
  357 + @ResponseBody
  358 + public Result createReceiptBatchTask(@RequestBody List<ReceiptContainerHeader> receiptContainerHeaderList, HttpServletRequest req) {
  359 + String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
  360 + for (ReceiptContainerHeader receiptContainerHeader : receiptContainerHeaderList) {
  361 + Result result = huahengMultiHandlerService.createReceiptTask(receiptContainerHeader, warehouseCode);
  362 + if (!result.isSuccess()) {
  363 + return result;
  364 + }
  365 + }
  366 + return Result.OK("批量创建入库任务成功");
  367 + }
  368 +
  369 + /**
345 370 * 选择分拣口
346 371 * @return
347 372 */
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiving/service/impl/ReceiveServiceImpl.java
... ... @@ -184,6 +184,9 @@ public class ReceiveServiceImpl extends ServiceImpl&lt;ReceiveMapper, Receive&gt; impl
184 184 if (qty == null || taskQty == null) {
185 185 throw new JeecgBootException("入库组盘,物料编码:" + receive.getMaterialCode() + " 收货数量或可收数量为空");
186 186 }
  187 + if (taskQty.compareTo(BigDecimal.ZERO) < 0) {
  188 + throw new JeecgBootException("入库组盘,物料编码:" + receive.getMaterialCode() + " 收货数量不能小于0,收货数量:" + taskQty + "可收数量:" + qty);
  189 + }
187 190 if (taskQty.compareTo(qty) > 0) {
188 191 throw new JeecgBootException("入库组盘,物料编码:" + receive.getMaterialCode() + " 收货数量不能大于可收数量,收货数量:" + taskQty + "可收数量:" + qty);
189 192 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
... ... @@ -118,7 +118,7 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi
118 118 LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
119 119 inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getWarehouseCode, warehouseCode).eq(InventoryDetail::getCompanyCode, companyCode)
120 120 .eq(InventoryDetail::getMaterialCode, materialCode).eq(InventoryDetail::getInventoryStatus, inventoryStatus)
121   - .eq(InventoryDetail::getController, QuantityConstant.CONTROLLER_NOT_ENABLE)
  121 + .eq(InventoryDetail::getEnable, QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE)
122 122 .eq(InventoryDetail::getContainerStatus, QuantityConstant.STATUS_CONTAINER_EMPTY);
123 123 List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper);
124 124 return inventoryDetailList;
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/controller/ShipmentContainerHeaderController.java
... ... @@ -137,7 +137,7 @@ public class ShipmentContainerHeaderController extends JeecgController&lt;ShipmentC
137 137 */
138 138 @AutoLog(value = "出库组盘-批量删除")
139 139 @ApiOperation(value = "出库组盘-批量删除", notes = "出库组盘-批量删除")
140   - @RequiresPermissions("shipmentContainerHeader:deleteBatch")
  140 + @RequiresPermissions("shipmentContainerHeader:delete")
141 141 @DeleteMapping(value = "/deleteBatch")
142 142 public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
143 143 List<String> idList = Arrays.asList(ids.split(","));
... ... @@ -145,6 +145,9 @@ public class ShipmentContainerHeaderController extends JeecgController&lt;ShipmentC
145 145 Result result = null;
146 146 for (Integer id : idInterList) {
147 147 result = huahengMultiHandlerService.cancelCombine(id);
  148 + if (!result.isSuccess()) {
  149 + return result;
  150 + }
148 151 }
149 152 return result;
150 153 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/impl/ShipmentDetailServiceImpl.java
... ... @@ -19,6 +19,7 @@ import org.jeecg.utils.StringUtils;
19 19 import org.jeecg.utils.constant.QuantityConstant;
20 20 import org.springframework.beans.factory.annotation.Autowired;
21 21 import org.springframework.stereotype.Service;
  22 +import org.springframework.transaction.annotation.Transactional;
22 23  
23 24 import com.alibaba.fastjson.JSON;
24 25 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
... ... @@ -52,6 +53,7 @@ public class ShipmentDetailServiceImpl extends ServiceImpl&lt;ShipmentDetailMapper,
52 53 }
53 54  
54 55 @Override
  56 + @Transactional(rollbackFor = JeecgBootException.class)
55 57 @OperationLog(bizId = "''", bizType = "'出库单追踪'", tag = "'详情添加'", extra = "#extraJsonString", msg = "''", recordReturnValue = true)
56 58 public Result saveShipmentDetail(ShipmentDetail shipmentDetail) {
57 59 ShipmentHeader shipmentHeader = shipmentHeaderService.getById(shipmentDetail.getShipmentId());
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/impl/ShipmentHeaderServiceImpl.java
... ... @@ -99,7 +99,7 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
99 99 }
100 100  
101 101 @Override
102   - @Transactional
  102 + @Transactional(rollbackFor = JeecgBootException.class)
103 103 @OperationLog(bizId = "#shipmentHeader.getCode()", bizType = "'出库单追踪'", tag = "'出库单新增'",
104 104 msg = "'上游单号:'+ #shipmentHeader.getReferCode() + ',仓库编码:' + #shipmentHeader.getWarehouseCode()", recordReturnValue = true)
105 105 public Result saveShipmentHeader(ShipmentHeader shipmentHeader) {
... ...
huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java
... ... @@ -552,10 +552,10 @@ public class QuantityConstant {
552 552 /* 不可用 */
553 553 public static final int STATUS_DISABLE = 0;
554 554  
555   - /* 库内有托盘 */
556   - public static final int STATUS_HAVE_CONTAINER = 1;
557   - /* 库内没有托盘 */
558   - public static final int STATUS_NOT_CONTAINER = 0;
  555 + /* 可用 */
  556 + public static final int INVENTORY_DETAIL_STATUS_ENABLE = 0;
  557 + /* 受控 */
  558 + public static final int INVENTORY_DETAIL_STATUS_CONTAINER = 1;
559 559  
560 560 public static final int HTTP_OK = 200;
561 561  
... ...