# GstLedgPaidAmountServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.frontoffice.entity.guestledgercheck.GstLedgOpBalanceReservation;
    import cloud.wconnect.frontoffice.entity.guestledgercheck.GstLedgPaidAmount;
    import cloud.wconnect.frontoffice.mapper.guestledgercheck.GstLedgOpBalanceReservationMapper;
    import cloud.wconnect.frontoffice.mapper.guestledgercheck.GstLedgPaidAmountMapper;
    import cloud.wconnect.frontoffice.pojo.dto.guestledgercheck.AmountPaidDTO;
    import cloud.wconnect.frontoffice.pojo.dto.guestledgercheck.AmountPaidWrapperDTO;
    import cloud.wconnect.frontoffice.service.guestledgercheck.IGstLedgPaidAmountService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.math.BigDecimal;
    import java.util.List;

    /**
     * <p>
     *  服务实现类
     * </p>
     *
     * @author lichen
     * @since 2023-03-17
     */
    @Service
    @DS("logbook")
    public class GstLedgPaidAmountServiceImpl extends ServiceImpl<GstLedgPaidAmountMapper, GstLedgPaidAmount> implements IGstLedgPaidAmountService {

        @Autowired
        private GstLedgOpBalanceReservationMapper opBalanceReservationMapper;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 编辑 Open Balance Reservation 中的 Amount Paid
         *
         * @param amountPaidWrapperDto Amount Paid 删除和新增的内容
         * @param loginUserId          登录用户id
         * @return void
         * @author lichen
         * @date 2025/8/25
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void saveAndRemove(AmountPaidWrapperDTO amountPaidWrapperDto, int loginUserId) {
            //根据主键id查询 GstLedgOpBalanceReservation
            GstLedgOpBalanceReservation reservation = opBalanceReservationMapper.getForUpdateById(amountPaidWrapperDto.getRvId());
            //批量删除
            removeByIds(amountPaidWrapperDto.getRemovedIds());
            //批量新增
            List<AmountPaidDTO> insertAmounts = amountPaidWrapperDto.getInsertAmounts();
            if(CollectionUtils.isNotEmpty(insertAmounts)){
                //List<AmountPaidDTO> -> List<GstLedgPaidAmount>
                List<GstLedgPaidAmount> paidAmountList = beanMapper.mapList(insertAmounts, GstLedgPaidAmount.class, (paidAmountDto, paidAmount) -> {
                    paidAmount.setOpBalRvId(amountPaidWrapperDto.getRvId());
                    paidAmount.setCreatedBy(loginUserId);
                    paidAmount.setCreatedTime(DateTimeUtils.nowTimestamp());
                });
                saveBatch(paidAmountList);
            }
            //重新计算open balance amount paid 值
            LambdaQueryWrapper<GstLedgPaidAmount> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(GstLedgPaidAmount::getOpBalRvId,amountPaidWrapperDto.getRvId());
            List<GstLedgPaidAmount> list = list(queryWrapper);
            BigDecimal totalAmountPaid = list.stream().map(GstLedgPaidAmount::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            /**
             * gst_ledg_op_balance_reservation 表三个金额字段解释
             * ori_bal_amount 入住资产用户提供的信用卡Card,资产可以扣减的金额
             * balance_amount 信用卡Card,剩余可以扣减的金额
             * amount_paid 用户入住资产消费后,提前扣减的部分金额(用户入住1年,但是不会一下扣完一年的金额,而是按照一定规则持续的扣减部分金额,比如预先扣减1月)
             *
             * Balance Amount，原 Balance Amount + 原 Amount Paid 总值 - 新 Amount Paid 总值 此算法解释：
             * 原 Balance Amount + 原 Amount Paid 总值 等于用户信用卡可扣减的总额，再减去 从数据库中查询出的消费总额（totalAmountPaid）
             * 就是 Balance Amount 剩余可以扣减的金额
             */
            //更新 Balance Amount，原 Balance Amount + 原 Amount Paid 总值 - 新 Amount Paid 总值
            BigDecimal newBalanceAmount = reservation.getBalanceAmount().add(reservation.getAmountPaid()).subtract(totalAmountPaid);
            GstLedgOpBalanceReservation opBalanceReservation = new GstLedgOpBalanceReservation();
            opBalanceReservation.setId(amountPaidWrapperDto.getRvId());
            opBalanceReservation.setAmountPaid(totalAmountPaid);
            opBalanceReservation.setBalanceAmount(newBalanceAmount);
            opBalanceReservation.setBalAmntUpdatedBy(loginUserId);
            opBalanceReservation.setBalAmntUpdatedTime(DateTimeUtils.nowTimestamp());
            opBalanceReservationMapper.updateById(opBalanceReservation);
        }
    }