# HistoryAndForecastServiceByPep.java

    package cloud.wconnect.frontoffice.parsereport.endofshift.impl;

    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.SystemPlatformEnum;
    import cloud.wconnect.commonlib.exception.ParseReportException;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.internationalization.InternationalizationNumberDTO;
    import cloud.wconnect.commonlib.util.CsvFileUtils;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.InternationalizationUtils;
    import cloud.wconnect.frontoffice.parsereport.endofshift.IHistoryAndForecastService;
    import cloud.wconnect.frontoffice.pojo.dto.endofshift.report.HistoryAndForecastForEndOfShiftReportDTO;
    import cloud.wconnect.frontoffice.service.endofshift.IEosShiftConfigService;
    import cloud.wconnect.frontoffice.service.endofshift.IShiftReportInfoService;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.csv.CSVFormat;
    import org.apache.commons.csv.CSVRecord;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.stereotype.Component;

    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.time.LocalDate;
    import java.util.Iterator;

    /**
     * 解析 PEP 系统的 History And Forecast 报告
     *
     * @author yyt
     * @date 2026/2/3
     */
    @RequiredArgsConstructor
    @Slf4j
    @Component
    public class HistoryAndForecastServiceByPep implements IHistoryAndForecastService {

        private final IShiftReportInfoService shiftReportInfoService;
        private final IEosShiftConfigService shiftConfigService;
        private final ObjectMapper objectMapper;

        /**
         * 支持的报告来源
         *
         * @param source 报告来源
         * @return boolean
         * @author yyt
         * @date 2026/2/3
         */
        @Override
        public boolean supports(String source) {
            return SystemPlatformEnum.PEP.getDesc().equals(source);
        }

        /**
         * 解析报告
         *
         * @param in     文件
         * @param property 资产
         * @return HistoryAndForecastForEndOfShiftReportDTO
         * @author yyt
         * @date 2026/2/3
         */
        @Override
        public HistoryAndForecastForEndOfShiftReportDTO parse(InputStream in, PropertyDTO property) throws ParseReportException {
            Integer propertyId = property.getId();
            String timeZone = property.getTimezone();
            InternationalizationNumberDTO number = property.getInternationalization().getNumber();
            RoundingMode roundingMode = InternationalizationUtils.getRoundingMode(number.getCalculationRule());

            long dateNowTime = DateTimeUtils.dateNowTimestamp(property.getTimezone());

            try (InputStreamReader inputStreamReader = new InputStreamReader(in)) {
                //获取CSV数据迭代器
                Iterable<CSVRecord> iterable = CSVFormat.EXCEL.parse(inputStreamReader);
                Iterator<CSVRecord> iterator = iterable.iterator();

                //跳过第一行标题行
                iterator.next();

                while (iterator.hasNext()) {
                    CSVRecord csvRecord = iterator.next();
                    String dateStr = CsvFileUtils.get(csvRecord, "A");
                    if (StringUtils.isEmpty(dateStr)) continue;

                    LocalDate localDate = DateTimeUtils.strToLocalDate(dateStr, BaseConstant.DATE_FORMAT_MMMDDYYYY_USA);
                    long targetDate = DateTimeUtils.localDateToLong(localDate, timeZone);

                    //判断目标日期是否在范围中
                    if (targetDate == dateNowTime) {
                        HistoryAndForecastForEndOfShiftReportDTO  historyAndForecastDTO = new HistoryAndForecastForEndOfShiftReportDTO();
                        historyAndForecastDTO.setTheDate(targetDate);
                        historyAndForecastDTO.setPropertyId(propertyId);

                        String arrivalRoomsStr = CsvFileUtils.getAndFormatNumber(csvRecord, "F");
                        historyAndForecastDTO.setArrRooms(StringUtils.isEmpty(arrivalRoomsStr) ? 0 : Integer.parseInt(arrivalRoomsStr));

                        String departureRoomsStr = CsvFileUtils.getAndFormatNumber(csvRecord, "H");
                        historyAndForecastDTO.setDepRooms(StringUtils.isEmpty(departureRoomsStr) ? 0 : Integer.parseInt(departureRoomsStr));

                        String occupancyStr = CsvFileUtils.getAndFormatNumber(csvRecord, "M");
                        historyAndForecastDTO.setOccPercent(StringUtils.isEmpty(occupancyStr) ? "0" : new BigDecimal(occupancyStr)
                                .setScale(BaseConstant.DATA_PRECISION, roundingMode).toString());

                        // 默认 0
                        historyAndForecastDTO.setCompRooms(BaseConstant.ZERO);
                        historyAndForecastDTO.setOooRooms(BaseConstant.ZERO);

                        return historyAndForecastDTO;
                    }
                }

                return null;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new ParseReportException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "parse pep [Occupancy Forecast] report error", e);
            }
        }

    }