# RevenueDailySummaryGroupPickupServiceImpl.java

    package cloud.wconnect.rateshop.service.revenue.impl;

    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.rateshop.entity.revenue.RevenueDailySummaryGroupPickup;
    import cloud.wconnect.rateshop.entity.revenue.RevenueMepsGroupConfig;
    import cloud.wconnect.rateshop.mapper.revenue.RevenueDailySummaryGroupPickupMapper;
    import cloud.wconnect.rateshop.pojo.bo.revenue.DailySummaryGroupPickupBO;
    import cloud.wconnect.rateshop.pojo.dto.revenue.DailySummaryMEPSDTO;
    import cloud.wconnect.rateshop.pojo.dto.revenue.GroupPickupDTO;
    import cloud.wconnect.rateshop.service.revenue.IRevenueDailySummaryGroupPickupService;
    import cloud.wconnect.rateshop.service.revenue.IRevenueMepsGroupConfigService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Collectors;

    /**
     * <p>
     *  服务实现类
     * </p>
     *
     * @author yyt
     * @since 2025-06-24
     */
    @Service
    @DS("rate_shop")
    public class RevenueDailySummaryGroupPickupServiceImpl extends ServiceImpl<RevenueDailySummaryGroupPickupMapper, RevenueDailySummaryGroupPickup> implements IRevenueDailySummaryGroupPickupService {

        @Autowired
        private IRevenueMepsGroupConfigService revenueMepsGroupConfigService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private ObjectMapper objectMapper;

        /**
         * 保存 group pickup 数据
         *
         * @param propertyDTO       资产
         * @param targetDate        指定日期（yyyyMMdd）
         * @param groupPickupBOList group pickup 数据
         * @param uid               操作人
         * @author yyt
         * @date 2025/6/25
         **/
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void saveGroupPickupData(PropertyDTO propertyDTO, Integer targetDate, List<DailySummaryGroupPickupBO> groupPickupBOList, int uid) {
            Integer propertyId = propertyDTO.getId();
            // 先清除当前日期的数据，然后再新增
            remove(new QueryWrapper<RevenueDailySummaryGroupPickup>().lambda()
                    .eq(RevenueDailySummaryGroupPickup::getPropertyId, propertyId)
                    .eq(RevenueDailySummaryGroupPickup::getTargetDate, targetDate));

            if (CollectionUtils.isEmpty(groupPickupBOList)) return;

            long now = DateTimeUtils.nowTimestamp();

            saveBatch(groupPickupBOList.stream().map(item ->
                    new RevenueDailySummaryGroupPickup()
                            .setPropertyId(propertyId)
                            .setTargetDate(targetDate)
                            .setBookingStatus(item.getBookingStatus())
                            .setGroupName(item.getGroupName())
                            .setRoomPickup(item.getRoomPickup())
                            .setUpdatedBy(uid)
                            .setUpdatedTime(now)
            ).toList());
        }

        /**
         * 保存 group pickup 数据
         *
         * @param propertyDTO        资产
         * @param groupPickupDTOList group pickup 数据
         * @author yyt
         * @date 2025/7/7
         **/
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void saveGroupPickupData(PropertyDTO propertyDTO, List<GroupPickupDTO> groupPickupDTOList) {
            Integer propertyId = propertyDTO.getId();
            // 先清除当前日期的数据，然后再新增
            remove(new QueryWrapper<RevenueDailySummaryGroupPickup>().lambda()
                    .eq(RevenueDailySummaryGroupPickup::getPropertyId, propertyId)
                    .in(RevenueDailySummaryGroupPickup::getTargetDate, groupPickupDTOList.stream().map(item -> Integer.parseInt(item.getTargetDate())).distinct().toList()));

            if (CollectionUtils.isEmpty(groupPickupDTOList)) return;

            long now = DateTimeUtils.nowTimestamp();

            saveBatch(groupPickupDTOList.stream().flatMap(item ->
                    item.getGroupPickups().stream().map(groupPickupDetailDTO ->
                            new RevenueDailySummaryGroupPickup()
                                    .setPropertyId(propertyId)
                                    .setTargetDate(Integer.parseInt(item.getTargetDate()))
                                    .setBookingStatus(groupPickupDetailDTO.getBookingStatus())
                                    .setGroupName(groupPickupDetailDTO.getGroupName())
                                    .setRoomPickup(groupPickupDetailDTO.getRoomPickup())
                                    .setUpdatedBy(BaseConstant.ZERO)
                                    .setUpdatedTime(now))
            ).toList());
        }

        /**
         * 查询 MEPS
         *
         * @param propertyId 资产 id
         * @param targetDate 指定日期
         * @return MEPS
         * @author yyt
         * @date 2025/6/25
         **/
        @Override
        public DailySummaryMEPSDTO getMEPS(Integer propertyId, long targetDate) {
            // 若资产未设置 mpes 配置，则返回 null
            if (!revenueMepsGroupConfigService.hasConfig(propertyId)) return null;

            // 查询当前日期的 MEPS 配置
            String timezone = propertyI18nRedisService.get(propertyId).getTimezone();
            RevenueMepsGroupConfig config = revenueMepsGroupConfigService.getByDate(propertyId,
                    Integer.parseInt(DateTimeUtils.localDateToStr(DateTimeUtils.longToLocalDate(targetDate, timezone), BaseConstant.DATE_FORMAT_YYYYMMDD)));
            if (Objects.isNull(config)) return null;

            // 查询当天的 Group pickup
            List<RevenueDailySummaryGroupPickup> groupPickups = list(new QueryWrapper<RevenueDailySummaryGroupPickup>().lambda()
                    .eq(RevenueDailySummaryGroupPickup::getPropertyId, propertyId)
                    .eq(RevenueDailySummaryGroupPickup::getTargetDate,
                            Integer.parseInt(DateTimeUtils.localDateToStr(DateTimeUtils.longToLocalDate(targetDate, timezone), BaseConstant.DATE_FORMAT_YYYYMMDD))));
            if (CollectionUtils.isEmpty(groupPickups)) return null;

            // 过滤包含关键字的 group pick 数据
            List<String> keyWords = JsonUtils.convertStringToList(objectMapper, config.getKeyWords(), String.class)
                    .stream().map(keyword -> keyword.trim().toLowerCase()).toList();
            List<RevenueDailySummaryGroupPickup> filteredGroupPickups = groupPickups.stream()
                    .filter(groupPickup -> keyWords.stream().anyMatch(groupPickup.getGroupName().toLowerCase()::contains))
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(filteredGroupPickups)) return null;

            return new DailySummaryMEPSDTO(filteredGroupPickups.stream().map(RevenueDailySummaryGroupPickup::getRoomPickup)
                    .filter(Objects::nonNull).reduce(Integer::sum).orElse(null), filteredGroupPickups.get(0).getUpdatedTime());
        }

    }