package cn.iocoder.yudao.module.mes.service.pro.cost; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; import cn.iocoder.yudao.module.mes.service.pro.cost.dto.MesProMaterialPriceRespDTO; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * MES 物料价格 Service 实现类 * * @author 超级管理员 */ @Service @Validated public class MesProMaterialPriceServiceImpl implements MesProMaterialPriceService { private static final String SOURCE_PURCHASE_PRICE = "PURCHASE_PRICE"; private static final String SOURCE_ERP_AVERAGE = "ERP_AVERAGE"; private static final String SOURCE_NONE = "NONE"; @Resource private MesMdItemService itemService; @Resource private MesMdmItemService mdmItemService; @Resource private ErpPurchaseOrderApi purchaseOrderApi; @Override public Map getMaterialPriceMap(Collection itemIds) { if (CollUtil.isEmpty(itemIds)) { return Collections.emptyMap(); } // 1. MES 物料 → MDM 物料 Map itemMap = itemService.getItemMap(itemIds); Set mdmItemIds = new HashSet<>(); for (MesMdItemDO item : itemMap.values()) { if (item.getMdmItemId() != null) { mdmItemIds.add(item.getMdmItemId()); } } Map mdmItemMap = mdmItemIds.isEmpty() ? Collections.emptyMap() : mdmItemService.getItemMap(mdmItemIds); // 2. 主数据没有采购价的,查已审核采购订单加权平均价 Set missingPriceMdmIds = new HashSet<>(); for (Long mdmItemId : mdmItemIds) { MesMdmItemDO mdmItem = mdmItemMap.get(mdmItemId); if (mdmItem == null || !isPositive(mdmItem.getPurchasePrice())) { missingPriceMdmIds.add(mdmItemId); } } Map averagePriceMap = missingPriceMdmIds.isEmpty() ? Collections.emptyMap() : purchaseOrderApi.getItemAveragePurchasePriceMap(missingPriceMdmIds).getCheckedData(); // 3. 组装结果 Map result = new HashMap<>(itemMap.size()); for (Long itemId : itemIds) { MesMdItemDO item = itemMap.get(itemId); MesMdmItemDO mdmItem = item != null && item.getMdmItemId() != null ? mdmItemMap.get(item.getMdmItemId()) : null; BigDecimal purchasePrice = mdmItem != null ? mdmItem.getPurchasePrice() : null; BigDecimal averagePrice = mdmItem != null ? averagePriceMap.get(mdmItem.getId()) : null; if (isPositive(purchasePrice)) { result.put(itemId, buildPrice(itemId, purchasePrice, SOURCE_PURCHASE_PRICE)); } else if (isPositive(averagePrice)) { result.put(itemId, buildPrice(itemId, averagePrice, SOURCE_ERP_AVERAGE)); } else { result.put(itemId, MesProMaterialPriceRespDTO.builder() .itemId(itemId).unitPrice(BigDecimal.ZERO) .source(SOURCE_NONE).priceMissing(true).build()); } } return result; } private static MesProMaterialPriceRespDTO buildPrice(Long itemId, BigDecimal price, String source) { return MesProMaterialPriceRespDTO.builder() .itemId(itemId) .unitPrice(price.setScale(6, RoundingMode.HALF_UP)) .source(source) .priceMissing(false) .build(); } private static boolean isPositive(BigDecimal value) { return value != null && value.compareTo(BigDecimal.ZERO) > 0; } }