|
|
|
|
@ -38,11 +38,13 @@ import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
import javax.validation.Valid;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.math.RoundingMode;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
|
|
|
|
@ -95,8 +97,10 @@ public class ErpStockController {
|
|
|
|
|
@Operation(summary = "获得产品库存分页")
|
|
|
|
|
@PreAuthorize("@ss.hasPermission('erp:stock:query')")
|
|
|
|
|
public CommonResult<PageResult<ErpStockRespVO>> getStockPage(@Valid ErpStockPageReqVO pageReqVO) {
|
|
|
|
|
PageResult<ErpStockDO> pageResult = stockService.getStockPage(pageReqVO);
|
|
|
|
|
return success(buildStockVOPageResult(pageResult));
|
|
|
|
|
ErpStockPageReqVO queryReqVO = BeanUtils.toBean(pageReqVO, ErpStockPageReqVO.class);
|
|
|
|
|
queryReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
PageResult<ErpStockRespVO> groupedResult = buildStockVOPageResult(stockService.getStockPage(queryReqVO));
|
|
|
|
|
return success(new PageResult<>(paginateStockList(groupedResult.getList(), pageReqVO), groupedResult.getTotal()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@GetMapping("/export-excel")
|
|
|
|
|
@ -121,7 +125,7 @@ public class ErpStockController {
|
|
|
|
|
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
|
|
|
|
|
convertSet(pageResult.getList(), ErpStockDO::getAreaId));
|
|
|
|
|
Map<String, Long> palletCountMap = buildPalletCountMap(pageResult.getList());
|
|
|
|
|
return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> {
|
|
|
|
|
PageResult<ErpStockRespVO> respPageResult = BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> {
|
|
|
|
|
MapUtils.findAndThen(productMap, stock.getProductId(), product -> {
|
|
|
|
|
stock.setProductName(product.getName()).setBarCode(product.getBarCode())
|
|
|
|
|
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())
|
|
|
|
|
@ -138,6 +142,8 @@ public class ErpStockController {
|
|
|
|
|
}
|
|
|
|
|
fillRecentRecordTime(stock);
|
|
|
|
|
});
|
|
|
|
|
List<ErpStockRespVO> mergedList = mergeStockByProductAndWarehouse(respPageResult.getList());
|
|
|
|
|
return new PageResult<>(mergedList, (long) mergedList.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockRespVO buildStockRespVO(ErpStockDO stock) {
|
|
|
|
|
@ -177,6 +183,79 @@ public class ErpStockController {
|
|
|
|
|
return respVO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<ErpStockRespVO> mergeStockByProductAndWarehouse(List<ErpStockRespVO> stockList) {
|
|
|
|
|
if (CollUtil.isEmpty(stockList)) {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
}
|
|
|
|
|
Map<String, ErpStockRespVO> mergedMap = new LinkedHashMap<>();
|
|
|
|
|
stockList.forEach(stock -> {
|
|
|
|
|
String key = buildStockGroupKey(stock.getProductId(), stock.getWarehouseId());
|
|
|
|
|
ErpStockRespVO merged = mergedMap.computeIfAbsent(key, item -> {
|
|
|
|
|
ErpStockRespVO target = BeanUtils.toBean(stock, ErpStockRespVO.class);
|
|
|
|
|
target.setId(null);
|
|
|
|
|
target.setAreaId(null);
|
|
|
|
|
target.setAreaName(null);
|
|
|
|
|
target.setCount(BigDecimal.ZERO);
|
|
|
|
|
target.setPalletCount(0L);
|
|
|
|
|
target.setAreaStocks(new ArrayList<>());
|
|
|
|
|
return target;
|
|
|
|
|
});
|
|
|
|
|
merged.setCount(defaultZero(merged.getCount()).add(defaultZero(stock.getCount())));
|
|
|
|
|
merged.setPalletCount((merged.getPalletCount() == null ? 0L : merged.getPalletCount())
|
|
|
|
|
+ (stock.getPalletCount() == null ? 0L : stock.getPalletCount()));
|
|
|
|
|
merged.getAreaStocks().add(buildAreaStock(stock));
|
|
|
|
|
if (merged.getRecentInTime() == null || stock.getRecentInTime() != null
|
|
|
|
|
&& stock.getRecentInTime().isAfter(merged.getRecentInTime())) {
|
|
|
|
|
merged.setRecentInTime(stock.getRecentInTime());
|
|
|
|
|
}
|
|
|
|
|
if (merged.getRecentOutTime() == null || stock.getRecentOutTime() != null
|
|
|
|
|
&& stock.getRecentOutTime().isAfter(merged.getRecentOutTime())) {
|
|
|
|
|
merged.setRecentOutTime(stock.getRecentOutTime());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
mergedMap.values().forEach(stock -> {
|
|
|
|
|
stock.setTotalBaseCount(stock.getCount());
|
|
|
|
|
stock.setTotalPackageCount(calculatePackageCount(stock, stock.getCount()));
|
|
|
|
|
stock.setPackagingRule(buildPackagingRule(stock));
|
|
|
|
|
stock.setStockDisplay(buildStockDisplay(stock));
|
|
|
|
|
});
|
|
|
|
|
return new ArrayList<>(mergedMap.values());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<ErpStockRespVO> paginateStockList(List<ErpStockRespVO> list, PageParam pageReqVO) {
|
|
|
|
|
if (CollUtil.isEmpty(list) || Objects.equals(pageReqVO.getPageSize(), PageParam.PAGE_SIZE_NONE)) {
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
int fromIndex = (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize();
|
|
|
|
|
if (fromIndex >= list.size()) {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
}
|
|
|
|
|
int toIndex = Math.min(fromIndex + pageReqVO.getPageSize(), list.size());
|
|
|
|
|
return list.subList(fromIndex, toIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockRespVO.AreaStock buildAreaStock(ErpStockRespVO stock) {
|
|
|
|
|
ErpStockRespVO.AreaStock areaStock = new ErpStockRespVO.AreaStock();
|
|
|
|
|
areaStock.setAreaId(stock.getAreaId());
|
|
|
|
|
areaStock.setAreaName(stock.getAreaName());
|
|
|
|
|
areaStock.setCount(defaultZero(stock.getCount()));
|
|
|
|
|
areaStock.setPackageCount(calculatePackageCount(stock, stock.getCount()));
|
|
|
|
|
areaStock.setBaseCount(calculateBaseCount(stock, stock.getCount()));
|
|
|
|
|
areaStock.setStockDisplay(buildAreaStockDisplay(stock, areaStock));
|
|
|
|
|
return areaStock;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String buildAreaStockDisplay(ErpStockRespVO stock, ErpStockRespVO.AreaStock areaStock) {
|
|
|
|
|
String prefix = areaStock.getAreaName() != null ? areaStock.getAreaName() + ":" : "";
|
|
|
|
|
String countDisplay = "(" + formatNumber(areaStock.getCount()) + nullToEmpty(stock.getUnitName()) + ")";
|
|
|
|
|
if (isProductType(stock.getCategoryType())) {
|
|
|
|
|
return prefix + formatNumber(areaStock.getPackageCount()) + "包"
|
|
|
|
|
+ formatNumber(areaStock.getBaseCount()) + stock.getUnitName() + countDisplay;
|
|
|
|
|
}
|
|
|
|
|
return prefix + formatNumber(areaStock.getPackageCount()) + nullToEmpty(stock.getPurchaseUnitName())
|
|
|
|
|
+ formatNumber(areaStock.getBaseCount()) + nullToEmpty(stock.getUnitName()) + countDisplay;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void fillRecentRecordTime(ErpStockRespVO stock) {
|
|
|
|
|
stock.setRecentInTime(stockRecordService.getLatestRecordTime(
|
|
|
|
|
stock.getProductId(), stock.getWarehouseId(), stock.getAreaId(), true));
|
|
|
|
|
@ -188,24 +267,32 @@ public class ErpStockController {
|
|
|
|
|
if (stock.getUnitId() == null) {
|
|
|
|
|
stock.setUnitId(product.getUnitId());
|
|
|
|
|
}
|
|
|
|
|
stock.setUnitName(product.getUnitName());
|
|
|
|
|
if (stock.getPurchaseUnitId() == null) {
|
|
|
|
|
stock.setPurchaseUnitId(product.getPurchaseUnitId());
|
|
|
|
|
}
|
|
|
|
|
if (stock.getPurchaseUnitName() == null) {
|
|
|
|
|
stock.setPurchaseUnitName(product.getPurchaseUnitName());
|
|
|
|
|
}
|
|
|
|
|
if (stock.getPurchaseUnitConvertQuantity() == null) {
|
|
|
|
|
stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity());
|
|
|
|
|
}
|
|
|
|
|
if (stock.getDefaultPackagingSchemeId() == null) {
|
|
|
|
|
stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId());
|
|
|
|
|
}
|
|
|
|
|
stock.setPurchaseUnitName(product.getPurchaseUnitName());
|
|
|
|
|
stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity());
|
|
|
|
|
stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId());
|
|
|
|
|
if (stock.getDefaultPackagingScheme() == null) {
|
|
|
|
|
stock.setDefaultPackagingScheme(findDefaultPackagingScheme(product));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void fillPackagingSnapshot(ErpStockRespVO stock, ErpProductRespVO product) {
|
|
|
|
|
if (isProductType(stock.getCategoryType())) {
|
|
|
|
|
ProductPackagingSchemeRespVO defaultScheme = findDefaultPackagingScheme(product);
|
|
|
|
|
if (defaultScheme == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
stock.setDefaultPackagingSchemeId(defaultScheme.getPackagingSchemeId());
|
|
|
|
|
stock.setDefaultPackagingScheme(defaultScheme);
|
|
|
|
|
stock.setDefaultPackagingSchemeName(defaultScheme.getPackagingSchemeName());
|
|
|
|
|
stock.setPackageQuantity(defaultScheme.getPackageQuantity());
|
|
|
|
|
stock.setPalletPackageQuantity(defaultScheme.getPalletPackageQuantity());
|
|
|
|
|
stock.setPalletTotalQuantity(defaultScheme.getPalletTotalQuantity());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (stock.getDefaultPackagingSchemeName() != null
|
|
|
|
|
&& stock.getPackageQuantity() != null
|
|
|
|
|
&& stock.getPalletPackageQuantity() != null
|
|
|
|
|
@ -273,9 +360,10 @@ public class ErpStockController {
|
|
|
|
|
if (stock.getPackageQuantity() == null || stock.getPackageQuantity().compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
return formatNumber(stock.getCount()) + stock.getUnitName();
|
|
|
|
|
}
|
|
|
|
|
BigDecimal packageCount = stock.getCount().divide(stock.getPackageQuantity(), 0, RoundingMode.CEILING);
|
|
|
|
|
BigDecimal packageCount = calculatePackageCount(stock, stock.getCount());
|
|
|
|
|
BigDecimal baseCount = calculateBaseCount(stock, stock.getCount());
|
|
|
|
|
return formatNumber(BigDecimal.valueOf(stock.getPalletCount() != null ? stock.getPalletCount() : 0L)) + "\u6258"
|
|
|
|
|
+ formatNumber(packageCount) + "\u5305" + formatNumber(stock.getCount()) + stock.getUnitName();
|
|
|
|
|
+ formatNumber(packageCount) + "\u5305" + formatNumber(baseCount) + stock.getUnitName();
|
|
|
|
|
}
|
|
|
|
|
if (stock.getPurchaseUnitConvertQuantity() == null || stock.getPurchaseUnitConvertQuantity().compareTo(BigDecimal.ZERO) <= 0
|
|
|
|
|
|| stock.getPurchaseUnitName() == null || stock.getUnitName() == null) {
|
|
|
|
|
@ -306,6 +394,37 @@ public class ErpStockController {
|
|
|
|
|
display.append(formatNumber(quantity)).append(unitName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal calculatePackageCount(ErpStockRespVO stock, BigDecimal count) {
|
|
|
|
|
BigDecimal convertQuantity = getDisplayConvertQuantity(stock);
|
|
|
|
|
if (convertQuantity == null || convertQuantity.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
return BigDecimal.ZERO;
|
|
|
|
|
}
|
|
|
|
|
return defaultZero(count).divideToIntegralValue(convertQuantity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal calculateBaseCount(ErpStockRespVO stock, BigDecimal count) {
|
|
|
|
|
BigDecimal convertQuantity = getDisplayConvertQuantity(stock);
|
|
|
|
|
if (convertQuantity == null || convertQuantity.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
return defaultZero(count);
|
|
|
|
|
}
|
|
|
|
|
return defaultZero(count).remainder(convertQuantity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal getDisplayConvertQuantity(ErpStockRespVO stock) {
|
|
|
|
|
if (isProductType(stock.getCategoryType())) {
|
|
|
|
|
return stock.getPackageQuantity();
|
|
|
|
|
}
|
|
|
|
|
return stock.getPurchaseUnitConvertQuantity();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal defaultZero(BigDecimal value) {
|
|
|
|
|
return value != null ? value : BigDecimal.ZERO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String nullToEmpty(String value) {
|
|
|
|
|
return value != null ? value : "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean isProductType(Integer categoryType) {
|
|
|
|
|
return Integer.valueOf(1).equals(categoryType);
|
|
|
|
|
}
|
|
|
|
|
@ -332,6 +451,10 @@ public class ErpStockController {
|
|
|
|
|
return String.valueOf(productId) + "_" + String.valueOf(warehouseId) + "_" + String.valueOf(areaId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String buildStockGroupKey(Long productId, Long warehouseId) {
|
|
|
|
|
return String.valueOf(productId) + "_" + String.valueOf(warehouseId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String formatNumber(BigDecimal value) {
|
|
|
|
|
return value == null ? "0" : value.stripTrailingZeros().toPlainString();
|
|
|
|
|
}
|
|
|
|
|
|