# HkInventoryRoomTypeServiceImpl.java

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

    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.workperformance.entity.hkinventory.HkInventoryCategoryConfig;
    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.HkInventoryRoomTypeMapper;
    import cloud.wconnect.workperformance.service.hkinventory.IHkInventoryRoomTypeConfigService;
    import cloud.wconnect.workperformance.service.hkinventory.IHkInventoryRoomTypeService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    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.math.BigDecimal;
    import java.util.*;
    import java.util.function.Function;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 客房库存管理-房型表 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2025-04-19
     */
    @Service
    @DS("work_performance")
    public class HkInventoryRoomTypeServiceImpl extends ServiceImpl<HkInventoryRoomTypeMapper, HkInventoryRoomType> implements IHkInventoryRoomTypeService {

        @Autowired
        @Lazy
        private IHkInventoryRoomTypeConfigService roomTypeConfigService;

        /**
         * 根据库存id和分类id获取库存分类下的房型
         *
         * @param propertyId    资产id
         * @param hkInventoryId 库存id
         * @param categoryIds   分类id集合
         * @return java.util.List<cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomType>
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        public List<HkInventoryRoomType> listByHkInventoryIdAndCategoryIds(Integer propertyId, Integer hkInventoryId, List<Integer> categoryIds) {
            if (CollectionUtils.isEmpty(categoryIds)) return Collections.emptyList();
            return list(new LambdaQueryWrapper<HkInventoryRoomType>().eq(HkInventoryRoomType::getPropertyId, propertyId)
                    .eq(HkInventoryRoomType::getHkInventoryId, hkInventoryId)
                    .in(HkInventoryRoomType::getCategoryId, categoryIds));
        }

        /**
         * 汇总多个客房库存管理下指定分类下指定房型下的数据
         *
         * @param propertyId    资产id
         * @param hkInventoryId 客房库存管理id
         * @param itemList      指定分类指定房型下的item集合
         * @return void
         * @author lichen
         * @date 2025/4/21
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void summary(Integer propertyId, Integer hkInventoryId, List<HkInventoryItem> itemList) {
            if (CollectionUtils.isEmpty(itemList)) return;
            //按照指定分类指定房型分组
            Map<Integer, Map<Integer, List<HkInventoryItem>>> categoryId2RoomTypeId2ItemList = itemList.stream().collect(Collectors.groupingBy(HkInventoryItem::getCategoryId,
                    Collectors.groupingBy(HkInventoryItem::getRoomTypeId)));
            //查询指定客房库存管理下的房型数据
            List<HkInventoryRoomType> roomTypeList = listByHkInventoryId(propertyId, hkInventoryId);
            ArrayList<HkInventoryRoomType> batchList = Lists.newArrayListWithCapacity(roomTypeList.size());

            for (HkInventoryRoomType hkInventoryRoomType : roomTypeList) {
                List<HkInventoryItem> itemListByCategoryIdByRoomTypeId = categoryId2RoomTypeId2ItemList.getOrDefault(hkInventoryRoomType.getCategoryId(), Collections.emptyMap())
                        .getOrDefault(hkInventoryRoomType.getRoomTypeId(), Collections.emptyList());
                //库存总金额
                BigDecimal totalBalance = itemListByCategoryIdByRoomTypeId.stream().map(HkInventoryItem::getTotalBalance).filter(Objects::nonNull)
                        .reduce(BigDecimal::add).orElse(null);
                //需求采购金额
                BigDecimal requiredPurchaseAmount = itemListByCategoryIdByRoomTypeId.stream().map(HkInventoryItem::getRequiredPurchaseAmount).filter(Objects::nonNull)
                        .reduce(BigDecimal::add).orElse(null);

                HkInventoryRoomType updateEntity = new HkInventoryRoomType();
                updateEntity.setId(hkInventoryRoomType.getId());
                updateEntity.setTotalBalance(totalBalance);
                updateEntity.setRequiredPurchaseAmount(requiredPurchaseAmount);
                batchList.add(updateEntity);
            }

            //更新库存分类表
            updateBatchById(batchList);
        }

        /**
         * 根据房型id和客房库存管理id集合获取库存分类下的房型
         *
         * @param propertyId     资产id
         * @param roomTypeId     房型id
         * @param hkInventoryIds 客房库存管理id
         * @return void
         * @author lichen
         * @date 2025/4/22
         */
        @Override
        public List<HkInventoryRoomType> listByRoomTypeIdAndHkInventoryIds(Integer propertyId, Integer roomTypeId, List<Integer> hkInventoryIds) {
            if (CollectionUtils.isEmpty(hkInventoryIds)) return Collections.emptyList();
            return list(new LambdaQueryWrapper<HkInventoryRoomType>()
                    .eq(HkInventoryRoomType::getPropertyId, propertyId)
                    .eq(HkInventoryRoomType::getRoomTypeId, roomTypeId)
                    .in(HkInventoryRoomType::getHkInventoryId, hkInventoryIds));
        }

        /**
         * 修改房型名称
         *
         * @param propertyId   资产id
         * @param roomTypeId   房型id
         * @param roomTypeName 房型名称
         * @return void
         * @author lichen
         * @date 2025/4/23
         */
        @Override
        public void updateRoomTypeNameByRoomTypeId(Integer propertyId, Integer roomTypeId, String roomTypeName) {
            update(new LambdaUpdateWrapper<HkInventoryRoomType>()
                    .eq(HkInventoryRoomType::getPropertyId, propertyId)
                    .eq(HkInventoryRoomType::getRoomTypeId, roomTypeId)
                    .set(HkInventoryRoomType::getRoomTypeName, roomTypeName));
        }

        /**
         * 查询指定客房库存管理下指定分类下指定房型的数据
         *
         * @param propertyId    资产id
         * @param hkInventoryId 客房库存管理id
         * @return java.util.List<cloud.wconnect.workperformance.entity.hkinventory.HkInventoryRoomType>
         * @author lichen
         * @date 2025/4/23
         */
        public List<HkInventoryRoomType> listByHkInventoryId(Integer propertyId, Integer hkInventoryId) {
            return list(new LambdaQueryWrapper<HkInventoryRoomType>()
                    .eq(HkInventoryRoomType::getPropertyId, propertyId)
                    .eq(HkInventoryRoomType::getHkInventoryId, hkInventoryId));
        }

        /**
         * 删除指定Housekeeping Inventory指定分类下关联的房型
         *
         * @param propertyId        资产id
         * @param hkInventoryIdList Housekeeping Inventory id集合
         * @param categoryId        分类id
         * @param deleteRoomTypeIds 删除的房型id集合
         * @return void
         * @author lichen
         * @date 2025/4/26
         */
        @Override
        public void deleteByHkInventoryIdsAndCategoryIdAndRoomTypeIds(Integer propertyId, List<Integer> hkInventoryIdList,
                                                                      Integer categoryId, List<Integer> deleteRoomTypeIds) {
            if (CollectionUtils.isEmpty(hkInventoryIdList) || CollectionUtils.isEmpty(deleteRoomTypeIds)) return;

            remove(new LambdaQueryWrapper<HkInventoryRoomType>()
                    .eq(HkInventoryRoomType::getPropertyId, propertyId)
                    .in(HkInventoryRoomType::getHkInventoryId, hkInventoryIdList)
                    .eq(HkInventoryRoomType::getCategoryId, categoryId)
                    .in(HkInventoryRoomType::getRoomTypeId, deleteRoomTypeIds));
        }

        /**
         * 初始化房型
         *
         * @param propertyDTO               资产DTO
         * @param hkInventoryIds            Housekeeping Inventory id集合
         * @param hkInventoryCategoryConfig 分类配置
         * @param roomTypeIds               房型id集合
         * @return void
         * @author lichen
         * @date 2025/5/9
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void initRoomType(PropertyDTO propertyDTO, List<Integer> hkInventoryIds, HkInventoryCategoryConfig hkInventoryCategoryConfig, List<Integer> roomTypeIds) {
            if (CollectionUtils.isEmpty(hkInventoryIds) || CollectionUtils.isEmpty(roomTypeIds)) return;

            //查询房型配置集合
            Map<Integer, HkInventoryRoomTypeConfig> roomTypeId2RoomType = roomTypeConfigService.listByIds(roomTypeIds)
                    .stream().collect(Collectors.toMap(HkInventoryRoomTypeConfig::getId, Function.identity()));

            ArrayList<HkInventoryRoomType> batchList = Lists.newArrayListWithCapacity(hkInventoryIds.size() * roomTypeIds.size());

            for (Integer hkInventoryId : hkInventoryIds) {

                List<HkInventoryRoomType> roomTypes = roomTypeIds.stream().map(roomTypeId -> {
                    //房型配置信息
                    HkInventoryRoomTypeConfig hkInventoryRoomTypeConfig = roomTypeId2RoomType.get(roomTypeId);

                    HkInventoryRoomType hkInventoryRoomType = new HkInventoryRoomType();
                    hkInventoryRoomType.setTenantId(propertyDTO.getTenantId());
                    hkInventoryRoomType.setPropertyId(propertyDTO.getId());
                    hkInventoryRoomType.setHkInventoryId(hkInventoryId);
                    hkInventoryRoomType.setCategoryId(hkInventoryCategoryConfig.getId());
                    hkInventoryRoomType.setRoomTypeId(roomTypeId);
                    hkInventoryRoomType.setRoomTypeName(hkInventoryRoomTypeConfig.getRoomTypeName());
                    hkInventoryRoomType.setTotalRooms(hkInventoryRoomTypeConfig.getTotalRooms());
                    return hkInventoryRoomType;
                }).toList();

                batchList.addAll(roomTypes);
            }

            //批量保存
            saveBatch(batchList);
        }
    }