# RevenueEmailConfigController.java

    package cloud.wconnect.rateshop.controller.revenue;

    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.cons.EmailConfigCons;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.pojo.dto.UsergroupDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.service.UsergroupInternalService;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.rateshop.cons.revenue.DailyRevenueNotifyTypeEnum;
    import cloud.wconnect.rateshop.pojo.dto.revenue.RevenueEmailConfigDTO;
    import cloud.wconnect.rateshop.pojo.dto.revenue.RevenueEmailTargetDTO;
    import cloud.wconnect.rateshop.service.revenue.IRevenueEmailConfigService;
    import cloud.wconnect.rateshop.service.revenue.IRevenueService;
    import com.google.common.collect.ImmutableMap;
    import com.google.common.collect.Lists;
    import jakarta.validation.Valid;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;

    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 邮件配置表 前端控制器
     * </p>
     *
     * @author yyt
     * @since 2023-10-26
     */
    @RestController
    @RequestMapping("/revenue/email-config")
    public class RevenueEmailConfigController {

        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private IRevenueEmailConfigService revenueEmailConfigService;
        @Autowired
        private UsergroupInternalService usergroupInternalService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private IRevenueService revenueService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 获取邮件配置
         *
         * @param property 资产标识
         * @param type       类型 (1:History and Forecast,2:Business Block,3:Reservation Statistics,4:Reservation Forecast,
         *                   5:Reservation Forecast Next Month,6:History Forecast Next Month,
         *                   8: Reservations Forecast Next 14 days,9:History and Forecast Next 90 days,10:Market Code,
         *                   11:Occ jump alert，12：History and Forecast this month（future），13：History and Forecast next month（future），
         *                   14：History and Forecast the month after next
         *                   16：Reservation Forecast next 90 days，17：History and Forecast Business Block next 90 days,
         *                   19：Manager flash 20：Detailed Availability 未来14天报告缺失 21：Rate Review 通知
         *                   22: Group Pickup 23: History and Forecast from thirty days ago to yesterday,
         *                   24: reservation forecast this month,
         *                   25：Occupancy Summary yesterday,
         *                   26：Market Segment Summary yesterday,
         *                   27：Market Segment Summary history 30 days)
         * @return 邮件配置
         * @author yyt
         * @date 2023/10/28
         */
        @ApiId(875)
        @GetMapping
        public RevenueEmailConfigDTO get(String property, @RequestParam int type) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(sessionContext.getPropertyId(property));
            revenueService.checkType(propertyDTO.getPmsType(), type);
            return revenueEmailConfigService.getDTO(propertyDTO, type);
        }

        /**
         * 保存邮件配置
         *
         * @param property  资产标识
         * @param configDTO 邮件配置
         * @return 配置 id
         * @author yyt
         * @date 2023/10/28
         */
        @ApiId(876)
        @PostMapping
        public Map save(String property, @Valid @RequestBody RevenueEmailConfigDTO configDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);
            // 检查目标（用户/用户组）是否存在
            checkTargetExist(propertyId, configDTO.getToList(), configDTO.getCcList());

            revenueService.checkType(propertyI18nRedisService.get(propertyId).getPmsType(), configDTO.getType());

            if (Objects.equals(configDTO.getType(), DailyRevenueNotifyTypeEnum.RATE_REVIEW_NOTIFY.getType())
                    && StringUtils.isNotBlank(configDTO.getSubject())) {
                throw new BadRequestException(CommonErrorI18nConstant.MUST_EMPTY,
                        i18nMessageUtils.getErrorParamMapNotNeedTranslate("subject"),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "rate review notify subject must be empty");
            }

            return ImmutableMap.of("id", revenueEmailConfigService.save(propertyId, configDTO));
        }

        /**
         * 检查目标（用户/用户组）是否存在
         *
         * @param propertyId 资产 id
         * @param toList     to
         * @param ccList     cc
         * @author yyt
         * @date 2024/3/11
         **/
        private void checkTargetExist(Integer propertyId, List<RevenueEmailTargetDTO> toList, List<RevenueEmailTargetDTO> ccList) {
            List<Integer> userIds = Lists.newArrayList();
            List<Integer> userGroupIds = Lists.newArrayList();
            if (CollectionUtils.isNotEmpty(toList)) {
                Map<Integer, List<Integer>> targetIdByUserSource = toList.stream().collect(Collectors.groupingBy(RevenueEmailTargetDTO::getSource,
                        Collectors.collectingAndThen(Collectors.toList(), item -> item.stream().map(RevenueEmailTargetDTO::getIdentityId).toList())));
                userIds.addAll(targetIdByUserSource.getOrDefault(EmailConfigCons.SOURCE_USER, Collections.emptyList()));
                userGroupIds.addAll(targetIdByUserSource.getOrDefault(EmailConfigCons.SOURCE_USERGROUP, Collections.emptyList()));
            }
            if (CollectionUtils.isNotEmpty(ccList)) {
                Map<Integer, List<Integer>> targetIdByUserSource = ccList.stream().collect(Collectors.groupingBy(RevenueEmailTargetDTO::getSource,
                        Collectors.collectingAndThen(Collectors.toList(), item -> item.stream().map(RevenueEmailTargetDTO::getIdentityId).toList())));
                userIds.addAll(targetIdByUserSource.getOrDefault(EmailConfigCons.SOURCE_USER, Collections.emptyList()));
                userGroupIds.addAll(targetIdByUserSource.getOrDefault(EmailConfigCons.SOURCE_USERGROUP, Collections.emptyList()));
            }
            Integer tenantId = sessionContext.getTenantSymbolBO().getId();
            if (CollectionUtils.isNotEmpty(userIds)) {
                List<UserDTO> users = userInternalService.getUsers(tenantId, userIds);
                if (users.size() != userIds.size()) {
                    throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_EXIST,
                            i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.USER),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the user is not found");
                }
            }
            if (CollectionUtils.isNotEmpty(userGroupIds)) {
                List<UsergroupDTO> usergroups = usergroupInternalService.getUsergroups(tenantId, propertyId, userGroupIds);
                if (usergroups.size() != userGroupIds.size()) {
                    throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_EXIST,
                            i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.USER_GROUP),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the userGroup is not found");
                }
            }
        }

    }