Commit 05a6e39935abd268d2c71ed5dde38b2bcddf6a01

Authored by 肖超群
1 parent ee8640c4

开发合盘功能

Showing 16 changed files with 431 additions and 72 deletions
ant-design-vue-jeecg/src/api/api.js
... ... @@ -246,6 +246,8 @@ export const shipmentInventoryHeader = (params) => postAction('/inventory/invent
246 246 export const shipmentInventoryDetail = (params) => postAction('/inventory/inventoryHeader/shipmentInventoryDetail', params);
247 247 //呼叫入库托盘
248 248 export const callReceiptBox = (params) => postAction('/receipt/receiptHeader/callbox', params);
  249 +//批量呼叫入库托盘
  250 +export const batchCallReceiptBox = (params) => postAction('/receipt/receiptHeader/batchCallBox', params);
249 251 //呼叫出库托盘
250 252 export const callShipmentBox = (params) => postAction('/shipment/shipmentHeader/callbox', params);
251 253 //根据收货ID查询收货单
... ...
ant-design-vue-jeecg/src/components/jeecgbiz/JSelectMultiCanUseContainer.vue 0 → 100644
  1 +<template>
  2 + <!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 -->
  3 + <j-select-biz-component
  4 + :value="value"
  5 + :multiple="false"
  6 + :ellipsisLength="25"
  7 + :listUrl="url.list"
  8 + :columns="columns"
  9 + v-on="$listeners"
  10 + v-bind="attrs"
  11 + />
  12 +
  13 +
  14 +</template>
  15 +
  16 +<script>
  17 +import JDate from '@comp/jeecg/JDate'
  18 +import JSelectBizComponent from './JSelectBizComponent'
  19 +
  20 +export default {
  21 + name: 'JSelectMultiCanUseContainer',
  22 + components: {JDate, JSelectBizComponent},
  23 + props: {
  24 + value: null, // any type
  25 + queryConfig: {
  26 + type: Array,
  27 + default: () => []
  28 + },
  29 + },
  30 + data() {
  31 + return {
  32 + url: {list: '/config/container/getCanUseListContainer'},
  33 + columns: [
  34 + {title: '容器编码', align: 'center', width: '25%', dataIndex: 'code'},
  35 + {title: '库位编码', align: 'center', width: '25%', dataIndex: 'locationCode'},
  36 + {title: '容器类型', align: 'center', width: '20%', dataIndex: 'containerTypeCode'},
  37 + {title: '填充状态', align: 'center', width: '20%', dataIndex: 'fillStatus'}
  38 + ],
  39 + // 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
  40 + default: {
  41 + name: "编码",
  42 + width: 1200,
  43 + displayKey: 'code',
  44 + returnKeys: ['id', 'code'],
  45 + queryParamText: '容器编码',
  46 + },
  47 + // 多条件查询配置
  48 + queryConfigDefault: [
  49 + {
  50 + key: 'locationCode',
  51 + label: '库位编码',
  52 + },
  53 + ],
  54 + }
  55 + },
  56 + computed: {
  57 + attrs() {
  58 + return Object.assign(this.default, this.$attrs, {
  59 + queryConfig: this.queryConfigDefault.concat(this.queryConfig)
  60 + })
  61 + }
  62 + }
  63 +}
  64 +</script>
  65 +
  66 +<style lang="less" scoped></style>
0 67 \ No newline at end of file
... ...
ant-design-vue-jeecg/src/views/system/inventory/InventoryHeaderList.vue
... ... @@ -64,6 +64,7 @@
64 64 <a-button type="primary" icon="import">导入</a-button>
65 65 </a-upload>
66 66 <a-button v-has="'inventoryHeader:quickShipmentInventoryHeader'" @click="quickShipment()" type="primary">快速出库</a-button>
  67 + <a-button v-has="'inventoryHeader:together'" @click="together()" type="primary">合托</a-button>
67 68 </div>
68 69  
69 70 <!-- table区域-begin -->
... ... @@ -147,6 +148,7 @@
147 148  
148 149 <inventoryHeader-modal ref="modalForm" @ok="modalFormOk"></inventoryHeader-modal>
149 150 <QuickShipmentModel ref='quickShipmentModel'></QuickShipmentModel>
  151 + <inventory-together-modal ref="inventoryTogetherModal"></inventory-together-modal>
150 152 </a-card>
151 153 </template>
152 154  
... ... @@ -160,6 +162,7 @@ import {initDictOptions, filterMultiDictText} from &#39;@/components/dict/JDictSelec
160 162 import '@/assets/less/TableExpand.less'
161 163 import { getZoneList } from '@api/api'
162 164 import QuickShipmentModel from "@views/system/shipment/modules/QuickShipmentModal";
  165 +import InventoryTogetherModal from "@views/system/inventory/modules/InventoryTogetherModal";
163 166  
164 167 export default {
165 168 name: "InventoryHeaderList",
... ... @@ -167,7 +170,8 @@ export default {
167 170 components: {
168 171 QuickShipmentModel,
169 172 InventoryDetailList,
170   - InventoryHeaderModal
  173 + InventoryHeaderModal,
  174 + InventoryTogetherModal,
171 175 },
172 176 data() {
173 177 return {
... ... @@ -378,6 +382,19 @@ export default {
378 382 this.$refs.quickShipmentModel.title = '选择出库口';
379 383 }
380 384 },
  385 + together() {
  386 + if (this.selectedRowKeys.length <= 0) {
  387 + this.$message.warning('请选择两条以上记录!');
  388 + } else {
  389 + let zoneCodes = this.selectRecord.map(row => row.zoneCode);
  390 + if (new Set(zoneCodes).size !== 1) {
  391 + this.$message.warning('所选数据非同库区');
  392 + return;
  393 + }
  394 + this.$refs.inventoryTogetherModal.edit(this.selectRecord);
  395 + this.$refs.inventoryTogetherModal.title = '选择分拣口';
  396 + }
  397 + },
381 398 getSuperFieldList() {
382 399 let fieldList = [];
383 400 fieldList.push({type: 'string', value: 'companyCode', text: '货主', dictCode: ''})
... ...
ant-design-vue-jeecg/src/views/system/inventory/modules/InventoryTogetherModal.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, selectPickPort, batchCallReceiptBox} from '@/api/api'
  32 +
  33 +export default {
  34 + name: 'InventoryTogetherModal',
  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 + selectPickPort(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["port"]=this.model.outPortCode;
  95 + })
  96 + batchCallReceiptBox(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
... ...
ant-design-vue-jeecg/src/views/system/task/modules/MaterialTaskModal.vue
... ... @@ -13,17 +13,9 @@
13 13 <!-- 主表单区域 -->
14 14 <a-row class="form-row" :gutter="0">
15 15 <a-col :lg="10">
16   -<!-- <a-form-model-item label="托盘号" :rules="[{ required: true, message: '请输入托盘号!' }]"> -->
17   -<!-- <j-search-select-tag-->
18   -<!-- placeholder="请输入托盘号"-->
19   -<!-- v-model="quickMainModel.containerCode"-->
20   -<!-- dict="container,code,code,status='empty'"-->
21   -<!-- :pageSize="10"-->
22   -<!-- :async="true">-->
23   -<!-- </j-search-select-tag>-->
24   -<!-- </a-form-model-item>-->
  16 +
25 17 <a-form-model-item label="容器编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="containerCode">
26   - <j-select-multi-all-empty-container v-model="quickMainModel.containerCode"></j-select-multi-all-empty-container>
  18 + <j-select-multi-can-use-container v-model="quickMainModel.containerCode"></j-select-multi-can-use-container>
27 19 </a-form-model-item>
28 20 </a-col>
29 21  
... ... @@ -100,12 +92,12 @@
100 92 import JEditableTable from '@/components/jeecg/JEditableTable'
101 93 import {execute, quickReceipt} from '@/api/api'
102 94 import JDate from '@/components/jeecg/JDate'
103   -import JSelectMultiAllEmptyContainer from "../../../../components/jeecgbiz/JSelectMultiAllEmptyContainer";
  95 +import JSelectMultiCanUseContainer from "../../../../components/jeecgbiz/JSelectMultiCanUseContainer";
104 96  
105 97 export default {
106 98 name: 'MaterialTaskModal',
107 99 components: {
108   - JDate, JEditableTable,JSelectMultiAllEmptyContainer
  100 + JDate, JEditableTable,JSelectMultiCanUseContainer
109 101 },
110 102 data() {
111 103 return {
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/container/controller/ContainerController.java
1 1 package org.jeecg.modules.wms.config.container.controller;
2 2  
3   -import java.lang.ref.WeakReference;
4 3 import java.util.Arrays;
5 4 import java.util.List;
6   -import java.util.Map;
7   -import java.util.stream.Collectors;
8   -import java.io.IOException;
9   -import java.io.UnsupportedEncodingException;
10   -import java.net.URLDecoder;
  5 +
11 6 import javax.annotation.Resource;
12 7 import javax.servlet.http.HttpServletRequest;
13 8 import javax.servlet.http.HttpServletResponse;
14 9  
15   -import org.jeecg.common.exception.JeecgBootException;
16   -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
17   -import com.baomidou.mybatisplus.core.toolkit.Wrappers;
18 10 import org.apache.shiro.authz.annotation.RequiresPermissions;
19 11 import org.jeecg.common.api.vo.Result;
  12 +import org.jeecg.common.aspect.annotation.AutoLog;
  13 +import org.jeecg.common.exception.JeecgBootException;
  14 +import org.jeecg.common.system.base.controller.JeecgController;
20 15 import org.jeecg.common.system.query.QueryGenerator;
21   -import org.jeecg.utils.HuahengJwtUtil;
22   -import org.jeecg.common.util.oConvertUtils;
23   -
24   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
25   -import com.baomidou.mybatisplus.core.metadata.IPage;
26   -import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
27   -import lombok.extern.slf4j.Slf4j;
28   -
29 16 import org.jeecg.modules.wms.config.container.entity.Container;
30 17 import org.jeecg.modules.wms.config.container.service.IContainerService;
31 18 import org.jeecg.modules.wms.config.location.entity.Location;
32 19 import org.jeecg.modules.wms.config.location.service.ILocationService;
  20 +import org.jeecg.utils.HuahengJwtUtil;
33 21 import org.jeecg.utils.StringUtils;
34   -import org.jeecg.utils.constant.QuantityConstant;
35   -import org.jeecgframework.poi.excel.ExcelImportUtil;
36   -import org.jeecgframework.poi.excel.def.NormalExcelConstants;
37   -import org.jeecgframework.poi.excel.entity.ExportParams;
38   -import org.jeecgframework.poi.excel.entity.ImportParams;
39   -import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
40   -import org.jeecg.common.system.base.controller.JeecgController;
41 22 import org.springframework.beans.factory.annotation.Autowired;
42 23 import org.springframework.web.bind.annotation.*;
43   -import org.springframework.web.multipart.MultipartFile;
44   -import org.springframework.web.multipart.MultipartHttpServletRequest;
45 24 import org.springframework.web.servlet.ModelAndView;
46   -import com.alibaba.fastjson.JSON;
  25 +
  26 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  27 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  28 +import com.baomidou.mybatisplus.core.metadata.IPage;
  29 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  30 +
47 31 import io.swagger.annotations.Api;
48 32 import io.swagger.annotations.ApiOperation;
49   -import org.jeecg.common.aspect.annotation.AutoLog;
  33 +import lombok.extern.slf4j.Slf4j;
50 34  
51 35 /**
52 36 * @Description: 容器管理
... ... @@ -217,7 +201,21 @@ public class ContainerController extends JeecgController&lt;Container, IContainerSe
217 201 @GetMapping(value = "/getEmptyAllContainer")
218 202 public Result getEmptyAllContainer(Container container, HttpServletRequest req) {
219 203 String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
220   - List<Container>containerList=containerService.getEmptyAllContainer(container,warehouseCode);
  204 + List<Container> containerList = containerService.getAllEmptyStatusContainer(container, warehouseCode);
  205 + return Result.OK(containerList);
  206 + }
  207 +
  208 + /**
  209 + * 选取空闲的托盘
  210 + * @param container
  211 + * @return
  212 + */
  213 + @AutoLog(value = "选取空闲的托盘")
  214 + @ApiOperation(value = "库位管理-选取空闲的托盘", notes = "库位管理-选取空闲的托盘")
  215 + @GetMapping(value = "/getCanUseListContainer")
  216 + public Result getCanUseListContainer(Container container, HttpServletRequest req) {
  217 + String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
  218 + List<Container> containerList = containerService.getCanUseListContainer(container, warehouseCode);
221 219 return Result.OK(containerList);
222 220 }
223 221  
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/container/service/IContainerService.java
... ... @@ -34,7 +34,9 @@ public interface IContainerService extends IService&lt;Container&gt; {
34 34  
35 35 List<Container> getContainerListByStatus(String status, String warehouseCode);
36 36  
37   - List<Container> getEmptyAllContainer(Container container, String warehouseCode);
  37 + List<Container> getAllEmptyStatusContainer(Container container, String warehouseCode);
38 38  
39 39 List<Container> getContainerListByCodeList(List<String> containerCodeList, String warehouseCode);
  40 +
  41 + List<Container> getCanUseListContainer(Container container, String warehouseCode);
40 42 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java
... ... @@ -4,6 +4,7 @@ import java.text.MessageFormat;
4 4 import java.util.ArrayList;
5 5 import java.util.Calendar;
6 6 import java.util.List;
  7 +import java.util.stream.Collectors;
7 8  
8 9 import javax.annotation.Resource;
9 10 import javax.transaction.Transactional;
... ... @@ -14,6 +15,8 @@ import org.jeecg.modules.wms.config.container.entity.Container;
14 15 import org.jeecg.modules.wms.config.container.mapper.ContainerMapper;
15 16 import org.jeecg.modules.wms.config.container.service.IContainerService;
16 17 import org.jeecg.modules.wms.config.containerType.service.IContainerTypeService;
  18 +import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
  19 +import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
17 20 import org.jeecg.utils.StringUtils;
18 21 import org.jeecg.utils.constant.QuantityConstant;
19 22 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -21,6 +24,7 @@ import org.springframework.stereotype.Service;
21 24  
22 25 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
23 26 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  27 +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
24 28 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
25 29 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
26 30  
... ... @@ -41,6 +45,8 @@ public class ContainerServiceImpl extends ServiceImpl&lt;ContainerMapper, Container
41 45  
42 46 @Autowired
43 47 IContainerService containerService;
  48 + @Resource
  49 + private ITaskHeaderService taskHeaderService;
44 50  
45 51 @Override
46 52 @Transactional
... ... @@ -166,6 +172,34 @@ public class ContainerServiceImpl extends ServiceImpl&lt;ContainerMapper, Container
166 172 return list(containerLambdaQueryWrapper);
167 173 }
168 174  
  175 + @Override
  176 + public List<Container> getCanUseListContainer(Container container, String warehouseCode) {
  177 + List<TaskHeader> taskHeaderList = taskHeaderService.getUnCompleteListTask(warehouseCode);
  178 + List<TaskHeader> removeTaskHeaderList = new ArrayList<>();
  179 + List<Container> containerList = new ArrayList<>();
  180 + if (CollectionUtils.isNotEmpty(taskHeaderList)) {
  181 + for (TaskHeader taskHeader : taskHeaderList) {
  182 + if (taskHeader.getCallBox() == QuantityConstant.NOT_CALL_BOX) {
  183 + removeTaskHeaderList.add(taskHeader);
  184 + }
  185 + }
  186 + taskHeaderList.removeAll(removeTaskHeaderList);
  187 + if (CollectionUtils.isNotEmpty(taskHeaderList)) {
  188 + List<String> containerCodeList = taskHeaderList.stream().map(TaskHeader::getContainerCode).collect(Collectors.toList());
  189 + if (CollectionUtils.isNotEmpty(containerCodeList)) {
  190 + containerList = containerService.getContainerListByCodeList(containerCodeList, warehouseCode);
  191 + }
  192 + }
  193 + }
  194 + LambdaQueryWrapper<Container> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  195 + lambdaQueryWrapper.eq(Container::getStatus, QuantityConstant.STATUS_CONTAINER_EMPTY).eq(Container::getWarehouseCode, warehouseCode)
  196 + .eq(StringUtils.isNotEmpty(container.getCode()), Container::getCode, container.getCode())
  197 + .eq(StringUtils.isNotEmpty(container.getLocationCode()), Container::getLocationCode, container.getLocationCode());
  198 + List<Container> list = this.list(lambdaQueryWrapper);
  199 + list.addAll(containerList);
  200 + return list;
  201 + }
  202 +
169 203 private int getStartNumber(String containerTypeCode, String warehouseCode) {
170 204 LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery();
171 205 containerLambdaQueryWrapper.eq(Container::getContainerTypeCode, containerTypeCode).eq(Container::getWarehouseCode, warehouseCode)
... ... @@ -179,13 +213,13 @@ public class ContainerServiceImpl extends ServiceImpl&lt;ContainerMapper, Container
179 213 }
180 214  
181 215 @Override
182   - public List<Container> getEmptyAllContainer(Container container, String warehouseCode) {
183   - LambdaQueryWrapper<Container>lambdaQueryWrapper=new LambdaQueryWrapper<>();
184   - lambdaQueryWrapper.eq(Container::getStatus,QuantityConstant.STATUS_CONTAINER_FILL_EMPTY)
185   - .eq(Container::getWarehouseCode,warehouseCode)
186   - .eq(StringUtils.isNotEmpty(container.getCode()),Container::getCode,container.getCode())
187   - .eq(StringUtils.isNotEmpty(container.getLocationCode()),Container::getLocationCode,container.getLocationCode());
188   - List<Container>list=this.list(lambdaQueryWrapper);
  216 + public List<Container> getAllEmptyStatusContainer(Container container, String warehouseCode) {
  217 + LambdaQueryWrapper<Container> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  218 + lambdaQueryWrapper.eq(Container::getStatus, QuantityConstant.STATUS_CONTAINER_EMPTY).eq(Container::getWarehouseCode, warehouseCode)
  219 + .eq(StringUtils.isNotEmpty(container.getCode()), Container::getCode, container.getCode())
  220 + .eq(StringUtils.isNotEmpty(container.getLocationCode()), Container::getLocationCode, container.getLocationCode());
  221 + List<Container> list = this.list(lambdaQueryWrapper);
189 222 return list;
190 223 }
  224 +
191 225 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/controller/InventoryHeaderController.java
... ... @@ -392,4 +392,17 @@ public class InventoryHeaderController extends JeecgController&lt;InventoryHeader,
392 392 String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
393 393 return inventoryHeaderService.shipmentInventoryDetail(inventoryDetailList, warehouseCode);
394 394 }
  395 +
  396 + @AutoLog("批量出库存详情")
  397 + @ApiOperation(value = "批量出库存详情", notes = "批量出库存详情")
  398 + @ApiLogger(apiName = "批量出库存详情")
  399 + @PostMapping("/decuceInventoryDetail")
  400 + @ResponseBody
  401 + public Result decuceInventoryDetail(@RequestBody List<InventoryDetail> inventoryDetailList, HttpServletRequest req) {
  402 + if (StringUtils.isEmpty(inventoryDetailList)) {
  403 + return Result.error("库存明细为空");
  404 + }
  405 + String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
  406 + return inventoryHeaderService.decuceInventoryDetail(inventoryDetailList, warehouseCode);
  407 + }
395 408 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryDetailService.java
... ... @@ -54,6 +54,14 @@ public interface IInventoryDetailService extends IService&lt;InventoryDetail&gt; {
54 54 */
55 55 boolean updateTaskQtyById(BigDecimal taskQty, int id);
56 56  
  57 + /**
  58 + * 更新库存详情的数量
  59 + * @param qty
  60 + * @param id
  61 + * @return
  62 + */
  63 + boolean updateQtyById(BigDecimal qty, int id);
  64 +
57 65 boolean updateQtyAndTaskQtyAndLocationCode(BigDecimal qty, BigDecimal taskQty, String locationCode, int id);
58 66  
59 67 boolean updateBatchLocationCodeById(List<InventoryDetail> inventoryDetailList);
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryHeaderService.java
... ... @@ -46,5 +46,7 @@ public interface IInventoryHeaderService extends IService&lt;InventoryHeader&gt; {
46 46  
47 47 Result shipmentInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode);
48 48  
  49 + Result decuceInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode);
  50 +
49 51 boolean updateInventory(String containerCode, String locationCode, String warehouseCode);
50 52 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
... ... @@ -164,6 +164,15 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
164 164 }
165 165  
166 166 @Override
  167 + public boolean updateQtyById(BigDecimal qty, int id) {
  168 + InventoryDetail inventoryDetail = new InventoryDetail();
  169 + inventoryDetail.setQty(qty);
  170 + inventoryDetail.setId(id);
  171 + boolean success = this.updateById(inventoryDetail);
  172 + return success;
  173 + }
  174 +
  175 + @Override
167 176 public boolean updateQtyAndTaskQtyAndLocationCode(BigDecimal qty, BigDecimal taskQty, String locationCode, int id) {
168 177 InventoryDetail inventoryDetail = new InventoryDetail();
169 178 inventoryDetail.setQty(qty);
... ... @@ -272,28 +281,26 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
272 281 }
273 282  
274 283 @Override
275   - public List<String> containerCodeList(String warehouseCode,String materiacode) {
276   - //查询有该物料的托盘
277   - List<String> codes =new ArrayList<>();
278   - LambdaQueryWrapper<InventoryDetail>lambdaQueryWrapper=new LambdaQueryWrapper<>();
279   - lambdaQueryWrapper.eq(InventoryDetail::getMaterialCode,materiacode)
280   - .eq(InventoryDetail::getWarehouseCode,warehouseCode);
281   - List<InventoryDetail>list=this.list(lambdaQueryWrapper);
  284 + public List<String> containerCodeList(String warehouseCode, String materiacode) {
  285 + // 查询有该物料的托盘
  286 + List<String> codes = new ArrayList<>();
  287 + LambdaQueryWrapper<InventoryDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  288 + lambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, materiacode).eq(InventoryDetail::getWarehouseCode, warehouseCode);
  289 + List<InventoryDetail> list = this.list(lambdaQueryWrapper);
282 290 codes = list.stream().map(InventoryDetail::getContainerCode).collect(Collectors.toList());
283   - //托盘填充状态
284   - List<String>fillStatus=new ArrayList<>();
  291 + // 托盘填充状态
  292 + List<String> fillStatus = new ArrayList<>();
285 293 fillStatus.add(QuantityConstant.STATUS_CONTAINER_FILL_EMPTY);
286 294 fillStatus.add(QuantityConstant.STATUS_CONTAINER_FILL_SOME);
287   - //根据有库存的托盘,筛查出符合状态的托盘
288   - List<Container>containerList=new ArrayList<>();
289   - List<String>containerCodeList=new ArrayList<>();
290   - if(codes.size()>0){
291   - LambdaQueryWrapper<Container>containerWrapper=new LambdaQueryWrapper<>();
292   - containerWrapper.in(Container::getCode,codes)
293   - .eq(Container::getStatus,QuantityConstant.STATUS_CONTAINER_EMPTY)
294   - .in(Container::getFillStatus,fillStatus);
295   - containerList=containerService.list(containerWrapper);
296   - containerCodeList=containerList.stream().map(Container::getCode).collect(Collectors.toList());
  295 + // 根据有库存的托盘,筛查出符合状态的托盘
  296 + List<Container> containerList = new ArrayList<>();
  297 + List<String> containerCodeList = new ArrayList<>();
  298 + if (codes.size() > 0) {
  299 + LambdaQueryWrapper<Container> containerWrapper = new LambdaQueryWrapper<>();
  300 + containerWrapper.in(Container::getCode, codes).eq(Container::getStatus, QuantityConstant.STATUS_CONTAINER_EMPTY).in(Container::getFillStatus,
  301 + fillStatus);
  302 + containerList = containerService.list(containerWrapper);
  303 + containerCodeList = containerList.stream().map(Container::getCode).collect(Collectors.toList());
297 304 }
298 305 return containerCodeList;
299 306 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java
1 1 package org.jeecg.modules.wms.inventory.inventoryHeader.service.impl;
2 2  
3 3 import java.io.Serializable;
  4 +import java.math.BigDecimal;
4 5 import java.util.ArrayList;
5 6 import java.util.Collection;
6 7 import java.util.List;
... ... @@ -21,6 +22,8 @@ import org.jeecg.modules.wms.inventory.inventoryHeader.mapper.InventoryDetailMap
21 22 import org.jeecg.modules.wms.inventory.inventoryHeader.mapper.InventoryHeaderMapper;
22 23 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
23 24 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
  25 +import org.jeecg.modules.wms.inventory.inventoryTransaction.entity.InventoryTransaction;
  26 +import org.jeecg.modules.wms.inventory.inventoryTransaction.service.IInventoryTransactionService;
24 27 import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
25 28 import org.jeecg.modules.wms.shipment.shipmentCombination.service.IShipmentCombinationService;
26 29 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
... ... @@ -31,11 +34,14 @@ import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
31 34 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
32 35 import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
33 36 import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
  37 +import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
  38 +import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
34 39 import org.jeecg.utils.StringUtils;
35 40 import org.jeecg.utils.constant.QuantityConstant;
36 41 import org.springframework.beans.factory.annotation.Autowired;
37 42 import org.springframework.stereotype.Service;
38 43 import org.springframework.transaction.annotation.Transactional;
  44 +import org.springframework.util.CollectionUtils;
39 45  
40 46 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
41 47 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
... ... @@ -74,6 +80,10 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
74 80 private IHuahengMultiHandlerService huahengMultiHandlerService;
75 81 @Resource
76 82 private ILocationService locationService;
  83 + @Resource
  84 + private ITaskHeaderService taskHeaderService;
  85 + @Resource
  86 + private IInventoryTransactionService inventoryTransactionService;
77 87  
78 88 @Override
79 89 @Transactional
... ... @@ -351,6 +361,75 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
351 361 }
352 362  
353 363 @Override
  364 + @Transactional(rollbackFor = JeecgBootException.class)
  365 + public Result decuceInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode) {
  366 + if (CollectionUtils.isEmpty(inventoryDetailList)) {
  367 + return Result.error("扣减库存失败,参数为空");
  368 + }
  369 + List<String> containerCodeList = inventoryDetailList.stream().map(InventoryDetail::getContainerCode).distinct().collect(Collectors.toList());
  370 + if (CollectionUtils.isEmpty(containerCodeList) || containerCodeList.size() != 1) {
  371 + return Result.error("扣减库存失败,不能同时操作多个托盘的库存");
  372 + }
  373 + String containerCode = containerCodeList.get(0);
  374 + TaskHeader taskHeader = taskHeaderService.getUnCompleteTaskByContainerCode(containerCode, warehouseCode);
  375 + if (taskHeader == null) {
  376 + return Result.error("扣减库存失败,任务为空");
  377 + }
  378 + if (taskHeader.getStatus() != QuantityConstant.TASK_STATUS_ARRIVED_STATION) {
  379 + return Result.error("扣减库存失败,任务必须到达分拣站台才能扣减库存");
  380 + }
  381 + List<InventoryTransaction> inventoryTransactionList = new ArrayList<>();
  382 + for (InventoryDetail inventoryDetail1 : inventoryDetailList) {
  383 + BigDecimal taskQty = inventoryDetail1.getTaskQty();
  384 + if (taskQty.compareTo(BigDecimal.ZERO) < 0) {
  385 + return Result.error("扣减库存失败,扣减数量必须是大于0");
  386 + }
  387 + int detail1Id = inventoryDetail1.getId();
  388 + InventoryDetail inventoryDetail = inventoryDetailService.getById(detail1Id);
  389 + BigDecimal qty = inventoryDetail.getQty();
  390 + BigDecimal inventoryQty = qty.subtract(taskQty);
  391 + if (inventoryQty.compareTo(BigDecimal.ZERO) == 0) {
  392 + if (!inventoryDetailService.removeById(detail1Id)) {
  393 + throw new JeecgBootException("扣减库存失败,删除库存失败" + detail1Id);
  394 + }
  395 + } else if (inventoryQty.compareTo(BigDecimal.ZERO) < 0) {
  396 + throw new JeecgBootException("扣减库存失败,库存数量不能小于0");
  397 + } else {
  398 + if (!inventoryDetailService.updateQtyById(inventoryQty, detail1Id)) {
  399 + throw new JeecgBootException("扣减库存失败, 更新库存失败");
  400 + }
  401 + }
  402 + InventoryTransaction inventoryTransaction = new InventoryTransaction();
  403 + inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_SHIPMENT);
  404 + inventoryTransaction.setWarehouseCode(warehouseCode);
  405 + inventoryTransaction.setCompanyCode(inventoryDetail.getCompanyCode());
  406 + inventoryTransaction.setContainerCode(inventoryDetail.getContainerCode());
  407 + inventoryTransaction.setZoneCode(inventoryDetail.getZoneCode());
  408 + inventoryTransaction.setFromLocationCode(inventoryDetail.getLocationCode());
  409 + inventoryTransaction.setMaterialCode(inventoryDetail.getMaterialCode());
  410 + inventoryTransaction.setMaterialName(inventoryDetail.getMaterialName());
  411 + inventoryTransaction.setMaterialSpec(inventoryDetail.getMaterialSpec());
  412 + inventoryTransaction.setMaterialUnit(inventoryDetail.getMaterialUnit());
  413 + inventoryTransaction.setInventoryStatus(inventoryDetail.getInventoryStatus());
  414 + inventoryTransaction.setBatch(inventoryDetail.getBatch());
  415 + inventoryTransaction.setLot(inventoryDetail.getLot());
  416 + inventoryTransaction.setProject(inventoryDetail.getProject());
  417 + inventoryTransaction.setQty(taskQty);
  418 + inventoryTransaction.setShipmentQty(taskQty);
  419 + BigDecimal inventorySumQty = inventoryDetailService.getInventorySumQty(inventoryDetail);
  420 + inventoryTransaction.setInventoryQty(inventorySumQty);
  421 + inventoryTransactionList.add(inventoryTransaction);
  422 + }
  423 + if (!inventoryTransactionService.saveBatch(inventoryTransactionList)) {
  424 + throw new JeecgBootException("扣减库存失败,保存库存交易失败");
  425 + }
  426 + if (!taskHeaderService.combineInventoryDetail(containerCode, warehouseCode)) {
  427 + throw new JeecgBootException("扣减库存失败,合并库存失败");
  428 + }
  429 + return Result.ok("扣减库存成功");
  430 + }
  431 +
  432 + @Override
354 433 public boolean updateInventory(String containerCode, String locationCode, String warehouseCode) {
355 434 InventoryHeader inventoryHeader = inventoryHeaderService.getInventoryHeaderByContainerCode(containerCode, warehouseCode);
356 435 if (inventoryHeader == null) {
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/controller/ReceiptHeaderController.java
... ... @@ -387,4 +387,20 @@ public class ReceiptHeaderController extends JeecgController&lt;ReceiptHeader, IRec
387 387 Result result = huahengMultiHandlerService.callBox(bean, warehouseCode);
388 388 return result;
389 389 }
  390 +
  391 + @AutoLog(value = "PDA入库-批量呼叫料盒")
  392 + @ApiOperation(value = "PDA入库-批量呼叫料盒", notes = "创建空的补充入库任务,并返回任务id")
  393 + @PostMapping("/batchCallBox")
  394 + @ResponseBody
  395 + @ApiLogger(apiName = "PDA入库-批量呼叫料盒", from = "PDA")
  396 + public Result<?> batchCallBox(@RequestBody List<CallBoxBean> callBoxBeanList, HttpServletRequest req) {
  397 + String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
  398 + Result result = null;
  399 + // 补充入库类型
  400 + for (CallBoxBean callBoxBean : callBoxBeanList) {
  401 + callBoxBean.setType(QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT);
  402 + result = huahengMultiHandlerService.callBox(callBoxBean, warehouseCode);
  403 + }
  404 + return result;
  405 + }
390 406 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
... ... @@ -2,6 +2,7 @@ package org.jeecg.modules.wms.task.taskHeader.service;
2 2  
3 3 import java.io.Serializable;
4 4 import java.util.Collection;
  5 +import java.util.List;
5 6  
6 7 import org.jeecg.common.api.vo.Result;
7 8 import org.jeecg.modules.wms.config.location.entity.Location;
... ... @@ -82,6 +83,8 @@ public interface ITaskHeaderService extends IService&lt;TaskHeader&gt; {
82 83 */
83 84 TaskHeader getUnCompleteTaskByPreTaskNo(int preTaskNo, String warehouseCode);
84 85  
  86 + List<TaskHeader> getUnCompleteListTask(String warehouseCode);
  87 +
85 88 /**
86 89 * 完成WMS任务
87 90 * @param taskId
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
... ... @@ -771,6 +771,14 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
771 771 return taskHeader;
772 772 }
773 773  
  774 + @Override
  775 + public List<TaskHeader> getUnCompleteListTask(String warehouseCode) {
  776 + LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  777 + taskHeaderLambdaQueryWrapper.eq(TaskHeader::getWarehouseCode, warehouseCode).lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
  778 + List<TaskHeader> taskHeaderList = taskHeaderService.list(taskHeaderLambdaQueryWrapper);
  779 + return taskHeaderList;
  780 + }
  781 +
774 782 /**
775 783 * WMS完成任务
776 784 */
... ... @@ -863,7 +871,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
863 871 if (preTaskHeader != null) {
864 872 return Result.error("取消任务失败,有前置任务" + preTaskHeader.getId());
865 873 }
866   - //保存历史任务表
  874 + // 保存历史任务表
867 875 taskHeaderHistoryService.saveById(taskHeader.getId());
868 876 if (!taskHeaderService.removeById(taskId)) {
869 877 throw new JeecgBootException("取消任务失败, 删除任务失败");
... ... @@ -1421,7 +1429,8 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
1421 1429 InventoryDetail inventoryDetail1 = inventoryDetailList.get(i);
1422 1430 InventoryDetail inventoryDetail2 = inventoryDetailList.get(j);
1423 1431 if (inventoryDetail1.getMaterialCode().equals(inventoryDetail2.getMaterialCode()) && inventoryDetail1.getBatch().equals(inventoryDetail2.getBatch())
1424   - && inventoryDetail1.getLot().equals(inventoryDetail2.getLot()) && inventoryDetail1.getProject().equals(inventoryDetail2.getProject())) {
  1432 + && inventoryDetail1.getLot().equals(inventoryDetail2.getLot()) && inventoryDetail1.getProject().equals(inventoryDetail2.getProject())
  1433 + && inventoryDetail1.getInventoryStatus().equals(inventoryDetail2.getInventoryStatus())) {
1425 1434 // 属性一样的库存,相加合并。
1426 1435 BigDecimal totalQty = inventoryDetail1.getQty().add(inventoryDetail2.getQty());
1427 1436 inventoryDetail1.setQty(totalQty);
... ... @@ -1874,7 +1883,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
1874 1883 }
1875 1884 TaskHeader taskHeader = (TaskHeader)result.getResult();
1876 1885 if (taskHeader.getTaskType() == QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT) {
1877   - if (port != null) {
  1886 + if (port == null) {
1878 1887 throw new JeecgBootException("快速入库, 生成补充任务时必须有入库口");
1879 1888 }
1880 1889 }
... ...