# MonthlyRevenueCommonServiceImpl.java

    package cloud.wconnect.rateshop.service.weeklymonthlyrevenue.impl;

    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.rateshop.service.weeklymonthlyrevenue.IMonthlyRevenueCommonService;
    import org.springframework.stereotype.Service;

    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.Objects;

    /**
     * @author zc
     * @date 2025/10/14
     */
    @Service
    public class MonthlyRevenueCommonServiceImpl implements IMonthlyRevenueCommonService {

        /**
         * 获取 OCC%
         *
         * @param roomsSold    售出房间数量
         * @param roomsTotal   房间总数
         * @param roundingMode 舍入模式
         * @return java.math.BigDecimal
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public BigDecimal getOcc(Integer roomsSold, Integer roomsTotal, RoundingMode roundingMode) {
            if (Objects.isNull(roomsSold) || Objects.isNull(roomsTotal) || roomsTotal == 0) {
                return null;
            }
            return new BigDecimal(roomsSold.toString()).multiply(new BigDecimal("100"))
                    .divide(new BigDecimal(roomsTotal.toString()),
                            BaseConstant.DATA_PRECISION, roundingMode);
        }

        /**
         * 获取 OCC% [Long]
         *
         * @param roomsSold    售出房间数量
         * @param roomsTotal   房间总数
         * @param roundingMode 舍入模式
         * @return java.math.BigDecimal
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public BigDecimal getOcc(Long roomsSold, Long roomsTotal, RoundingMode roundingMode) {
            if (Objects.isNull(roomsSold) || Objects.isNull(roomsTotal) || roomsTotal == 0) {
                return null;
            }
            return new BigDecimal(roomsSold.toString()).multiply(new BigDecimal("100"))
                    .divide(new BigDecimal(roomsTotal.toString()),
                            BaseConstant.DATA_PRECISION, roundingMode);
        }

        /**
         * 获取可售房间数
         *
         * @param roomsTotal 房间总数
         * @param ooo        OOO 房间数
         * @return java.lang.Integer
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public Integer getSellableCapacity(Integer roomsTotal, Integer ooo) {
            if (Objects.isNull(roomsTotal)) {
                return null;
            }
            if (Objects.isNull(ooo)) {
                ooo = 0;
            }
            return roomsTotal - ooo;
        }

        /**
         * 获取可售房间数 [Long]
         *
         * @param roomsTotal 房间总数
         * @param ooo        OOO 房间数
         * @return java.lang.Long
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public Long getSellableCapacity(Long roomsTotal, Long ooo) {
            if (Objects.isNull(roomsTotal)) {
                return null;
            }
            if (Objects.isNull(ooo)) {
                ooo = 0L;
            }
            return roomsTotal - ooo;
        }

        /**
         * 获取剩余可售房间数
         *
         * @param roomsTotal 房间总数
         * @param roomsSold  售出房间数量
         * @param ooo        OOO 房间数
         * @return java.lang.Integer
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public Integer getRoomLeftToSell(Integer roomsTotal, Integer roomsSold, Integer ooo) {
            if (Objects.isNull(roomsTotal)) {
                return null;
            }
            if (Objects.isNull(roomsSold)) {
                roomsSold = 0;
            }
            if (Objects.isNull(ooo)) {
                ooo = 0;
            }
            return roomsTotal - roomsSold - ooo;
        }

        /**
         * 获取剩余可售房间数 [Long]
         *
         * @param roomsTotal 房间总数
         * @param roomsSold  售出房间数量
         * @param ooo        OOO 房间数
         * @return java.lang.Long
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public Long getRoomLeftToSell(Long roomsTotal, Long roomsSold, Long ooo) {
            if (Objects.isNull(roomsTotal)) {
                return null;
            }
            if (Objects.isNull(roomsSold)) {
                roomsSold = 0L;
            }
            if (Objects.isNull(ooo)) {
                ooo = 0L;
            }
            return roomsTotal - roomsSold - ooo;
        }

        /**
         * 获取 ADR
         *
         * @param totalRevenue 总收入
         * @param roomsSold    售出房间数量
         * @param roundingMode 舍入模式
         * @return java.math.BigDecimal
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public BigDecimal getAdr(BigDecimal totalRevenue, Integer roomsSold, RoundingMode roundingMode) {
            if (Objects.isNull(totalRevenue) || Objects.isNull(roomsSold) || roomsSold == 0) {
                return null;
            }
            return totalRevenue.divide(new BigDecimal(roomsSold.toString()), BaseConstant.DATA_PRECISION, roundingMode);
        }

        /**
         * 获取 ADR [Long]
         *
         * @param totalRevenue 总收入
         * @param roomsSold    售出房间数量
         * @param roundingMode 舍入模式
         * @return java.math.BigDecimal
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public BigDecimal getAdr(BigDecimal totalRevenue, Long roomsSold, RoundingMode roundingMode) {
            if (Objects.isNull(totalRevenue) || Objects.isNull(roomsSold) || roomsSold == 0) {
                return null;
            }
            return totalRevenue.divide(new BigDecimal(roomsSold.toString()), BaseConstant.DATA_PRECISION, roundingMode);
        }

        /**
         * 获取 RevPar
         *
         * @param totalRevenue 总收入
         * @param roomsTotal   房间总数
         * @param roundingMode 舍入模式
         * @return java.math.BigDecimal
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public BigDecimal getRevPar(BigDecimal totalRevenue, Integer roomsTotal, RoundingMode roundingMode) {
            if (Objects.isNull(totalRevenue) || Objects.isNull(roomsTotal) || roomsTotal == 0) {
                return null;
            }
            return totalRevenue.divide(new BigDecimal(roomsTotal.toString()), BaseConstant.DATA_PRECISION, roundingMode);
        }

        /**
         * 获取 RevPar [Long]
         *
         * @param totalRevenue 总收入
         * @param roomsTotal   房间总数
         * @param roundingMode 舍入模式
         * @return java.math.BigDecimal
         * @author zc
         * @date 2025/10/14
         */
        @Override
        public BigDecimal getRevPar(BigDecimal totalRevenue, Long roomsTotal, RoundingMode roundingMode) {
            if (Objects.isNull(totalRevenue) || Objects.isNull(roomsTotal) || roomsTotal == 0) {
                return null;
            }
            return totalRevenue.divide(new BigDecimal(roomsTotal.toString()), BaseConstant.DATA_PRECISION, roundingMode);
        }
    }