1 # -*- encoding: utf-8 -*-
\r
2 ##############################################################################
\r
4 # OpenERP, Open Source Management Solution
\r
6 # Copyright (c) 2011 Noviat nv/sa (www.noviat.be). All rights reserved.
\r
8 # This program is free software: you can redistribute it and/or modify
\r
9 # it under the terms of the GNU Affero General Public License as
\r
10 # published by the Free Software Foundation, either version 3 of the
\r
11 # License, or (at your option) any later version.
\r
13 # This program is distributed in the hope that it will be useful,
\r
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 # GNU Affero General Public License for more details.
\r
18 # You should have received a copy of the GNU Affero General Public License
\r
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
21 ##############################################################################
\r
23 import re, time, random
\r
24 from osv import fields, osv
\r
25 from tools.translate import _
\r
27 logger=netsvc.Logger()
\r
30 account.invoice object:
\r
31 - Add support for Belgian structured communication
\r
32 - Rename 'reference' field labels to 'Communication'
\r
35 class account_invoice(osv.osv):
\r
36 _inherit = 'account.invoice'
\r
38 def _get_reference_type(self, cursor, user, context=None):
\r
39 """Add BBA Structured Communication Type and change labels from 'reference' into 'communication' """
\r
40 res = super(account_invoice, self)._get_reference_type(cursor, user,
\r
42 res[[i for i,x in enumerate(res) if x[0] == 'none'][0]] = ('none', 'Free Communication')
\r
43 res.append(('bba', 'BBA Structured Communication'))
\r
44 #logger.notifyChannel('addons.'+self._name, netsvc.LOG_WARNING, 'reference_type = %s' %res )
\r
47 def check_bbacomm(self, val):
\r
48 supported_chars = '0-9+*/ '
\r
49 pattern = re.compile('[^' + supported_chars + ']')
\r
50 if pattern.findall(val or ''):
\r
52 bbacomm = re.sub('\D', '', val or '')
\r
53 if len(bbacomm) == 12:
\r
54 base = int(bbacomm[:10])
\r
55 mod = base % 97 or 97
\r
56 if mod == int(bbacomm[-2:]):
\r
60 def _check_communication(self, cr, uid, ids):
\r
61 for inv in self.browse(cr, uid, ids):
\r
62 if inv.reference_type == 'bba':
\r
63 return self.check_bbacomm(inv.reference)
\r
66 def onchange_partner_id(self, cr, uid, ids, type, partner_id,
\r
67 date_invoice=False, payment_term=False, partner_bank_id=False, company_id=False):
\r
68 result = super(account_invoice, self).onchange_partner_id(cr, uid, ids, type, partner_id,
\r
69 date_invoice, payment_term, partner_bank_id, company_id)
\r
70 # reference_type = self.default_get(cr, uid, ['reference_type'])['reference_type']
\r
71 # logger.notifyChannel('addons.'+self._name, netsvc.LOG_WARNING, 'partner_id %s' % partner_id)
\r
73 reference_type = 'none'
\r
75 if (type == 'out_invoice'):
\r
76 reference_type = self.pool.get('res.partner').browse(cr, uid, partner_id).out_inv_comm_type
\r
78 algorithm = self.pool.get('res.partner').browse(cr, uid, partner_id).out_inv_comm_algorithm
\r
80 algorithm = 'random'
\r
81 reference = self.generate_bbacomm(cr, uid, ids, type, reference_type, algorithm, partner_id, '')['value']['reference']
\r
83 'reference_type': reference_type or 'none',
\r
84 'reference': reference,
\r
86 result['value'].update(res_update)
\r
89 def generate_bbacomm(self, cr, uid, ids, type, reference_type, algorithm, partner_id, reference):
\r
90 partner_obj = self.pool.get('res.partner')
\r
91 reference = reference or ''
\r
92 if (type == 'out_invoice'):
\r
93 if reference_type == 'bba':
\r
96 algorithm = partner_obj.browse(cr, uid, partner_id).out_inv_comm_algorithm
\r
99 algorithm = 'random'
\r
100 if algorithm == 'date':
\r
101 if not self.check_bbacomm(reference):
\r
102 doy = time.strftime('%j')
\r
103 year = time.strftime('%Y')
\r
105 seq_ids = self.search(cr, uid,
\r
106 [('type', '=', 'out_invoice'), ('reference_type', '=', 'bba'),
\r
107 ('reference', 'like', '+++%s/%s/%%' % (doy, year))], order='reference')
\r
109 prev_seq = int(self.browse(cr, uid, seq_ids[-1]).reference[12:15])
\r
111 seq = '%03d' % (prev_seq + 1)
\r
113 raise osv.except_osv(_('Warning!'),
\r
114 _('The daily maximum of outgoing invoices with an automatically generated BBA Structured Communications has been exceeded!' \
\r
115 '\nPlease create manually a unique BBA Structured Communication.'))
\r
116 bbacomm = doy + year + seq
\r
117 base = int(bbacomm)
\r
118 mod = base % 97 or 97
\r
119 reference = '+++%s/%s/%s%02d+++' % (doy, year, seq, mod)
\r
120 elif algorithm == 'partner_ref':
\r
121 if not self.check_bbacomm(reference):
\r
122 partner_ref = self.pool.get('res.partner').browse(cr, uid, partner_id).ref
\r
123 partner_ref_nr = re.sub('\D', '', partner_ref or '')
\r
124 if (len(partner_ref_nr) < 3) or (len(partner_ref_nr) > 7):
\r
125 raise osv.except_osv(_('Warning!'),
\r
126 _('The Partner should have a 3-7 digit Reference Number for the generation of BBA Structured Communications!' \
\r
127 '\nPlease correct the Partner record.'))
\r
129 partner_ref_nr = partner_ref_nr.ljust(7, '0')
\r
131 seq_ids = self.search(cr, uid,
\r
132 [('type', '=', 'out_invoice'), ('reference_type', '=', 'bba'),
\r
133 ('reference', 'like', '+++%s/%s/%%' % (partner_ref_nr[:3], partner_ref_nr[3:]))], order='reference')
\r
135 prev_seq = int(self.browse(cr, uid, seq_ids[-1]).reference[12:15])
\r
137 seq = '%03d' % (prev_seq + 1)
\r
139 raise osv.except_osv(_('Warning!'),
\r
140 _('The daily maximum of outgoing invoices with an automatically generated BBA Structured Communications has been exceeded!' \
\r
141 '\nPlease create manually a unique BBA Structured Communication.'))
\r
142 bbacomm = partner_ref_nr + seq
\r
143 base = int(bbacomm)
\r
144 mod = base % 97 or 97
\r
145 reference = '+++%s/%s/%s%02d+++' % (partner_ref_nr[:3], partner_ref_nr[3:], seq, mod)
\r
146 elif algorithm == 'random':
\r
147 if not self.check_bbacomm(reference):
\r
148 base = random.randint(1, 9999999999)
\r
149 bbacomm = str(base).rjust(7, '0')
\r
150 base = int(bbacomm)
\r
151 mod = base % 97 or 97
\r
152 mod = str(mod).rjust(2, '0')
\r
153 reference = '+++%s/%s/%s%s+++' % (bbacomm[:3], bbacomm[3:7], bbacomm[7:], mod)
\r
155 raise osv.except_osv(_('Error!'),
\r
156 _("Unsupported Structured Communication Type Algorithm '%s' !" \
\r
157 "\nPlease contact your OpenERP support channel.") % algorithm)
\r
158 return {'value': {'reference': reference}}
\r
160 def create(self, cr, uid, vals, context=None):
\r
161 if vals.has_key('reference_type'):
\r
162 reference_type = vals['reference_type']
\r
163 if reference_type == 'bba':
\r
164 if vals.has_key('reference'):
\r
165 bbacomm = vals['reference']
\r
167 raise osv.except_osv(_('Warning!'),
\r
168 _('Empty BBA Structured Communication!' \
\r
169 '\nPlease fill in a unique BBA Structured Communication.'))
\r
170 if self.check_bbacomm(bbacomm):
\r
171 reference = re.sub('\D', '', bbacomm)
\r
172 vals['reference'] = '+++' + reference[0:3] + '/' + reference[3:7] + '/' + reference[7:] + '+++'
\r
173 same_ids = self.search(cr, uid,
\r
174 [('type', '=', 'out_invoice'), ('reference_type', '=', 'bba'),
\r
175 ('reference', '=', vals['reference'])])
\r
177 raise osv.except_osv(_('Warning!'),
\r
178 _('The BBA Structured Communication has already been used!' \
\r
179 '\nPlease create manually a unique BBA Structured Communication.'))
\r
180 return super(account_invoice, self).create(cr, uid, vals, context=context)
\r
182 def write(self, cr, uid, ids, vals, context={}):
\r
183 if isinstance(ids, (int, long)):
\r
185 for inv in self.browse(cr, uid, ids, context):
\r
186 if vals.has_key('reference_type'):
\r
187 reference_type = vals['reference_type']
\r
189 reference_type = inv.reference_type or ''
\r
190 if reference_type == 'bba':
\r
191 if vals.has_key('reference'):
\r
192 bbacomm = vals['reference']
\r
194 bbacomm = inv.reference or ''
\r
195 if self.check_bbacomm(bbacomm):
\r
196 reference = re.sub('\D', '', bbacomm)
\r
197 vals['reference'] = '+++' + reference[0:3] + '/' + reference[3:7] + '/' + reference[7:] + '+++'
\r
198 same_ids = self.search(cr, uid,
\r
199 [('id', '!=', inv.id), ('type', '=', 'out_invoice'),
\r
200 ('reference_type', '=', 'bba'), ('reference', '=', vals['reference'])])
\r
202 raise osv.except_osv(_('Warning!'),
\r
203 _('The BBA Structured Communication has already been used!' \
\r
204 '\nPlease create manually a unique BBA Structured Communication.'))
\r
205 return super(account_invoice, self).write(cr, uid, ids, vals, context)
\r
208 'reference': fields.char('Communication', size=64, help="The partner reference of this invoice."),
\r
209 'reference_type': fields.selection(_get_reference_type, 'Communication Type',
\r
214 (_check_communication, 'Invalid BBA Structured Communication !', ['Communication']),
\r
219 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: