You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo15中发票/供应商账单支付匹配与分配实现问询

Odoo15 发票/供应商账单支付分配实现方案

已在Odoo15的account.payment模型中添加one2many字段,用于列出客户未全额支付的发票/供应商账单,现需实现过账支付时的部分/全额支付分配功能,以下是当前已编写的代码:

现有代码实现

AccountPayment 模型扩展

class AccountPayment(models.Model):
    _inherit = "account.payment"

    payment_line_ids = fields.One2many('account.payment.line', 'payment_id', string="发票调整")

    @api.onchange('partner_id')
    def _onchange_partner_id(self):
        line_vals = []
        for rec in self:
            rec.payment_line_ids = False
            if rec.partner_id:
                partner_moves = self.env['account.move'].search([
                    ('partner_id', '=', rec.partner_id.id),
                    ('state', '=', 'posted'), 
                    ('payment_state', 'in', ('not_paid', 'partial'))
                ])

                for mov in partner_moves:
                    open_invoice_lines = {
                        'move_id': mov.id,
                        'date': mov.date,
                        'date_due': mov.invoice_date_due,
                        'original_amount': mov.amount_total,
                        'balance_amount': mov.amount_residual,
                        'payment_id': rec.id,
                    }
                    line_vals.append((0, 0, open_invoice_lines))
            rec.payment_line_ids = line_vals

AccountPaymentLine 模型定义

class AccountPaymentLine(models.Model):
    _name = 'account.payment.line'

    payment_id = fields.Many2one('account.payment')
    move_id = fields.Many2one('account.move', string="发票/账单")
    date = fields.Date(string="日期")
    date_due = fields.Date(string="到期日")
    original_amount = fields.Float(string="原始金额")
    balance_amount = fields.Float(string="剩余金额")
    allocation_amount = fields.Float(string="分配金额")

支付分配界面

支付分配界面


核心实现思路

1. 分配金额合法性校验

  • 在account.payment.line中添加约束,避免分配金额超出剩余金额或为负数:
    from odoo.exceptions import ValidationError
    
    @api.constrains('allocation_amount', 'balance_amount')
    def _check_allocation_amount(self):
        for line in self:
            if line.allocation_amount < 0 or line.allocation_amount > line.balance_amount:
                raise ValidationError("分配金额不能为负,且不能超过账单剩余金额")
    
  • 在account.payment中校验总分配金额不超过支付金额:
    @api.constrains('payment_line_ids', 'amount')
    def _check_total_allocation(self):
        for rec in self:
            total_allocated = sum(line.allocation_amount for line in rec.payment_line_ids)
            if total_allocated > rec.amount:
                raise ValidationError("总分配金额不能超过支付金额")
    

2. 过账时自动创建对账记录

重写account.payment的post方法,根据分配金额自动完成支付与账单的对账:

def post(self):
    res = super(AccountPayment, self).post()
    for payment in self:
        if payment.payment_line_ids:
            for line in payment.payment_line_ids.filtered(lambda l: l.allocation_amount > 0):
                # 获取支付凭证的对应科目行
                payment_lines = payment.move_id.line_ids.filtered(
                    lambda l: l.account_id == payment.destination_account_id
                )
                # 获取账单的未清科目行
                invoice_lines = line.move_id.line_ids.filtered(
                    lambda l: l.account_id == payment.destination_account_id and l.amount_residual != 0
                )
                # 执行对账(Odoo自动处理部分/全额对账逻辑)
                (payment_lines + invoice_lines).reconcile()
    return res

3. 前端交互优化

  • 在支付表单视图中设置payment_line_ids为可编辑树形视图,方便输入分配金额:
    <field name="payment_line_ids">
        <tree editable="bottom">
            <field name="move_id"/>
            <field name="date"/>
            <field name="date_due"/>
            <field name="original_amount"/>
            <field name="balance_amount"/>
            <field name="allocation_amount"/>
        </tree>
    </field>
    
  • 添加实时计算的剩余可分配金额字段:
    remaining_amount = fields.Float(compute='_compute_remaining_amount', string="剩余可分配金额")
    
    @api.depends('amount', 'payment_line_ids.allocation_amount')
    def _compute_remaining_amount(self):
        for rec in self:
            total_allocated = sum(line.allocation_amount for line in rec.payment_line_ids)
            rec.remaining_amount = rec.amount - total_allocated
    

4. 多币种场景适配(可选)

若涉及多币种支付,需在onchange方法或约束中添加币种校验,确保分配金额的币种与支付、账单币种一致,必要时处理汇率转换逻辑。

内容的提问来源于stack exchange,提问作者code_explorer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:23:15