# GmWeeklyReportConfigController.java

    package cloud.wconnect.workperformance.controller.gmwr;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.cons.CommonFieldI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.workperformance.cons.gmwr.GmwrCategoryEnum;
    import cloud.wconnect.workperformance.cons.gmwr.GmwrErrorI18nConstant;
    import cloud.wconnect.workperformance.cons.gmwr.GmwrHotelKpiCategoryEnum;
    import cloud.wconnect.workperformance.cons.gmwr.GmwrI18nConstant;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.hotelkpi.config.GmwrHotelKpiConfigItemMetricsDTO;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.hotelkpi.config.GmwrHotelKpiConfigSaveDTO;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.monthend.GmwrMonthEndForecastConfigBasicDTO;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.monthend.GmwrMonthEndForecastConfigDTO;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.selloutefficiency.GmwrOccSelloutConfigDTO;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.view.GmwrViewItemDTO;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.view.GmwrViewModuleDTO;
    import cloud.wconnect.workperformance.service.gmwr.IGmwrHotelKpiViewConfigService;
    import cloud.wconnect.workperformance.service.gmwr.IGmwrMonthEndForecastConfigService;
    import cloud.wconnect.workperformance.service.gmwr.IGmwrOccSelloutConfigService;
    import cloud.wconnect.workperformance.service.gmwr.IGmwrViewConfigService;
    import com.google.common.collect.Sets;
    import jakarta.annotation.Resource;
    import jakarta.validation.Valid;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.*;

    import java.util.*;

    /**
     * Controller: GM Weekly Report Config
     *
     * @author zc
     * @date 2024/10/19
     */
    @Validated
    @RestController
    @RequestMapping("/gm-weekly-report")
    public class GmWeeklyReportConfigController {
        @Resource
        private IGmwrHotelKpiViewConfigService hotelKpiViewConfigService;
        @Resource
        private IGmwrOccSelloutConfigService occSelloutConfigService;
        @Resource
        private IGmwrMonthEndForecastConfigService monthEndForecastConfigService;
        @Resource
        private IGmwrViewConfigService viewConfigService;
        @Resource
        private SessionContext sessionContext;
        @Resource
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 获取 Hotel KPI 显示配置
         *
         * @param property 资产标识
         * @param category Hotel KPI 分类
         * @return GmwrHotelKpiDetailDTO 集合
         * @author zc
         * @date 2024/12/30
         */
        @ApiId(1283)
        @GetMapping("/hotel-kpi/view-config")
        public List<GmwrHotelKpiConfigItemMetricsDTO> listHotelKpiViewConfig(@RequestParam String property, int category) {
            String categoryTitle = GmwrHotelKpiCategoryEnum.getTitle(category);
            if (StringUtils.isBlank(categoryTitle)) {
                return Collections.emptyList();
            }
            int propertyId = sessionContext.getPropertyId(property);
            return hotelKpiViewConfigService.list(propertyId, category, categoryTitle);
        }

        /**
         * 保存 Hotel KPI 显示配置
         *
         * @param property 资产标识
         * @return empty map
         * @author zc
         * @date 2024/12/30
         */
        @ApiId(1284)
        @PostMapping("/hotel-kpi/view-config")
        public Map<Object, Object> saveHotelKpiViewConfig(@RequestParam String property, @RequestBody @Valid GmwrHotelKpiConfigSaveDTO configSaveDTO) {
            int propertyId = sessionContext.getPropertyId(property);
            hotelKpiViewConfigService.save(propertyId, configSaveDTO, sessionContext.getLoginUserId());
            return Collections.emptyMap();
        }

        /**
         * 获取 Sellout Efficiency 配置
         *
         * @param property 资产标识
         * @return GmwrOccJudgmentConfigDTO
         * @author zc
         * @date 2024/12/30
         */
        @ApiId(1286)
        @GetMapping("/sellout-efficiency/config")
        public GmwrOccSelloutConfigDTO getSelloutEfficiencyConfig(@RequestParam String property) {
            int propertyId = sessionContext.getPropertyId(property);
            return occSelloutConfigService.getByPropertyId(propertyId);
        }

        /**
         * 保存 Sellout Efficiency 配置
         *
         * @param property 资产标识
         * @return empty map
         * @author zc
         * @date 2024/12/30
         */
        @ApiId(1287)
        @PostMapping("/sellout-efficiency/config")
        public Map<Object, Object> saveSelloutEfficiencyConfig(@RequestParam String property, @RequestBody @Valid GmwrOccSelloutConfigDTO saveConfigDTO) {
            int propertyId = sessionContext.getPropertyId(property);
            occSelloutConfigService.save(propertyId, saveConfigDTO, sessionContext.getLoginUserId());
            return Collections.emptyMap();
        }

        /**
         * 获取 Month End Forecast Config
         *
         * @param property 资产标识
         * @return GmwrMonthEndForecastConfigDTO
         * @author zc
         * @date 2024/10/16
         */
        @ApiId(1294)
        @GetMapping("/month-end/forecast-config")
        public List<GmwrMonthEndForecastConfigDTO> getMonthEndForecastConfig(@RequestParam String property) {
            int propertyId = sessionContext.getPropertyId(property);
            return monthEndForecastConfigService.get(propertyId);
        }

        /**
         * 保存 Month End Forecast Config
         *
         * @param property      资产标识
         * @param configDTOList 配置集合
         * @return empty map
         * @author zc
         * @date 2024/10/16
         */
        @ApiId(1295)
        @PostMapping("/month-end/forecast-config")
        public Map<Object, Object> saveMonthEndForecastConfig(@RequestParam String property,
                                                              @RequestBody List<@Valid GmwrMonthEndForecastConfigBasicDTO> configDTOList) {
            // 校验数据长度
            if (configDTOList.size() != 6) {
                throw new BadRequestException(CommonErrorI18nConstant.LIST_SIZE_MUST_BE,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(GmwrI18nConstant.ROOM_REVENUE_CATEGORY_DATA_EXTRACTION_CONFIG, 6),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The configDTOList size must be 6");
            }
            // 校验数据分类不能重复
            if (configDTOList.stream().map(GmwrMonthEndForecastConfigBasicDTO::getCategory).distinct().count() != configDTOList.size()) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_CANNOT_REPEAT,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.CATEGORY),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The category cannot be repeated");
            }
            int propertyId = sessionContext.getPropertyId(property);
            monthEndForecastConfigService.save(propertyId, configDTOList, sessionContext.getLoginUserId());
            return Collections.emptyMap();
        }

        /**
         * 获取 View Config
         *
         * @param property 资产标识
         * @return GmwrViewModuleDTO
         * @author zc
         * @date 2024/12/31
         */
        @ApiId(1320)
        @GetMapping("/view-config")
        public List<GmwrViewModuleDTO> getViewConfig(@RequestParam String property) {
            int propertyId = sessionContext.getPropertyId(property);
            return viewConfigService.get(propertyId);
        }

        /**
         * 保存 View Config
         *
         * @param property          资产标识
         * @param saveConfigDTOList 保存配置DTO
         * @return empty map
         * @author zc
         * @date 2024/12/31
         */
        @ApiId(1321)
        @PostMapping("/view-config")
        public Map<Object, Object> saveViewConfig(@RequestParam String property, @RequestBody List<@Valid GmwrViewModuleDTO> saveConfigDTOList) {
            if (CollectionUtils.isNotEmpty(saveConfigDTOList)) {
                List<Integer> saveCategoryList = saveConfigDTOList.stream().map(GmwrViewModuleDTO::getList)
                        .flatMap(Collection::stream).map(GmwrViewItemDTO::getCategory).toList();
                HashSet<Integer> saveCategorySet = Sets.newHashSet(saveCategoryList);
                if (saveCategoryList.size() != saveCategorySet.size()) {
                    throw new BadRequestException(CommonErrorI18nConstant.DATA_CANNOT_REPEAT,
                            i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.CATEGORY),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                            "The category cannot be repeat.");
                }
                List<Integer> necessaryCategoryList = GmwrCategoryEnum.getNecessaryCategoryList();
                if (!saveCategorySet.containsAll(necessaryCategoryList)) {
                    List<Integer> lackNeccessaryCategoryList = necessaryCategoryList.stream()
                            .filter(category -> !saveCategorySet.contains(category)).toList();
                    throw new BadRequestException(GmwrErrorI18nConstant.MODULE_VIEW_CONFIG_MISS_NECESSARY_CATEGORY,
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                            "The category is not enough; lack of the necessary category:" + lackNeccessaryCategoryList);
                }
            }
            int propertyId = sessionContext.getPropertyId(property);
            viewConfigService.save(propertyId, saveConfigDTOList, sessionContext.getLoginUserId());
            return Collections.emptyMap();
        }
    }