| | |
| | | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemUpdateReqDTO; |
| | | import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | |
| | | /** |
| | | * ERP 产品 Service 实现类 |
| | | * |
| | | * 改造说明:产品数据统一使用 MDM 主数据管理(itemType=2 产品类型) |
| | | * - 创建、更新、删除操作通过 MDM API 进行 |
| | | * - 查询操作从 MDM 获取数据 |
| | | * |
| | | * @author 芋道源码 |
| | | */ |
| | | @Service |
| | |
| | | private ErpProductMapper productMapper; |
| | | |
| | | @Resource |
| | | private ErpProductCategoryService productCategoryService; |
| | | @Resource |
| | | private ErpProductUnitService productUnitService; |
| | | private MdmItemApi mdmItemApi; |
| | | |
| | | @Override |
| | | public Long createProduct(ProductSaveReqVO createReqVO) { |
| | | // TODO 芋艿:校验分类 |
| | | // 插入 |
| | | ErpProductDO product = BeanUtils.toBean(createReqVO, ErpProductDO.class); |
| | | productMapper.insert(product); |
| | | // 返回 |
| | | return product.getId(); |
| | | // 1. 校验条码是否重复 |
| | | MdmItemRespDTO existItem = mdmItemApi.getItemByBarCode(createReqVO.getBarCode()).getCheckedData(); |
| | | if (existItem != null) { |
| | | throw exception(PRODUCT_BAR_CODE_EXISTS); |
| | | } |
| | | // 2. 通过 MDM API 创建产品 |
| | | MdmItemCreateReqDTO createReqDTO = new MdmItemCreateReqDTO(); |
| | | createReqDTO.setCode(createReqVO.getBarCode()); // 使用条码作为编码 |
| | | createReqDTO.setName(createReqVO.getName()); |
| | | createReqDTO.setBarCode(createReqVO.getBarCode()); |
| | | createReqDTO.setSpecification(createReqVO.getStandard()); |
| | | createReqDTO.setCategoryId(createReqVO.getCategoryId()); |
| | | createReqDTO.setUnitMeasureId(createReqVO.getUnitId()); |
| | | createReqDTO.setItemType(MdmItemTypeEnum.PRODUCT.getType()); // 产品类型 |
| | | createReqDTO.setStatus(createReqVO.getStatus() != null ? createReqVO.getStatus() : CommonStatusEnum.ENABLE.getStatus()); |
| | | createReqDTO.setPurchasePrice(createReqVO.getPurchasePrice()); |
| | | createReqDTO.setSalesPrice(createReqVO.getSalePrice()); |
| | | createReqDTO.setCostPrice(createReqVO.getMinPrice()); |
| | | createReqDTO.setExpiryDay(createReqVO.getExpiryDay()); |
| | | createReqDTO.setWeight(createReqVO.getWeight()); |
| | | createReqDTO.setRemark(createReqVO.getRemark()); |
| | | return mdmItemApi.createItem(createReqDTO).getCheckedData(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateProduct(ProductSaveReqVO updateReqVO) { |
| | | // TODO 芋艿:校验分类 |
| | | // 校验存在 |
| | | validateProductExists(updateReqVO.getId()); |
| | | // 更新 |
| | | ErpProductDO updateObj = BeanUtils.toBean(updateReqVO, ErpProductDO.class); |
| | | productMapper.updateById(updateObj); |
| | | // 1. 校验存在 |
| | | MdmItemRespDTO existItem = mdmItemApi.getItem(updateReqVO.getId()).getCheckedData(); |
| | | if (existItem == null) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | // 2. 校验条码是否重复 |
| | | if (!existItem.getBarCode().equals(updateReqVO.getBarCode())) { |
| | | MdmItemRespDTO barCodeItem = mdmItemApi.getItemByBarCode(updateReqVO.getBarCode()).getCheckedData(); |
| | | if (barCodeItem != null) { |
| | | throw exception(PRODUCT_BAR_CODE_EXISTS); |
| | | } |
| | | } |
| | | // 3. 通过 MDM API 更新产品 |
| | | MdmItemUpdateReqDTO updateReqDTO = new MdmItemUpdateReqDTO(); |
| | | updateReqDTO.setId(updateReqVO.getId()); |
| | | updateReqDTO.setCode(updateReqVO.getBarCode()); |
| | | updateReqDTO.setName(updateReqVO.getName()); |
| | | updateReqDTO.setBarCode(updateReqVO.getBarCode()); |
| | | updateReqDTO.setSpecification(updateReqVO.getStandard()); |
| | | updateReqDTO.setCategoryId(updateReqVO.getCategoryId()); |
| | | updateReqDTO.setUnitMeasureId(updateReqVO.getUnitId()); |
| | | updateReqDTO.setItemType(MdmItemTypeEnum.PRODUCT.getType()); |
| | | updateReqDTO.setStatus(updateReqVO.getStatus()); |
| | | updateReqDTO.setPurchasePrice(updateReqVO.getPurchasePrice()); |
| | | updateReqDTO.setSalesPrice(updateReqVO.getSalePrice()); |
| | | updateReqDTO.setCostPrice(updateReqVO.getMinPrice()); |
| | | updateReqDTO.setExpiryDay(updateReqVO.getExpiryDay()); |
| | | updateReqDTO.setWeight(updateReqVO.getWeight()); |
| | | updateReqDTO.setRemark(updateReqVO.getRemark()); |
| | | mdmItemApi.updateItem(updateReqDTO); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteProduct(Long id) { |
| | | // 校验存在 |
| | | validateProductExists(id); |
| | | // 删除 |
| | | productMapper.deleteById(id); |
| | | MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); |
| | | if (item == null) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | // 通过 MDM API 删除(更新状态为禁用) |
| | | mdmItemApi.updateItemStatus(id, CommonStatusEnum.DISABLE.getStatus()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<ErpProductDO> list = productMapper.selectByIds(ids); |
| | | Map<Long, ErpProductDO> productMap = convertMap(list, ErpProductDO::getId); |
| | | // 从 MDM 获取产品数据 |
| | | List<MdmItemRespDTO> items = mdmItemApi.getItemList(ids).getCheckedData(); |
| | | Map<Long, MdmItemRespDTO> itemMap = convertMap(items, MdmItemRespDTO::getId); |
| | | List<ErpProductDO> result = new ArrayList<>(); |
| | | for (Long id : ids) { |
| | | ErpProductDO product = productMap.get(id); |
| | | if (productMap.get(id) == null) { |
| | | MdmItemRespDTO item = itemMap.get(id); |
| | | if (item == null) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | if (CommonStatusEnum.isDisable(product.getStatus())) { |
| | | throw exception(PRODUCT_NOT_ENABLE, product.getName()); |
| | | if (CommonStatusEnum.isDisable(item.getStatus())) { |
| | | throw exception(PRODUCT_NOT_ENABLE, item.getName()); |
| | | } |
| | | // 转换为 ErpProductDO |
| | | result.add(convertToErpProduct(item)); |
| | | } |
| | | return list; |
| | | return result; |
| | | } |
| | | |
| | | private void validateProductExists(Long id) { |
| | | if (productMapper.selectById(id) == null) { |
| | | // 从 MDM 校验 |
| | | MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); |
| | | if (item == null) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public ErpProductDO getProduct(Long id) { |
| | | return productMapper.selectById(id); |
| | | // 从 MDM 获取产品数据 |
| | | MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); |
| | | if (item == null) { |
| | | return null; |
| | | } |
| | | // 检查是否为产品类型 |
| | | if (!MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) { |
| | | return null; |
| | | } |
| | | return convertToErpProduct(item); |
| | | } |
| | | |
| | | @Override |
| | | public ErpProductRespVO getProductVO(Long id) { |
| | | // 从 MDM 获取产品数据 |
| | | MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); |
| | | if (item == null) { |
| | | return null; |
| | | } |
| | | // 检查是否为产品类型 |
| | | if (!MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) { |
| | | return null; |
| | | } |
| | | return convertToErpProductVO(item); |
| | | } |
| | | |
| | | /** |
| | | * 将 MDM 物料转换为 ERP 产品 VO |
| | | */ |
| | | private ErpProductRespVO convertToErpProductVO(MdmItemRespDTO item) { |
| | | ErpProductRespVO vo = new ErpProductRespVO(); |
| | | vo.setId(item.getId()); |
| | | vo.setName(item.getName()); |
| | | vo.setBarCode(item.getBarCode()); |
| | | vo.setStandard(item.getSpecification()); |
| | | vo.setCategoryId(item.getCategoryId()); |
| | | vo.setUnitId(item.getUnitMeasureId()); |
| | | vo.setStatus(item.getStatus()); |
| | | vo.setExpiryDay(item.getExpiryDay()); |
| | | vo.setWeight(item.getWeight()); |
| | | vo.setPurchasePrice(item.getPurchasePrice()); |
| | | vo.setSalePrice(item.getSalesPrice()); |
| | | vo.setMinPrice(item.getCostPrice()); |
| | | vo.setRemark(item.getRemark()); |
| | | return vo; |
| | | } |
| | | |
| | | @Override |
| | | public List<ErpProductRespVO> getProductVOListByStatus(Integer status) { |
| | | List<ErpProductDO> list = productMapper.selectListByStatus(status); |
| | | return buildProductVOList(list); |
| | | // 从 MDM 获取产品数据(itemType=2) |
| | | List<MdmItemRespDTO> items = mdmItemApi.getItemListByStatus(status).getCheckedData(); |
| | | // 过滤产品类型 |
| | | items = items.stream() |
| | | .filter(item -> MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) |
| | | .toList(); |
| | | return buildProductVOListFromMdm(items); |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<ErpProductDO> list = productMapper.selectByIds(ids); |
| | | return buildProductVOList(list); |
| | | // 从 MDM 获取产品数据 |
| | | List<MdmItemRespDTO> items = mdmItemApi.getItemList(ids).getCheckedData(); |
| | | return buildProductVOListFromMdm(items); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<ErpProductRespVO> getProductVOPage(ErpProductPageReqVO pageReqVO) { |
| | | PageResult<ErpProductDO> pageResult = productMapper.selectPage(pageReqVO); |
| | | return new PageResult<>(buildProductVOList(pageResult.getList()), pageResult.getTotal()); |
| | | // 从 MDM 获取产品分页数据 |
| | | cn.iocoder.yudao.framework.common.pojo.PageResult<MdmItemRespDTO> mdmPageResult = |
| | | mdmItemApi.getItemPage(MdmItemTypeEnum.PRODUCT.getType(), null, |
| | | pageReqVO.getPageNo(), pageReqVO.getPageSize()).getCheckedData(); |
| | | return new PageResult<>(buildProductVOListFromMdm(mdmPageResult.getList()), mdmPageResult.getTotal()); |
| | | } |
| | | |
| | | private List<ErpProductRespVO> buildProductVOList(List<ErpProductDO> list) { |
| | | if (CollUtil.isEmpty(list)) { |
| | | /** |
| | | * 从 MDM 数据构建 ERP 产品 VO 列表 |
| | | */ |
| | | private List<ErpProductRespVO> buildProductVOListFromMdm(List<MdmItemRespDTO> items) { |
| | | if (CollUtil.isEmpty(items)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | Map<Long, ErpProductCategoryDO> categoryMap = productCategoryService.getProductCategoryMap( |
| | | convertSet(list, ErpProductDO::getCategoryId)); |
| | | Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap( |
| | | convertSet(list, ErpProductDO::getUnitId)); |
| | | return BeanUtils.toBean(list, ErpProductRespVO.class, product -> { |
| | | MapUtils.findAndThen(categoryMap, product.getCategoryId(), |
| | | category -> product.setCategoryName(category.getName())); |
| | | MapUtils.findAndThen(unitMap, product.getUnitId(), |
| | | unit -> product.setUnitName(unit.getName())); |
| | | }); |
| | | List<ErpProductRespVO> result = new ArrayList<>(); |
| | | for (MdmItemRespDTO item : items) { |
| | | ErpProductRespVO vo = new ErpProductRespVO(); |
| | | vo.setId(item.getId()); |
| | | vo.setName(item.getName()); |
| | | vo.setBarCode(item.getBarCode()); |
| | | vo.setStandard(item.getSpecification()); |
| | | vo.setCategoryId(item.getCategoryId()); |
| | | vo.setUnitId(item.getUnitMeasureId()); |
| | | vo.setStatus(item.getStatus()); |
| | | vo.setExpiryDay(item.getExpiryDay()); |
| | | vo.setWeight(item.getWeight()); |
| | | vo.setPurchasePrice(item.getPurchasePrice()); |
| | | vo.setSalePrice(item.getSalesPrice()); |
| | | vo.setMinPrice(item.getCostPrice()); // 使用成本价作为最低价 |
| | | vo.setRemark(item.getRemark()); |
| | | // 分类名称和单位名称需要额外查询(简化处理,后续可优化) |
| | | result.add(vo); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 将 MDM 物料转换为 ERP 产品 DO |
| | | */ |
| | | private ErpProductDO convertToErpProduct(MdmItemRespDTO item) { |
| | | ErpProductDO product = new ErpProductDO(); |
| | | product.setId(item.getId()); |
| | | product.setName(item.getName()); |
| | | product.setBarCode(item.getBarCode()); |
| | | product.setStandard(item.getSpecification()); |
| | | product.setCategoryId(item.getCategoryId()); |
| | | product.setUnitId(item.getUnitMeasureId()); |
| | | product.setStatus(item.getStatus()); |
| | | product.setExpiryDay(item.getExpiryDay()); |
| | | product.setWeight(item.getWeight()); |
| | | product.setPurchasePrice(item.getPurchasePrice()); |
| | | product.setSalePrice(item.getSalesPrice()); |
| | | product.setMinPrice(item.getCostPrice()); |
| | | product.setRemark(item.getRemark()); |
| | | return product; |
| | | } |
| | | |
| | | @Override |
| | | public Long getProductCountByCategoryId(Long categoryId) { |
| | | return productMapper.selectCountByCategoryId(categoryId); |
| | | return mdmItemApi.getItemCountByCategoryId(categoryId).getCheckedData(); |
| | | } |
| | | |
| | | @Override |
| | | public Long getProductCountByUnitId(Long unitId) { |
| | | return productMapper.selectCountByUnitId(unitId); |
| | | return mdmItemApi.getItemCountByUnitMeasureId(unitId).getCheckedData(); |
| | | } |
| | | |
| | | } |