# WeeklyMonthlyRevenueOtherController.java

    package cloud.wconnect.rateshop.controller.weeklymonthlyrevenue;

    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.rateshop.cons.weeklymonthlyrevenue.MonthlyRevenueI18nConstant;
    import cloud.wconnect.rateshop.entity.weeklymonthlyrevenue.WeeklyMonthlyRevenueOther;
    import cloud.wconnect.rateshop.pojo.dto.weeklymonthlyrevenue.WeeklyMonthlyRevenueOtherCopyToDTO;
    import cloud.wconnect.rateshop.pojo.dto.weeklymonthlyrevenue.WeeklyMonthlyRevenueOtherDTO;
    import cloud.wconnect.rateshop.pojo.dto.weeklymonthlyrevenue.WeeklyMonthlyRevenueOtherRevenueDTO;
    import cloud.wconnect.rateshop.pojo.dto.weeklymonthlyrevenue.WeeklyMonthlyRevenueOtherValueDTO;
    import cloud.wconnect.rateshop.service.weeklymonthlyrevenue.IWeeklyMonthlyRevenueOtherService;
    import com.google.common.collect.Lists;
    import jakarta.annotation.Resource;
    import jakarta.validation.Valid;
    import org.springframework.web.bind.annotation.*;

    import java.text.MessageFormat;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;

    /**
     * <p>
     * Weekly Monthly Revenue other 前端控制器
     * </p>
     *
     * @author zc
     * @since 2024-05-13
     */
    @RestController
    @RequestMapping("/weekly-monthly-revenue/other-revenue")
    public class WeeklyMonthlyRevenueOtherController {

        @Resource
        private IWeeklyMonthlyRevenueOtherService revenueOtherService;
        @Resource
        private SessionContext sessionContext;
        @Resource
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 获取指定年月的 Other Revenue
         *
         * @param property 资产标识
         * @param theMonth 年月（yyyyMM）
         * @param category 分类 （1:"F&B"; 2:"MISC"）
         * @return WeeklyMonthlyRevenueOtherRevenueDTO 集合
         * @author zc
         * @date 2024/5/15
         */
        @ApiId(1163)
        @GetMapping
        public List<WeeklyMonthlyRevenueOtherRevenueDTO> get(@RequestParam String property, @RequestParam long theMonth,
                                                             @RequestParam int category) {
            if (!Lists.newArrayList(WeeklyMonthlyRevenueOther.CATEGORY_F_B,
                    WeeklyMonthlyRevenueOther.CATEGORY_MISC).contains(category)) {
                throw new BadRequestException(CommonErrorI18nConstant.MUST_IN_LIST,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.CATEGORY,
                                List.of(MonthlyRevenueI18nConstant.OTHER_CATEGORY_FB,
                                        MonthlyRevenueI18nConstant.OTHER_CATEGORY_MISC)),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The category must be in [1:F&B, 2:MISC]");
            }
            int propertyId = sessionContext.getPropertyId(property);
            return revenueOtherService.getOtherRevenue(propertyId, theMonth, category);
        }

        /**
         * 保存指定年月的 Other Revenue
         *
         * @param property        资产标识
         * @param revenueOtherDTO Other Revenue DTO
         * @return empty map
         * @author zc
         * @date 2024/5/15
         */
        @ApiId(1164)
        @PostMapping
        public Map<Object, Object> save(@RequestParam String property, @RequestBody @Valid WeeklyMonthlyRevenueOtherDTO revenueOtherDTO) {
            // 校验入参
            List<WeeklyMonthlyRevenueOtherRevenueDTO> otherRevenues = revenueOtherDTO.getOtherRevenues();
            if (otherRevenues.stream().map(WeeklyMonthlyRevenueOtherRevenueDTO::getType)
                    .distinct().count() != otherRevenues.size()) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_CANNOT_REPEAT,
                        i18nMessageUtils.getErrorParamMapNotNeedTranslate("otherRevenues"),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The otherRevenues cannot contain duplicate type");
            }
            for (WeeklyMonthlyRevenueOtherRevenueDTO otherRevenue : otherRevenues) {
                List<WeeklyMonthlyRevenueOtherValueDTO> otherRevenueValues = otherRevenue.getValues();
                if (otherRevenueValues.stream().map(WeeklyMonthlyRevenueOtherValueDTO::getTitle)
                        .distinct().count() != otherRevenueValues.size()) {
                    throw new BadRequestException(CommonErrorI18nConstant.DATA_CANNOT_REPEAT,
                            i18nMessageUtils.getErrorParamMapNotNeedTranslate("otherRevenueValues"),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                            "The otherRevenueValues cannot contain duplicate title");
                }
            }
            int propertyId = sessionContext.getPropertyId(property);
            revenueOtherService.saveOtherRevenue(propertyId, revenueOtherDTO, sessionContext.getLoginUserId());
            return Collections.emptyMap();
        }

        /**
         * 获取指定年份中没有指定分类 Other revenue 数据的月份
         *
         * @param property 资产标识
         * @param theYear  年（yyyy）
         * @param category 分类 （0:"ALL"; 1:"F&B"; 2:"MISC"）
         * @return java.util.List<java.lang.Long>
         * @author zc
         * @date 2024/5/15
         */
        @ApiId(1165)
        @GetMapping("/no-data-month")
        public List<Long> listNoDataMonth(@RequestParam String property, @RequestParam long theYear, @RequestParam int category) {
            if (!Lists.newArrayList(WeeklyMonthlyRevenueOther.CATEGORY_ALL, WeeklyMonthlyRevenueOther.CATEGORY_F_B,
                    WeeklyMonthlyRevenueOther.CATEGORY_MISC).contains(category)) {
                throw new BadRequestException(CommonErrorI18nConstant.MUST_IN_LIST,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.CATEGORY,
                                List.of(MonthlyRevenueI18nConstant.OTHER_CATEGORY_ALL,
                                        MonthlyRevenueI18nConstant.OTHER_CATEGORY_FB,
                                        MonthlyRevenueI18nConstant.OTHER_CATEGORY_MISC)),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The category must be in [0:ALL, 1:F&B, 2:MISC]");
            }
            int propertyId = sessionContext.getPropertyId(property);
            return revenueOtherService.listNoDataMonth(propertyId, theYear, category);
        }

        /**
         * 拷贝指定年月 Other Revenue 到指定年月
         *
         * @param property  资产标识
         * @param copyToDTO Copy To DTO
         * @return empty map
         * @author zc
         * @date 2024/5/15
         */
        @ApiId(1166)
        @PostMapping("/copy-to")
        public Map<Object, Object> copyTo(@RequestParam String property, @RequestBody @Valid WeeklyMonthlyRevenueOtherCopyToDTO copyToDTO) {
            // From month 不能等于 To month
            if (copyToDTO.getFromMonth().equals(copyToDTO.getToMonth())) {
                throw new BadRequestException(CommonErrorI18nConstant.START_DATE_CANNOT_GREATER_THAN_END_DATE,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The fromMonth cannot equal to the toMonth");
            }
            int propertyId = sessionContext.getPropertyId(property);
            // 若 fromMonth otherRevenueData 不存在，则不能 copy
            if (!revenueOtherService.checkAlreadyExist(propertyId, copyToDTO.getFromMonth(), copyToDTO.getCategory())) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_EXIST,
                        i18nMessageUtils.getErrorParamMapNotNeedTranslate("fromMonth otherRevenueData"),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        MessageFormat.format("The fromMonth otherRevenueData is not exist, fromMonth:{0}; category:{1}",
                                copyToDTO.getFromMonth().toString(), copyToDTO.getCategory()));
            }
            // 若 toMonth otherRevenueData 已存在，则不能 copy
            if (revenueOtherService.checkAlreadyExist(propertyId, copyToDTO.getToMonth(), copyToDTO.getCategory())) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_ALREADY_EXIST,
                        i18nMessageUtils.getErrorParamMapNotNeedTranslate("toMonth otherRevenueData"),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        MessageFormat.format("The toMonth otherRevenueData already exist, toMonth:{0}; category:{1}",
                                copyToDTO.getToMonth().toString(), copyToDTO.getCategory()));
            }

            revenueOtherService.copyTo(propertyId, copyToDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }
    }