# GroupPickupFileParseImpl.java

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

    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.cons.SystemPlatformEnum;
    import cloud.wconnect.commonlib.pojo.bo.ReportDataBO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.rateshop.cons.rateshop.BookingStatusForOperaGroupPicupEnum;
    import cloud.wconnect.rateshop.pojo.bo.revenue.DailySummaryGroupPickupBO;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.Node;
    import org.dom4j.io.SAXReader;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.io.InputStream;
    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.time.format.DateTimeFormatter;
    import java.util.List;
    import java.util.Locale;

    /**
     * @author yyt
     * 2025/6/24
     */
    @Service
    @DS("rate_shop")
    public class GroupPickupFileParseImpl implements IGroupPickupFileParse {

        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;

        private static final String SOURCE = SystemPlatformEnum.OPERA.getDesc();

        /**
         * 判断支持的平台
         *
         * @param source 平台
         * @return boolean
         * @author yyt
         * @date 2025/6/24
         */
        @Override
        public boolean supports(String source) {
            return SOURCE.equals(source);
        }

        /**
         * 解析报告 group pickup 数据
         *
         * @param propertyId 资产 id
         * @param timeZone   时区
         * @param in         文件流
         * @param startDate  开始日期
         * @param endDate    结束日期
         * @return group pickup
         * @author yyt
         * @date 2025/6/24
         */
        @Override
        public ReportDataBO<DailySummaryGroupPickupBO> parseReport(Integer propertyId, String timeZone, InputStream in,
                                                                   Long startDate, Long endDate) throws Exception {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(BaseConstant.DATE_FORMAT_DD_MMM_YY, Locale.ENGLISH);
            ZoneId zoneId = ZoneId.of(propertyDTO.getTimezone());

            // 报告中的数据在处理范围内
            boolean isInScope = false;
            List<DailySummaryGroupPickupBO> groupPickupBOList = Lists.newArrayList();

            Document document = new SAXReader().read(in);
            List<Node> nodes = document.selectNodes("//G_ALLOTMENT_CODE");
            for (Node node : nodes) {
                Element dataElement = (Element) node;

                Element listAllotmentDate = dataElement.element("LIST_G_ALLOTMENT_DATE");
                List<Element> allotmentDateList = listAllotmentDate.elements("G_ALLOTMENT_DATE");
                if (CollectionUtils.isEmpty(allotmentDateList)) {
                    continue;
                }

                String description = dataElement.element("DESCRIPTION").getTextTrim();

                // Booking status
                String bookingStatusStr = dataElement.element("BOOKING_STATUS").getTextTrim();
                if (StringUtils.isBlank(bookingStatusStr)) {
                    continue;
                }
                int bookingStatus = BookingStatusForOperaGroupPicupEnum.getCodeBySymbol(bookingStatusStr);
                if (bookingStatus == BaseConstant.ZERO) {
                    continue;
                }

                for (Element allotmentDateElement : allotmentDateList) {
                    Element listBlockSize = allotmentDateElement.element("LIST_G_BLOCKSIZE");
                    List<Element> blocksizeList = listBlockSize.elements("G_BLOCKSIZE");
                    if (CollectionUtils.isEmpty(blocksizeList)) {
                        continue;
                    }

                    String allotmentDateStr = allotmentDateElement.element("ALLOTMENT_DATE").getTextTrim();
                    String[] consideredDateArr = StringUtils.split(allotmentDateStr, "-");
                    consideredDateArr[1] = DateTimeUtils.capitalize(consideredDateArr[1]);
                    LocalDate localDate = LocalDate.parse(String.join("-", consideredDateArr), dateTimeFormatter);
                    long allotmentDate = DateTimeUtils.toTimestamp(localDate.atStartOfDay(zoneId));

                    // 判断数据日期是否在开始日期 和 结束日期之间
                    if (allotmentDate < startDate || allotmentDate > endDate) {
                        continue;
                    } else {
                        isInScope = true;
                    }

                    for (Element blocksizeElement : blocksizeList) {
                        // Rooms pickup
                        String pickupStr = blocksizeElement.element("PICKUP").getTextTrim();
                        Integer pickup = StringUtils.isEmpty(pickupStr) ? null : Integer.parseInt(pickupStr);

                        groupPickupBOList.add(DailySummaryGroupPickupBO.builder()
                                .bookingStatus(bookingStatus)
                                .groupName(description)
                                .roomPickup(pickup)
                                .build());
                    }
                }
            }

            return new ReportDataBO<>(isInScope, groupPickupBOList);
        }

    }