|
@@ -1,6 +1,5 @@
|
|
|
package com.sd.business.service.inventory.impl;
|
|
|
|
|
|
-import cn.hutool.core.collection.CollUtil;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.ruoyi.common.exception.ServiceException;
|
|
@@ -11,7 +10,6 @@ import com.sd.business.entity.in.po.InOutStorageDetails;
|
|
|
import com.sd.business.entity.inventory.bo.InOutFun;
|
|
|
import com.sd.business.entity.inventory.dto.InventorySelectDto;
|
|
|
import com.sd.business.entity.inventory.dto.QuantityByWarehouseDto;
|
|
|
-import com.sd.business.entity.inventory.po.BalancePriceNum;
|
|
|
import com.sd.business.entity.inventory.po.Inventory;
|
|
|
import com.sd.business.entity.inventory.po.InventoryBackup;
|
|
|
import com.sd.business.entity.inventory.vo.InventoryVo;
|
|
@@ -20,7 +18,6 @@ import com.sd.business.entity.inventory.vo.QuantityByWarehouseVo;
|
|
|
import com.sd.business.mapper.inventory.InventoryMapper;
|
|
|
import com.sd.business.service.bom.BomSpecService;
|
|
|
import com.sd.business.service.in.InOutStorageDetailsService;
|
|
|
-import com.sd.business.service.in.impl.InOutStorageServiceImpl;
|
|
|
import com.sd.business.service.inventory.InventoryService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -28,7 +25,7 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
-import java.util.ArrayList;
|
|
|
+import java.util.Collection;
|
|
|
import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
@@ -48,6 +45,8 @@ import java.util.stream.Collectors;
|
|
|
@Service
|
|
|
public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory> implements InventoryService {
|
|
|
|
|
|
+ private final static BigDecimal tempUnitPrice = BigDecimal.TEN;
|
|
|
+
|
|
|
@Autowired
|
|
|
private BomSpecService bomSpecService;
|
|
|
|
|
@@ -92,75 +91,71 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
|
|
|
List<Long> bomSpecIdList = list.stream().map(InOutFun::getBomSpecId).collect(Collectors.toList());
|
|
|
|
|
|
synchronized (this) {
|
|
|
+
|
|
|
+
|
|
|
+ List<InOutStorageDetails> inOutStorageDetailsList = list.stream().map(item -> {
|
|
|
+ InOutStorageDetails inOutStorageDetails = new InOutStorageDetails();
|
|
|
+ inOutStorageDetails.setDepartmentId(departmentId);
|
|
|
+ inOutStorageDetails.setWarehouseId(warehouseId);
|
|
|
+ inOutStorageDetails.setBomSpecId(item.getBomSpecId());
|
|
|
+ inOutStorageDetails.setInUnitPrice(tempUnitPrice);
|
|
|
+ inOutStorageDetails.setQuantity(item.getQuantity());
|
|
|
+ return inOutStorageDetails;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ inOutStorageDetailsService.saveBatch(inOutStorageDetailsList);
|
|
|
+
|
|
|
+
|
|
|
List<Inventory> inventoryList = getInventoryList(departmentId, warehouseId, bomSpecIdList);
|
|
|
+
|
|
|
+
|
|
|
+ Map<Long, List<InOutStorageDetails>> inOutStorageDetailsMap = getInOutStorageDetailsMap(warehouseId, bomSpecIdList);
|
|
|
+
|
|
|
+
|
|
|
Map<Long, Inventory> map = inventoryList.stream().collect(Collectors.toMap(Inventory::getBomSpecId, Function.identity()));
|
|
|
|
|
|
for (InOutFun inOutFun : list) {
|
|
|
- Long bomSpecId = inOutFun.getBomSpecId();
|
|
|
- BigDecimal quantity = inOutFun.getQuantity();
|
|
|
- BigDecimal unitPrice = InOutStorageServiceImpl.UNITPRICE;
|
|
|
- Inventory inventory = map.get(bomSpecId);
|
|
|
-
|
|
|
- if (inventory != null) {
|
|
|
- inventory.setQuantity(inventory.getQuantity().add(quantity));
|
|
|
- } else {
|
|
|
- inventory = new Inventory();
|
|
|
- inventory.setWarehouseId(warehouseId);
|
|
|
- inventory.setDepartmentId(departmentId);
|
|
|
- inventory.setBomSpecId(bomSpecId);
|
|
|
- inventory.setQuantity(quantity);
|
|
|
- inventoryList.add(inventory);
|
|
|
- map.put(bomSpecId, inventory);
|
|
|
- }
|
|
|
- Map<Long, List<InOutStorageDetails>> inOutStorageDetailsMap = getInOutStorageDetailsMap(warehouseId, bomSpecIdList);
|
|
|
-
|
|
|
-
|
|
|
- BigDecimal sumQuantity = inOutStorageDetailsMap.getOrDefault(inOutFun.getBomSpecId(), Collections.emptyList())
|
|
|
- .stream().map(InOutStorageDetails::getQuantity)
|
|
|
- .filter(item -> item.compareTo(BigDecimal.ZERO) > 0)
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
-
|
|
|
- BigDecimal sumPrice = inOutStorageDetailsMap.getOrDefault(inOutFun.getBomSpecId(), Collections.emptyList()).stream()
|
|
|
- .filter(item -> item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
|
|
|
- .map(item -> item.getQuantity().multiply(item.getInUnitPrice()))
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
-
|
|
|
-
|
|
|
- sumQuantity = sumQuantity.add(quantity);
|
|
|
- BigDecimal balancep = quantity.multiply(unitPrice);
|
|
|
- sumPrice = sumPrice.add(balancep);
|
|
|
- BigDecimal balanceUnitPrice = sumPrice.divide(sumQuantity, 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+
|
|
|
+ Inventory inventory = map.computeIfAbsent(inOutFun.getBomSpecId(), item -> {
|
|
|
+ Inventory tempInventory = new Inventory();
|
|
|
+ tempInventory.setWarehouseId(warehouseId);
|
|
|
+ tempInventory.setDepartmentId(departmentId);
|
|
|
+ tempInventory.setBomSpecId(item);
|
|
|
+ tempInventory.setQuantity(BigDecimal.ZERO);
|
|
|
+ inventoryList.add(tempInventory);
|
|
|
+ return tempInventory;
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ BigDecimal balanceUnitPrice = getBalanceUnitPrice(inOutStorageDetailsMap, inOutFun);
|
|
|
+
|
|
|
+ inventory.setQuantity(inventory.getQuantity().add(inOutFun.getQuantity()));
|
|
|
inventory.setBalanceUnitPrice(balanceUnitPrice);
|
|
|
}
|
|
|
+
|
|
|
saveOrUpdateBatch(inventoryList);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void out(Long departmentId, Long warehouseId, List<? extends InOutFun> list) {
|
|
|
-
|
|
|
-
|
|
|
- Map<Long, BigDecimal> map = list.stream()
|
|
|
- .collect(Collectors.toMap(InOutFun::getBomSpecId, InOutFun::getQuantity));
|
|
|
-
|
|
|
- List<Long> bomSpecIdList = new ArrayList<>(map.keySet());
|
|
|
+ List<Long> bomSpecIdList = list.stream().map(InOutFun::getBomSpecId).collect(Collectors.toList());
|
|
|
|
|
|
synchronized (this) {
|
|
|
|
|
|
+
|
|
|
List<Inventory> inventoryList = getInventoryList(departmentId, warehouseId, bomSpecIdList);
|
|
|
+ Map<Long, Inventory> inventoryMap = inventoryList.stream().collect(Collectors.toMap(Inventory::getBomSpecId, Function.identity()));
|
|
|
|
|
|
|
|
|
Map<Long, List<InOutStorageDetails>> inOutStorageDetailsMap = getInOutStorageDetailsMap(warehouseId, bomSpecIdList);
|
|
|
|
|
|
-
|
|
|
- List<InOutStorageDetails> updateList = new ArrayList<>();
|
|
|
-
|
|
|
-
|
|
|
- for (Inventory inventory : inventoryList) {
|
|
|
-
|
|
|
- Long bomSpecId = inventory.getBomSpecId();
|
|
|
+ for (InOutFun inOutFun : list) {
|
|
|
+ Long bomSpecId = inOutFun.getBomSpecId();
|
|
|
+ BigDecimal quantity = inOutFun.getQuantity();
|
|
|
|
|
|
- if (!bomSpecIdList.contains(bomSpecId)) {
|
|
|
+ Inventory inventory = inventoryMap.get(bomSpecId);
|
|
|
+ if (inventory == null || inventory.getQuantity().compareTo(quantity) < 0) {
|
|
|
BomSpec bomSpec = bomSpecService.getById(bomSpecId);
|
|
|
if (bomSpec == null) {
|
|
|
throw new ServiceException("未知bom规格id:" + bomSpecId);
|
|
@@ -168,69 +163,27 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
|
|
|
throw new ServiceException("出库失败,品名为:" + bomSpec.getName() + "的bom库存不足");
|
|
|
}
|
|
|
|
|
|
- List<InOutStorageDetails> outStorageDetails = inOutStorageDetailsMap.getOrDefault(bomSpecId, Collections.emptyList());
|
|
|
-
|
|
|
- int j = 0;
|
|
|
+
|
|
|
+ BigDecimal balanceUnitPrice = getOutBalanceUnitPrice(inOutStorageDetailsMap, inOutFun);
|
|
|
|
|
|
-
|
|
|
- BigDecimal quantity = map.get(bomSpecId);
|
|
|
-
|
|
|
- do {
|
|
|
- if (outStorageDetails.size() == j) {
|
|
|
- throw new ServiceException("数据异常,无法计算库存单价!!");
|
|
|
- }
|
|
|
-
|
|
|
- InOutStorageDetails inOutStorageDetails = outStorageDetails.get(j);
|
|
|
-
|
|
|
-
|
|
|
- BigDecimal tempQuantity = inOutStorageDetails.getQuantity();
|
|
|
-
|
|
|
- if (tempQuantity.compareTo(quantity) > 0) {
|
|
|
- inOutStorageDetails.setQuantity(tempQuantity.subtract(quantity));
|
|
|
- quantity = BigDecimal.ZERO;
|
|
|
- } else if (tempQuantity.compareTo(quantity) < 0) {
|
|
|
- inOutStorageDetails.setQuantity(BigDecimal.ZERO);
|
|
|
- quantity = tempQuantity.subtract(quantity).abs();
|
|
|
- } else {
|
|
|
- inOutStorageDetails.setQuantity(BigDecimal.ZERO);
|
|
|
- quantity = BigDecimal.ZERO;
|
|
|
- }
|
|
|
- updateList.add(inOutStorageDetails);
|
|
|
- j++;
|
|
|
-
|
|
|
- } while (quantity.compareTo(BigDecimal.ZERO) > 0);
|
|
|
-
|
|
|
-
|
|
|
- BigDecimal totalInventory = outStorageDetails.stream()
|
|
|
- .map(InOutStorageDetails::getQuantity)
|
|
|
- .filter(item -> item.compareTo(BigDecimal.ZERO) > 0)
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
-
|
|
|
-
|
|
|
- BigDecimal totalInventoryAmount = outStorageDetails.stream()
|
|
|
- .filter(item -> item.getQuantity().compareTo(BigDecimal.ZERO) > 0)
|
|
|
- .map(item -> item.getQuantity().multiply(item.getInUnitPrice()))
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
-
|
|
|
- BigDecimal balanceUnitPrice;
|
|
|
-
|
|
|
- if (totalInventory.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
- balanceUnitPrice = BigDecimal.ZERO;
|
|
|
- } else {
|
|
|
- balanceUnitPrice = totalInventoryAmount.divide(totalInventory, 2, RoundingMode.HALF_UP);
|
|
|
- }
|
|
|
|
|
|
inventory.setBalanceUnitPrice(balanceUnitPrice);
|
|
|
- inventory.setQuantity(totalInventory);
|
|
|
+ inventory.setQuantity(inventory.getQuantity().subtract(quantity));
|
|
|
}
|
|
|
|
|
|
|
|
|
- inOutStorageDetailsService.updateBatchById(updateList);
|
|
|
+ List<InOutStorageDetails> inOutStorageDetailsList = inOutStorageDetailsMap.values()
|
|
|
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
|
|
|
+ inOutStorageDetailsService.updateBatchById(inOutStorageDetailsList);
|
|
|
|
|
|
|
|
|
updateBatchById(inventoryList);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ * 通过事业部id和出库id获取bom规格库存
|
|
|
+ */
|
|
|
private List<Inventory> getInventoryList(Long departmentId, Long warehouseId, List<Long> bomSpecIdList) {
|
|
|
return list(q -> q
|
|
|
.eq(Inventory::getDepartmentId, departmentId)
|
|
@@ -238,6 +191,10 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
|
|
|
.in(Inventory::getBomSpecId, bomSpecIdList)
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ * 通过出库id获取bom规格结存列表
|
|
|
+ */
|
|
|
private Map<Long, List<InOutStorageDetails>> getInOutStorageDetailsMap(Long warehouseId, List<Long> bomSpecIdList) {
|
|
|
List<InOutStorageDetails> list = inOutStorageDetailsService.list(q -> q
|
|
|
.eq(InOutStorageDetails::getWarehouseId, warehouseId)
|
|
@@ -247,4 +204,74 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
|
|
|
return list.stream().collect(Collectors.groupingBy(InOutStorageDetails::getBomSpecId));
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * 获取入库结存单价
|
|
|
+ */
|
|
|
+ private BigDecimal getBalanceUnitPrice(Map<Long, List<InOutStorageDetails>> inOutStorageDetailsMap, InOutFun inOutFun) {
|
|
|
+
|
|
|
+
|
|
|
+ BigDecimal sumQuantity = inOutStorageDetailsMap
|
|
|
+ .getOrDefault(inOutFun.getBomSpecId(), Collections.emptyList())
|
|
|
+ .stream()
|
|
|
+ .map(InOutStorageDetails::getQuantity)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+
|
|
|
+
|
|
|
+ BigDecimal sumPrice = inOutStorageDetailsMap
|
|
|
+ .getOrDefault(inOutFun.getBomSpecId(), Collections.emptyList())
|
|
|
+ .stream()
|
|
|
+ .map(item -> item.getQuantity().multiply(item.getInUnitPrice()))
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+
|
|
|
+
|
|
|
+ if (sumQuantity.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return sumPrice.divide(sumQuantity, 2, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 获取出库结存单价
|
|
|
+ */
|
|
|
+ private BigDecimal getOutBalanceUnitPrice(Map<Long, List<InOutStorageDetails>> inOutStorageDetailsMap, InOutFun inOutFun) {
|
|
|
+
|
|
|
+ Long bomSpecId = inOutFun.getBomSpecId();
|
|
|
+ BigDecimal quantity = inOutFun.getQuantity();
|
|
|
+
|
|
|
+ List<InOutStorageDetails> outStorageDetails = inOutStorageDetailsMap.getOrDefault(bomSpecId, Collections.emptyList());
|
|
|
+
|
|
|
+
|
|
|
+ int j = 0;
|
|
|
+
|
|
|
+ do {
|
|
|
+ if (outStorageDetails.size() == j) {
|
|
|
+ throw new ServiceException("数据异常,无法计算库存单价!!");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ InOutStorageDetails inOutStorageDetails = outStorageDetails.get(j);
|
|
|
+
|
|
|
+
|
|
|
+ BigDecimal tempQuantity = inOutStorageDetails.getQuantity();
|
|
|
+
|
|
|
+ if (tempQuantity.compareTo(quantity) > 0) {
|
|
|
+ inOutStorageDetails.setQuantity(tempQuantity.subtract(quantity));
|
|
|
+ quantity = BigDecimal.ZERO;
|
|
|
+ } else if (tempQuantity.compareTo(quantity) < 0) {
|
|
|
+ inOutStorageDetails.setQuantity(BigDecimal.ZERO);
|
|
|
+ quantity = quantity.subtract(tempQuantity);
|
|
|
+ } else {
|
|
|
+ inOutStorageDetails.setQuantity(BigDecimal.ZERO);
|
|
|
+ quantity = BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+ j++;
|
|
|
+
|
|
|
+ } while (quantity.compareTo(BigDecimal.ZERO) > 0);
|
|
|
+
|
|
|
+ return getBalanceUnitPrice(inOutStorageDetailsMap, inOutFun);
|
|
|
+ }
|
|
|
+
|
|
|
}
|