Commit 898110c0716cf2a44535e72207d7249827591467

Authored by 易文鹏
1 parent f35cdbd5

feat:重写呆滞库存功能

src/main/java/com/huaheng/pc/inventory/inventoryDetail/controller/InventoryDetailController.java
... ... @@ -141,14 +141,11 @@ public class InventoryDetailController extends BaseController {
141 141 .eq(StringUtils.isNotEmpty(inventoryDetail.getWarehouse()), InventoryDetail::getWarehouse, inventoryDetail.getWarehouse()) //原仓库编码
142 142 .eq(inventoryDetail.getSelfCreated() != null, InventoryDetail::getSelfCreated, inventoryDetail.getSelfCreated())//是否自建库
143 143 .eq(StringUtils.isNotNull(inventoryDetail.getIsFlatWarehouse()), InventoryDetail::getIsFlatWarehouse, inventoryDetail.getIsFlatWarehouse())//仓库类型
  144 + .ne(StringUtils.isNotEmpty(inventoryDetail.getDeadTime()), InventoryDetail::getDeadTime, "")
144 145 .orderByDesc(InventoryDetail::getId);
145   - if (StringUtils.isNotEmpty(inventoryDetail.getDeadTime()) && !inventoryDetail.getDeadTime().equals("-1")) {
146   - List<InventoryDetail> list = inventoryDetailService.list(lambdaQueryWrapper);
147   - //处理呆滞库存
148   - list = inventoryDetailService.expiringInventoryHandle(list, inventoryDetail.getDeadTime());
149   - return getDataTable(list);
150   - } else if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
151   - //分页查询
  146 +
  147 +
  148 + if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
152 149 Page<InventoryDetail> page = new Page<>(pageNum, pageSize);
153 150 IPage<InventoryDetail> iPage = inventoryDetailService.page(page, lambdaQueryWrapper);
154 151 return getMpDataTable(iPage.getRecords(), iPage.getTotal());
... ...
src/main/java/com/huaheng/pc/inventory/inventoryDetail/domain/InventoryDetail.java
... ... @@ -316,7 +316,7 @@ public class InventoryDetail implements Serializable {
316 316 * 呆滞时长
317 317 */
318 318 @ApiModelProperty(value = "呆滞时长")
319   - @TableField(exist = false)
  319 + @TableField(value = "deadTime")
320 320 private String deadTime;
321 321  
322 322 /**
... ... @@ -389,6 +389,12 @@ public class InventoryDetail implements Serializable {
389 389 @TableField(exist = false)
390 390 private String materialVolumePercentage;
391 391  
  392 + /**
  393 + * 真实更新时间
  394 + */
  395 + @TableField(value = "realUpdated")
  396 + private Date realUpdated;
  397 +
392 398 public void setQty(BigDecimal qty) {
393 399 if (qty.compareTo(BigDecimal.ZERO) < 0) {
394 400 throw new ServiceException(containerCode + ",库存数量不能为负数");
... ...
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java
... ... @@ -42,13 +42,6 @@ public interface InventoryDetailService extends IService&lt;InventoryDetail&gt; {
42 42 List<LinkedHashMap<String, Object>> getCompanyInventoryProp(String companyCode);
43 43  
44 44 /**
45   - * @param inventoryDetails
46   - * @param expiring true 呆滞库存 false 未呆滞库存
47   - * @return
48   - */
49   - List<InventoryDetail> expiringInventoryHandle(List<InventoryDetail> inventoryDetails, String expiring);
50   -
51   - /**
52 45 * 通过id获取当前库位所存储的物料编码集合
53 46 *
54 47 * @param inventoryHeaderId
... ...
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java
... ... @@ -279,72 +279,6 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
279 279 }
280 280  
281 281 @Override
282   - public List<InventoryDetail> expiringInventoryHandle(List<InventoryDetail> inventoryDetails, String expiring) {
283   - // 获取库存呆滞时间配置
284   - int days = Integer.parseInt(configService.getKey(QuantityConstant.DEAD_TIME));
285   - int daysBatch = Integer.parseInt(configService.getKey(QuantityConstant.DEAD_TIME_BATCH));
286   - int daysFlammable = Integer.parseInt(configService.getKey(QuantityConstant.DEAD_TIME_FLAMMABLE));
287   -
288   - // 如果 inventoryDetails 为空,直接返回空列表
289   - if (CollectionUtils.isEmpty(inventoryDetails)) {
290   - return Collections.emptyList();
291   - }
292   -
293   - // 获取所有物料编码
294   - Set<String> materialCodes = inventoryDetails.stream()
295   - .map(InventoryDetail::getMaterialCode)
296   - .collect(Collectors.toSet());
297   -
298   - // 批量查询物料信息
299   - List<Material> materials = getMaterialsByCodes(materialCodes);
300   -
301   - // 创建物料编码和物料对象的映射关系
302   - Map<String, Material> materialMap = new HashMap<>();
303   - for (Material material : materials) {
304   - materialMap.put(material.getCode(), material);
305   - }
306   -
307   - return inventoryDetails.stream().collect(Collectors.partitioningBy(inventoryDetail -> {
308   - // 计算库存的更新时间和当前时间之间的差距
309   - long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getLastUpdated());
310   -
311   - // 从 Map 中获取物料信息
312   - Material material = materialMap.get(inventoryDetail.getMaterialCode());
313   - if (material == null) {
314   - return false;
315   - }
316   -
317   - int materialDays = days;
318   - if (Objects.equals(material.getIsFlammable(), "是")) {
319   - materialDays = Math.min(materialDays, daysFlammable);
320   - } else if (Objects.equals(material.getIsBatch(), "是")) {
321   - materialDays = Math.min(materialDays, daysBatch);
322   - }
323   -
324   - // 计算呆滞时长
325   - int differenceDay = DateUtils.secondToDays(difference);
326   - int num = differenceDay - materialDays;
327   -
328   - // 判断是否为呆滞库存
329   - if (num > 0) {
330   - inventoryDetail.setDeadTime(num + "天");
331   - return true;
332   - }
333   - return false;
334   - })).getOrDefault(expiring.equals("1"), Collections.emptyList());
335   - }
336   -
337   - public List<Material> getMaterialsByCodes(Set<String> materialCodes) {
338   - if (CollectionUtils.isEmpty(materialCodes)) {
339   - return Collections.emptyList();
340   - }
341   - //in 方法进行批量查询
342   - LambdaQueryWrapper<Material> queryWrapper = new LambdaQueryWrapper<>();
343   - queryWrapper.in(Material::getCode, materialCodes);
344   - return materialService.list(queryWrapper);
345   - }
346   -
347   - @Override
348 282 public List<InventoryDetail> queryReceiptDetailById(Integer inventoryHeaderId) {
349 283 LambdaQueryWrapper<InventoryDetail> lam = Wrappers.lambdaQuery();
350 284 lam.eq(InventoryDetail::getInventoryHeaderId, inventoryHeaderId)
... ...
src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java
... ... @@ -15,6 +15,7 @@ import com.huaheng.common.utils.DateUtils;
15 15 import com.huaheng.common.utils.StringUtils;
16 16 import com.huaheng.framework.web.controller.BaseController;
17 17 import com.huaheng.framework.web.domain.AjaxResult;
  18 +import com.huaheng.framework.web.service.ConfigService;
18 19 import com.huaheng.pc.config.company.service.CompanyService;
19 20 import com.huaheng.pc.config.container.domain.Container;
20 21 import com.huaheng.pc.config.container.service.ContainerService;
... ... @@ -28,6 +29,8 @@ import com.huaheng.pc.config.station.service.StationService;
28 29 import com.huaheng.pc.config.wcsscanbarcode.service.WcsscanbarcodeService;
29 30 import com.huaheng.pc.config.zone.domain.Zone;
30 31 import com.huaheng.pc.config.zone.service.ZoneService;
  32 +import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
  33 +import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
31 34 import com.huaheng.pc.inventory.inventoryHeader.domain.InventoryHeader;
32 35 import com.huaheng.pc.inventory.inventoryHeader.service.InventoryHeaderService;
33 36 import com.huaheng.pc.monitor.apilog.domain.ApiLog;
... ... @@ -74,6 +77,7 @@ import org.apache.commons.collections.MapUtils;
74 77 import org.springframework.stereotype.Component;
75 78 import org.springframework.transaction.annotation.Transactional;
76 79 import org.springframework.ui.ModelMap;
  80 +import org.springframework.util.CollectionUtils;
77 81  
78 82 import javax.annotation.Resource;
79 83 import java.math.BigDecimal;
... ... @@ -87,7 +91,8 @@ import java.util.stream.Collectors;
87 91 */
88 92 @Component("RyTask")
89 93 public class RyTask extends BaseController {
90   -
  94 + @Resource
  95 + private ConfigService configService;
91 96 @Resource
92 97 private MaterialMapper materialMapper;
93 98 @Resource
... ... @@ -154,6 +159,8 @@ public class RyTask extends BaseController {
154 159 private TaskNumMapper taskNumMapper;
155 160 @Resource
156 161 private SrmStatusTimeMapper srmStatusTimeMapper;
  162 + @Resource
  163 + private InventoryDetailService inventoryDetailService;
157 164  
158 165 //并发控制
159 166 Map<String, Boolean> runningTaskMap = new HashMap<>();
... ... @@ -806,4 +813,64 @@ public class RyTask extends BaseController {
806 813 }
807 814  
808 815  
  816 + //每天计算呆滞库存
  817 + public void expiringInventoryHandle() {
  818 + List<InventoryDetail> inventoryDetails = inventoryDetailService.list();
  819 + if (CollectionUtils.isEmpty(inventoryDetails)) {
  820 + return;
  821 + }
  822 +
  823 + // 获取库存呆滞时间配置
  824 + int days = Integer.parseInt(configService.getKey(QuantityConstant.DEAD_TIME));
  825 + int daysBatch = Integer.parseInt(configService.getKey(QuantityConstant.DEAD_TIME_BATCH));
  826 + int daysFlammable = Integer.parseInt(configService.getKey(QuantityConstant.DEAD_TIME_FLAMMABLE));
  827 +
  828 + // 获取所有物料编码
  829 + Set<String> materialCodes = inventoryDetails.stream()
  830 + .map(InventoryDetail::getMaterialCode).collect(Collectors.toSet());
  831 +
  832 + List<Material> materials = materialService.list(new LambdaQueryWrapper<Material>().in(Material::getCode, materialCodes));
  833 +
  834 + // 创建物料编码和物料对象的映射关系
  835 + Map<String, Material> materialMap = new HashMap<>();
  836 + for (Material material : materials) {
  837 + materialMap.put(material.getCode(), material);
  838 + }
  839 +
  840 + List<InventoryDetail> updatedInventoryDetails = inventoryDetails.stream()
  841 + .map(inventoryDetail -> {
  842 + // 计算库存的更新时间和当前时间之间的差距
  843 + long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getRealUpdated());
  844 +
  845 + // 从 Map 中获取物料信息
  846 + Material material = materialMap.get(inventoryDetail.getMaterialCode());
  847 + if (material == null) {
  848 + return inventoryDetail;
  849 + }
  850 +
  851 + int materialDays = days;
  852 + if (Objects.equals(material.getIsFlammable(), "是")) {
  853 + materialDays = Math.min(materialDays, daysFlammable);
  854 + } else if (Objects.equals(material.getIsBatch(), "是")) {
  855 + materialDays = Math.min(materialDays, daysBatch);
  856 + }
  857 +
  858 + // 计算呆滞时长
  859 + int differenceDay = DateUtils.secondToDays(difference);
  860 + int deadTime = Math.max(differenceDay - materialDays, 0);
  861 + if (deadTime == 0) {
  862 + inventoryDetail.setDeadTime("");
  863 + } else {
  864 + inventoryDetail.setDeadTime(deadTime + "天");
  865 + }
  866 +
  867 + return inventoryDetail;
  868 + })
  869 + .collect(Collectors.toList());
  870 +
  871 + // 保存更新后的库存信息
  872 + inventoryDetailService.updateBatchById(updatedInventoryDetails);
  873 + }
  874 +
  875 +
809 876 }
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java
... ... @@ -338,7 +338,7 @@ public class ReceiptTaskService {
338 338 if (!locationService.update(updateLocation, locationLambdaUpdateWrapper)) {
339 339 throw new ServiceException("补充入库,更新库位失败");
340 340 }
341   -
  341 +
342 342 //解除右侧库位禁用和对应4个库位标记
343 343 Container container = containerService.getContainerByCode(task.getContainerCode());
344 344 locationService.unbanRightLocationAndUnmark(container.getContainerType(), fromLocationCode);
... ... @@ -552,6 +552,7 @@ public class ReceiptTaskService {
552 552 }
553 553 if (StringUtils.isNotNull(inventoryDetail)) {
554 554 inventoryDetail.setQty(inventoryDetail.getQty().add(taskDetail.getQty()));
  555 + inventoryDetail.setRealUpdated(new Date());
555 556 } else {
556 557 ReceiptHeader receiptHeader = receiptHeaderService.getById(receiptDetail.getReceiptId());
557 558 inventoryDetail = new InventoryDetail();
... ... @@ -568,6 +569,7 @@ public class ReceiptTaskService {
568 569 inventoryDetail.setMaterialUnit(material.getUnit());
569 570 inventoryDetail.setQty(receiptQty);
570 571 inventoryDetail.setTaskQty(new BigDecimal(0));
  572 + inventoryDetail.setRealUpdated(new Date());
571 573  
572 574 inventoryDetail.setSupplierCode(receiptDetail.getSupplierCode());
573 575 inventoryDetail.setReferCode(receiptDetail.getReferCode());
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java
... ... @@ -390,6 +390,7 @@ public class ShipmentTaskService {
390 390 //扣减库存明细
391 391 inventoryDetail.setTaskQty(inventoryDetail.getTaskQty().subtract(taskDetail.getQty()));
392 392 inventoryDetail.setQty(inventoryDetail.getQty().subtract(taskDetail.getQty()));
  393 + inventoryDetail.setRealUpdated(new Date());
393 394  
394 395 if (inventoryDetail.getQty().signum() == -1) {
395 396 throw new ServiceException("扣减库存大于wms库存");
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/TaskHeaderServiceImpl.java
... ... @@ -656,11 +656,18 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
656 656 && inventoryDetail.getMaterialColor().equals(inventoryDetail2.getMaterialColor())
657 657 && inventoryDetail.getRemarks().equals(inventoryDetail2.getRemarks())
658 658 && inventoryDetail.getPaintStatus().equals(inventoryDetail2.getPaintStatus())) {
  659 +
  660 + //如果都相同的话,合并库存,
659 661 BigDecimal totalQty = inventoryDetailList.get(i).getQty().add(inventoryDetailList.get(j).getQty());
660 662 inventoryDetailList.get(i).setQty(totalQty);
  663 + // 更新 realUpdated 字段为当前时间
  664 + inventoryDetailList.get(i).setRealUpdated(new Date());
  665 +
  666 + //计算两个对象的 qty 属性之和,赋值给外层循环的 inventoryDetail 对象
661 667 LambdaQueryWrapper<InventoryDetail> wrapper = Wrappers.lambdaQuery();
662 668 wrapper.eq(InventoryDetail::getId, inventoryDetailList.get(i).getId());
663 669 inventoryDetailService.update(inventoryDetailList.get(i), wrapper);
  670 + //删除
664 671 LambdaQueryWrapper<InventoryDetail> wrapper2 = Wrappers.lambdaQuery();
665 672 wrapper2.eq(InventoryDetail::getId, inventoryDetailList.get(j).getId());
666 673 inventoryDetailService.remove(wrapper2);
... ... @@ -964,11 +971,12 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
964 971 .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED));
965 972  
966 973 }
  974 +
967 975 @Override
968 976 public Integer getShipmentTaskBy5Road() {
969 977 //组盘表新建状态任务+任务表任务
970   - Integer tasknum=shipmentContainerHeaderService.list(new LambdaQueryWrapper<ShipmentContainerHeader>()
971   - .in(ShipmentContainerHeader::getStatus, 1,10)
  978 + Integer tasknum = shipmentContainerHeaderService.list(new LambdaQueryWrapper<ShipmentContainerHeader>()
  979 + .in(ShipmentContainerHeader::getStatus, 1, 10)
972 980 .apply("(SUBSTRING(locationCode, 1, 3) in ('K05','K06','K07','K08') )")).size();
973 981 return tasknum;
974 982 }
... ...
src/main/resources/templates/inventory/inventoryDetail/inventoryDetail.html
... ... @@ -94,11 +94,9 @@
94 94 入库明细ID:<input type="text" name="receiptDetailId"/>
95 95 </li>
96 96 <li>
97   - 是否查询呆滞库存:
  97 + 呆滞库存:
98 98 <select name="deadTime">
99   - <option value="-1">不查询</option>
100   - <option value="3">全部查询</option>
101   - <option value="2">非呆滞库存</option>
  99 + <option value="">全部查询</option>
102 100 <option value="1">呆滞库存</option>
103 101 </select>
104 102 </li>
... ... @@ -325,6 +323,10 @@
325 323 visible: true
326 324 },
327 325 {
  326 + field: 'realUpdated',
  327 + title: '真实更新时间'
  328 + },
  329 + {
328 330 field: 'qcCheck',
329 331 title: '质检',
330 332 visible: false
... ...