bank-payment/account_payment_order/models/bank_payment_line.py
2021-03-23 20:28:51 +01:00

170 lines
6.7 KiB
Python

# © 2015-2016 Akretion - Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from flectra import api, fields, models, _
from flectra.exceptions import UserError
class BankPaymentLine(models.Model):
_name = 'bank.payment.line'
_description = 'Bank Payment Lines'
name = fields.Char(
string='Bank Payment Line Ref', required=True,
readonly=True)
order_id = fields.Many2one(
'account.payment.order', string='Order', ondelete='cascade',
index=True, readonly=True)
payment_type = fields.Selection(
related='order_id.payment_type', string="Payment Type",
readonly=True, store=True)
state = fields.Selection(
related='order_id.state', string='State',
readonly=True, store=True)
payment_line_ids = fields.One2many(
'account.payment.line', 'bank_line_id', string='Payment Lines',
readonly=True)
partner_id = fields.Many2one(
'res.partner', related='payment_line_ids.partner_id',
readonly=True, store=True) # store=True for groupby
# Function Float fields are sometimes badly displayed in tree view,
# see bug report https://github.com/flectra/flectra/issues/8632
# But is it still true in v9 ?
amount_currency = fields.Monetary(
string='Amount', currency_field='currency_id',
compute='_compute_amount', store=True, readonly=True)
amount_company_currency = fields.Monetary(
string='Amount in Company Currency',
currency_field='company_currency_id',
compute='_compute_amount', store=True, readonly=True)
currency_id = fields.Many2one(
'res.currency', required=True, readonly=True,
related='payment_line_ids.currency_id') # v8 field: currency
partner_bank_id = fields.Many2one(
'res.partner.bank', string='Bank Account', readonly=True,
related='payment_line_ids.partner_bank_id') # v8 field: bank_id
date = fields.Date(
related='payment_line_ids.date', readonly=True)
communication_type = fields.Selection(
related='payment_line_ids.communication_type', readonly=True)
communication = fields.Char(
string='Communication', required=True,
readonly=True)
company_id = fields.Many2one(
'res.company',
related='order_id.payment_mode_id.company_id', store=True,
readonly=True)
company_currency_id = fields.Many2one(
'res.currency',
related='order_id.payment_mode_id.company_id.currency_id',
readonly=True, store=True)
@api.model
def same_fields_payment_line_and_bank_payment_line(self):
"""
This list of fields is used both to compute the grouping
hashcode and to copy the values from payment line
to bank payment line
The fields must have the same name on the 2 objects
"""
same_fields = [
'currency_id', 'partner_id',
'partner_bank_id', 'date', 'communication_type']
return same_fields
@api.multi
@api.depends('payment_line_ids', 'payment_line_ids.amount_currency')
def _compute_amount(self):
for bline in self:
amount_currency = sum(
bline.mapped('payment_line_ids.amount_currency'))
amount_company_currency = bline.currency_id.with_context(
date=bline.date).compute(
amount_currency, bline.company_currency_id)
bline.amount_currency = amount_currency
bline.amount_company_currency = amount_company_currency
@api.model
@api.returns('self')
def create(self, vals):
if vals.get('name', 'New') == 'New':
vals['name'] = self.env['ir.sequence'].next_by_code(
'bank.payment.line') or 'New'
return super(BankPaymentLine, self).create(vals)
@api.multi
def move_line_offsetting_account_hashcode(self):
"""
This method is inherited in the module
account_banking_sepa_direct_debit
"""
self.ensure_one()
if self.order_id.payment_mode_id.move_option == 'date':
hashcode = self.date
else:
hashcode = str(self.id)
return hashcode
@api.multi
def reconcile_payment_lines(self):
for bline in self:
if all([pline.move_line_id for pline in bline.payment_line_ids]):
bline.reconcile()
else:
bline.no_reconcile_hook()
@api.multi
def no_reconcile_hook(self):
"""This method is designed to be inherited if needed"""
return
@api.multi
def reconcile(self):
self.ensure_one()
amlo = self.env['account.move.line']
transit_mlines = amlo.search([('bank_payment_line_id', '=', self.id)])
assert len(transit_mlines) == 1, 'We should have only 1 move'
transit_mline = transit_mlines[0]
assert not transit_mline.reconciled,\
'Transit move should not be reconciled'
lines_to_rec = transit_mline
for payment_line in self.payment_line_ids:
if not payment_line.move_line_id:
raise UserError(_(
"Can not reconcile: no move line for "
"payment line %s of partner '%s'.") % (
payment_line.name,
payment_line.partner_id.name))
if payment_line.move_line_id.reconciled:
raise UserError(_(
"Move line '%s' of partner '%s' has already "
"been reconciled") % (
payment_line.move_line_id.name,
payment_line.partner_id.name))
if (
payment_line.move_line_id.account_id !=
transit_mline.account_id):
raise UserError(_(
"For partner '%s', the account of the account "
"move line to pay (%s) is different from the "
"account of of the transit move line (%s).") % (
payment_line.move_line_id.partner_id.name,
payment_line.move_line_id.account_id.code,
transit_mline.account_id.code))
lines_to_rec += payment_line.move_line_id
lines_to_rec.reconcile()
@api.multi
def unlink(self):
for line in self:
order_state = line.order_id.state
if order_state == 'uploaded':
raise UserError(_(
'Cannot delete a payment order line whose payment order is'
' in state \'%s\'. You need to cancel it first.')
% order_state)
return super(BankPaymentLine, self).unlink()