package com.dk.mdm.service.mac;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.annotaiton.Pagination;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.model.pojo.PageList;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.mdm.infrastructure.convert.mac.OtherPayableConvert;
import com.dk.mdm.infrastructure.convert.mac.OtherPayableItemConvert;
import com.dk.mdm.infrastructure.convert.mac.RecPayItemConvert;
import com.dk.mdm.mapper.mac.*;
import com.dk.mdm.mapper.mst.MoneyAccountItemMapper;
import com.dk.mdm.mapper.mst.MoneyAccountMapper;
import com.dk.mdm.model.pojo.mac.*;
import com.dk.common.service.BaseService;
import com.dk.common.mapper.BaseMapper;
import com.dk.mdm.model.pojo.mac.OtherPayable;
import com.dk.mdm.model.pojo.mst.MoneyAccount;
import com.dk.mdm.model.pojo.mst.MoneyAccountItem;
import com.dk.mdm.model.query.mac.OtherPayableItemQuery;
import com.dk.mdm.model.query.mac.OtherPayableQuery;
import com.dk.mdm.model.query.mac.RecPayHandleItemQuery;
import com.dk.mdm.model.query.mac.RecPayItemQuery;
import com.dk.mdm.model.response.mac.*;
import com.dk.mdm.model.vo.mac.OtherPayableItemVO;
import com.dk.mdm.model.vo.mac.OtherPayableVO;
import com.dk.mdm.model.vo.mac.RecPayItemVO;
import com.dk.mdm.service.common.CommonService;
import com.dk.mdm.service.mst.MoneyAccountService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class OtherPayableService extends BaseService<OtherPayable> {

    @Override
    public String getPrimaryKey() {
        return "payable_id";
    }

    @Override
    public BaseMapper<OtherPayable> getRepository() {
        return otherPayableMapper;
    }

    @Autowired
    private OtherPayableMapper otherPayableMapper;

    @Autowired
    private OtherPayableItemMapper otherPayableItemMapper;

    @Autowired
    private CommonService commonService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private AccountItemService accountItemService;

    @Autowired
    private MoneyAccountMapper moneyAccountMapper;

    @Autowired
    private AccountItemMapper accountItemMapper;

    @Autowired
    private MoneyAccountService moneyAccountService;

    @Autowired
    private MoneyAccountItemMapper moneyAccountItemMapper;

    @Autowired
    private RecPayHandleItemMapper recPayHandleItemMapper;

    @Autowired
    private RecPayMapper recPayMapper;

    @Autowired
    private RecPayHandleItemService recPayHandleItemService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private RecPayItemService recPayItemService;

    @Autowired
    private RecPayItemMapper recPayItemMapper;

    @Autowired
    private RecPayItemConvert recPayItemConvert;

    @Autowired
    private OtherPayableConvert otherPayableConvert;

    @Autowired
    private OtherPayableItemConvert otherPayableItemConvert;

    /**
     * @desc : 查询明细（货物、付款、附件）
     * @author : 付斌
     * @date : 2024-02-28 13:25
     */
    @Pagination
    public ResponseResultVO<Map<String, Object>> selectOtherPayableInfoById(String id) {
        Map<String, Object> result = new HashMap<>();
        // 商品明细
        List<OtherPayableItemResponse> otherPayableItem = otherPayableItemMapper.selectByCond(new OtherPayableItemQuery().setPayableId(id));
        result.put("otherPayableItem", otherPayableItem);

        // 附件
        return ResponseResultUtil.success(result);
    }

    /**
     * @desc : 条件查询
     * @author : 付斌
     * @date : 2023/1/9 10:40
     */
    @Pagination
    public ResponseResultVO<PageList<OtherPayableResponse>> selectByCond(OtherPayableQuery otherPayableQuery) {
        return super.mergeListWithCount(otherPayableQuery, otherPayableMapper.selectByCond(otherPayableQuery),
                otherPayableMapper.countByCond(otherPayableQuery));
    }

    /**
     * @desc : 新建方法
     * @author : 付斌
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> insert(OtherPayableVO otherPayableVO) {
        // 付款金额不能大于支出金额
        if (otherPayableVO.getSumAmtPay().compareTo(otherPayableVO.getSumAmtPayable()) == 1) {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.PAYABLE_NO_LESS_PAYMENT.getMessage());
        }

        // 获取单号
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.OTHERPAYABLE.getName(), false);
        otherPayableVO.setPayableId(codeMap.get("outId").toString()).setPayableNo(codeMap.get("outNote").toString())
                .setObjectType(Constant.ObjectType.SUP.getName());
        // 转化实体
        OtherPayable otherPayable = otherPayableConvert.convertToPo(otherPayableVO);
        // 总单保存
        super.insert(otherPayable);

        // 明细保存
        if (otherPayableVO.getItemList() != null && otherPayableVO.getItemList().size() > 0) {
            for (OtherPayableItemVO otherPayableItemVO : otherPayableVO.getItemList()) {
                OtherPayableItem otherPayableItem = otherPayableItemConvert.convertToPo(otherPayableItemVO);
                otherPayableItem.setPayableId(otherPayable.getPayableId()).setCpId(otherPayable.getCpId());
                otherPayableItemMapper.insert(otherPayableItem);
            }
        }

        // 应付记账
        accountService.accPayable(otherPayable.getPayableId(), "t_mac_other_payable");

        // 如果有付款，再做应付付款
        if (otherPayableVO.getPaymentList() != null && otherPayableVO.getPaymentList().size() > 0) {
            /*******************************************  付款的处理 begin ********************************************/
            RecPay recPay = new RecPay();
            // 获取单号
            codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.RECPAY.getName(), false);
            recPay.setRpId(codeMap.get("outId").toString()).setRpNo(codeMap.get("outNote").toString())
                    .setRpType(Constant.RpType.FU_KUAN.getName()).setObjectId(otherPayableVO.getObjectId())
                    .setOrgId(otherPayableVO.getOrgId()).setStaffId(otherPayableVO.getStaffId())
                    .setSumAmtPay(otherPayableVO.getSumAmtPay()).setSumAmtPayableHandle(otherPayableVO.getSumAmtPay())
                    .setAccDate(otherPayableVO.getAccDate()).setBiznisType(Constant.InventoryDocCode.OTHER_PAYABLE.getTableName())
                    .setBiznisId(otherPayableVO.getPayableId()).setBiznisNo(otherPayableVO.getPayableNo())
                    .setMakeStaff(otherPayableVO.getMakeStaff()).setCpId(otherPayableVO.getCpId());
            // 总单保存
            recPayMapper.insert(recPay);

            for (RecPayItemVO recPayItemVO : otherPayableVO.getPaymentList()) {
                RecPayItem recPayItem = recPayItemConvert.convertToPo(recPayItemVO);
                recPayItem.setRpId(recPay.getRpId()).setCpId(recPay.getCpId()).setMakeStaff(recPay.getMakeStaff()).setAccDate(recPay.getAccDate());
                recPayItemMapper.insert(recPayItem);

                // 插入账款明细
                AccountItem accountItem = new AccountItem();
                accountItem.setAccItemType(Constant.accItemType.FU_KUAN.getName())
                        .setObjectId(recPay.getObjectId()).setOrgId(recPay.getOrgId()).setStaffId(recPay.getStaffId())
                        .setAccDate(recPay.getAccDate()).setRecStatus(Constant.recStatuse.QUE_DING.getName()).setAmtPay(recPayItem.getAmtPay())
                        .setBiznisType("t_mac_rec_pay_item").setBiznisId(recPayItem.getItemId()).setBiznisNo(recPay.getRpNo())
                        .setMakeStaff(recPay.getMakeStaff()).setCpId(recPay.getCpId());
                accountItemMapper.insert(accountItem);

                // 更新付款单上的账款明细Id
                RecPayItem recPayItemUpdate = new RecPayItem();
                recPayItemUpdate.setAccItemId(accountItem.getItemId()).setItemId(recPayItem.getItemId());
                recPayItemService.updateByUuid(recPayItemUpdate);

                // 插入资金流水
                MoneyAccountItem moneyAccountItem = new MoneyAccountItem();
                moneyAccountItem.setMacId(recPayItem.getMacId()).setFlowType(Constant.FlowType.SHOU_FU_KUAN.getName())
                        .setInvoiceId(recPayItem.getItemId()).setAmtInflow(recPayItem.getAmtPay().negate()).setAccDate(recPay.getAccDate())
                        .setMakeStaff(recPayItem.getMakeStaff()).setCpId(recPayItem.getCpId());
                moneyAccountItemMapper.insert(moneyAccountItem);

                // 更新资金账户
                MoneyAccount moneyAccountForUpdate = moneyAccountMapper.selectByIdForUpdate(recPayItem.getMacId());
                MoneyAccount moneyAccountUpdate = new MoneyAccount();
                moneyAccountUpdate.setBalance(moneyAccountForUpdate.getBalance().add(recPayItem.getAmtPay().negate()))
                        .setMacId(moneyAccountForUpdate.getMacId());
                moneyAccountService.updateByUuid(moneyAccountUpdate);
            }
            // 插入账款总表
            Account accountForUpdate = accountService.getCusAccountForUpdate(recPay.getObjectId());
            // 更新账款总表上付款的相关字段
            Account accountUpdate = new Account();
            accountUpdate.setPayment(accountForUpdate.getPayment().add(recPay.getSumAmtPay()))// 总付款金额
                    .setPaymentResidue(accountForUpdate.getPaymentResidue().add(recPay.getSumAmtPay()))//  可退金额
                    .setObjectId(accountForUpdate.getObjectId());
            accountService.updateByUuid(accountUpdate);
            /*******************************************  付款的处理 end ********************************************/

            /*******************************************  应付付款的处理 begin ********************************************/
            OtherPayable otherPayableForUpdate = otherPayableMapper.selectByIdForUpdate(otherPayableVO.getPayableId());

            // 应付付款的处理
            RecPayHandleItem recPayHandleItem = new RecPayHandleItem();
            recPayHandleItem.setRpId(recPay.getRpId()).setAccItemId(otherPayableForUpdate.getAccItemId())
                    .setAmtPayableHandle(recPay.getSumAmtPay()).setCpId(recPay.getCpId()).setAccDate(recPay.getAccDate());
            recPayHandleItemMapper.insert(recPayHandleItem);

            // 账款明细的核销金额和优惠金额
            AccountItem accountItemForUpdate = accountItemMapper.selectByIdForUpdate(recPayHandleItem.getAccItemId());
            AccountItem accountItemUpdate = new AccountItem();
            // 核销金额，超出剩余应付金额
            if (accountItemForUpdate.getAmtResidue().compareTo(recPayHandleItem.getAmtPayableHandle()) == -1) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.AMT_HANDLE_NO_LESS_AMT_SHOULD.getMessage());
            }
            accountItemUpdate.setAmtHandle(accountItemForUpdate.getAmtHandle().add(recPayHandleItem.getAmtPayableHandle()))
                    .setAmtWaive(accountItemForUpdate.getAmtWaive())
                    .setItemId(recPayHandleItem.getAccItemId());
            // 剩余金额 = 应付金额-应付付款金额
            accountItemUpdate.setAmtResidue(accountItemForUpdate.getAmtShould().subtract(accountItemUpdate.getAmtHandle()));
            accountItemService.updateByUuid(accountItemUpdate);

            // 更新总账上
            accountForUpdate = accountMapper.selectByIdForUpdate(recPay.getObjectId());
            accountUpdate = new Account();
            accountUpdate.setPayableHandle(accountForUpdate.getPayableHandle().add(recPayHandleItem.getAmtPayableHandle()))// 总应付付款金额
                    .setPayableWaive(accountForUpdate.getPayableWaive())//  总应付优惠金额
                    .setObjectId(accountForUpdate.getObjectId());
            // 剩余应付 = 总应付账款-总应付付款金额
            accountUpdate.setPayableResidue(accountForUpdate.getPayable().subtract(accountUpdate.getPayableHandle()));
            // 可退金额 = 总付款金额-总应付付款金额+总应付优惠金额
            accountUpdate.setPaymentResidue(accountForUpdate.getPayment().subtract(accountUpdate.getPayableHandle()).add(accountUpdate.getPayableWaive()));

            // 更新前的最后校验
            // 剩余应付为负数，则不能保存
