提交基础采购

This commit is contained in:
2025-11-18 16:45:05 +08:00
parent cc9b1c0e92
commit 7c04e13198
77 changed files with 5733 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
package com.klp.erp.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.erp.domain.bo.ErpPurchaseOrderItemBo;
import com.klp.erp.domain.vo.ErpPurchaseOrderItemVo;
import java.util.Collection;
import java.util.List;
/**
* 采购订单明细Service接口
*/
public interface IErpPurchaseOrderItemService {
ErpPurchaseOrderItemVo queryById(Long itemId);
TableDataInfo<ErpPurchaseOrderItemVo> queryPageList(ErpPurchaseOrderItemBo bo, PageQuery pageQuery);
List<ErpPurchaseOrderItemVo> queryList(ErpPurchaseOrderItemBo bo);
Boolean insertByBo(ErpPurchaseOrderItemBo bo);
Boolean updateByBo(ErpPurchaseOrderItemBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,25 @@
package com.klp.erp.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.erp.domain.bo.ErpPurchaseReceiptBo;
import com.klp.erp.domain.vo.ErpPurchaseReceiptVo;
import java.util.Collection;
import java.util.List;
public interface IErpPurchaseReceiptService {
ErpPurchaseReceiptVo queryById(Long receiptId);
TableDataInfo<ErpPurchaseReceiptVo> queryPageList(ErpPurchaseReceiptBo bo, PageQuery pageQuery);
List<ErpPurchaseReceiptVo> queryList(ErpPurchaseReceiptBo bo);
Boolean insertByBo(ErpPurchaseReceiptBo bo);
Boolean updateByBo(ErpPurchaseReceiptBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,12 @@
package com.klp.erp.service;
import com.klp.erp.domain.bo.PurchaseRequirementAnalyzeBo;
import com.klp.erp.domain.vo.PurchaseRequirementVo;
import java.util.List;
public interface IErpPurchaseRequirementService {
List<PurchaseRequirementVo> analyze(PurchaseRequirementAnalyzeBo bo);
}

View File

@@ -0,0 +1,25 @@
package com.klp.erp.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.erp.domain.bo.ErpPurchaseReturnItemBo;
import com.klp.erp.domain.vo.ErpPurchaseReturnItemVo;
import java.util.Collection;
import java.util.List;
public interface IErpPurchaseReturnItemService {
ErpPurchaseReturnItemVo queryById(Long returnItemId);
TableDataInfo<ErpPurchaseReturnItemVo> queryPageList(ErpPurchaseReturnItemBo bo, PageQuery pageQuery);
List<ErpPurchaseReturnItemVo> queryList(ErpPurchaseReturnItemBo bo);
Boolean insertByBo(ErpPurchaseReturnItemBo bo);
Boolean updateByBo(ErpPurchaseReturnItemBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,25 @@
package com.klp.erp.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.erp.domain.bo.ErpPurchaseReturnBo;
import com.klp.erp.domain.vo.ErpPurchaseReturnVo;
import java.util.Collection;
import java.util.List;
public interface IErpPurchaseReturnService {
ErpPurchaseReturnVo queryById(Long returnId);
TableDataInfo<ErpPurchaseReturnVo> queryPageList(ErpPurchaseReturnBo bo, PageQuery pageQuery);
List<ErpPurchaseReturnVo> queryList(ErpPurchaseReturnBo bo);
Boolean insertByBo(ErpPurchaseReturnBo bo);
Boolean updateByBo(ErpPurchaseReturnBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,32 @@
package com.klp.erp.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.erp.domain.bo.ErpSupplierPriceBo;
import com.klp.erp.domain.bo.MaterialTypeQueryBo;
import com.klp.erp.domain.vo.ErpSupplierPriceVo;
import com.klp.erp.domain.vo.MaterialTypeOptionVo;
import java.util.Collection;
import java.util.List;
/**
* 供应商价格Service接口
*/
public interface IErpSupplierPriceService {
ErpSupplierPriceVo queryById(Long priceId);
TableDataInfo<ErpSupplierPriceVo> queryPageList(ErpSupplierPriceBo bo, PageQuery pageQuery);
List<ErpSupplierPriceVo> queryList(ErpSupplierPriceBo bo);
Boolean insertByBo(ErpSupplierPriceBo bo);
Boolean updateByBo(ErpSupplierPriceBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<MaterialTypeOptionVo> queryMaterialTypeOptions(MaterialTypeQueryBo bo);
}

View File

@@ -0,0 +1,28 @@
package com.klp.erp.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.erp.domain.bo.ErpSupplierBo;
import com.klp.erp.domain.vo.ErpSupplierVo;
import java.util.Collection;
import java.util.List;
/**
* 供应商档案Service接口
*/
public interface IErpSupplierService {
ErpSupplierVo queryById(Long supplierId);
TableDataInfo<ErpSupplierVo> queryPageList(ErpSupplierBo bo, PageQuery pageQuery);
List<ErpSupplierVo> queryList(ErpSupplierBo bo);
Boolean insertByBo(ErpSupplierBo bo);
Boolean updateByBo(ErpSupplierBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,83 @@
package com.klp.erp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.utils.StringUtils;
import com.klp.erp.domain.ErpPurchaseOrderItem;
import com.klp.erp.domain.bo.ErpPurchaseOrderItemBo;
import com.klp.erp.domain.vo.ErpPurchaseOrderItemVo;
import com.klp.erp.mapper.ErpPurchaseOrderItemMapper;
import com.klp.erp.service.IErpPurchaseOrderItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
@RequiredArgsConstructor
@Service
public class ErpPurchaseOrderItemServiceImpl implements IErpPurchaseOrderItemService {
private final ErpPurchaseOrderItemMapper baseMapper;
@Override
public ErpPurchaseOrderItemVo queryById(Long itemId) {
return baseMapper.selectVoById(itemId);
}
@Override
public TableDataInfo<ErpPurchaseOrderItemVo> queryPageList(ErpPurchaseOrderItemBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ErpPurchaseOrderItem> lqw = buildQueryWrapper(bo);
Page<ErpPurchaseOrderItemVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<ErpPurchaseOrderItemVo> queryList(ErpPurchaseOrderItemBo bo) {
LambdaQueryWrapper<ErpPurchaseOrderItem> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ErpPurchaseOrderItem> buildQueryWrapper(ErpPurchaseOrderItemBo bo) {
LambdaQueryWrapper<ErpPurchaseOrderItem> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getOrderId() != null, ErpPurchaseOrderItem::getOrderId, bo.getOrderId());
lqw.like(StringUtils.isNotBlank(bo.getMaterialTypeCode()), ErpPurchaseOrderItem::getMaterialTypeCode, bo.getMaterialTypeCode());
lqw.like(StringUtils.isNotBlank(bo.getSpecification()), ErpPurchaseOrderItem::getSpecification, bo.getSpecification());
return lqw;
}
@Override
public Boolean insertByBo(ErpPurchaseOrderItemBo bo) {
ErpPurchaseOrderItem add = BeanUtil.toBean(bo, ErpPurchaseOrderItem.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setItemId(add.getItemId());
}
return flag;
}
@Override
public Boolean updateByBo(ErpPurchaseOrderItemBo bo) {
ErpPurchaseOrderItem update = BeanUtil.toBean(bo, ErpPurchaseOrderItem.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
private void validEntityBeforeSave(ErpPurchaseOrderItem entity) {
// TODO: 数量/金额校验
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO: 删除校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,135 @@
package com.klp.erp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.exception.ServiceException;
import com.klp.erp.domain.ErpPurchaseOrderItem;
import com.klp.erp.domain.ErpPurchaseReceipt;
import com.klp.erp.domain.bo.ErpPurchaseReceiptBo;
import com.klp.erp.domain.vo.ErpPurchaseReceiptVo;
import com.klp.erp.mapper.ErpPurchaseOrderItemMapper;
import com.klp.erp.mapper.ErpPurchaseReceiptMapper;
import com.klp.erp.service.IErpPurchaseOrderService;
import com.klp.erp.service.IErpPurchaseReceiptService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
@RequiredArgsConstructor
public class ErpPurchaseReceiptServiceImpl implements IErpPurchaseReceiptService {
private final ErpPurchaseReceiptMapper baseMapper;
private final ErpPurchaseOrderItemMapper orderItemMapper;
private final IErpPurchaseOrderService orderService;
@Override
public ErpPurchaseReceiptVo queryById(Long receiptId) {
return baseMapper.selectVoById(receiptId);
}
@Override
public TableDataInfo<ErpPurchaseReceiptVo> queryPageList(ErpPurchaseReceiptBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ErpPurchaseReceipt> lqw = buildQueryWrapper(bo);
Page<ErpPurchaseReceiptVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<ErpPurchaseReceiptVo> queryList(ErpPurchaseReceiptBo bo) {
LambdaQueryWrapper<ErpPurchaseReceipt> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ErpPurchaseReceipt> buildQueryWrapper(ErpPurchaseReceiptBo bo) {
LambdaQueryWrapper<ErpPurchaseReceipt> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getOrderId() != null, ErpPurchaseReceipt::getOrderId, bo.getOrderId());
lqw.eq(bo.getItemId() != null, ErpPurchaseReceipt::getItemId, bo.getItemId());
return lqw;
}
@Override
public Boolean insertByBo(ErpPurchaseReceiptBo bo) {
ErpPurchaseReceipt add = BeanUtil.toBean(bo, ErpPurchaseReceipt.class);
validateReceiptQuantity(null, bo);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setReceiptId(add.getReceiptId());
if (isQualified(bo.getQualityResult())) {
orderService.refreshOrderStatus(bo.getOrderId());
}
}
return flag;
}
@Override
public Boolean updateByBo(ErpPurchaseReceiptBo bo) {
ErpPurchaseReceipt origin = baseMapper.selectById(bo.getReceiptId());
if (origin == null) {
throw new ServiceException("收货记录不存在");
}
ErpPurchaseReceipt update = BeanUtil.toBean(bo, ErpPurchaseReceipt.class);
validateReceiptQuantity(origin, bo);
boolean flag = baseMapper.updateById(update) > 0;
if (flag) {
orderService.refreshOrderStatus(origin.getOrderId());
}
return flag;
}
private void validateReceiptQuantity(ErpPurchaseReceipt origin, ErpPurchaseReceiptBo bo) {
ErpPurchaseOrderItem item = orderItemMapper.selectById(bo.getItemId());
if (item == null) {
throw new ServiceException("订单明细不存在");
}
if (!item.getOrderId().equals(bo.getOrderId())) {
throw new ServiceException("订单与明细不匹配");
}
BigDecimal ordered = safe(item.getQuantity());
BigDecimal existingQualified = safe(baseMapper.sumQualifiedQtyByItem(bo.getItemId()));
BigDecimal originQualified = origin != null && isQualified(origin.getQualityResult())
? safe(origin.getReceivedQty()) : BigDecimal.ZERO;
BigDecimal newQualified = isQualified(bo.getQualityResult()) ? safe(bo.getReceivedQty()) : BigDecimal.ZERO;
BigDecimal effective = existingQualified.subtract(originQualified).add(newQualified);
if (effective.compareTo(ordered) > 0) {
throw new ServiceException("收货数量不能超过订单明细数量");
}
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
List<ErpPurchaseReceipt> receipts = baseMapper.selectBatchIds(ids);
boolean flag = baseMapper.deleteBatchIds(ids) > 0;
if (flag && receipts != null && !receipts.isEmpty()) {
Set<Long> orderIds = new HashSet<>();
for (ErpPurchaseReceipt receipt : receipts) {
orderIds.add(receipt.getOrderId());
}
orderIds.forEach(orderService::refreshOrderStatus);
}
return flag;
}
private boolean isQualified(String qualityResult) {
if (qualityResult == null) {
return true;
}
String upper = qualityResult.trim().toUpperCase();
return !"NG".equals(upper) && !"不合格".equals(qualityResult.trim());
}
private BigDecimal safe(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
}

View File

@@ -0,0 +1,235 @@
package com.klp.erp.service.impl;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.klp.domain.WmsProduct;
import com.klp.domain.WmsRawMaterial;
import com.klp.erp.domain.ErpPurchaseRequirement;
import com.klp.erp.domain.bo.PurchaseRequirementAnalyzeBo;
import com.klp.erp.domain.bo.PurchaseRequirementMappingBo;
import com.klp.erp.domain.dto.ProductDemandDTO;
import com.klp.erp.domain.dto.ProductStockDTO;
import com.klp.erp.domain.dto.RawStockDTO;
import com.klp.erp.domain.dto.RawTransitDTO;
import com.klp.erp.domain.vo.PurchaseRequirementRawDetailVo;
import com.klp.erp.domain.vo.PurchaseRequirementVo;
import com.klp.erp.mapper.ErpPurchaseRequirementMapper;
import com.klp.erp.mapper.PurchaseRequirementCalcMapper;
import com.klp.erp.service.IErpPurchaseRequirementService;
import com.klp.mapper.WmsProductMapper;
import com.klp.mapper.WmsRawMaterialMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@RequiredArgsConstructor
public class ErpPurchaseRequirementServiceImpl implements IErpPurchaseRequirementService {
private static final BigDecimal ZERO = BigDecimal.ZERO;
private final PurchaseRequirementCalcMapper calcMapper;
private final ErpPurchaseRequirementMapper requirementMapper;
private final WmsProductMapper productMapper;
private final WmsRawMaterialMapper rawMaterialMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public List<PurchaseRequirementVo> analyze(PurchaseRequirementAnalyzeBo bo) {
Map<Long, List<PurchaseRequirementMappingBo>> mappingByProduct = bo.getMappings()
.stream()
.collect(Collectors.groupingBy(PurchaseRequirementMappingBo::getProductId));
Set<Long> productIds = new HashSet<>(mappingByProduct.keySet());
Set<Long> rawIds = bo.getMappings().stream().map(PurchaseRequirementMappingBo::getRawMaterialId).collect(Collectors.toSet());
Map<Long, BigDecimal> demandMap = toBigDecimalMap(streamOf(calcMapper.selectProductDemand()),
ProductDemandDTO::getProductId, ProductDemandDTO::getDemandQuantity);
productIds.addAll(demandMap.keySet());
Map<Long, ProductStockDTO> productStockMap = streamOf(calcMapper.selectProductStock())
.collect(Collectors.toMap(ProductStockDTO::getProductId, Function.identity(), (a, b) -> a));
Map<Long, RawStockDTO> rawStockMap = streamOf(calcMapper.selectRawStock())
.collect(Collectors.toMap(RawStockDTO::getRawMaterialId, Function.identity(), (a, b) -> a));
Map<Long, BigDecimal> rawInTransitMap = toBigDecimalMap(streamOf(calcMapper.selectRawInTransit()),
RawTransitDTO::getRawMaterialId, RawTransitDTO::getQuantity);
Map<Long, BigDecimal> rawPendingMap = toBigDecimalMap(streamOf(calcMapper.selectRawPending()),
RawTransitDTO::getRawMaterialId, RawTransitDTO::getQuantity);
Map<Long, WmsProduct> productInfoMap = loadProducts(productIds);
Map<Long, WmsRawMaterial> rawInfoMap = loadRawMaterials(rawIds);
List<PurchaseRequirementVo> result = productIds.stream()
.sorted()
.map(productId -> buildRequirement(productId,
mappingByProduct.getOrDefault(productId, Collections.emptyList()),
demandMap,
productStockMap,
rawStockMap,
rawInTransitMap,
rawPendingMap,
productInfoMap,
rawInfoMap))
.collect(Collectors.toList());
if (Boolean.TRUE.equals(bo.getPersistResult())) {
persistRequirements(result);
}
return result;
}
private PurchaseRequirementVo buildRequirement(Long productId,
List<PurchaseRequirementMappingBo> mappings,
Map<Long, BigDecimal> demandMap,
Map<Long, ProductStockDTO> productStockMap,
Map<Long, RawStockDTO> rawStockMap,
Map<Long, BigDecimal> rawInTransitMap,
Map<Long, BigDecimal> rawPendingMap,
Map<Long, WmsProduct> productInfoMap,
Map<Long, WmsRawMaterial> rawInfoMap) {
PurchaseRequirementVo vo = new PurchaseRequirementVo();
vo.setProductId(productId);
WmsProduct product = productInfoMap.get(productId);
if (product != null) {
vo.setProductCode(product.getProductCode());
vo.setProductName(product.getProductName());
vo.setSpecification(product.getSpecification());
}
vo.setSalesDemand(safeNumber(demandMap.get(productId)));
ProductStockDTO stockDTO = productStockMap.get(productId);
if (stockDTO != null) {
vo.setProductStockWeight(safeNumber(stockDTO.getTotalWeight()));
vo.setProductStockCoilCount(Optional.ofNullable(stockDTO.getCoilCount()).orElse(0L));
}
BigDecimal rawStockWeightSum = ZERO;
long rawCoilCountSum = 0L;
BigDecimal rawStockConvertedSum = ZERO;
BigDecimal inTransitWeightSum = ZERO;
BigDecimal inTransitConvertedSum = ZERO;
BigDecimal pendingWeightSum = ZERO;
BigDecimal pendingConvertedSum = ZERO;
for (PurchaseRequirementMappingBo mapping : mappings) {
WmsRawMaterial rawMaterial = rawInfoMap.get(mapping.getRawMaterialId());
if (rawMaterial == null) {
continue;
}
PurchaseRequirementRawDetailVo detail = new PurchaseRequirementRawDetailVo();
detail.setRawMaterialId(rawMaterial.getRawMaterialId());
detail.setRawMaterialCode(rawMaterial.getRawMaterialCode());
detail.setRawMaterialName(rawMaterial.getRawMaterialName());
detail.setConversionRate(mapping.getConversionRate());
RawStockDTO rawStock = rawStockMap.get(rawMaterial.getRawMaterialId());
BigDecimal stockWeight = rawStock == null ? ZERO : safeNumber(rawStock.getTotalWeight());
long stockCoilCount = rawStock == null ? 0L : Optional.ofNullable(rawStock.getCoilCount()).orElse(0L);
BigDecimal convertedStock = stockWeight.multiply(mapping.getConversionRate()).setScale(4, RoundingMode.HALF_UP);
BigDecimal inTransitWeight = safeNumber(rawInTransitMap.get(rawMaterial.getRawMaterialId()));
BigDecimal convertedTransit = inTransitWeight.multiply(mapping.getConversionRate()).setScale(4, RoundingMode.HALF_UP);
BigDecimal pendingWeight = safeNumber(rawPendingMap.get(rawMaterial.getRawMaterialId()));
BigDecimal convertedPending = pendingWeight.multiply(mapping.getConversionRate()).setScale(4, RoundingMode.HALF_UP);
detail.setStockWeight(stockWeight);
detail.setStockCoilCount(stockCoilCount);
detail.setConvertedStock(convertedStock);
detail.setInTransitWeight(inTransitWeight);
detail.setConvertedInTransit(convertedTransit);
detail.setPendingWeight(pendingWeight);
detail.setConvertedPending(convertedPending);
vo.getRawDetails().add(detail);
rawStockWeightSum = rawStockWeightSum.add(stockWeight);
rawCoilCountSum += stockCoilCount;
rawStockConvertedSum = rawStockConvertedSum.add(convertedStock);
inTransitWeightSum = inTransitWeightSum.add(inTransitWeight);
inTransitConvertedSum = inTransitConvertedSum.add(convertedTransit);
pendingWeightSum = pendingWeightSum.add(pendingWeight);
pendingConvertedSum = pendingConvertedSum.add(convertedPending);
}
vo.setRawStockWeight(rawStockWeightSum);
vo.setRawStockCoilCount(rawCoilCountSum);
vo.setRawStockConverted(rawStockConvertedSum);
vo.setInTransitWeight(inTransitWeightSum);
vo.setInTransitConverted(inTransitConvertedSum);
vo.setPendingWeight(pendingWeightSum);
vo.setPendingConverted(pendingConvertedSum);
BigDecimal suggestion = vo.getSalesDemand()
.subtract(vo.getProductStockWeight())
.subtract(vo.getRawStockConverted())
.subtract(vo.getInTransitConverted())
.subtract(vo.getPendingConverted());
if (suggestion.signum() < 0) {
suggestion = ZERO;
}
vo.setSuggestedPurchase(suggestion.setScale(4, RoundingMode.HALF_UP));
return vo;
}
private <T> Stream<T> streamOf(List<T> list) {
return list == null ? Stream.empty() : list.stream();
}
private BigDecimal safeNumber(BigDecimal value) {
return value == null ? ZERO : value;
}
private Map<Long, WmsProduct> loadProducts(Set<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
return Collections.emptyMap();
}
List<WmsProduct> list = productMapper.selectBatchIds(new ArrayList<>(ids));
return list == null ? Collections.emptyMap() : list.stream()
.collect(Collectors.toMap(WmsProduct::getProductId, Function.identity(), (a, b) -> a));
}
private Map<Long, WmsRawMaterial> loadRawMaterials(Set<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
return Collections.emptyMap();
}
List<WmsRawMaterial> list = rawMaterialMapper.selectBatchIds(new ArrayList<>(ids));
return list == null ? Collections.emptyMap() : list.stream()
.collect(Collectors.toMap(WmsRawMaterial::getRawMaterialId, Function.identity(), (a, b) -> a));
}
private void persistRequirements(List<PurchaseRequirementVo> vos) {
requirementMapper.deleteAll();
for (PurchaseRequirementVo vo : vos) {
ErpPurchaseRequirement entity = new ErpPurchaseRequirement();
entity.setMaterialTypeCode(vo.getProductCode());
entity.setSpecification(vo.getSpecification());
entity.setSalesDemand(vo.getSalesDemand());
entity.setProductStock(vo.getProductStockWeight());
entity.setRawStock(vo.getRawStockWeight());
entity.setRawStockConv(vo.getRawStockConverted());
entity.setOnTheWay(vo.getInTransitWeight());
entity.setOnTheWayConv(vo.getInTransitConverted());
entity.setSuggestPurchaseQty(vo.getSuggestedPurchase());
entity.setRemark("自动分析");
requirementMapper.insert(entity);
}
}
private <T> Map<Long, BigDecimal> toBigDecimalMap(Stream<T> stream,
Function<T, Long> keyExtractor,
Function<T, BigDecimal> valueExtractor) {
return stream == null ? Collections.emptyMap()
: stream.filter(Objects::nonNull)
.collect(Collectors.toMap(keyExtractor, valueExtractor, BigDecimal::add));
}
}

View File

@@ -0,0 +1,134 @@
package com.klp.erp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.exception.ServiceException;
import com.klp.erp.domain.ErpPurchaseReturn;
import com.klp.erp.domain.ErpPurchaseReturnItem;
import com.klp.erp.domain.bo.ErpPurchaseReturnItemBo;
import com.klp.erp.domain.vo.ErpPurchaseReturnItemVo;
import com.klp.erp.mapper.ErpPurchaseReceiptMapper;
import com.klp.erp.mapper.ErpPurchaseReturnItemMapper;
import com.klp.erp.mapper.ErpPurchaseReturnMapper;
import com.klp.erp.service.IErpPurchaseOrderService;
import com.klp.erp.service.IErpPurchaseReturnItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
@RequiredArgsConstructor
public class ErpPurchaseReturnItemServiceImpl implements IErpPurchaseReturnItemService {
private final ErpPurchaseReturnItemMapper baseMapper;
private final ErpPurchaseReceiptMapper receiptMapper;
private final ErpPurchaseReturnMapper returnMapper;
private final IErpPurchaseOrderService orderService;
@Override
public ErpPurchaseReturnItemVo queryById(Long returnItemId) {
return baseMapper.selectVoById(returnItemId);
}
@Override
public TableDataInfo<ErpPurchaseReturnItemVo> queryPageList(ErpPurchaseReturnItemBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ErpPurchaseReturnItem> lqw = buildQueryWrapper(bo);
Page<ErpPurchaseReturnItemVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<ErpPurchaseReturnItemVo> queryList(ErpPurchaseReturnItemBo bo) {
LambdaQueryWrapper<ErpPurchaseReturnItem> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ErpPurchaseReturnItem> buildQueryWrapper(ErpPurchaseReturnItemBo bo) {
LambdaQueryWrapper<ErpPurchaseReturnItem> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getReturnId() != null, ErpPurchaseReturnItem::getReturnId, bo.getReturnId());
lqw.eq(bo.getItemId() != null, ErpPurchaseReturnItem::getItemId, bo.getItemId());
return lqw;
}
@Override
public Boolean insertByBo(ErpPurchaseReturnItemBo bo) {
ErpPurchaseReturnItem add = BeanUtil.toBean(bo, ErpPurchaseReturnItem.class);
validateReturnQuantity(null, bo);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setReturnItemId(add.getReturnItemId());
Long orderId = resolveOrderId(add.getReturnId());
if (orderId != null) {
orderService.refreshOrderStatus(orderId);
}
}
return flag;
}
@Override
public Boolean updateByBo(ErpPurchaseReturnItemBo bo) {
ErpPurchaseReturnItem origin = baseMapper.selectById(bo.getReturnItemId());
if (origin == null) {
return false;
}
ErpPurchaseReturnItem update = BeanUtil.toBean(bo, ErpPurchaseReturnItem.class);
validateReturnQuantity(origin, bo);
boolean flag = baseMapper.updateById(update) > 0;
if (flag) {
Long orderId = resolveOrderId(update.getReturnId());
if (orderId != null) {
orderService.refreshOrderStatus(orderId);
}
}
return flag;
}
private void validateReturnQuantity(ErpPurchaseReturnItem origin, ErpPurchaseReturnItemBo bo) {
BigDecimal received = safe(receiptMapper.sumQualifiedQtyByItem(bo.getItemId()));
BigDecimal existing = safe(baseMapper.sumAllReturnQtyByItem(bo.getItemId()));
BigDecimal originQty = origin == null ? BigDecimal.ZERO : safe(origin.getReturnQty());
BigDecimal effective = existing.subtract(originQty).add(safe(bo.getReturnQty()));
if (effective.compareTo(received) > 0) {
throw new ServiceException("退货数量不能超过已收货数量");
}
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
List<ErpPurchaseReturnItem> items = baseMapper.selectBatchIds(ids);
boolean flag = baseMapper.deleteBatchIds(ids) > 0;
if (flag && items != null && !items.isEmpty()) {
Set<Long> orderIds = new HashSet<>();
for (ErpPurchaseReturnItem item : items) {
Long orderId = resolveOrderId(item.getReturnId());
if (orderId != null) {
orderIds.add(orderId);
}
}
orderIds.forEach(orderService::refreshOrderStatus);
}
return flag;
}
private Long resolveOrderId(Long returnId) {
if (returnId == null) {
return null;
}
ErpPurchaseReturn purchaseReturn = returnMapper.selectById(returnId);
return purchaseReturn == null ? null : purchaseReturn.getOrderId();
}
private BigDecimal safe(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
}

View File

@@ -0,0 +1,92 @@
package com.klp.erp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.erp.domain.ErpPurchaseReturn;
import com.klp.erp.domain.bo.ErpPurchaseReturnBo;
import com.klp.erp.domain.vo.ErpPurchaseReturnVo;
import com.klp.erp.mapper.ErpPurchaseReturnMapper;
import com.klp.erp.service.IErpPurchaseOrderService;
import com.klp.erp.service.IErpPurchaseReturnService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
@Service
@RequiredArgsConstructor
public class ErpPurchaseReturnServiceImpl implements IErpPurchaseReturnService {
private final ErpPurchaseReturnMapper baseMapper;
private final IErpPurchaseOrderService orderService;
@Override
public ErpPurchaseReturnVo queryById(Long returnId) {
return baseMapper.selectVoById(returnId);
}
@Override
public TableDataInfo<ErpPurchaseReturnVo> queryPageList(ErpPurchaseReturnBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ErpPurchaseReturn> lqw = buildQueryWrapper(bo);
Page<ErpPurchaseReturnVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<ErpPurchaseReturnVo> queryList(ErpPurchaseReturnBo bo) {
LambdaQueryWrapper<ErpPurchaseReturn> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ErpPurchaseReturn> buildQueryWrapper(ErpPurchaseReturnBo bo) {
LambdaQueryWrapper<ErpPurchaseReturn> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getOrderId() != null, ErpPurchaseReturn::getOrderId, bo.getOrderId());
lqw.eq(bo.getStatus() != null, ErpPurchaseReturn::getStatus, bo.getStatus());
return lqw;
}
@Override
public Boolean insertByBo(ErpPurchaseReturnBo bo) {
ErpPurchaseReturn add = BeanUtil.toBean(bo, ErpPurchaseReturn.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setReturnId(add.getReturnId());
if (Objects.equals(add.getStatus(), 1)) {
orderService.refreshOrderStatus(add.getOrderId());
}
}
return flag;
}
@Override
public Boolean updateByBo(ErpPurchaseReturnBo bo) {
ErpPurchaseReturn update = BeanUtil.toBean(bo, ErpPurchaseReturn.class);
validEntityBeforeSave(update);
boolean flag = baseMapper.updateById(update) > 0;
if (flag && Objects.equals(update.getStatus(), 1)) {
orderService.refreshOrderStatus(update.getOrderId());
}
return flag;
}
private void validEntityBeforeSave(ErpPurchaseReturn entity) {
// TODO: 校验退货状态流转
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO: 校验是否允许删除
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,90 @@
package com.klp.erp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.utils.StringUtils;
import com.klp.erp.domain.ErpSupplierPrice;
import com.klp.erp.domain.bo.ErpSupplierPriceBo;
import com.klp.erp.domain.bo.MaterialTypeQueryBo;
import com.klp.erp.domain.vo.ErpSupplierPriceVo;
import com.klp.erp.domain.vo.MaterialTypeOptionVo;
import com.klp.erp.mapper.ErpSupplierPriceMapper;
import com.klp.erp.service.IErpSupplierPriceService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
@RequiredArgsConstructor
@Service
public class ErpSupplierPriceServiceImpl implements IErpSupplierPriceService {
private final ErpSupplierPriceMapper baseMapper;
@Override
public ErpSupplierPriceVo queryById(Long priceId) {
return baseMapper.selectVoById(priceId);
}
@Override
public TableDataInfo<ErpSupplierPriceVo> queryPageList(ErpSupplierPriceBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ErpSupplierPrice> lqw = buildQueryWrapper(bo);
Page<ErpSupplierPriceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<ErpSupplierPriceVo> queryList(ErpSupplierPriceBo bo) {
LambdaQueryWrapper<ErpSupplierPrice> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ErpSupplierPrice> buildQueryWrapper(ErpSupplierPriceBo bo) {
LambdaQueryWrapper<ErpSupplierPrice> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getSupplierId() != null, ErpSupplierPrice::getSupplierId, bo.getSupplierId());
lqw.like(StringUtils.isNotBlank(bo.getMaterialTypeCode()), ErpSupplierPrice::getMaterialTypeCode, bo.getMaterialTypeCode());
lqw.like(StringUtils.isNotBlank(bo.getSpecification()), ErpSupplierPrice::getSpecification, bo.getSpecification());
return lqw;
}
@Override
public Boolean insertByBo(ErpSupplierPriceBo bo) {
ErpSupplierPrice add = BeanUtil.toBean(bo, ErpSupplierPrice.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setPriceId(add.getPriceId());
}
return flag;
}
@Override
public Boolean updateByBo(ErpSupplierPriceBo bo) {
ErpSupplierPrice update = BeanUtil.toBean(bo, ErpSupplierPrice.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
private void validEntityBeforeSave(ErpSupplierPrice entity) {
// TODO: 唯一性/有效期校验
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO: 删除前校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public List<MaterialTypeOptionVo> queryMaterialTypeOptions(MaterialTypeQueryBo bo) {
return baseMapper.selectMaterialTypeOptions(bo);
}
}

View File

@@ -0,0 +1,84 @@
package com.klp.erp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.utils.StringUtils;
import com.klp.erp.domain.ErpSupplier;
import com.klp.erp.domain.bo.ErpSupplierBo;
import com.klp.erp.domain.vo.ErpSupplierVo;
import com.klp.erp.mapper.ErpSupplierMapper;
import com.klp.erp.service.IErpSupplierService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
@RequiredArgsConstructor
@Service
public class ErpSupplierServiceImpl implements IErpSupplierService {
private final ErpSupplierMapper baseMapper;
@Override
public ErpSupplierVo queryById(Long supplierId) {
return baseMapper.selectVoById(supplierId);
}
@Override
public TableDataInfo<ErpSupplierVo> queryPageList(ErpSupplierBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ErpSupplier> lqw = buildQueryWrapper(bo);
Page<ErpSupplierVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<ErpSupplierVo> queryList(ErpSupplierBo bo) {
LambdaQueryWrapper<ErpSupplier> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ErpSupplier> buildQueryWrapper(ErpSupplierBo bo) {
LambdaQueryWrapper<ErpSupplier> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getSupplierCode()), ErpSupplier::getSupplierCode, bo.getSupplierCode());
lqw.like(StringUtils.isNotBlank(bo.getName()), ErpSupplier::getName, bo.getName());
lqw.eq(StringUtils.isNotBlank(bo.getType()), ErpSupplier::getType, bo.getType());
lqw.eq(StringUtils.isNotBlank(bo.getCreditRating()), ErpSupplier::getCreditRating, bo.getCreditRating());
return lqw;
}
@Override
public Boolean insertByBo(ErpSupplierBo bo) {
ErpSupplier add = BeanUtil.toBean(bo, ErpSupplier.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setSupplierId(add.getSupplierId());
}
return flag;
}
@Override
public Boolean updateByBo(ErpSupplierBo bo) {
ErpSupplier update = BeanUtil.toBean(bo, ErpSupplier.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
private void validEntityBeforeSave(ErpSupplier entity) {
// TODO: 唯一性校验
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO: 删除校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}