bank-payment/account_payment_partner/models/account_invoice.py

141 lines
5.9 KiB
Python
Raw Normal View History

2021-03-23 19:28:51 +00:00
# Copyright 2014-16 Akretion - Alexis de Lattre <alexis.delattre@akretion.com>
# Copyright 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from flectra import api, fields, models, _
from flectra.exceptions import ValidationError
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
payment_mode_id = fields.Many2one(
comodel_name='account.payment.mode', string="Payment Mode",
ondelete='restrict',
readonly=True, states={'draft': [('readonly', False)]})
bank_account_required = fields.Boolean(
related='payment_mode_id.payment_method_id.bank_account_required',
readonly=True)
partner_bank_id = fields.Many2one(ondelete='restrict')
@api.onchange('partner_id', 'company_id')
def _onchange_partner_id(self):
if self.company_id:
company = self.company_id
else:
company = self.env.user.company_id
res = super(AccountInvoice, self)._onchange_partner_id()
if self.partner_id:
if self.type == 'in_invoice':
pay_mode = self.with_context(
force_company=company.id
).partner_id.supplier_payment_mode_id
self.payment_mode_id = pay_mode
if (
pay_mode and
pay_mode.payment_type == 'outbound' and
pay_mode.payment_method_id.bank_account_required and
self.commercial_partner_id.bank_ids
):
self.partner_bank_id = \
self.commercial_partner_id.bank_ids.filtered(
lambda b: b.company_id == company or not
b.company_id)[:1]
else:
self.partner_bank_id = False
elif self.type == 'out_invoice':
# No bank account assignation is done here as this is only
# needed for printing purposes and it can conflict with
# SEPA direct debit payments. Current report prints it.
self.payment_mode_id = self.with_context(
force_company=company.id,
).partner_id.customer_payment_mode_id
else:
self.payment_mode_id = False
if self.type == 'in_invoice':
self.partner_bank_id = False
return res
@api.onchange('payment_mode_id')
def _onchange_payment_mode_id(self):
pay_mode = self.payment_mode_id
if (
pay_mode and
pay_mode.payment_type == 'outbound' and not
pay_mode.payment_method_id.bank_account_required
):
self.partner_bank_id = False
elif not self.payment_mode_id:
self.partner_bank_id = False
@api.model
def create(self, vals):
"""Fill the payment_mode_id from the partner if none is provided on
creation, using same method as upstream."""
onchanges = {
'_onchange_partner_id': ['payment_mode_id'],
}
for onchange_method, changed_fields in onchanges.items():
if any(f not in vals for f in changed_fields):
invoice = self.new(vals)
getattr(invoice, onchange_method)()
for field in changed_fields:
if field not in vals and invoice[field]:
vals[field] = invoice._fields[field].convert_to_write(
invoice[field], invoice,
)
return super(AccountInvoice, self).create(vals)
@api.model
def line_get_convert(self, line, part):
"""Copy payment mode from invoice to account move line"""
res = super(AccountInvoice, self).line_get_convert(line, part)
if line.get('type') == 'dest' and line.get('invoice_id'):
invoice = self.browse(line['invoice_id'])
res['payment_mode_id'] = invoice.payment_mode_id.id or False
return res
# I think copying payment mode from invoice to refund by default
# is a good idea because the most common way of "paying" a refund is to
# deduct it on the payment of the next invoice (and OCA/bank-payment
# allows to have negative payment lines since March 2016)
@api.model
def _prepare_refund(
self, invoice, date_invoice=None, date=None, description=None,
journal_id=None):
vals = super(AccountInvoice, self)._prepare_refund(
invoice, date_invoice=date_invoice, date=date,
description=description, journal_id=journal_id)
vals['payment_mode_id'] = invoice.payment_mode_id.id
if invoice.type == 'in_invoice':
vals['partner_bank_id'] = invoice.partner_bank_id.id
return vals
@api.constrains('company_id', 'payment_mode_id')
def _check_payment_mode_company_constrains(self):
for rec in self.sudo():
if (rec.payment_mode_id and rec.company_id !=
rec.payment_mode_id.company_id):
raise ValidationError(
_("The company of the invoice %s does not match "
"with that of the payment mode") % rec.name)
def partner_banks_to_show(self):
self.ensure_one()
if self.partner_bank_id:
return self.partner_bank_id
if self.payment_mode_id.show_bank_account_from_journal:
if self.payment_mode_id.bank_account_link == 'fixed':
return self.payment_mode_id.fixed_journal_id.bank_account_id
else:
return self.payment_mode_id.variable_journal_ids.mapped(
'bank_account_id')
if self.payment_mode_id.payment_method_id.code == \
'sepa_direct_debit': # pragma: no cover
return (self.mandate_id.partner_bank_id or
self.partner_id.valid_mandate_id.partner_bank_id)
# Return this as empty recordset
return self.partner_bank_id