Server IP : 127.0.0.2 / Your IP : 3.138.36.87 Web Server : Apache/2.4.18 (Ubuntu) System : User : www-data ( ) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : disk_free_space,disk_total_space,diskfreespace,dl,exec,fpaththru,getmyuid,getmypid,highlight_file,ignore_user_abord,leak,listen,link,opcache_get_configuration,opcache_get_status,passthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,php_uname,phpinfo,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,pclose,popen,proc_open,proc_close,proc_get_status,proc_nice,proc_terminate,shell_exec,source,show_source,system,virtual MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /opt/odoo/addons/l10n_be_invoice_bba/models/ |
Upload File : |
# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. # Copyright (c) 2011 Noviat nv/sa (www.noviat.be). All rights reserved. import random import re from odoo import api, fields, models, _ from odoo.exceptions import UserError, ValidationError """ account.invoice object: - Add support for Belgian structured communication - Rename 'reference' field labels to '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') 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 @api.multi 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) 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!' '\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'] 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!' '\nPlease create manually a unique BBA Structured Communication.')) return super(AccountInvoice, self).write(vals) @api.multi def copy(self, default=None): 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)