diff options
| author | Laurent Smet <las@odoo.com> | 2018-06-11 15:22:16 +0200 |
|---|---|---|
| committer | qdp-odoo <qdp@odoo.com> | 2018-07-26 22:45:41 +0200 |
| commit | b5bb5bd421ad5c643f72602f6a0f97a4a0eb8711 (patch) | |
| tree | 735fff1ab8bbee09911c1821aed9a65d46897b53 /addons/l10n_be_invoice_bba | |
| parent | 71200fdc9b9c5da570271465c33eff9a3c1fc515 (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__.py | 9 | ||||
| -rw-r--r-- | addons/l10n_be_invoice_bba/models/account_invoice.py | 218 | ||||
| -rw-r--r-- | addons/l10n_be_invoice_bba/models/res_partner.py | 15 | ||||
| -rw-r--r-- | addons/l10n_be_invoice_bba/views/account_invoice_view.xml | 15 | ||||
| -rw-r--r-- | addons/l10n_be_invoice_bba/views/report_invoice.xml | 10 |
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> |
