|
|
|
|
@ -4,17 +4,36 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockStatisticsRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutItemMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.framework.bean.ProductTypeEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_COUNT_NEGATIVE;
|
|
|
|
|
@ -42,6 +61,14 @@ public class ErpStockServiceImpl implements ErpStockService {
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockMapper stockMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockInMapper stockInMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockInItemMapper stockInItemMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockOutMapper stockOutMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockOutItemMapper stockOutItemMapper;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ErpStockDO getStock(Long id) {
|
|
|
|
|
@ -93,6 +120,21 @@ public class ErpStockServiceImpl implements ErpStockService {
|
|
|
|
|
return stockMapper.selectPage(pageReqVO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ErpStockStatisticsRespVO getStockStatistics() {
|
|
|
|
|
ErpStockStatisticsRespVO respVO = new ErpStockStatisticsRespVO();
|
|
|
|
|
List<ErpStockDO> stockList = stockMapper.selectList(new LambdaQueryWrapper<ErpStockDO>());
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(stockList.stream()
|
|
|
|
|
.map(ErpStockDO::getProductId).collect(Collectors.toSet()));
|
|
|
|
|
fillStockCards(respVO, stockList, productMap);
|
|
|
|
|
|
|
|
|
|
LocalDateTime beginTime = LocalDate.now().atStartOfDay();
|
|
|
|
|
LocalDateTime endTime = beginTime.plusDays(1);
|
|
|
|
|
fillTodayInCard(respVO, beginTime, endTime, productMap);
|
|
|
|
|
fillTodayOutCard(respVO, beginTime, endTime, productMap);
|
|
|
|
|
return respVO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public BigDecimal updateStockCountIncrement(Long categoryId, Long productId, Long warehouseId, Long areaId,
|
|
|
|
|
String areaName, BigDecimal count) {
|
|
|
|
|
@ -140,6 +182,266 @@ public class ErpStockServiceImpl implements ErpStockService {
|
|
|
|
|
return stock.getCount().add(count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void fillStockCards(ErpStockStatisticsRespVO respVO, List<ErpStockDO> stockList,
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
ErpStockStatisticsRespVO.ProductStockCard productStockCard = new ErpStockStatisticsRespVO.ProductStockCard();
|
|
|
|
|
|
|
|
|
|
List<ErpStockDO> productStockList = filterStockByCategory(stockList, productMap, ProductTypeEnum.ITEM.getTypeId());
|
|
|
|
|
List<ErpStockDO> materialStockList = filterStockByCategory(stockList, productMap, ProductTypeEnum.PRODUCT.getTypeId());
|
|
|
|
|
List<ErpStockDO> sparePartStockList = filterStockByCategory(stockList, productMap, ProductTypeEnum.BEIJIAN.getTypeId());
|
|
|
|
|
|
|
|
|
|
productStockCard.setSkuCount(countDistinctProduct(productStockList));
|
|
|
|
|
productStockCard.setStockDisplay(formatProductStockDisplay(productStockList));
|
|
|
|
|
productStockCard.setTodayFinishedInDisplay(formatProductStockDisplay(Collections.emptyList()));
|
|
|
|
|
respVO.setProductStock(productStockCard);
|
|
|
|
|
|
|
|
|
|
respVO.setMaterialStock(buildUnitGroupedStockCard(materialStockList));
|
|
|
|
|
respVO.setSparePartStock(buildUnitGroupedStockCard(sparePartStockList));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void fillTodayInCard(ErpStockStatisticsRespVO respVO, LocalDateTime beginTime, LocalDateTime endTime,
|
|
|
|
|
Map<Long, ErpProductRespVO> stockProductMap) {
|
|
|
|
|
ErpStockStatisticsRespVO.TodayInCard todayInCard = new ErpStockStatisticsRespVO.TodayInCard();
|
|
|
|
|
List<ErpStockInDO> stockInList = stockInMapper.selectList(new LambdaQueryWrapper<ErpStockInDO>()
|
|
|
|
|
.eq(ErpStockInDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
|
|
|
|
|
.between(ErpStockInDO::getInTime, beginTime, endTime));
|
|
|
|
|
List<Long> stockInIds = stockInList.stream().map(ErpStockInDO::getId).collect(Collectors.toList());
|
|
|
|
|
List<ErpStockInItemDO> itemList = stockInIds.isEmpty() ? Collections.emptyList()
|
|
|
|
|
: stockInItemMapper.selectListByInIds(stockInIds);
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap = buildProductMap(itemList.stream()
|
|
|
|
|
.map(ErpStockInItemDO::getProductId).collect(Collectors.toSet()), stockProductMap);
|
|
|
|
|
|
|
|
|
|
todayInCard.setOrderCount((long) stockInIds.size());
|
|
|
|
|
todayInCard.setItemCount((long) itemList.size());
|
|
|
|
|
todayInCard.setProductStock(buildInItemUnitGroupedStockCard(filterInItemByCategory(itemList, productMap, ProductTypeEnum.ITEM.getTypeId()), productMap));
|
|
|
|
|
todayInCard.setMaterialStock(buildInItemUnitGroupedStockCard(filterInItemByCategory(itemList, productMap, ProductTypeEnum.PRODUCT.getTypeId()), productMap));
|
|
|
|
|
todayInCard.setSparePartStock(buildInItemUnitGroupedStockCard(filterInItemByCategory(itemList, productMap, ProductTypeEnum.BEIJIAN.getTypeId()), productMap));
|
|
|
|
|
respVO.setTodayIn(todayInCard);
|
|
|
|
|
respVO.getProductStock().setTodayFinishedInDisplay(todayInCard.getProductStock().getStockDisplay());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void fillTodayOutCard(ErpStockStatisticsRespVO respVO, LocalDateTime beginTime, LocalDateTime endTime,
|
|
|
|
|
Map<Long, ErpProductRespVO> stockProductMap) {
|
|
|
|
|
ErpStockStatisticsRespVO.TodayOutCard todayOutCard = new ErpStockStatisticsRespVO.TodayOutCard();
|
|
|
|
|
List<ErpStockOutDO> stockOutList = stockOutMapper.selectList(new LambdaQueryWrapper<ErpStockOutDO>()
|
|
|
|
|
.eq(ErpStockOutDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
|
|
|
|
|
.between(ErpStockOutDO::getOutTime, beginTime, endTime));
|
|
|
|
|
List<Long> stockOutIds = stockOutList.stream().map(ErpStockOutDO::getId).collect(Collectors.toList());
|
|
|
|
|
List<ErpStockOutItemDO> itemList = stockOutIds.isEmpty() ? Collections.emptyList()
|
|
|
|
|
: stockOutItemMapper.selectListByOutIds(stockOutIds);
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap = buildProductMap(itemList.stream()
|
|
|
|
|
.map(ErpStockOutItemDO::getProductId).collect(Collectors.toSet()), stockProductMap);
|
|
|
|
|
|
|
|
|
|
todayOutCard.setOrderCount((long) stockOutIds.size());
|
|
|
|
|
todayOutCard.setItemCount((long) itemList.size());
|
|
|
|
|
todayOutCard.setProductStock(buildOutItemUnitGroupedStockCard(filterOutItemByCategory(itemList, productMap, ProductTypeEnum.ITEM.getTypeId()), productMap));
|
|
|
|
|
todayOutCard.setMaterialStock(buildOutItemUnitGroupedStockCard(filterOutItemByCategory(itemList, productMap, ProductTypeEnum.PRODUCT.getTypeId()), productMap));
|
|
|
|
|
todayOutCard.setSparePartStock(buildOutItemUnitGroupedStockCard(filterOutItemByCategory(itemList, productMap, ProductTypeEnum.BEIJIAN.getTypeId()), productMap));
|
|
|
|
|
respVO.setTodayOut(todayOutCard);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<Long, ErpProductRespVO> buildProductMap(Set<Long> productIds, Map<Long, ErpProductRespVO> stockProductMap) {
|
|
|
|
|
Set<Long> missingProductIds = new HashSet<>(productIds);
|
|
|
|
|
missingProductIds.removeAll(stockProductMap.keySet());
|
|
|
|
|
if (missingProductIds.isEmpty()) {
|
|
|
|
|
return stockProductMap;
|
|
|
|
|
}
|
|
|
|
|
Map<Long, ErpProductRespVO> resultMap = productService.getProductVOMap(productIds);
|
|
|
|
|
resultMap.putAll(stockProductMap);
|
|
|
|
|
return resultMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<ErpStockDO> filterStockByCategory(List<ErpStockDO> stockList, Map<Long, ErpProductRespVO> productMap,
|
|
|
|
|
Integer categoryType) {
|
|
|
|
|
return stockList.stream()
|
|
|
|
|
.filter(stock -> categoryType.equals(resolveCategoryType(stock, productMap)))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<ErpStockInItemDO> filterInItemByCategory(List<ErpStockInItemDO> itemList,
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap,
|
|
|
|
|
Integer categoryType) {
|
|
|
|
|
return itemList.stream()
|
|
|
|
|
.filter(item -> categoryType.equals(resolveCategoryType(item.getProductId(), productMap)))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<ErpStockOutItemDO> filterOutItemByCategory(List<ErpStockOutItemDO> itemList,
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap,
|
|
|
|
|
Integer categoryType) {
|
|
|
|
|
return itemList.stream()
|
|
|
|
|
.filter(item -> categoryType.equals(resolveCategoryType(item.getProductId(), productMap)))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockStatisticsRespVO.UnitGroupedStockCard buildUnitGroupedStockCard(List<ErpStockDO> stockList) {
|
|
|
|
|
ErpStockStatisticsRespVO.UnitGroupedStockCard card = new ErpStockStatisticsRespVO.UnitGroupedStockCard();
|
|
|
|
|
card.setSkuCount(countDistinctProduct(stockList));
|
|
|
|
|
List<ErpStockStatisticsRespVO.UnitStock> unitStocks = stockList.stream()
|
|
|
|
|
.collect(Collectors.groupingBy(stock -> buildUnitKey(stock.getUnitId(), stock.getUnitName())))
|
|
|
|
|
.values().stream()
|
|
|
|
|
.map(this::buildUnitStock)
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
card.setUnitStocks(unitStocks);
|
|
|
|
|
card.setStockDisplay(unitStocks.stream()
|
|
|
|
|
.map(ErpStockStatisticsRespVO.UnitStock::getStockDisplay)
|
|
|
|
|
.collect(Collectors.joining(" / ")));
|
|
|
|
|
return card;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockStatisticsRespVO.UnitStock buildUnitStock(List<ErpStockDO> stockList) {
|
|
|
|
|
ErpStockDO firstStock = stockList.get(0);
|
|
|
|
|
BigDecimal count = stockList.stream().map(stock -> defaultZero(stock.getCount()))
|
|
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
|
|
return buildUnitStock(firstStock.getUnitId(), firstStock.getUnitName(), count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String buildUnitKey(Long unitId, String unitName) {
|
|
|
|
|
return String.valueOf(unitId) + "_" + String.valueOf(unitName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockStatisticsRespVO.UnitGroupedStockCard buildInItemUnitGroupedStockCard(List<ErpStockInItemDO> itemList,
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
ErpStockStatisticsRespVO.UnitGroupedStockCard card = new ErpStockStatisticsRespVO.UnitGroupedStockCard();
|
|
|
|
|
card.setSkuCount(itemList.stream().map(ErpStockInItemDO::getProductId).distinct().count());
|
|
|
|
|
List<ErpStockStatisticsRespVO.UnitStock> unitStocks = itemList.stream()
|
|
|
|
|
.collect(Collectors.groupingBy(item -> buildProductUnitKey(item.getProductId(), productMap)))
|
|
|
|
|
.values().stream()
|
|
|
|
|
.map(items -> buildInItemUnitStock(items, productMap))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
card.setUnitStocks(unitStocks);
|
|
|
|
|
card.setStockDisplay(unitStocks.stream()
|
|
|
|
|
.map(ErpStockStatisticsRespVO.UnitStock::getStockDisplay)
|
|
|
|
|
.collect(Collectors.joining(" / ")));
|
|
|
|
|
return card;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockStatisticsRespVO.UnitGroupedStockCard buildOutItemUnitGroupedStockCard(List<ErpStockOutItemDO> itemList,
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
ErpStockStatisticsRespVO.UnitGroupedStockCard card = new ErpStockStatisticsRespVO.UnitGroupedStockCard();
|
|
|
|
|
card.setSkuCount(itemList.stream().map(ErpStockOutItemDO::getProductId).distinct().count());
|
|
|
|
|
List<ErpStockStatisticsRespVO.UnitStock> unitStocks = itemList.stream()
|
|
|
|
|
.collect(Collectors.groupingBy(item -> buildProductUnitKey(item.getProductId(), productMap)))
|
|
|
|
|
.values().stream()
|
|
|
|
|
.map(items -> buildOutItemUnitStock(items, productMap))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
card.setUnitStocks(unitStocks);
|
|
|
|
|
card.setStockDisplay(unitStocks.stream()
|
|
|
|
|
.map(ErpStockStatisticsRespVO.UnitStock::getStockDisplay)
|
|
|
|
|
.collect(Collectors.joining(" / ")));
|
|
|
|
|
return card;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockStatisticsRespVO.UnitStock buildInItemUnitStock(List<ErpStockInItemDO> itemList,
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
ErpStockInItemDO firstItem = itemList.get(0);
|
|
|
|
|
ErpProductRespVO product = productMap.get(firstItem.getProductId());
|
|
|
|
|
BigDecimal count = itemList.stream().map(item -> defaultZero(item.getCount()))
|
|
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
|
|
return buildUnitStock(product != null ? product.getUnitId() : null,
|
|
|
|
|
product != null ? product.getUnitName() : null, count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockStatisticsRespVO.UnitStock buildOutItemUnitStock(List<ErpStockOutItemDO> itemList,
|
|
|
|
|
Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
ErpStockOutItemDO firstItem = itemList.get(0);
|
|
|
|
|
ErpProductRespVO product = productMap.get(firstItem.getProductId());
|
|
|
|
|
BigDecimal count = itemList.stream().map(item -> defaultZero(item.getCount()))
|
|
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
|
|
return buildUnitStock(product != null ? product.getUnitId() : null,
|
|
|
|
|
product != null ? product.getUnitName() : null, count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockStatisticsRespVO.UnitStock buildUnitStock(Long unitId, String unitName, BigDecimal count) {
|
|
|
|
|
ErpStockStatisticsRespVO.UnitStock unitStock = new ErpStockStatisticsRespVO.UnitStock();
|
|
|
|
|
unitStock.setUnitId(unitId);
|
|
|
|
|
unitStock.setUnitName(unitName);
|
|
|
|
|
unitStock.setCount(count);
|
|
|
|
|
unitStock.setStockDisplay(formatNumber(count) + nullToEmpty(unitName));
|
|
|
|
|
return unitStock;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String buildProductUnitKey(Long productId, Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
ErpProductRespVO product = productMap.get(productId);
|
|
|
|
|
return product != null ? buildUnitKey(product.getUnitId(), product.getUnitName()) : buildUnitKey(null, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Integer resolveCategoryType(ErpStockDO stock, Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
if (stock.getCategoryType() != null) {
|
|
|
|
|
return stock.getCategoryType();
|
|
|
|
|
}
|
|
|
|
|
return resolveCategoryType(stock.getProductId(), productMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Integer resolveCategoryType(Long productId, Map<Long, ErpProductRespVO> productMap) {
|
|
|
|
|
ErpProductRespVO product = productMap.get(productId);
|
|
|
|
|
return product != null ? product.getCategoryType() : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Long countDistinctProduct(List<ErpStockDO> stockList) {
|
|
|
|
|
return stockList.stream().map(ErpStockDO::getProductId).distinct().count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String formatProductStockDisplay(List<ErpStockDO> stockList) {
|
|
|
|
|
BigDecimal palletCount = BigDecimal.ZERO;
|
|
|
|
|
BigDecimal packageCount = BigDecimal.ZERO;
|
|
|
|
|
BigDecimal pieceCount = BigDecimal.ZERO;
|
|
|
|
|
for (ErpStockDO stock : stockList) {
|
|
|
|
|
ProductQuantity quantity = calculateProductQuantity(stock.getCount(), stock.getPalletTotalQuantity(), stock.getPackageQuantity());
|
|
|
|
|
palletCount = palletCount.add(quantity.getPalletCount());
|
|
|
|
|
packageCount = packageCount.add(quantity.getPackageCount());
|
|
|
|
|
pieceCount = pieceCount.add(quantity.getPieceCount());
|
|
|
|
|
}
|
|
|
|
|
return formatProductQuantity(palletCount, packageCount, pieceCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ProductQuantity calculateProductQuantity(BigDecimal count, BigDecimal palletTotalQuantity, BigDecimal packageQuantity) {
|
|
|
|
|
BigDecimal safeCount = defaultZero(count);
|
|
|
|
|
BigDecimal palletCount = BigDecimal.ZERO;
|
|
|
|
|
BigDecimal packageCount = BigDecimal.ZERO;
|
|
|
|
|
BigDecimal pieceCount = safeCount;
|
|
|
|
|
if (palletTotalQuantity != null && palletTotalQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
|
|
|
|
palletCount = safeCount.divideToIntegralValue(palletTotalQuantity);
|
|
|
|
|
pieceCount = safeCount.remainder(palletTotalQuantity);
|
|
|
|
|
}
|
|
|
|
|
if (packageQuantity != null && packageQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
|
|
|
|
packageCount = pieceCount.divideToIntegralValue(packageQuantity);
|
|
|
|
|
pieceCount = pieceCount.remainder(packageQuantity);
|
|
|
|
|
}
|
|
|
|
|
return new ProductQuantity(palletCount, packageCount, pieceCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String formatProductQuantity(BigDecimal palletCount, BigDecimal packageCount, BigDecimal pieceCount) {
|
|
|
|
|
StringBuilder display = new StringBuilder();
|
|
|
|
|
appendDisplay(display, palletCount, "托", false);
|
|
|
|
|
appendDisplay(display, packageCount, "包", false);
|
|
|
|
|
appendDisplay(display, pieceCount, "个", display.length() == 0);
|
|
|
|
|
return display.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void appendDisplay(StringBuilder display, BigDecimal quantity, String unitName, boolean keepZero) {
|
|
|
|
|
if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
if (!keepZero) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
display.append("0").append(unitName);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
display.append(formatNumber(quantity)).append(unitName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal defaultZero(BigDecimal value) {
|
|
|
|
|
return value != null ? value : BigDecimal.ZERO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String nullToEmpty(String value) {
|
|
|
|
|
return value != null ? value : "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String formatNumber(BigDecimal value) {
|
|
|
|
|
return value == null ? "0" : value.stripTrailingZeros().toPlainString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void fillStockSnapshot(ErpStockDO stock, ErpProductRespVO product,
|
|
|
|
|
ProductPackagingSchemeRespVO defaultPackagingScheme) {
|
|
|
|
|
if (product == null) {
|
|
|
|
|
@ -196,4 +498,16 @@ public class ErpStockServiceImpl implements ErpStockService {
|
|
|
|
|
.setPalletTotalQuantity(stock.getPalletTotalQuantity());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@lombok.Data
|
|
|
|
|
@lombok.AllArgsConstructor
|
|
|
|
|
private static class ProductQuantity {
|
|
|
|
|
|
|
|
|
|
private BigDecimal palletCount;
|
|
|
|
|
|
|
|
|
|
private BigDecimal packageCount;
|
|
|
|
|
|
|
|
|
|
private BigDecimal pieceCount;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|