Commit 22e26ccbc55b7d5a088353cb682679607923c1b7
1 parent
03b43a78
1. 修复一个托盘有多种物料,出库其中一种后,库存详情没有改变的问题。
2. 修复出多个物料时库存详情不准确的问题。
Showing
9 changed files
with
179 additions
and
22 deletions
ant-design-vue-jeecg/src/api/api.js
... | ... | @@ -221,6 +221,8 @@ export const getAllWarehouseList = (params) => getAction("/config/warehouse/getA |
221 | 221 | export const getAllZoneList = (params) => getAction("/config/zone/getAllZoneList", params); |
222 | 222 | //批量快速出整托 |
223 | 223 | export const shipmentInventoryHeader = (params) => postAction('/inventory/inventoryHeader/shipmentInventoryHeader', params); |
224 | +//批量快速出库存详情 | |
225 | +export const shipmentInventoryDetail = (params) => postAction('/inventory/inventoryHeader/shipmentInventoryDetail', params); | |
224 | 226 | // 中转HTTP请求 |
225 | 227 | export const transitRESTful = { |
226 | 228 | get: (url, parameter) => getAction(getTransitURL(url), parameter), |
... | ... |
ant-design-vue-jeecg/src/views/system/inventory/InventoryTransactionList.vue
... | ... | @@ -299,9 +299,14 @@ export default { |
299 | 299 | scopedSlots: {customRender: 'inventoryStatus_dictText'} |
300 | 300 | }, |
301 | 301 | { |
302 | - title: '数量', | |
302 | + title: '入库数量', | |
303 | 303 | align: "center", |
304 | - dataIndex: 'qty' | |
304 | + dataIndex: 'receiptQty' | |
305 | + }, | |
306 | + { | |
307 | + title: '出库数量', | |
308 | + align: "center", | |
309 | + dataIndex: 'shipmentQty' | |
305 | 310 | }, |
306 | 311 | { |
307 | 312 | title: '库存数量', |
... | ... |
ant-design-vue-jeecg/src/views/system/inventory/SimpleInventoryDetailList.vue
... | ... | @@ -138,6 +138,7 @@ |
138 | 138 | </a-upload> |
139 | 139 | <a-button v-has="'inventoryDetail:controller'" @click='controller()' type='primary'>冻结</a-button> |
140 | 140 | <a-button v-has="'inventoryDetail:releaseController'" @click='releaseController()' type='primary'>释放冻结</a-button> |
141 | + <a-button v-has="'inventoryHeader:quickShipmentInventoryHeader'" @click='quickShipment()' type='primary'>快速出库</a-button> | |
141 | 142 | <!-- 高级查询区域 --> |
142 | 143 | <j-super-query |
143 | 144 | :fieldList="superFieldList" |
... | ... | @@ -225,6 +226,7 @@ |
225 | 226 | </div> |
226 | 227 | |
227 | 228 | <simple-inventory-detail-modal ref="modalForm" @ok="modalFormOk"></simple-inventory-detail-modal> |
229 | + <QuickShipmentDetailModel ref='quickShipmentModel' @ok='quickShipmentModalFormOk'></QuickShipmentDetailModel> | |
228 | 230 | </a-card> |
229 | 231 | </template> |
230 | 232 | |
... | ... | @@ -236,11 +238,13 @@ import SimpleInventoryDetailModal from './modules/SimpleInventoryDetailModal' |
236 | 238 | import {filterMultiDictText} from '@/components/dict/JDictSelectUtil' |
237 | 239 | import {getCompanyList, getZoneList, } from "@api/api"; |
238 | 240 | import {postAction} from '@/api/manage' |
241 | +import QuickShipmentDetailModel from "@views/system/shipment/modules/QuickShipmentDetailModal"; | |
239 | 242 | |
240 | 243 | export default { |
241 | 244 | name: 'InventoryDetailList', |
242 | 245 | mixins: [JeecgListMixin, mixinDevice], |
243 | 246 | components: { |
247 | + QuickShipmentDetailModel, | |
244 | 248 | SimpleInventoryDetailModal |
245 | 249 | }, |
246 | 250 | data() { |
... | ... | @@ -392,7 +396,8 @@ export default { |
392 | 396 | releaseController: 'inventory/inventoryHeader/releaseController', |
393 | 397 | }, |
394 | 398 | dictOptions: {}, |
395 | - superFieldList: [] | |
399 | + superFieldList: [], | |
400 | + selectRecord:[], | |
396 | 401 | } |
397 | 402 | }, |
398 | 403 | created() { |
... | ... | @@ -491,22 +496,22 @@ export default { |
491 | 496 | }) |
492 | 497 | } |
493 | 498 | }, |
499 | + onSelectChange(selectedRowKeys, selectionRows) { | |
500 | + this.selectedMainId = selectedRowKeys[0].toString(); | |
501 | + this.selectedRowKeys = selectedRowKeys; | |
502 | + this.selectRecord = selectionRows; | |
503 | + }, | |
494 | 504 | quickShipment() { |
495 | 505 | if (this.selectedRowKeys.length <= 0) { |
496 | 506 | this.$message.warning('请选择一条记录!'); |
497 | 507 | } else { |
498 | - let zoneCodes = this.selectRecord.map(row => row.zoneCode) | |
508 | + let zoneCodes = this.selectRecord.map(row => row.zoneCode); | |
499 | 509 | if (new Set(zoneCodes).size !== 1) { |
500 | 510 | this.$message.warning('所选数据非同库区'); |
501 | 511 | return; |
502 | 512 | } |
503 | - if ('D' !== this.selectRecord[0].zoneCode){ | |
504 | - this.$refs.quickShipmentModel.model.containerCode = this.selectRecord[0].containerCode; | |
505 | - this.$refs.quickShipmentModel.edit(); | |
506 | - this.$refs.quickShipmentModel.title = '选择出库口'; | |
507 | - }else { | |
508 | - this.quickShipmentModalFormOk(null) | |
509 | - } | |
513 | + this.$refs.quickShipmentModel.edit(this.selectRecord); | |
514 | + this.$refs.quickShipmentModel.title = '选择出库口'; | |
510 | 515 | } |
511 | 516 | }, |
512 | 517 | solutionCompany(value) { |
... | ... |
ant-design-vue-jeecg/src/views/system/receipt/ReceiptContainerHeaderList.vue
... | ... | @@ -72,7 +72,7 @@ |
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> | |
75 | + <a-button v-has="'receiptContainerHeader:createTask'" @click="createBatchTask" type="primary" >批量生成任务</a-button> | |
76 | 76 | <a-button v-has="'receiptContainerHeader:delete'" @click="cancelBatchTask" type="primary" >批量取消组盘</a-button> |
77 | 77 | </div> |
78 | 78 | |
... | ... | @@ -117,12 +117,12 @@ |
117 | 117 | size="small" |
118 | 118 | @click="downloadFile(text)">下载 |
119 | 119 | </a-button> |
120 | - </template> | |
120 | + </template>selectPort | |
121 | 121 | <span slot="action" slot-scope="text, record"> |
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> | |
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> | |
124 | -<!-- <a v-if="record.status == 0 && record.taskType == 200" @click="selectPort(record)" v-has="'receiptContainerHeader:createTask'">生成任务<a-divider type="vertical"/></a>--> | |
125 | -<!-- <a v-else-if="record.status == 0" @click="createTask(record)" v-has="'receiptContainerHeader:createTask'">生成任务<a-divider type="vertical"/></a>--> | |
122 | +<!-- <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>--> | |
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>--> | |
124 | + <a v-if="record.status == 0 && record.taskType == 200" @click="selectPort(record)" v-has="'receiptContainerHeader:createTask'">生成任务<a-divider type="vertical"/></a> | |
125 | + <a v-else-if="record.status == 0" @click="createTask(record)" v-has="'receiptContainerHeader:createTask'">生成任务<a-divider type="vertical"/></a> | |
126 | 126 | <a-popconfirm v-if="record.status == 0" v-has="'receiptContainerHeader:delete'" title="确定取消配盘吗?" @confirm="() => handleDelete(record.id)"> |
127 | 127 | <a><a-button type="danger">取消配盘</a-button> <a-divider type="vertical"/></a> |
128 | 128 | </a-popconfirm> |
... | ... |
ant-design-vue-jeecg/src/views/system/shipment/modules/QuickShipmentDetailModal.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, shipmentInventoryDetail} from '@/api/api' | |
32 | + | |
33 | +export default { | |
34 | + name: 'QuickShipmentDetailModel', | |
35 | + components: { }, | |
36 | + data() { | |
37 | + return { | |
38 | + title: '操作', | |
39 | + width: 400, | |
40 | + portList: [], | |
41 | + inventoryDetailList: [], | |
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.inventoryDetailList = 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.inventoryDetailList.forEach(x=>{ | |
94 | + x["toPortCode"]=this.model.outPortCode; | |
95 | + }) | |
96 | + shipmentInventoryDetail(this.inventoryDetailList).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/inventory/inventoryHeader/service/IInventoryDetailService.java
... | ... | @@ -27,7 +27,10 @@ public interface IInventoryDetailService extends IService<InventoryDetail> { |
27 | 27 | |
28 | 28 | List<InventoryDetail> getInventoryDetailListByContainerCode(String containerCode, String warehouseCode); |
29 | 29 | |
30 | - // 求一种物料的库存之和 | |
30 | + // 求一种物料的库存之和(总数) | |
31 | + BigDecimal getInventorySumQty(InventoryDetail inventoryDetail); | |
32 | + | |
33 | + // 求一种物料的库存之和(扣除了配盘数量) | |
31 | 34 | BigDecimal getSumQty(InventoryDetail inventoryDetail); |
32 | 35 | |
33 | 36 | // 求一种物料的可出库存之和 |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
... | ... | @@ -89,6 +89,23 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe |
89 | 89 | } |
90 | 90 | |
91 | 91 | @Override |
92 | + public BigDecimal getInventorySumQty(InventoryDetail inventoryDetail) { | |
93 | + LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery(); | |
94 | + inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getInventoryStatus, inventoryDetail.getInventoryStatus()) | |
95 | + .eq(InventoryDetail::getMaterialCode, inventoryDetail.getMaterialCode()).eq(InventoryDetail::getWarehouseCode, inventoryDetail.getWarehouseCode()) | |
96 | + .eq(StringUtils.isNotEmpty(inventoryDetail.getBatch()), InventoryDetail::getBatch, inventoryDetail.getBatch()) | |
97 | + .eq(StringUtils.isNotEmpty(inventoryDetail.getLot()), InventoryDetail::getLot, inventoryDetail.getLot()) | |
98 | + .eq(StringUtils.isNotEmpty(inventoryDetail.getProject()), InventoryDetail::getProject, inventoryDetail.getLot()) | |
99 | + .eq(InventoryDetail::getCompanyCode, inventoryDetail.getCompanyCode()); | |
100 | + List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper); | |
101 | + if (inventoryDetailList.size() == 0) { | |
102 | + return BigDecimal.ZERO; | |
103 | + } | |
104 | + BigDecimal totalQty = inventoryDetailList.stream().map(InventoryDetail::getQty).reduce(BigDecimal.ZERO, BigDecimal::add); | |
105 | + return totalQty; | |
106 | + } | |
107 | + | |
108 | + @Override | |
92 | 109 | public BigDecimal getSumQty(InventoryDetail inventoryDetail) { |
93 | 110 | LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery(); |
94 | 111 | inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getInventoryStatus, inventoryDetail.getInventoryStatus()) |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java
... | ... | @@ -168,6 +168,7 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe |
168 | 168 | if (StringUtils.isEmpty(toPortCode)) { |
169 | 169 | return Result.error("批量快速出库,出库站台编码为空"); |
170 | 170 | } |
171 | + String companyCode = inventoryHeaderList.get(0).getCompanyCode(); | |
171 | 172 | List<InventoryHeader> shipmentInventoryHeaderList = |
172 | 173 | inventoryHeaderList.stream().filter((item) -> item.getContainerStatus().equals(QuantityConstant.STATUS_CONTAINER_EMPTY)).collect(Collectors.toList()); |
173 | 174 | if (StringUtils.isEmpty(shipmentInventoryHeaderList)) { |
... | ... | @@ -178,9 +179,9 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe |
178 | 179 | if (StringUtils.isEmpty(inventoryDetails)) { |
179 | 180 | return Result.error("批量快速出库, 排除锁定库存后没有可出库存详情"); |
180 | 181 | } |
181 | - | |
182 | 182 | ShipmentHeader shipmentHeader = new ShipmentHeader(); |
183 | 183 | shipmentHeader.setWarehouseCode(warehouseCode); |
184 | + shipmentHeader.setCompanyCode(companyCode); | |
184 | 185 | shipmentHeader.setType(QuantityConstant.SHIPMENT_BILL_TYPE_QTC); |
185 | 186 | shipmentHeader.setRemark("快速出库"); |
186 | 187 | Result result = shipmentHeaderService.saveShipmentHeader(shipmentHeader); |
... | ... | @@ -263,9 +264,10 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe |
263 | 264 | if (StringUtils.isEmpty(inventoryDetailList)) { |
264 | 265 | return Result.error("批量快速出库, 排除锁定库存后没有可出库存详情"); |
265 | 266 | } |
266 | - | |
267 | + String companyCode = inventoryDetailList.get(0).getCompanyCode(); | |
267 | 268 | ShipmentHeader shipmentHeader = new ShipmentHeader(); |
268 | 269 | shipmentHeader.setWarehouseCode(warehouseCode); |
270 | + shipmentHeader.setCompanyCode(companyCode); | |
269 | 271 | shipmentHeader.setType(QuantityConstant.SHIPMENT_BILL_TYPE_QTC); |
270 | 272 | shipmentHeader.setRemark("快速出库"); |
271 | 273 | Result result = shipmentHeaderService.saveShipmentHeader(shipmentHeader); |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
... | ... | @@ -1142,7 +1142,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea |
1142 | 1142 | inventoryTransaction.setQty(receiptQty); |
1143 | 1143 | inventoryTransaction.setReceiptQty(receiptQty); |
1144 | 1144 | // 获得库存数量 |
1145 | - BigDecimal inventoryQty = inventoryDetailService.getSumQty(inventoryDetail); | |
1145 | + BigDecimal inventoryQty = inventoryDetailService.getInventorySumQty(inventoryDetail); | |
1146 | 1146 | inventoryQty = inventoryQty.add(receiptQty); |
1147 | 1147 | inventoryTransaction.setInventoryQty(inventoryQty); |
1148 | 1148 | inventoryTransactionList.add(inventoryTransaction); |
... | ... | @@ -1317,6 +1317,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea |
1317 | 1317 | inventoryTransaction.setContainerCode(containerCode); |
1318 | 1318 | inventoryTransaction.setZoneCode(zoneCode); |
1319 | 1319 | inventoryTransaction.setFromLocationCode(fromLocationCode); |
1320 | + inventoryTransaction.setToLocationCode(toLocationCode); | |
1320 | 1321 | inventoryTransaction.setMaterialCode(inventoryDetail.getMaterialCode()); |
1321 | 1322 | inventoryTransaction.setMaterialName(inventoryDetail.getMaterialName()); |
1322 | 1323 | inventoryTransaction.setMaterialSpec(inventoryDetail.getMaterialSpec()); |
... | ... | @@ -1332,7 +1333,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea |
1332 | 1333 | inventoryTransaction.setProject(inventoryDetail.getProject()); |
1333 | 1334 | inventoryTransaction.setQty(taskDetail.getQty()); |
1334 | 1335 | inventoryTransaction.setShipmentQty(taskDetail.getQty()); |
1335 | - BigDecimal inventoryQty = inventoryDetailService.getSumQty(inventoryDetail); | |
1336 | + BigDecimal inventoryQty = inventoryDetailService.getInventorySumQty(inventoryDetail); | |
1336 | 1337 | inventoryTransaction.setInventoryQty(inventoryQty); |
1337 | 1338 | inventoryTransactionList.add(inventoryTransaction); |
1338 | 1339 | shipmentIdList.add(taskDetail.getShipmentId()); |
... | ... | @@ -1353,6 +1354,17 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea |
1353 | 1354 | if (!success) { |
1354 | 1355 | throw new JeecgBootException("完成出库任务,更新库存头失败"); |
1355 | 1356 | } |
1357 | + List<InventoryDetail> updateInventoryDetailList = new ArrayList<>(); | |
1358 | + for (InventoryDetail inventoryDetail : inventoryDetailList) { | |
1359 | + InventoryDetail inventoryDetail1 = new InventoryDetail(); | |
1360 | + inventoryDetail1.setId(inventoryDetail.getId()); | |
1361 | + inventoryDetail1.setLocationCode(toLocationCode); | |
1362 | + updateInventoryDetailList.add(inventoryDetail1); | |
1363 | + } | |
1364 | + success = inventoryDetailService.updateBatchLocationCodeById(updateInventoryDetailList); | |
1365 | + if (!success) { | |
1366 | + throw new JeecgBootException("完成出库任务,更新库存详情失败"); | |
1367 | + } | |
1356 | 1368 | } |
1357 | 1369 | success = inventoryTransactionService.saveBatch(inventoryTransactionList); |
1358 | 1370 | if (!success) { |
... | ... |