//            if (accountUpdate.getPayableResidue().compareTo(BigDecimal.ZERO) == -1) {
//                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.AMT_HANDLE_NO_LESS_AMT_SHOULD.getMessage());
//            }
            // 可用金额为负数，则不能保存
            if (accountUpdate.getPaymentResidue().compareTo(BigDecimal.ZERO) == -1) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.RESIDUE_NO_LESS.getMessage());
            }
            accountService.updateByUuid(accountUpdate);
            /*******************************************  应付付款的处理 end ********************************************/
        }
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 编辑方法
     * @author : 付斌
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> update(OtherPayableVO otherPayableVO) {
        OtherPayable otherPayableForUpdate = otherPayableMapper.selectByIdForUpdate(otherPayableVO.getPayableId());
        // 并发校验
        if (!otherPayableForUpdate.getFlgValid()) {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.ISFLGVALID_FALSE.getMessage());
        }
        // 期初数据不允许编辑
        if (otherPayableForUpdate.getBusinessType() == 0) {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVOICE_ISQICHU.getMessage());
        }
        // 付款金额不能大于支出金额
        if (otherPayableVO.getSumAmtPay().compareTo(otherPayableVO.getSumAmtPayable()) == 1) {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.PAYABLE_NO_LESS_PAYMENT.getMessage());
        }

        /*******************************************  应付付款的处理 begin ********************************************/
        RecPay recPayForUpdate = recPayMapper.selectByBiznisIdForUpdate(otherPayableVO.getPayableId(), false);
        if (recPayForUpdate != null && recPayForUpdate.getFlgValid()) {
            // 查出并锁定所有应付核销明细
            AccountItem accountItemForUpdate;
            List<RecPayHandleItem> recPayHandleItemForUpdateList = recPayHandleItemMapper.selectByZIdForUpdate(recPayForUpdate.getRpId());
            for (RecPayHandleItem recPayHandleItemForUpdate : recPayHandleItemForUpdateList) {
                // 更新账款明细应付付款
                accountItemForUpdate = accountItemMapper.selectByIdForUpdate(recPayHandleItemForUpdate.getAccItemId());
                AccountItem accountItemUpdate = new AccountItem();
                accountItemUpdate.setAmtHandle(accountItemForUpdate.getAmtHandle().subtract(recPayHandleItemForUpdate.getAmtPayableHandle()))
                        .setAmtWaive(accountItemForUpdate.getAmtWaive().subtract(recPayHandleItemForUpdate.getAmtWaive()))
                        .setItemId(recPayHandleItemForUpdate.getAccItemId());
                accountItemUpdate.setAmtResidue(accountItemForUpdate.getAmtShould().subtract(accountItemUpdate.getAmtHandle()).subtract(accountItemUpdate.getAmtWaive()));
                accountItemService.updateByUuid(accountItemUpdate);

                // 将核销明细有效标识置为false
                RecPayHandleItem recPayHandleItemUpdate = new RecPayHandleItem();
                recPayHandleItemUpdate.setFlgValid(false).setItemId(recPayHandleItemForUpdate.getItemId());
                recPayHandleItemService.updateByUuid(recPayHandleItemUpdate);
            }

            // 把总帐上的钱加回来
            Account accountForUpdate = accountMapper.selectByIdForUpdate(recPayForUpdate.getObjectId());
            Account accountUpdate = new Account();
            accountUpdate.setPayableHandle(accountForUpdate.getPayableHandle().subtract(recPayForUpdate.getSumAmtPayableHandle()))// 总应付付款金额
                    .setPayableWaive(accountForUpdate.getPayableWaive().subtract(recPayForUpdate.getSumWaiveAmt()))//  总应付优惠金额
                    .setObjectId(accountForUpdate.getObjectId());
            // 剩余应付 = 总应付账款-总应付付款金额
            accountUpdate.setPayableResidue(accountForUpdate.getPayable().subtract(accountUpdate.getPayableHandle()));
            // 可退金额 = 总付款金额-总应付付款金额+总应付优惠金额
            accountUpdate.setPaymentResidue(accountForUpdate.getPayment().subtract(accountUpdate.getPayableHandle()).add(accountUpdate.getPayableWaive()));

            // 更新前的最后校验
            // 剩余应付为负数，则不能保存
//            if (accountUpdate.getPayableResidue().compareTo(BigDecimal.ZERO) == -1) {
//                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.AMT_HANDLE_NO_LESS_AMT_SHOULD.getMessage());
//            }
            // 可用金额为负数，则不能保存
            if (accountUpdate.getPaymentResidue().compareTo(BigDecimal.ZERO) == -1) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.RESIDUE_NO_LESS.getMessage());
            }
            accountService.updateByUuid(accountUpdate);

            // 将之前的明细全部删除
            List<RecPayItem> recPayItemOriginalList = recPayItemMapper.selectByZIdForUpdate(recPayForUpdate.getRpId());
            // 需要重新计算的资金账户
            List<String> macList = new ArrayList<>();
            for (RecPayItem recPayItem : recPayItemOriginalList) {
                // 删除收付款明细
                recPayItemMapper.deleteById(recPayItem.getItemId());
                // 删除账款明细
                accountItemMapper.deleteById(recPayItem.getAccItemId());
                // 删除账户流水
                moneyAccountItemMapper.deleteByInvoiceId(recPayItem.getItemId());

                if (!macList.contains(recPayItem.getMacId())) {
                    macList.add(recPayItem.getMacId());
                }
            }
            // 更新总账表的总付款额和可用额
            accountService.updatePayment(recPayForUpdate.getObjectId());
            // 更新账户余额
            for (String macId : macList) {
                accountService.updateMac(macId);
            }
            // 作废
            RecPay recPayUpdate = new RecPay();
            recPayUpdate.setFlgValid(false).setRpId(recPayForUpdate.getRpId());
            paymentService.updateByUuid(recPayUpdate);
        }
        /*******************************************  应付付款的处理 end ********************************************/

        // 先更新付款单总表，否则id又更错了
        OtherPayable otherPayable = otherPayableConvert.convertToPo(otherPayableVO);
        super.update(otherPayable, new UpdateWrapper<OtherPayable>().lambda().eq(OtherPayable::getPayableId,
                UUID.fromString(otherPayable.getPayableId())));

        // 应付反记账
        accountService.reversePayable(otherPayableVO.getPayableId(), "t_mac_other_payable");

        // 将之前的明细全部删除
        List<OtherPayableItem> otherPayableItemOriginalList = otherPayableItemMapper.selectByZIdForUpdate(otherPayableVO.getPayableId());
        for (OtherPayableItem otherPayableItem : otherPayableItemOriginalList) {
            otherPayableItemMapper.deleteById(otherPayableItem.getItemId());
        }

        // 明细保存
        if (otherPayableVO.getItemList() != null && otherPayableVO.getItemList().size() > 0) {
            for (OtherPayableItemVO otherPayableItemVO : otherPayableVO.getItemList()) {
                OtherPayableItem otherPayableItem = otherPayableItemConvert.convertToPo(otherPayableItemVO);
                otherPayableItem.setItemId(null).setPayableId(otherPayableVO.getPayableId()).setCpId(otherPayableVO.getCpId());
                otherPayableItemMapper.insert(otherPayableItem);
            }
        }

        // 应付记账
        accountService.accPayable(otherPayableVO.getPayableId(), "t_mac_other_payable");

        // 如果有付款，再做应付付款
        if (otherPayableVO.getPaymentList() != null && otherPayableVO.getPaymentList().size() > 0) {
            /*******************************************  付款的处理 begin ********************************************/
            RecPay recPay = new RecPay();
            // 获取单号
            Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.RECPAY.getName(), false);
            recPay.setRpId(codeMap.get("outId").toString()).setRpNo(codeMap.get("outNote").toString())
                    .setRpType(Constant.RpType.FU_KUAN.getName()).setObjectId(otherPayableVO.getObjectId())
                    .setOrgId(otherPayableVO.getOrgId()).setStaffId(otherPayableVO.getStaffId())
                    .setSumAmtPay(otherPayableVO.getSumAmtPay()).setSumAmtPayableHandle(otherPayableVO.getSumAmtPay())
                    .setAccDate(otherPayableVO.getAccDate()).setBiznisType(Constant.InventoryDocCode.OTHER_PAYABLE.getTableName())
                    .setBiznisId(otherPayableVO.getPayableId()).setBiznisNo(otherPayableVO.getPayableNo())
                    .setMakeStaff(otherPayableVO.getMakeStaff()).setCpId(otherPayableVO.getCpId());
            // 总单保存
            recPayMapper.insert(recPay);

            for (RecPayItemVO recPayItemVO : otherPayableVO.getPaymentList()) {
                RecPayItem recPayItem = recPayItemConvert.convertToPo(recPayItemVO);
                recPayItem.setItemId(null).setRpId(recPay.getRpId()).setCpId(recPay.getCpId()).setMakeStaff(recPay.getMakeStaff()).setAccDate(recPay.getAccDate());
                recPayItemMapper.insert(recPayItem);

                // 插入账款明细
                AccountItem accountItem = new AccountItem();
                accountItem.setAccItemType(Constant.accItemType.FU_KUAN.getName())
                        .setObjectId(recPay.getObjectId()).setOrgId(recPay.getOrgId()).setStaffId(recPay.getStaffId())
                        .setAccDate(recPay.getAccDate()).setRecStatus(Constant.recStatuse.QUE_DING.getName()).setAmtPay(recPayItem.getAmtPay())
                        .setBiznisType("t_mac_rec_pay_item").setBiznisId(recPayItem.getItemId()).setBiznisNo(recPay.getRpNo())
                        .setMakeStaff(recPay.getMakeStaff()).setCpId(recPay.getCpId());
                accountItemMapper.insert(accountItem);

                // 更新付款单上的账款明细Id
                RecPayItem recPayItemUpdate = new RecPayItem();
                recPayItemUpdate.setAccItemId(accountItem.getItemId()).setItemId(recPayItem.getItemId());
                recPayItemService.updateByUuid(recPayItemUpdate);

                // 插入资金流水
                MoneyAccountItem moneyAccountItem = new MoneyAccountItem();
                moneyAccountItem.setMacId(recPayItem.getMacId()).setFlowType(Constant.FlowType.SHOU_FU_KUAN.getName())
                        .setInvoiceId(recPayItem.getItemId()).setAmtInflow(recPayItem.getAmtPay().negate()).setAccDate(recPay.getAccDate())
                        .setMakeStaff(recPayItem.getMakeStaff()).setCpId(recPayItem.getCpId());
                moneyAccountItemMapper.insert(moneyAccountItem);

                // 更新资金账户
                MoneyAccount moneyAccountForUpdate = moneyAccountMapper.selectByIdForUpdate(recPayItem.getMacId());
                MoneyAccount moneyAccountUpdate = new MoneyAccount();
                moneyAccountUpdate.setBalance(moneyAccountForUpdate.getBalance().add(recPayItem.getAmtPay().negate()))
                        .setMacId(moneyAccountForUpdate.getMacId());
                moneyAccountService.updateByUuid(moneyAccountUpdate);
            }
            // 插入账款总表
            Account accountForUpdate = accountService.getCusAccountForUpdate(recPay.getObjectId());
            // 更新账款总表上付款的相关字段
            Account accountUpdate = new Account();
            accountUpdate.setPayment(accountForUpdate.getPayment().add(recPay.getSumAmtPay()))// 总付款金额
                    .setPaymentResidue(accountForUpdate.getPaymentResidue().add(recPay.getSumAmtPay()))//  可退金额
                    .setObjectId(accountForUpdate.getObjectId());
            accountService.updateByUuid(accountUpdate);
            /*******************************************  付款的处理 end ********************************************/

            /*******************************************  应付付款的处理 begin ********************************************/
            otherPayableForUpdate = otherPayableMapper.selectByIdForUpdate(otherPayableVO.getPayableId());
            // 应付付款的处理
            RecPayHandleItem recPayHandleItem = new RecPayHandleItem();
            recPayHandleItem.setRpId(recPay.getRpId()).setAccItemId(otherPayableForUpdate.getAccItemId())
                    .setAmtPayableHandle(recPay.getSumAmtPay()).setCpId(recPay.getCpId()).setAccDate(recPay.getAccDate());
            recPayHandleItemMapper.insert(recPayHandleItem);

            // 账款明细的核销金额和优惠金额
            AccountItem accountItemForUpdate = accountItemMapper.selectByIdForUpdate(recPayHandleItem.getAccItemId());
            AccountItem accountItemUpdate = new AccountItem();
            // 核销金额，超出剩余应付金额
            if (accountItemForUpdate.getAmtResidue().compareTo(recPayHandleItem.getAmtPayableHandle()) == -1) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.AMT_HANDLE_NO_LESS_AMT_SHOULD.getMessage());
            }
            accountItemUpdate.setAmtHandle(accountItemForUpdate.getAmtHandle().add(recPayHandleItem.getAmtPayableHandle()))
                    .setAmtWaive(accountItemForUpdate.getAmtWaive())
                    .setItemId(recPayHandleItem.getAccItemId());
            // 剩余金额 = 应付金额-应付付款金额
            accountItemUpdate.setAmtResidue(accountItemForUpdate.getAmtShould().subtract(accountItemUpdate.getAmtHandle()));
            accountItemService.updateByUuid(accountItemUpdate);

            // 更新总账上
            accountForUpdate = accountMapper.selectByIdForUpdate(recPay.getObjectId());
            accountUpdate = new Account();
            accountUpdate.setPayableHandle(accountForUpdate.getPayableHandle().add(recPayHandleItem.getAmtPayableHandle()))// 总应付付款金额
                    .setPayableWaive(accountForUpdate.getPayableWaive())//  总应付优惠金额
                    .setObjectId(accountForUpdate.getObjectId());
            // 剩余应付 = 总应付账款-总应付付款金额
            accountUpdate.setPayableResidue(accountForUpdate.getPayable().subtract(accountUpdate.getPayableHandle()));
            // 可退金额 = 总付款金额-总应付付款金额+总应付优惠金额
            accountUpdate.setPaymentResidue(accountForUpdate.getPayment().subtract(accountUpdate.getPayableHandle()).add(accountUpdate.getPayableWaive()));

            // 更新前的最后校验
            // 剩余应付为负数，则不能保存
