# GstLedgOvBalanceReservationServiceImpl.java

    package cloud.wconnect.frontoffice.service.guestledgercheck.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.frontoffice.entity.guestledgercheck.GstLedgOpBalanceReservation;
    import cloud.wconnect.frontoffice.entity.guestledgercheck.GstLedgOvBalanceReservation;
    import cloud.wconnect.frontoffice.mapper.guestledgercheck.GstLedgOvBalanceReservationMapper;
    import cloud.wconnect.frontoffice.pojo.dto.guestledgercheck.OvBalanceRvAmountDTO;
    import cloud.wconnect.frontoffice.pojo.dto.guestledgercheck.OvBalanceRvDTO;
    import cloud.wconnect.frontoffice.service.guestledgercheck.IGstLedgOpBalanceReservationService;
    import cloud.wconnect.frontoffice.service.guestledgercheck.IGstLedgOvBalanceReservationService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.List;
    import java.util.Map;
    import java.util.stream.Stream;

    import static java.util.stream.Collectors.toList;

    /**
     * <p>
     * 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2023-03-17
     */
    @Service
    @DS("logbook")
    public class GstLedgOvBalanceReservationServiceImpl extends ServiceImpl<GstLedgOvBalanceReservationMapper, GstLedgOvBalanceReservation> implements IGstLedgOvBalanceReservationService {

        @Autowired
        private IGstLedgOpBalanceReservationService opBalanceReservationService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 把OverBalance移动到OpenBalance
         *
         * @param propertyDTO 资产DTO
         * @param rvId        移动的OverBalanceId
         * @param newRv       新的OpenBalance对象
         * @param loginUserId 登录用户id
         * @return void
         * @author lichen
         * @date 2023/12/9
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void move(PropertyDTO propertyDTO, long rvId, GstLedgOpBalanceReservation newRv, int loginUserId) {
            opBalanceReservationService.save(propertyDTO, newRv, null, loginUserId);
            removeById(rvId);
        }

        /**
         * 更新Current Balance/Auth Amount
         *
         * @param ovBalanceRvAmountDTO 修改的OverBalance数据
         * @param oriRv                原始OverBalance数据
         * @param loginUserId          登录用户Id
         * @return void
         * @author lichen
         * @date 2025/8/25
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void update(OvBalanceRvAmountDTO ovBalanceRvAmountDTO, GstLedgOvBalanceReservation oriRv, int loginUserId) {
            if (ovBalanceRvAmountDTO.getType() == OvBalanceRvAmountDTO.TYPE_CURRENT_BALANCE) {
                if (oriRv.getCurrentBalance().compareTo(ovBalanceRvAmountDTO.getAmount()) != 0) {
                    oriRv.setCurrentBalance(ovBalanceRvAmountDTO.getAmount());
                    oriRv.setCurrBalUpdatedBy(loginUserId);
                    oriRv.setCurrBalUpdatedTime(DateTimeUtils.nowTimestamp());
                }
            } else {
                if (oriRv.getAuthAmount().compareTo(ovBalanceRvAmountDTO.getAmount()) != 0) {
                    oriRv.setAuthAmount(ovBalanceRvAmountDTO.getAmount());
                    oriRv.setAuthAmntUpdateBy(loginUserId);
                    oriRv.setAuthAmntUpdatedTime(DateTimeUtils.nowTimestamp());
                }
            }
            updateById(oriRv);
        }

        /**
         * 查询OverBalance数据
         *
         * @param propertyId 资产Id
         * @return java.util.List<cloud.wconnect.frontoffice.entity.guestledger.GstLedgOvBalanceReservation>
         * @author lichen
         * @date 2024/3/16
         */
        @Override
        public List<GstLedgOvBalanceReservation> listByPropertyId(Integer propertyId) {
            return list(new LambdaQueryWrapper<GstLedgOvBalanceReservation>()
                    .eq(GstLedgOvBalanceReservation::getPropertyId, propertyId)
                    .orderByDesc(GstLedgOvBalanceReservation::getId));
        }

        /**
         * 分页查询OverBalance数据
         *
         * @param tenantId   租户Id
         * @param propertyId 资产Id
         * @param page       页码
         * @param size       每页数量
         * @return cloud.wconnect.commonlib.pojo.dto.ListPagedDTO<cloud.wconnect.frontoffice.pojo.dto.guestledgercheck.OvBalanceRvDTO>
         * @author lichen
         * @date 2025/8/25
         */
        @Override
        public ListPagedDTO<OvBalanceRvDTO> pageList(Integer tenantId, int propertyId, Integer page, Integer size) {
            //查询over balance Reservation列表
            Page<GstLedgOvBalanceReservation> resultPage = page(new Page<>(page, size),
                    new LambdaQueryWrapper<GstLedgOvBalanceReservation>().eq(GstLedgOvBalanceReservation::getPropertyId, propertyId)
                            .orderByDesc(GstLedgOvBalanceReservation::getId));
            if (resultPage.getTotal() == BaseConstant.ZERO) {
                return new ListPagedDTO<>();
            }
            List<GstLedgOvBalanceReservation> reservations = resultPage.getRecords();

            //获取用户信息
            List<Integer> userList = reservations.stream()
                    .flatMap(rv -> Stream.of(rv.getCurrBalUpdatedBy(), rv.getAuthAmntUpdateBy()))
                    .distinct().collect(toList());

            Map<Integer, String> userId2Name = userInternalService.getNameMapByIds(tenantId, userList);

            //List<GstLedgOvBalanceReservation> -> List<OvBalanceRvDTO>
            List<OvBalanceRvDTO> ovRvDtos = beanMapper.mapList(reservations, OvBalanceRvDTO.class, (rv, rvDto) -> {
                rvDto.setCrsNumberList(Stream.of(StringUtils.split(rv.getCrsNumbers(), ",")).collect(toList()));
                rvDto.setCurrBalUpdatedByName(userId2Name.get(rv.getCurrBalUpdatedBy()));
                rvDto.setAuthAmntUpdateByName(userId2Name.get(rv.getAuthAmntUpdateBy()));
            });
            return new ListPagedDTO<>(resultPage.getTotal(), ovRvDtos);
        }

    }