# HotelKpiReportServiceImpl.java

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

    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.exception.ListenerException;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.workperformance.cons.hotelkpi.HotelKpiReportCategoryEnum;
    import cloud.wconnect.workperformance.pojo.bo.hotelkpi.HotelKpiHistoryAndForecastBO;
    import cloud.wconnect.workperformance.pojo.bo.hotelkpi.HotelKpiManagerFlashBO;
    import cloud.wconnect.workperformance.service.hotelkpi.IHotelKpiReportService;
    import cloud.wconnect.workperformance.service.hotelkpi.historyandforecast.IHotelKpiHistoryAndForecastParseService;
    import cloud.wconnect.workperformance.service.hotelkpi.managerflash.IHotelKpiManagerFlashParseService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import jakarta.annotation.Resource;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Service;

    import java.io.InputStream;
    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.List;

    /**
     * <p>
     * Hotel KPI Report 服务实现类
     * </p>
     *
     * @author zc
     * @since 2024-07-01
     */
    @Slf4j
    @Service
    @DS("work_performance")
    public class HotelKpiReportServiceImpl implements IHotelKpiReportService {
        @Resource
        private ApplicationContext applicationContext;

        /**
         * 解析报告 History and Forecast
         *
         * @param propertyDTO 资产
         * @param in          报告文件流
         * @param source      报告来源
         * @param dateRange   数据日期范围(yyyyMMdd)
         * @return HotelKpiHistoryAndForecastBO 集合
         * @author zc
         * @date 2024/7/10
         */
        @Override
        public List<HotelKpiHistoryAndForecastBO> parseHistoryAndForecastReport(PropertyDTO propertyDTO, InputStream in, String source, List<Long> dateRange) {
            Collection<IHotelKpiHistoryAndForecastParseService> parserList = applicationContext.getBeansOfType(IHotelKpiHistoryAndForecastParseService.class).values();
            for (IHotelKpiHistoryAndForecastParseService parser : parserList) {
                if (parser.supports(source)) {
                    return parser.parse(propertyDTO, in, dateRange);
                }
            }
            throw new ListenerException("Not found report parser");
        }

        /**
         * 解析报告 Manager Flash
         *
         * @param propertyDTO 资产
         * @param in          报告文件流
         * @param source      报告来源
         * @return HotelKpiManagerFlashBO 集合
         * @author zc
         * @date 2024/7/1
         */
        @Override
        public List<HotelKpiManagerFlashBO> parseManagerFlashReport(PropertyDTO propertyDTO, InputStream in, String source) {
            Collection<IHotelKpiManagerFlashParseService> parserList = applicationContext.getBeansOfType(IHotelKpiManagerFlashParseService.class).values();
            for (IHotelKpiManagerFlashParseService parser : parserList) {
                if (parser.supports(source)) {
                    return parser.parse(propertyDTO, in);
                }
            }
            throw new ListenerException("Not found report parser");
        }

        /**
         * 获取数据的时间范围
         *
         * @param timezone 时区
         * @param category 分类
         * @return 时间范围
         * @author zc
         * @date 2025/7/23
         */
        @Override
        public List<Long> getDateRange(String timezone, int category) {
            LocalDate nowLocalDate = LocalDate.now(ZoneId.of(timezone));
            List<Long> dateRange = Arrays.stream(HotelKpiReportCategoryEnum.getDateRange(category)
                    .split(",")).map(Long::parseLong).toList();

            return List.of(Long.parseLong(DateTimeUtils.localDateToStr(nowLocalDate.plusDays(dateRange.get(0)),
                            BaseConstant.DATE_FORMAT_YYYYMMDD)),
                    Long.parseLong(DateTimeUtils.localDateToStr(nowLocalDate.plusDays(dateRange.get(1)),
                            BaseConstant.DATE_FORMAT_YYYYMMDD)));
        }
    }