# HistoryAndForecastServiceByShiji.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.DateTimeUtils;
    import cloud.wconnect.commonlib.util.InternationalizationUtils;
    import cloud.wconnect.commonlib.util.ShijiFileCheckUtils;
    import cloud.wconnect.frontoffice.parsereport.endofshift.IHistoryAndForecastService;
    import cloud.wconnect.frontoffice.pojo.dto.endofshift.report.HistoryAndForecastForEndOfShiftReportDTO;
    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.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.Iterator;

    /**
     * 解析shiji系统的History and Forecast Report
     */
    @Slf4j
    @Component
    public class HistoryAndForecastServiceByShiji implements IHistoryAndForecastService {

        /**
         * 支持的报告来源
         *
         * @param source 报告来源
         * @return boolean
         * @author lichen
         * @date 2025/7/26
         */
        @Override
        public boolean supports(String source) {
            return SystemPlatformEnum.SHI_JI.getDesc().equals(source);
        }

        /**
         * 解析报告
         *
         * @param in          文件
         * @param propertyDTO 资产DTO
         * @return cloud.wconnect.frontoffice.pojo.dto.endofshift.report.HistoryAndForecastForEndOfShiftReportDTO
         * @author lichen
         * @date 2025/7/26
         */
        @Override
        public HistoryAndForecastForEndOfShiftReportDTO parse(InputStream in, PropertyDTO propertyDTO) throws ParseReportException {
            //获取国际化的配置
            InternationalizationNumberDTO number = propertyDTO.getInternationalization().getNumber();
            RoundingMode roundingMode = InternationalizationUtils.getRoundingMode(number.getCalculationRule());

            long currentDate = DateTimeUtils.dateNowTimestamp(propertyDTO.getTimezone());
            HistoryAndForecastForEndOfShiftReportDTO historyAndForecastDTO = null;

            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();
                    //日期格式Wed  07/02/25
                    String dateStr = ShijiFileCheckUtils.get(csvRecord, "A");
                    String[] split = dateStr.split("  ");
                    long date = DateTimeUtils.dateStrToEpochSecond(split[1], BaseConstant.DATE_TIME_FORMAT_MM_DD_YY, propertyDTO.getTimezone());

                    //判断是否等于当前日期
                    if (date == currentDate) {
                        String arrivalRoomsStr = ShijiFileCheckUtils.getAndFormatNumber(csvRecord, "C");
                        String departureRoomsStr = ShijiFileCheckUtils.getAndFormatNumber(csvRecord, "D");
                        String occupancyStr = ShijiFileCheckUtils.getAndFormatNumber(csvRecord, "E");
                        String oooRoomsStr = ShijiFileCheckUtils.getAndFormatNumber(csvRecord, "S");
                        String compRoomsStr = ShijiFileCheckUtils.getAndFormatNumber(csvRecord, "U");

                        historyAndForecastDTO = new HistoryAndForecastForEndOfShiftReportDTO();
                        historyAndForecastDTO.setTheDate(date);
                        historyAndForecastDTO.setPropertyId(propertyDTO.getId());
                        historyAndForecastDTO.setArrRooms(StringUtils.isEmpty(arrivalRoomsStr) ? 0 : Integer.parseInt(arrivalRoomsStr));
                        historyAndForecastDTO.setCompRooms(StringUtils.isEmpty(compRoomsStr) ? 0 : Integer.parseInt(compRoomsStr));
                        historyAndForecastDTO.setOccPercent(StringUtils.isEmpty(occupancyStr) ? "0" : new BigDecimal(occupancyStr)
                                .setScale(BaseConstant.DATA_PRECISION, roundingMode).toString());
                        historyAndForecastDTO.setDepRooms(StringUtils.isEmpty(departureRoomsStr) ? 0 : Integer.parseInt(departureRoomsStr));
                        historyAndForecastDTO.setOooRooms(StringUtils.isEmpty(oooRoomsStr) ? 0 : Integer.parseInt(oooRoomsStr));
                        break;
                    }else{
                        iterator.next();
                        iterator.next();
                    }
                }
                return historyAndForecastDTO;
            } catch (IOException e) {
                log.error(e.getMessage(), e);
                throw new ParseReportException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(),
                        "parse shiji [History and Forecast Report] report error", e);
            }
        }

    }