# HkInventoryRoomTypeConfigServiceImpl.java

    package cloud.wconnect.workperformance.service.hkinventory.impl;

    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.util.UpdateLogUtil;
    import cloud.wconnect.workperformance.cons.hkinventory.StatusEnum;
    import cloud.wconnect.workperformance.entity.hkinventory.HkInventory;
    import cloud.wconnect.workperformance.entity.hkinventory.HkInventoryItem;
    import cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomType;
    import cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomTypeConfig;
    import cloud.wconnect.workperformance.mapper.hkinventory.HkInventoryRoomTypeConfigMapper;
    import cloud.wconnect.workperformance.pojo.dto.hkinventory.HkInventoryRoomTypeConfigDTO;
    import cloud.wconnect.workperformance.service.hkinventory.*;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.text.MessageFormat;
    import java.util.*;

    /**
     * <p>
     * 客房库存管理-房型配置表 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2025-04-19
     */
    @Service
    @DS("work_performance")
    public class HkInventoryRoomTypeConfigServiceImpl extends ServiceImpl<HkInventoryRoomTypeConfigMapper, HkInventoryRoomTypeConfig> implements IHkInventoryRoomTypeConfigService {

        @Autowired
        private UpdateLogUtil updateLogUtil;
        @Autowired
        @Lazy
        private IHkInventoryService hkInventoryService;
        @Autowired
        @Lazy
        private IHkInventoryRoomTypeService roomTypeService;
        @Autowired
        @Lazy
        private IHkInventoryPurchaseOrderService purchaseOrderService;
        @Autowired
        @Lazy
        private IHkInventoryItemService itemService;
        @Autowired
        @Lazy
        private IHkInventoryCategoryConfigService categoryConfigService;
        @Autowired
        @Lazy
        private IHkInventoryItemConfigService itemConfigService;

        /**
         * 校验房型是否存在
         *
         * @param roomTypeId 房型id
         * @return cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomTypeConfig
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        public HkInventoryRoomTypeConfig checkExist(Integer roomTypeId) {
            HkInventoryRoomTypeConfig hkInventoryRoomTypeConfig = getById(roomTypeId);
            if (Objects.isNull(hkInventoryRoomTypeConfig)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_FOUND,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "Housekeeping Inventory room type config not found,id=" + roomTypeId);
            }
            return hkInventoryRoomTypeConfig;
        }

        /**
         * 校验房型配置是否归属于资产
         *
         * @param hkInventoryRoomTypeConfig 房型配置
         * @param propertyId                资产id
         * @return void
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        public void checkBelongProperty(HkInventoryRoomTypeConfig hkInventoryRoomTypeConfig, Integer propertyId) {
            if (!hkInventoryRoomTypeConfig.getPropertyId().equals(propertyId)) {
                throw new BadRequestException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(), BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        MessageFormat.format("The Housekeeping Inventory room type config not belong currentPropertyId, hkInventoryRoomTypeConfigId:{0}, belongPropertyId:{1}, currentPropertyId:{2}",
                                hkInventoryRoomTypeConfig.getId(), hkInventoryRoomTypeConfig.getPropertyId(), propertyId));
            }
        }

        /**
         * 校验房型配置是否归属于资产
         *
         * @param hkInventoryRoomTypeConfig 房型配置集合
         * @param propertyId                资产id
         * @return void
         * @author lichen
         * @date 2025/4/22
         */
        @Override
        public void checkBelongProperty(List<HkInventoryRoomTypeConfig> hkInventoryRoomTypeConfig, Integer propertyId) {
            if (CollectionUtils.isEmpty(hkInventoryRoomTypeConfig)) return;
            List<Integer> roomTypeConfigIds = hkInventoryRoomTypeConfig.stream()
                    .filter(item -> !item.getPropertyId().equals(propertyId))
                    .map(HkInventoryRoomTypeConfig::getId).toList();
            if (CollectionUtils.isNotEmpty(roomTypeConfigIds)) {
                throw new BadRequestException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(), BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        MessageFormat.format("The Housekeeping Inventory room type config not belong currentPropertyId, hkInventoryRoomTypeConfigId:{0}, currentPropertyId:{1}",
                                roomTypeConfigIds, propertyId));
            }
        }

        /**
         * 根据房型名称查询房型配置
         *
         * @param propertyId   资产id
         * @param roomTypeName 房型名称
         * @return java.util.List<cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomTypeConfig>
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        public List<HkInventoryRoomTypeConfig> listByName(Integer propertyId, String roomTypeName) {
            return list(new LambdaQueryWrapper<HkInventoryRoomTypeConfig>()
                    .eq(HkInventoryRoomTypeConfig::getPropertyId, propertyId)
                    .eq(StringUtils.isNotBlank(roomTypeName), HkInventoryRoomTypeConfig::getRoomTypeName, roomTypeName)
                    .orderByDesc(HkInventoryRoomTypeConfig::getId));
        }

        /**
         * 新增房型配置
         *
         * @param tenantId                     租户id
         * @param propertyId                   资产id
         * @param hkInventoryRoomTypeConfigDTO 房型配置DTO
         * @param loginUserId                  用户id
         * @return java.lang.Integer
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        public Integer insert(Integer tenantId, int propertyId, HkInventoryRoomTypeConfigDTO hkInventoryRoomTypeConfigDTO, int loginUserId) {
            HkInventoryRoomTypeConfig roomTypeConfig = new HkInventoryRoomTypeConfig()
                    .setPropertyId(propertyId)
                    .setTenantId(tenantId)
                    .setRoomTypeName(hkInventoryRoomTypeConfigDTO.getRoomTypeName())
                    .setTotalRooms(hkInventoryRoomTypeConfigDTO.getTotalRooms())
                    .setUpdateLog(updateLogUtil.get(loginUserId));
            //新增
            save(roomTypeConfig);
            return roomTypeConfig.getId();
        }

        /**
         * 校验房型名称重复
         *
         * @param propertyId   资产id
         * @param roomTypeName 房型名称
         * @param roomTypeId   房型id
         * @return void
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        public void checkNameRepeat(Integer propertyId, String roomTypeName, Integer roomTypeId) {
            long count = count(new LambdaQueryWrapper<HkInventoryRoomTypeConfig>()
                    .eq(HkInventoryRoomTypeConfig::getPropertyId, propertyId)
                    .eq(HkInventoryRoomTypeConfig::getRoomTypeName, roomTypeName)
                    .ne(roomTypeId > 0, HkInventoryRoomTypeConfig::getId, roomTypeId));
            if (count > 0) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_EXISTED,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        MessageFormat.format("The Housekeeping Inventory room type config name already exists, propertyId:{0}, roomTypeName:{1}",
                                propertyId, roomTypeName));
            }
        }

        /**
         * 更新房型配置
         *
         * @param propertyId        资产id
         * @param oriRoomTypeConfig 更新前的房型配置
         * @param roomTypeConfigDTO 更新后的房型配置
         * @param loginUserId       登录用户ID
         * @return void
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void update(int propertyId, HkInventoryRoomTypeConfig oriRoomTypeConfig, HkInventoryRoomTypeConfigDTO roomTypeConfigDTO, int loginUserId) {
            //修改房型配置
            HkInventoryRoomTypeConfig updateEntity = new HkInventoryRoomTypeConfig();
            updateEntity.setId(oriRoomTypeConfig.getId());
            updateEntity.setRoomTypeName(roomTypeConfigDTO.getRoomTypeName());
            updateEntity.setTotalRooms(roomTypeConfigDTO.getTotalRooms());
            updateById(updateEntity);

            //判断房型名称是否发生变更
            if (!oriRoomTypeConfig.getRoomTypeName().equals(roomTypeConfigDTO.getRoomTypeName())) {
                //更新客房库存管理房型表
                roomTypeService.updateRoomTypeNameByRoomTypeId(propertyId, oriRoomTypeConfig.getId(), roomTypeConfigDTO.getRoomTypeName());
                //更新物品采购订单表
                purchaseOrderService.updateRoomTypeNameByRoomTypeId(propertyId, oriRoomTypeConfig.getId(), roomTypeConfigDTO.getRoomTypeName());
            }

            if (!oriRoomTypeConfig.getTotalRooms().equals(roomTypeConfigDTO.getTotalRooms())) {
                //查询未发布的客房库存管理
                List<HkInventory> hkInventoryList = hkInventoryService.listByStatus(propertyId, StatusEnum.PENDING.getStatus());
                //如果没有未发布客房库存管理，则不需要更新totalRooms
                if (CollectionUtils.isEmpty(hkInventoryList)) return;
                List<Integer> hkInventoryIds = hkInventoryList.stream().map(HkInventory::getId).toList();
                //查询房型数据
                List<HkInventoryRoomType> hkInventoryRoomTypes = roomTypeService.listByRoomTypeIdAndHkInventoryIds(propertyId, oriRoomTypeConfig.getId(), hkInventoryIds);
                for (HkInventoryRoomType roomType : hkInventoryRoomTypes) {
                    roomType.setTotalRooms(roomTypeConfigDTO.getTotalRooms());
                }
                //更新
                roomTypeService.updateBatchById(hkInventoryRoomTypes);
            }
        }

        /**
         * 删除房型配置
         *
         * @param propertyId                资产id
         * @param hkInventoryRoomTypeConfig 房型配置
         * @return void
         * @author lichen
         * @date 2025/4/22
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void delete(int propertyId, HkInventoryRoomTypeConfig hkInventoryRoomTypeConfig) {
            //删除房型配置
            removeById(hkInventoryRoomTypeConfig.getId());
            //删除分类中关联的该房型
            categoryConfigService.removeCategoryRelateRoomTypeId(propertyId, hkInventoryRoomTypeConfig.getId());
            //删除房型下的item配置
            itemConfigService.deleteByRoomTypeId(propertyId, hkInventoryRoomTypeConfig.getId());

            //查询未发布的客房库存管理
            List<HkInventory> hkInventoryList = hkInventoryService.listByStatus(propertyId, StatusEnum.PENDING.getStatus());
            if (CollectionUtils.isEmpty(hkInventoryList)) return;
            List<Integer> hkInventoryIds = hkInventoryList.stream().map(HkInventory::getId).toList();

            //查询指定客房库存所有分类指定房型下的数据
            List<HkInventoryRoomType> hkInventoryRoomTypes = roomTypeService.listByRoomTypeIdAndHkInventoryIds(propertyId,
                    hkInventoryRoomTypeConfig.getId(), hkInventoryIds);
            if (CollectionUtils.isEmpty(hkInventoryRoomTypes)) return;
            //删除房型数据
            roomTypeService.removeByIds(hkInventoryRoomTypes.stream().map(HkInventoryRoomType::getId).toList());

            //查询指定客房库存所有分类指定房型下的item数据
            List<HkInventoryItem> hkInventoryItems = itemService.listByHkInventoryIdsAndRoomTypeId(propertyId, hkInventoryIds, hkInventoryRoomTypeConfig.getId());
            if (CollectionUtils.isEmpty(hkInventoryItems)) return;
            //删除房型下的item数据
            itemService.removeByIds(hkInventoryItems.stream().map(HkInventoryItem::getId).toList());
        }

        /**
         * 校验是否存在
         *
         * @param roomTypeIds 房型id集合
         * @return java.util.List<cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomTypeConfig>
         * @author lichen
         * @date 2025/4/22
         */
        @Override
        public List<HkInventoryRoomTypeConfig> checkExistByIds(ArrayList<Integer> roomTypeIds) {
            if (CollectionUtils.isEmpty(roomTypeIds)) return Collections.emptyList();
            List<HkInventoryRoomTypeConfig> roomTypeConfigList = listByIds(roomTypeIds);
            if (roomTypeConfigList.size() != roomTypeIds.size()) {
                List<Integer> existRoomTypeIds = roomTypeConfigList.stream().map(HkInventoryRoomTypeConfig::getId).toList();
                List<Integer> notExistRoomTypeIds = roomTypeIds.stream().filter(roomTypeId -> !existRoomTypeIds.contains(roomTypeId)).toList();
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_FOUND,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "Housekeeping Inventory room type config not found,ids=" + notExistRoomTypeIds);
            }
            return roomTypeConfigList;
        }

        /**
         * 房型配置
         *
         * @param propertyIds 资产id集合
         * @return java.util.Collection<cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomTypeConfig>
         * @author lichen
         * @date 2025/4/25
         */
        @Override
        public Collection<HkInventoryRoomTypeConfig> listByPropertyIds(List<Integer> propertyIds) {
            if (CollectionUtils.isEmpty(propertyIds)) return Collections.emptyList();
            return list(new LambdaQueryWrapper<HkInventoryRoomTypeConfig>().in(HkInventoryRoomTypeConfig::getPropertyId, propertyIds));
        }

    }