|
|
@@ -4,10 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
-import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
-import com.haha.common.dto.FloorConfig;
|
|
|
-import com.haha.common.dto.GoodsItem;
|
|
|
import com.haha.common.enums.ReplenishmentOrderStatusEnum;
|
|
|
import com.haha.common.exception.BusinessException;
|
|
|
import com.haha.entity.*;
|
|
|
@@ -49,13 +45,10 @@ public class ReplenishmentOrderServiceImpl extends ServiceImpl<ReplenishmentOrde
|
|
|
private final ReplenishmentOrderItemMapper orderItemMapper;
|
|
|
private final DeviceMapper deviceMapper;
|
|
|
private final ShopMapper shopMapper;
|
|
|
- private final LayerTemplateMapper layerTemplateMapper;
|
|
|
private final DeviceInventoryMapper deviceInventoryMapper;
|
|
|
private final ProductMapper productMapper;
|
|
|
private final ErpGoodsMapper erpGoodsMapper;
|
|
|
|
|
|
- private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
-
|
|
|
@Autowired(required = false)
|
|
|
private QdbClient qdbClient;
|
|
|
|
|
|
@@ -588,39 +581,14 @@ public class ReplenishmentOrderServiceImpl extends ServiceImpl<ReplenishmentOrde
|
|
|
.collect(Collectors.toMap(Shop::getId, Shop::getName, (a, b) -> a));
|
|
|
}
|
|
|
|
|
|
- // 批量查询层模版
|
|
|
- List<LayerTemplate> allTemplates = new java.util.ArrayList<>();
|
|
|
- for (String deviceId : deviceIds) {
|
|
|
- allTemplates.addAll(layerTemplateMapper.selectByDeviceId(deviceId));
|
|
|
- }
|
|
|
- Map<String, List<LayerTemplate>> templateMap = allTemplates.stream()
|
|
|
- .collect(Collectors.groupingBy(LayerTemplate::getDeviceId));
|
|
|
-
|
|
|
- // 批量查询当前库存
|
|
|
+ // 批量查询库存(含 standardStock 字段)
|
|
|
List<DeviceInventory> allInventories = deviceInventoryMapper.selectList(
|
|
|
new LambdaQueryWrapper<DeviceInventory>().in(DeviceInventory::getDeviceId, deviceIds));
|
|
|
- Map<String, Map<String, DeviceInventory>> inventoryMap = new HashMap<>();
|
|
|
- for (DeviceInventory inv : allInventories) {
|
|
|
- inventoryMap.computeIfAbsent(inv.getDeviceId(), k -> new HashMap<>())
|
|
|
- .put(inv.getProductCode(), inv);
|
|
|
- }
|
|
|
-
|
|
|
- // 收集所有需要查询的 productCode
|
|
|
+ Map<String, List<DeviceInventory>> inventoryByDevice = new HashMap<>();
|
|
|
Set<String> allCodes = new HashSet<>();
|
|
|
- for (String deviceId : deviceIds) {
|
|
|
- List<LayerTemplate> temps = templateMap.getOrDefault(deviceId, java.util.Collections.emptyList());
|
|
|
- for (LayerTemplate temp : temps) {
|
|
|
- for (FloorConfig floor : parseFloors(temp.getLeftFloors())) {
|
|
|
- for (GoodsItem goods : floor.getGoods()) {
|
|
|
- if (goods.getKey() != null) allCodes.add(goods.getKey());
|
|
|
- }
|
|
|
- }
|
|
|
- for (FloorConfig floor : parseFloors(temp.getRightFloors())) {
|
|
|
- for (GoodsItem goods : floor.getGoods()) {
|
|
|
- if (goods.getKey() != null) allCodes.add(goods.getKey());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ for (DeviceInventory inv : allInventories) {
|
|
|
+ inventoryByDevice.computeIfAbsent(inv.getDeviceId(), k -> new java.util.ArrayList<>()).add(inv);
|
|
|
+ if (inv.getProductCode() != null) allCodes.add(inv.getProductCode());
|
|
|
}
|
|
|
|
|
|
// 批量查询 Product(按 code)
|
|
|
@@ -631,58 +599,34 @@ public class ReplenishmentOrderServiceImpl extends ServiceImpl<ReplenishmentOrde
|
|
|
productMap = products.stream().collect(Collectors.toMap(Product::getCode, p -> p, (a, b) -> a));
|
|
|
}
|
|
|
|
|
|
- // 生成补货建议
|
|
|
+ // 生成补货建议:直接使用 DeviceInventory.standardStock
|
|
|
List<ReplenishmentSuggestionVO> result = new java.util.ArrayList<>();
|
|
|
|
|
|
for (String deviceId : deviceIds) {
|
|
|
Device device = deviceMap.get(deviceId);
|
|
|
if (device == null) continue;
|
|
|
|
|
|
- // 解析模版,按 productCode 累加标准库存
|
|
|
- Map<String, Accumulator> accumulators = new LinkedHashMap<>();
|
|
|
- List<LayerTemplate> temps = templateMap.getOrDefault(deviceId, java.util.Collections.emptyList());
|
|
|
- for (LayerTemplate temp : temps) {
|
|
|
- int floorNum = temp.getShelfNum() != null ? temp.getShelfNum() : 1;
|
|
|
- for (FloorConfig floor : parseFloors(temp.getLeftFloors())) {
|
|
|
- for (GoodsItem goods : floor.getGoods()) {
|
|
|
- if (goods.getKey() != null && goods.getStock() != null && goods.getStock() > 0) {
|
|
|
- accumulators.computeIfAbsent(goods.getKey(), k -> new Accumulator())
|
|
|
- .addTemplateStock(goods.getStock(), floorNum, "left", goods.getPic());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- for (FloorConfig floor : parseFloors(temp.getRightFloors())) {
|
|
|
- for (GoodsItem goods : floor.getGoods()) {
|
|
|
- if (goods.getKey() != null && goods.getStock() != null && goods.getStock() > 0) {
|
|
|
- accumulators.computeIfAbsent(goods.getKey(), k -> new Accumulator())
|
|
|
- .addTemplateStock(goods.getStock(), floorNum, "right", goods.getPic());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (accumulators.isEmpty()) continue;
|
|
|
-
|
|
|
- // 获取当前库存
|
|
|
- Map<String, DeviceInventory> deviceInvs = inventoryMap.getOrDefault(deviceId, new HashMap<>());
|
|
|
+ List<DeviceInventory> deviceInvs = inventoryByDevice.getOrDefault(deviceId, new java.util.ArrayList<>());
|
|
|
+ if (deviceInvs.isEmpty()) continue;
|
|
|
|
|
|
List<SuggestionItem> items = new java.util.ArrayList<>();
|
|
|
- for (Map.Entry<String, Accumulator> entry : accumulators.entrySet()) {
|
|
|
- String code = entry.getKey();
|
|
|
- Accumulator acc = entry.getValue();
|
|
|
- int currentStock = deviceInvs.containsKey(code) ? deviceInvs.get(code).getStock() : 0;
|
|
|
- int suggestedQty = acc.templateStock - currentStock;
|
|
|
+ for (DeviceInventory inv : deviceInvs) {
|
|
|
+ int standardStock = inv.getStandardStock() != null ? inv.getStandardStock() : 0;
|
|
|
+ if (standardStock == 0) continue; // 无标准库存的跳过
|
|
|
+
|
|
|
+ int currentStock = inv.getStock() != null ? inv.getStock() : 0;
|
|
|
+ int suggestedQty = standardStock - currentStock;
|
|
|
if (suggestedQty <= 0) continue;
|
|
|
|
|
|
SuggestionItem item = new SuggestionItem();
|
|
|
- item.setProductCode(code);
|
|
|
- item.setTemplateStock(acc.templateStock);
|
|
|
+ item.setProductCode(inv.getProductCode());
|
|
|
+ item.setTemplateStock(standardStock);
|
|
|
item.setCurrentStock(currentStock);
|
|
|
item.setSuggestedQuantity(suggestedQty);
|
|
|
- item.setShelfNum(acc.shelfNum);
|
|
|
- item.setPosition(acc.position);
|
|
|
+ item.setShelfNum(inv.getShelfNum());
|
|
|
+ item.setPosition(inv.getPosition());
|
|
|
|
|
|
- Product product = productMap.get(code);
|
|
|
+ Product product = productMap.get(inv.getProductCode());
|
|
|
if (product != null) {
|
|
|
item.setProductId(product.getId());
|
|
|
item.setProductName(product.getName());
|
|
|
@@ -693,9 +637,6 @@ public class ReplenishmentOrderServiceImpl extends ServiceImpl<ReplenishmentOrde
|
|
|
item.setProductImage(product.getPic());
|
|
|
}
|
|
|
}
|
|
|
- if (item.getProductImage() == null && acc.productImage != null) {
|
|
|
- item.setProductImage(acc.productImage);
|
|
|
- }
|
|
|
items.add(item);
|
|
|
}
|
|
|
|
|
|
@@ -713,41 +654,6 @@ public class ReplenishmentOrderServiceImpl extends ServiceImpl<ReplenishmentOrde
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 解析楼层 JSON 字符串
|
|
|
- */
|
|
|
- private List<FloorConfig> parseFloors(String floorsJson) {
|
|
|
- if (!StringUtils.hasText(floorsJson)) {
|
|
|
- return java.util.Collections.emptyList();
|
|
|
- }
|
|
|
- try {
|
|
|
- return objectMapper.readValue(floorsJson, new TypeReference<List<FloorConfig>>() {});
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("解析楼层JSON失败: {}", e.getMessage());
|
|
|
- return java.util.Collections.emptyList();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 累加器:合并同一商品在多层的标准库存
|
|
|
- */
|
|
|
- private static class Accumulator {
|
|
|
- int templateStock = 0;
|
|
|
- int shelfNum = 0;
|
|
|
- String position = "";
|
|
|
- String productImage;
|
|
|
-
|
|
|
- void addTemplateStock(int stock, int floor, String pos, String image) {
|
|
|
- this.templateStock += stock;
|
|
|
- if (this.position.isEmpty()) {
|
|
|
- this.shelfNum = floor;
|
|
|
- this.position = pos;
|
|
|
- }
|
|
|
- if (this.productImage == null && image != null) {
|
|
|
- this.productImage = image;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
/**
|
|
|
* 生成补货单号:RO + yyyyMMdd + 4位序号
|
|
|
*/
|