summaryrefslogtreecommitdiff
path: root/addons/l10n_be_invoice_bba
diff options
context:
space:
mode:
authorLaurent Smet <las@odoo.com>2018-06-11 15:22:16 +0200
committerqdp-odoo <qdp@odoo.com>2018-07-26 22:45:41 +0200
commitb5bb5bd421ad5c643f72602f6a0f97a4a0eb8711 (patch)
tree735fff1ab8bbee09911c1821aed9a65d46897b53 /addons/l10n_be_invoice_bba
parent71200fdc9b9c5da570271465c33eff9a3c1fc515 (diff)
[IMP] account: automatic communication management on out_invoices
On the accounting config, you can select an automatic way to compute the reference on invoice and then, improve the reconciliation in a later task: - free communication: set what you want as reference (default) - based on partner: find the partner more easily - based on number: retrieve the invoice directly Was task: 1847703 Was part of PR #25921
Diffstat (limited to 'addons/l10n_be_invoice_bba')
-rw-r--r--addons/l10n_be_invoice_bba/__manifest__.py9
-rw-r--r--addons/l10n_be_invoice_bba/models/account_invoice.py218
-rw-r--r--addons/l10n_be_invoice_bba/models/res_partner.py15
-rw-r--r--addons/l10n_be_invoice_bba/views/account_invoice_view.xml15
-rw-r--r--addons/l10n_be_invoice_bba/views/report_invoice.xml10
5 files changed, 73 insertions, 194 deletions
diff --git a/addons/l10n_be_invoice_bba/__manifest__.py b/addons/l10n_be_invoice_bba/__manifest__.py
index dd5d13f35e2..b3e8b3924f0 100644
--- a/addons/l10n_be_invoice_bba/__manifest__.py
+++ b/addons/l10n_be_invoice_bba/__manifest__.py
@@ -10,11 +10,8 @@
'website': 'https://www.odoo.com/page/accounting',
'category': 'Localization',
'description': """
-
-Belgian localization for in- and outgoing invoices (prereq to account_coda):
-============================================================================
- - Rename 'reference' field labels to 'Communication'
- - Add support for Belgian Structured Communication
+
+Add support for Belgian Structured Communication
A Structured Communication can be generated automatically on outgoing invoices according to the following algorithms:
---------------------------------------------------------------------------------------------------------------------
@@ -34,7 +31,5 @@ generated if no algorithm is specified on the Partner record.
'data' : [
'data/mail_template_data.xml',
'views/res_partner_view.xml',
- 'views/account_invoice_view.xml',
- 'views/report_invoice.xml',
],
}
diff --git a/addons/l10n_be_invoice_bba/models/account_invoice.py b/addons/l10n_be_invoice_bba/models/account_invoice.py
index d66669747f5..e02761163dc 100644
--- a/addons/l10n_be_invoice_bba/models/account_invoice.py
+++ b/addons/l10n_be_invoice_bba/models/account_invoice.py
@@ -7,179 +7,75 @@ import random
import re
from odoo import api, fields, models, _
-from odoo.exceptions import UserError, ValidationError
+from odoo.exceptions import UserError
"""
-account.invoice object:
- - Add support for Belgian structured communication
- - Rename 'reference' field labels to 'Communication'
+account.invoice object: add support for Belgian structured communication
"""
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
- @api.model
- def _get_reference_type(self):
- """Add BBA Structured Communication Type and change labels from 'reference' into 'communication' """
- res = super(AccountInvoice, self)._get_reference_type()
- res[[i for i, x in enumerate(res) if x[0] == 'none'][0]] = ('none', _('Free Communication'))
- res.append(('bba', 'BBA Structured Communication'))
- return res
-
- reference_type = fields.Selection('_get_reference_type', string='Payment Reference',
- required=True, readonly=True)
-
- @api.constrains('reference', 'reference_type')
- def _check_communication(self):
- for inv in self:
- if inv.reference_type == 'bba' and not self.check_bbacomm(inv.reference):
- raise ValidationError(_('Invalid BBA Structured Communication.'))
-
- def check_bbacomm(self, val):
- supported_chars = '0-9+*/ '
- pattern = re.compile('[^' + supported_chars + ']')
- if pattern.findall(val or ''):
- return False
- bbacomm = re.sub('\D', '', val or '')
- if len(bbacomm) == 12:
- base = int(bbacomm[:10])
- mod = base % 97 or 97
- if mod == int(bbacomm[-2:]):
- return True
-
- @api.onchange('partner_id', 'type', 'reference_type')
- def _onchange_partner_id(self):
- result = super(AccountInvoice, self)._onchange_partner_id()
- reference = False
- reference_type = 'none'
- if self.partner_id:
- if (self.type == 'out_invoice'):
- reference_type = self.partner_id.out_inv_comm_type
- if reference_type:
- reference = self.generate_bbacomm(self.type, reference_type, self.partner_id.id, '')['value']['reference']
- self.reference_type = reference_type or 'none'
- self.reference = reference
- return result
-
- def generate_bbacomm(self, type, reference_type, partner_id, reference):
- reference = reference or ''
- algorithm = False
- if partner_id:
- algorithm = self.env['res.partner'].browse(partner_id).out_inv_comm_algorithm
- algorithm = algorithm or 'random'
- if (type == 'out_invoice'):
- if reference_type == 'bba':
- if algorithm == 'date':
- if not self.check_bbacomm(reference):
- date = fields.Date.from_string(fields.Date.today())
- doy = date.strftime('%j')
- year = date.strftime('%Y')
- seq = '001'
- invoices = self.search([('type', '=', 'out_invoice'), ('reference_type', '=', 'bba'),
- ('reference', 'like', '+++%s/%s/%%' % (doy, year))], order='reference')
- if invoices:
- prev_seq = int(invoices[-1].reference[12:15])
- if prev_seq < 999:
- seq = '%03d' % (prev_seq + 1)
- else:
- raise UserError(_('The daily maximum of outgoing invoices with an automatically generated BBA Structured Communications has been exceeded!'
- '\nPlease create manually a unique BBA Structured Communication.'))
- bbacomm = doy + year + seq
- base = int(bbacomm)
- mod = base % 97 or 97
- reference = '+++%s/%s/%s%02d+++' % (doy, year, seq, mod)
- elif algorithm == 'partner_ref':
- if not self.check_bbacomm(reference):
- partner_ref = self.env['res.partner'].browse(partner_id).ref
- partner_ref_nr = re.sub('\D', '', partner_ref or '')
- if (len(partner_ref_nr) < 3) or (len(partner_ref_nr) > 7):
- raise UserError(_('The Partner should have a 3-7 digit Reference Number for the generation of BBA Structured Communications!'
- '\nPlease correct the Partner record.'))
- else:
- partner_ref_nr = partner_ref_nr.ljust(7, '0')
- seq = '001'
- invoices = self.search([('type', '=', 'out_invoice'), ('reference_type', '=', 'bba'),
- ('reference', 'like', '+++%s/%s/%%' % (partner_ref_nr[:3], partner_ref_nr[3:]))], order='reference')
- if invoices:
- prev_seq = int(invoices[-1].reference[12:15])
- if prev_seq < 999:
- seq = '%03d' % (prev_seq + 1)
- else:
- raise UserError(_('The daily maximum of outgoing invoices with an automatically generated BBA Structured Communications has been exceeded!'
- '\nPlease create manually a unique BBA Structured Communication.'))
- bbacomm = partner_ref_nr + seq
- base = int(bbacomm)
- mod = base % 97 or 97
- reference = '+++%s/%s/%s%02d+++' % (partner_ref_nr[:3], partner_ref_nr[3:], seq, mod)
- elif algorithm == 'random':
- if not self.check_bbacomm(reference):
- base = random.randint(1, 9999999999)
- bbacomm = str(base).rjust(10, '0')
- base = int(bbacomm)
- mod = base % 97 or 97
- mod = str(mod).rjust(2, '0')
- reference = '+++%s/%s/%s%s+++' % (bbacomm[:3], bbacomm[3:7], bbacomm[7:], mod)
+ def generate_bbacomm(self, partner):
+ reference = ''
+ algorithm = partner.out_inv_comm_algorithm or 'random'
+ if algorithm == 'date':
+ date = fields.Date.from_string(fields.Date.today())
+ doy = date.strftime('%j')
+ year = date.strftime('%Y')
+ seq = '001'
+ invoices = self.search([('type', '=', 'out_invoice'),
+ ('reference', 'like', '+++%s/%s/%%' % (doy, year))], order='reference')
+ if invoices:
+ prev_seq = int(invoices[-1].reference[12:15])
+ if prev_seq < 999:
+ seq = '%03d' % (prev_seq + 1)
else:
- raise UserError(_("Unsupported Structured Communication Type Algorithm '%s' !"
- "\nPlease contact your Odoo support channel.") % algorithm)
- return {'value': {'reference': reference}}
-
- @api.model
- def create(self, vals):
- reference = vals.get('reference', False)
- reference_type = vals.get('reference_type', False)
- if vals.get('type') == 'out_invoice' and not reference_type:
- # fallback on default communication type for partner
- partner = self.env['res.partner'].browse(vals['partner_id'])
- reference_type = partner.out_inv_comm_type
- if reference_type == 'bba':
- reference = self.generate_bbacomm(vals['type'], reference_type, partner.id, '')['value']['reference']
- vals.update({
- 'reference_type': reference_type or 'none',
- 'reference': reference,
- })
-
- if reference_type == 'bba':
- if not reference:
- raise UserError(_('Empty BBA Structured Communication!'
- '\nPlease fill in a unique BBA Structured Communication.'))
- if self.check_bbacomm(reference):
- reference = re.sub('\D', '', reference)
- vals['reference'] = '+++' + reference[0:3] + '/' + reference[3:7] + '/' + reference[7:] + '+++'
- same_ids = self.search([('type', '=', 'out_invoice'), ('reference_type', '=', 'bba'), ('reference', '=', vals['reference'])])
- if same_ids:
- raise UserError(_('The BBA Structured Communication has already been used!'
+ raise UserError(_('The daily maximum of outgoing invoices with an automatically generated BBA Structured Communications has been exceeded!'
'\nPlease create manually a unique BBA Structured Communication.'))
- return super(AccountInvoice, self).create(vals)
-
- @api.multi
- def write(self, vals):
- for invoice in self:
- if 'reference_type' in vals:
- reference_type = vals['reference_type']
+ bbacomm = doy + year + seq
+ base = int(bbacomm)
+ mod = base % 97 or 97
+ reference = '+++%s/%s/%s%02d+++' % (doy, year, seq, mod)
+ elif algorithm == 'partner_ref':
+ partner_ref = partner.ref
+ print(partner_ref)
+ partner_ref_nr = re.sub('\D', '', partner_ref or '')
+ if (len(partner_ref_nr) < 3) or (len(partner_ref_nr) > 7):
+ raise UserError(_('The Partner should have a 3-7 digit Reference Number for the generation of BBA Structured Communications!'
+ '\nPlease correct the Partner record.'))
else:
- reference_type = invoice.reference_type or ''
-
- if reference_type == 'bba' and 'reference' in vals:
- if self.check_bbacomm(vals['reference']):
- reference = re.sub('\D', '', vals['reference'])
- vals['reference'] = '+++' + reference[0:3] + '/' + reference[3:7] + '/' + reference[7:] + '+++'
- same_ids = self.search([('id', '!=', invoice.id), ('type', '=', 'out_invoice'),
- ('reference_type', '=', 'bba'), ('reference', '=', vals['reference'])])
- if same_ids:
- raise UserError(_('The BBA Structured Communication has already been used!'
+ partner_ref_nr = partner_ref_nr.ljust(7, '0')
+ seq = '001'
+ invoices = self.search([('type', '=', 'out_invoice'),
+ ('reference', 'like', '+++%s/%s/%%' % (partner_ref_nr[:3], partner_ref_nr[3:]))], order='reference')
+ if invoices:
+ prev_seq = int(invoices[-1].reference[12:15])
+ if prev_seq < 999:
+ seq = '%03d' % (prev_seq + 1)
+ else:
+ raise UserError(_('The daily maximum of outgoing invoices with an automatically generated BBA Structured Communications has been exceeded!'
'\nPlease create manually a unique BBA Structured Communication.'))
- return super(AccountInvoice, self).write(vals)
+ bbacomm = partner_ref_nr + seq
+ base = int(bbacomm)
+ mod = base % 97 or 97
+ reference = '+++%s/%s/%s%02d+++' % (partner_ref_nr[:3], partner_ref_nr[3:], seq, mod)
+ elif algorithm == 'random':
+ base = random.randint(1, 9999999999)
+ bbacomm = str(base).rjust(10, '0')
+ base = int(bbacomm)
+ mod = base % 97 or 97
+ mod = str(mod).rjust(2, '0')
+ reference = '+++%s/%s/%s%s+++' % (bbacomm[:3], bbacomm[3:7], bbacomm[7:], mod)
+ else:
+ raise UserError(_("Unsupported Structured Communication Type Algorithm '%s' !"
+ "\nPlease contact your Odoo support channel.") % algorithm)
+ return reference
@api.multi
- @api.returns('self', lambda value: value.id)
- def copy(self, default=None):
+ def _get_computed_reference(self):
self.ensure_one()
- default = default or {}
- if self.type in ['out_invoice']:
- reference_type = self.reference_type or 'none'
- default['reference_type'] = reference_type
- if reference_type == 'bba':
- default['reference'] = self.generate_bbacomm(self.type, reference_type, self.partner_id.id, '')['value']['reference']
- return super(AccountInvoice, self).copy(default)
+ if self.company_id.invoice_reference_type == 'bba':
+ return self.generate_bbacomm(self.partner_id)
+ return super(AccountInvoice, self)._get_computed_reference()
diff --git a/addons/l10n_be_invoice_bba/models/res_partner.py b/addons/l10n_be_invoice_bba/models/res_partner.py
index 853b0418c85..20fa17ab95a 100644
--- a/addons/l10n_be_invoice_bba/models/res_partner.py
+++ b/addons/l10n_be_invoice_bba/models/res_partner.py
@@ -6,13 +6,26 @@
from odoo import api, fields, models
+class ResCompany(models.Model):
+ _inherit = "res.company"
+
+ @api.model
+ def _get_invoice_reference_types(self):
+ res = super(ResCompany, self)._get_invoice_reference_types()
+ # Add BBA Structured Communication Type
+ res.append(('bba', 'BBA Structured Communication'))
+ return res
+
+ invoice_reference_type = fields.Selection(string='Default Communication Type', selection='_get_invoice_reference_types',
+ default='bba', help='You can set here the default communication that will appear on customer invoices, once validated, to help the customer to refer to that particular invoice when making the payment.')
+
class ResPartner(models.Model):
""" add field to indicate default 'Communication Type' on customer invoices """
_inherit = 'res.partner'
@api.model
def _get_comm_type(self):
- return self.env['account.invoice']._get_reference_type()
+ return self.env['res.company']._get_invoice_reference_types()
out_inv_comm_type = fields.Selection('_get_comm_type', string='Communication Type', change_default=True,
help='Select Default Communication Type for Outgoing Invoices.', default='none')
diff --git a/addons/l10n_be_invoice_bba/views/account_invoice_view.xml b/addons/l10n_be_invoice_bba/views/account_invoice_view.xml
deleted file mode 100644
index 9ab348940a1..00000000000
--- a/addons/l10n_be_invoice_bba/views/account_invoice_view.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<odoo>
- <!-- Adapt Customer Invoices to support bba structured communication -->
- <record id="customer_invoice_bbacomm_form" model="ir.ui.view">
- <field name="name">account.invoice.form.inherit</field>
- <field name="model">account.invoice</field>
- <field name="inherit_id" ref="account.invoice_form"/>
- <field name="arch" type="xml">
- <field name="date_due" position="after">
- <field name="reference_type" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}"/>
- <field name="reference" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}"/>
- </field>
- </field>
- </record>
-</odoo>
diff --git a/addons/l10n_be_invoice_bba/views/report_invoice.xml b/addons/l10n_be_invoice_bba/views/report_invoice.xml
deleted file mode 100644
index 0cbc51adfb7..00000000000
--- a/addons/l10n_be_invoice_bba/views/report_invoice.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<odoo>
- <template id="report_invoice_document_inherit" inherit_id="account.report_invoice_document">
- <xpath expr="//div[@id='total']" position="after">
- <p t-if="o.reference_type=='bba' and o.reference">
- Please use the following communication for your payment : <b><span t-field="o.reference"/></b>
- </p>
- </xpath>
- </template>
-</odoo>