mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
Better constraints for multicompany environments.
This commit is contained in:
committed by
Pedro M. Baeza
parent
78772a8392
commit
151349449e
@@ -6,12 +6,15 @@
|
||||
Account Payment Mode
|
||||
====================
|
||||
|
||||
This module adds a new object *account.payment.mode*. In Odoo v8, this object was part of the *account_payment* module from the official addons, but this module was dropped by the editor in Odoo v9. This object is also designed to replace the *payment.method* object of the *sale\_payment\_method* module of the `e-commerce <https://github.com/OCA/e-commerce>`_ OCA project in v9.
|
||||
This module adds a new object *account.payment.mode*, that is used to better
|
||||
classify and route incoming/outgoing payment orders with the banks.
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
To configure this module, you need to go to the menu *Account > Configuration > Management > Payment Mode*.
|
||||
To configure this module, you need to go to the menu
|
||||
*Invoicing/Accounting > Configuration > Management > Payment Modes*.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, fields
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class AccountJournal(models.Model):
|
||||
@@ -25,3 +26,25 @@ class AccountJournal(models.Model):
|
||||
company_partner_id = fields.Many2one(
|
||||
'res.partner', related='company_id.partner_id',
|
||||
readonly=True) # Used in domain of field bank_account_id
|
||||
|
||||
@api.constrains('company_id')
|
||||
def company_id_account_payment_mode_constrains(self):
|
||||
for journal in self:
|
||||
mode = self.env['account.payment.mode'].search([
|
||||
('fixed_journal_id', '=', journal.id),
|
||||
('company_id', '!=', journal.company_id.id)], limit=1)
|
||||
if mode:
|
||||
raise ValidationError(_(
|
||||
"The company of the journal '%s' does not match "
|
||||
"with the company of the payment mode '%s' where it is "
|
||||
"being used as Fixed Bank Journal.") % (
|
||||
journal.name, mode.name))
|
||||
mode = self.env['account.payment.mode'].search([
|
||||
('variable_journal_ids', 'in', [journal.id]),
|
||||
('company_id', '!=', journal.company_id.id)], limit=1)
|
||||
if mode:
|
||||
raise ValidationError(_(
|
||||
"The company of the journal '%s' does not match "
|
||||
"with the company of the payment mode '%s' where it is "
|
||||
"being used in the Allowed Bank Journals.") % (
|
||||
journal.name, mode.name))
|
||||
|
||||
@@ -7,11 +7,10 @@ from odoo import models, fields, api
|
||||
|
||||
class AccountPaymentMethod(models.Model):
|
||||
_inherit = 'account.payment.method'
|
||||
_rec_name = 'display_name'
|
||||
|
||||
code = fields.Char(
|
||||
string='Code (Do Not Modify)',
|
||||
help="This code is used in the code of the Odoo module that handle "
|
||||
help="This code is used in the code of the Odoo module that handles "
|
||||
"this payment method. Therefore, if you change it, "
|
||||
"the generation of the payment file may fail.")
|
||||
active = fields.Boolean(string='Active', default=True)
|
||||
@@ -19,19 +18,20 @@ class AccountPaymentMethod(models.Model):
|
||||
string='Bank Account Required',
|
||||
help="Activate this option if this payment method requires you to "
|
||||
"know the bank account number of your customer or supplier.")
|
||||
display_name = fields.Char(
|
||||
compute='compute_display_name',
|
||||
store=True, string='Display Name')
|
||||
payment_mode_ids = fields.One2many(
|
||||
comodel_name='account.payment.mode', inverse_name='payment_method_id',
|
||||
string='Payment modes')
|
||||
|
||||
@api.multi
|
||||
@api.depends('code', 'name', 'payment_type')
|
||||
def compute_display_name(self):
|
||||
def name_get(self):
|
||||
result = []
|
||||
for method in self:
|
||||
method.display_name = u'[%s] %s (%s)' % (
|
||||
method.code, method.name, method.payment_type)
|
||||
result.append((
|
||||
method.id, u'[%s] %s (%s)' % (
|
||||
method.code, method.name, method.payment_type)
|
||||
))
|
||||
return result
|
||||
|
||||
_sql_constraints = [(
|
||||
'code_payment_type_unique',
|
||||
|
||||
@@ -28,7 +28,7 @@ class AccountPaymentMode(models.Model):
|
||||
"SEPA direct debit from suppliers), select "
|
||||
"'Fixed'. For payment modes that are not always attached to the same "
|
||||
"bank account (such as SEPA Direct debit for customers, wire transfer "
|
||||
"to suppliers), you should choose 'Variable', which means that you "
|
||||
"to suppliers), you should select 'Variable', which means that you "
|
||||
"will select the bank account on the payment order. If your company "
|
||||
"only has one bank account, you should always select 'Fixed'.")
|
||||
fixed_journal_id = fields.Many2one(
|
||||
@@ -37,11 +37,10 @@ class AccountPaymentMode(models.Model):
|
||||
# I need to use the old definition, because I have 2 M2M fields
|
||||
# pointing to account.journal
|
||||
variable_journal_ids = fields.Many2many(
|
||||
'account.journal',
|
||||
'account_payment_mode_variable_journal_rel',
|
||||
'payment_mode_id', 'journal_id',
|
||||
string='Allowed Bank Journals',
|
||||
domain=[('type', '=', 'bank')])
|
||||
comodel_name='account.journal',
|
||||
relation='account_payment_mode_variable_journal_rel',
|
||||
column1='payment_mode_id', column2='journal_id',
|
||||
string='Allowed Bank Journals')
|
||||
payment_method_id = fields.Many2one(
|
||||
'account.payment.method', string='Payment Method', required=True,
|
||||
ondelete='restrict') # equivalent v8 field : type
|
||||
@@ -59,7 +58,12 @@ class AccountPaymentMode(models.Model):
|
||||
# and one for wire transfer to your suppliers (outbound)
|
||||
note = fields.Text(string="Note", translate=True)
|
||||
|
||||
@api.multi
|
||||
@api.onchange('company_id')
|
||||
def _onchange_company_id(self):
|
||||
for mode in self:
|
||||
mode.variable_journal_ids = False
|
||||
mode.fixed_journal_id = False
|
||||
|
||||
@api.constrains(
|
||||
'bank_account_link', 'fixed_journal_id', 'payment_method_id')
|
||||
def bank_account_link_constrains(self):
|
||||
@@ -98,3 +102,22 @@ class AccountPaymentMode(models.Model):
|
||||
mode.name,
|
||||
mode.payment_method_id.name,
|
||||
mode.fixed_journal_id.name))
|
||||
|
||||
@api.constrains('company_id', 'fixed_journal_id')
|
||||
def company_id_fixed_journal_id_constrains(self):
|
||||
for mode in self:
|
||||
if mode.fixed_journal_id and mode.company_id != \
|
||||
mode.fixed_journal_id.company_id:
|
||||
raise ValidationError(_(
|
||||
"The company of the payment mode '%s', does not match "
|
||||
"with the company of journal '%s'.") % (
|
||||
mode.name, mode.fixed_journal_id.name))
|
||||
|
||||
@api.constrains('company_id', 'variable_journal_ids')
|
||||
def company_id_variable_journal_ids_constrains(self):
|
||||
for mode in self:
|
||||
if any(mode.company_id != j.company_id for j in
|
||||
mode.variable_journal_ids):
|
||||
raise ValidationError(_(
|
||||
"The company of the payment mode '%s', does not match "
|
||||
"with the one of the Allowed Bank Journals.") % mode.name)
|
||||
|
||||
BIN
account_payment_mode/static/description/icon.png
Normal file
BIN
account_payment_mode/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
4
account_payment_mode/tests/__init__.py
Normal file
4
account_payment_mode/tests/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
from . import test_account_payment_mode
|
||||
117
account_payment_mode/tests/test_account_payment_mode.py
Normal file
117
account_payment_mode/tests/test_account_payment_mode.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class TestAccountPaymentMode(TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestAccountPaymentMode, self).setUp()
|
||||
self.res_users_model = self.env['res.users']
|
||||
self.journal_model = self.env['account.journal']
|
||||
self.payment_mode_model = self.env['account.payment.mode']
|
||||
|
||||
# refs
|
||||
self.manual_out = self.env.ref(
|
||||
'account.account_payment_method_manual_out')
|
||||
# Company
|
||||
self.company = self.env.ref('base.main_company')
|
||||
|
||||
# Company 2
|
||||
self.company_2 = self.env['res.company'].create({
|
||||
'name': 'Company 2',
|
||||
})
|
||||
|
||||
self.journal_c1 = self._create_journal('J1', self.company)
|
||||
self.journal_c2 = self._create_journal('J2', self.company_2)
|
||||
self.journal_c3 = self._create_journal('J3', self.company)
|
||||
|
||||
self.payment_mode_c1 = self.payment_mode_model.create({
|
||||
'name': 'Direct Debit of suppliers from Bank 1',
|
||||
'bank_account_link': 'variable',
|
||||
'payment_method_id': self.manual_out.id,
|
||||
'company_id': self.company.id,
|
||||
'fixed_journal_id': self.journal_c1.id,
|
||||
'variable_journal_ids': [(6, 0, [self.journal_c1.id,
|
||||
self.journal_c3.id])]
|
||||
})
|
||||
|
||||
def _create_journal(self, name, company):
|
||||
# Create a cash account
|
||||
# Create a journal for cash account
|
||||
journal = self.journal_model.create({
|
||||
'name': name,
|
||||
'code': name,
|
||||
'type': 'bank',
|
||||
'company_id': company.id,
|
||||
})
|
||||
return journal
|
||||
|
||||
def test_payment_mode_company_consistency_change(self):
|
||||
# Assertion on the constraints to ensure the consistency
|
||||
# for company dependent fields
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_c1. \
|
||||
write({'fixed_journal_id': self.journal_c2.id})
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_c1.write({
|
||||
'variable_journal_ids': [
|
||||
(6, 0, [
|
||||
self.journal_c1.id,
|
||||
self.journal_c2.id,
|
||||
self.journal_c3.id
|
||||
])
|
||||
]
|
||||
})
|
||||
with self.assertRaises(ValidationError):
|
||||
self.journal_c1.write({'company_id': self.company_2.id})
|
||||
|
||||
def test_payment_mode_company_consistency_create(self):
|
||||
# Assertion on the constraints to ensure the consistency
|
||||
# for company dependent fields
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_model.create({
|
||||
'name': 'Direct Debit of suppliers from Bank 2',
|
||||
'bank_account_link': 'variable',
|
||||
'payment_method_id': self.manual_out.id,
|
||||
'company_id': self.company.id,
|
||||
'fixed_journal_id': self.journal_c2.id
|
||||
})
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_model.create({
|
||||
'name': 'Direct Debit of suppliers from Bank 3',
|
||||
'bank_account_link': 'variable',
|
||||
'payment_method_id': self.manual_out.id,
|
||||
'company_id': self.company.id,
|
||||
'variable_journal_ids': [(6, 0, [self.journal_c2.id])]
|
||||
})
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_model.create({
|
||||
'name': 'Direct Debit of suppliers from Bank 4',
|
||||
'bank_account_link': 'fixed',
|
||||
'payment_method_id': self.manual_out.id,
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
self.journal_c1.outbound_payment_method_ids = False
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_model.create({
|
||||
'name': 'Direct Debit of suppliers from Bank 5',
|
||||
'bank_account_link': 'fixed',
|
||||
'payment_method_id': self.manual_out.id,
|
||||
'company_id': self.company.id,
|
||||
'fixed_journal_id': self.journal_c1.id
|
||||
})
|
||||
self.journal_c1.inbound_payment_method_ids = False
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_model.create({
|
||||
'name': 'Direct Debit of suppliers from Bank 5',
|
||||
'bank_account_link': 'fixed',
|
||||
'payment_method_id': self.env.ref(
|
||||
'account.account_payment_method_manual_in').id,
|
||||
'company_id': self.company.id,
|
||||
'fixed_journal_id': self.journal_c1.id
|
||||
})
|
||||
@@ -15,9 +15,11 @@
|
||||
<field name="bank_account_link"/>
|
||||
<field name="fixed_journal_id"
|
||||
attrs="{'invisible': [('bank_account_link', '!=', 'fixed')], 'required': [('bank_account_link', '=', 'fixed')]}"
|
||||
domain="[('company_id', '=', company_id), ('type', '=', 'bank')]"
|
||||
widget="selection"/>
|
||||
<field name="variable_journal_ids"
|
||||
attrs="{'invisible': [('bank_account_link', '!=', 'variable')], 'required': [('bank_account_link', '=', 'variable')]}"
|
||||
domain="[('company_id', '=', company_id), ('type', '=', 'bank')]"
|
||||
widget="many2many_tags"/>
|
||||
</group>
|
||||
<group string="Note" name="note">
|
||||
|
||||
Reference in New Issue
Block a user