//            if (accountUpdate.getPayableResidue().compareTo(BigDecimal.ZERO) == -1) {
//                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.AMT_HANDLE_NO_LESS_AMT_SHOULD.getMessage());
//            }
            // 可用金额为负数，则不能保存
            if (accountUpdate.getPaymentResidue().compareTo(BigDecimal.ZERO) == -1) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.RESIDUE_NO_LESS.getMessage());
            }
            accountService.updateByUuid(accountUpdate);
            /*******************************************  应付付款的处理 end ********************************************/
        }
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 获取信息（编辑用）
     * @author : 付斌
     * @date : 2024-03-02 17:27
     */
    public ResponseResultVO<?> getOtherPayableForUpdate(String id) {
        Map<String, Object> dataInfo = new HashMap<>();
        OtherPayableResponse otherPayableResponse = otherPayableMapper.selectById(id);

        // 判断是否能大编辑
        otherPayableResponse.setDaEdit(true);
        if (otherPayableResponse.getAccItemId() != null) {
            // 查出新建时是否付款了
            RecPay recPayForUpdate = recPayMapper.selectByBiznisIdForUpdate(id, false);
            // 查出有多少次付款
            List<RecPayHandleItemResponse> RecPayHandleItemResponseList = recPayHandleItemMapper.selectByCond(new RecPayHandleItemQuery().setAccItemId(otherPayableResponse.getAccItemId()));
            if (RecPayHandleItemResponseList != null && RecPayHandleItemResponseList.size() > 0) {
                // 如果有付款，并且新建时没付款，则不能大编辑
                if(recPayForUpdate == null){
                    otherPayableResponse.setDaEdit(false);
                }else{
                    for(RecPayHandleItemResponse  recPayHandleItemResponse :RecPayHandleItemResponseList){
                        // 如果核销id不是第一次付款id,不能大编辑
                        if(!recPayHandleItemResponse.getRpId().equals(recPayForUpdate.getRpId())){
                            otherPayableResponse.setDaEdit(false);
                        }
                    }
                }
            }
        }
        // 支出明细
        dataInfo.put("data", otherPayableResponse);

        // 商品明细
        List<OtherPayableItemResponse> otherPayableItemResponseList = otherPayableItemMapper.selectByCond(new OtherPayableItemQuery().setPayableId(id));
        dataInfo.put("dataItem", otherPayableItemResponseList);

        // 付款明细
        RecPay recPayForUpdate = recPayMapper.selectByBiznisId(id);
        if (recPayForUpdate != null) {
            List<RecPayItemResponse> recPayItemResponseList = recPayItemMapper.selectByCond(new RecPayItemQuery().setRpId(recPayForUpdate.getRpId()));
            dataInfo.put("paymentItem", recPayItemResponseList);
        } else {
            dataInfo.put("paymentItem", new ArrayList<RecPayResponse>());
        }

        return ResponseResultUtil.success(dataInfo);
    }

    /**
     * @desc : 作废
     * @author : 付斌
     * @date : 2024-03-08 16:38
     */
    public ResponseResultVO<?> invalid(String id) {
        OtherPayable otherPayableForUpdate = otherPayableMapper.selectByIdForUpdate(id);
        // 并发校验
        if (!otherPayableForUpdate.getFlgValid()) {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.ISFLGVALID_FALSE.getMessage());
        }
        // 如果所在月份已结账，则不能作废 todo

        /*******************************************  应付付款的处理 begin ********************************************/
        RecPay recPayForUpdate = recPayMapper.selectByBiznisIdForUpdate(id, false);
        if (recPayForUpdate != null && recPayForUpdate.getFlgValid()) {
            // 查出并锁定所有应付核销明细
            AccountItem accountItemForUpdate;
            List<RecPayHandleItem> recPayHandleItemForUpdateList = recPayHandleItemMapper.selectByZIdForUpdate(recPayForUpdate.getRpId());
            for (RecPayHandleItem recPayHandleItemForUpdate : recPayHandleItemForUpdateList) {
                // 更新账款明细应付付款
                accountItemForUpdate = accountItemMapper.selectByIdForUpdate(recPayHandleItemForUpdate.getAccItemId());
                AccountItem accountItemUpdate = new AccountItem();
                accountItemUpdate.setAmtHandle(accountItemForUpdate.getAmtHandle().subtract(recPayHandleItemForUpdate.getAmtPayableHandle()))
                        .setAmtWaive(accountItemForUpdate.getAmtWaive().subtract(recPayHandleItemForUpdate.getAmtWaive()))
                        .setItemId(recPayHandleItemForUpdate.getAccItemId());
                accountItemUpdate.setAmtResidue(accountItemForUpdate.getAmtShould().subtract(accountItemUpdate.getAmtHandle()).subtract(accountItemUpdate.getAmtWaive()));
                accountItemService.updateByUuid(accountItemUpdate);

                // 将核销明细有效标识置为false
                RecPayHandleItem recPayHandleItemUpdate = new RecPayHandleItem();
                recPayHandleItemUpdate.setFlgValid(false).setItemId(recPayHandleItemForUpdate.getItemId());
                recPayHandleItemService.updateByUuid(recPayHandleItemUpdate);
            }

            // 把总帐上的钱加回来
            Account accountForUpdate = accountMapper.selectByIdForUpdate(recPayForUpdate.getObjectId());
            Account accountUpdate = new Account();
            accountUpdate.setPayableHandle(accountForUpdate.getPayableHandle().subtract(recPayForUpdate.getSumAmtPayableHandle()))// 总应付付款金额
                    .setPayableWaive(accountForUpdate.getPayableWaive().subtract(recPayForUpdate.getSumWaiveAmt()))//  总应付优惠金额
                    .setObjectId(accountForUpdate.getObjectId());
            // 剩余应付 = 总应付账款-总应付付款金额
            accountUpdate.setPayableResidue(accountForUpdate.getPayable().subtract(accountUpdate.getPayableHandle()));
            // 可退金额 = 总付款金额-总应付付款金额+总应付优惠金额
            accountUpdate.setPaymentResidue(accountForUpdate.getPayment().subtract(accountUpdate.getPayableHandle()).add(accountUpdate.getPayableWaive()));

            // 更新前的最后校验
            // 剩余应付为负数，则不能保存
            if (accountUpdate.getPayableResidue().compareTo(BigDecimal.ZERO) == -1) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.AMT_HANDLE_NO_LESS_AMT_SHOULD.getMessage());
            }
            // 可用金额为负数，则不能保存
            if (accountUpdate.getPaymentResidue().compareTo(BigDecimal.ZERO) == -1) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.RESIDUE_NO_LESS.getMessage());
            }
            accountService.updateByUuid(accountUpdate);

            // 将之前的明细全部删除
            List<RecPayItem> recPayItemOriginalList = recPayItemMapper.selectByZIdForUpdate(recPayForUpdate.getRpId());
            // 需要重新计算的资金账户
            List<String> macList = new ArrayList<>();
            for (RecPayItem recPayItem : recPayItemOriginalList) {
                // 删除收付款明细
                recPayItemMapper.deleteById(recPayItem.getItemId());
                // 删除账款明细
                accountItemMapper.deleteById(recPayItem.getAccItemId());
                // 删除账户流水
                moneyAccountItemMapper.deleteByInvoiceId(recPayItem.getItemId());

                if (!macList.contains(recPayItem.getMacId())) {
                    macList.add(recPayItem.getMacId());
                }
            }
            // 更新总账表的总付款额和可用额
            accountService.updatePayment(recPayForUpdate.getObjectId());
            // 更新账户余额
            for (String macId : macList) {
                accountService.updateMac(macId);
            }
            // 作废
            RecPay recPayUpdate = new RecPay();
            recPayUpdate.setFlgValid(false).setRpId(recPayForUpdate.getRpId());
            paymentService.updateByUuid(recPayUpdate);
        }
        /*******************************************  应付付款的处理 end ********************************************/

        // 应付反记账
        accountService.reversePayable(id, "t_mac_other_payable");

        // 作废
        OtherPayable otherPayableUpdate = new OtherPayable();
        otherPayableUpdate.setFlgValid(false).setPayableId(id);
        super.updateByUuid(otherPayableUpdate);
        return ResponseResultUtil.success();
    }
}
