Commit 898110c0716cf2a44535e72207d7249827591467
1 parent
f35cdbd5
feat:重写呆滞库存功能
Showing
9 changed files
with
99 additions
and
89 deletions
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<InventoryDetail> { |
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<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<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<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 |
... | ... |