[MERGE]: survey: fixed a bug in warning message when users exceed maximal number...
[odoo/odoo.git] / addons / l10n_be_invoice_bba / invoice.py
1 # -*- encoding: utf-8 -*-\r
2 ##############################################################################\r
3 #\r
4 #    OpenERP, Open Source Management Solution\r
5 #    \r
6 #    Copyright (c) 2011 Noviat nv/sa (www.noviat.be). All rights reserved.\r
7\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
12 #\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
17 #\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
20 #\r
21 ##############################################################################\r
22 \r
23 import re, time, random\r
24 from osv import fields, osv\r
25 from tools.translate import _\r
26 import netsvc\r
27 logger=netsvc.Logger()\r
28 \r
29 """\r
30 account.invoice object:\r
31     - Add support for Belgian structured communication\r
32     - Rename 'reference' field labels to 'Communication'\r
33 """\r
34 \r
35 class account_invoice(osv.osv):\r
36     _inherit = 'account.invoice'\r
37 \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
41                 context=context)\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
45         return res\r
46 \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
51             return False                \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
57                 return True\r
58         return False\r
59 \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
64         return True\r
65 \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
72         reference = False\r
73         reference_type = 'none'\r
74         if partner_id:        \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
77                 if reference_type:\r
78                     algorithm = self.pool.get('res.partner').browse(cr, uid, partner_id).out_inv_comm_algorithm\r
79                     if not algorithm:\r
80                         algorithm = 'random' \r
81                     reference = self.generate_bbacomm(cr, uid, ids, type, reference_type, algorithm, partner_id, '')['value']['reference']\r
82         res_update = {       \r
83             'reference_type': reference_type or 'none',\r
84             'reference': reference,\r
85         }\r
86         result['value'].update(res_update)\r
87         return result                    \r
88 \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
94                 if not algorithm:\r
95                     if partner_id:\r
96                         algorithm = partner_obj.browse(cr, uid, partner_id).out_inv_comm_algorithm\r
97                     if not algorithm:\r
98                         if not 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
104                         seq = '001'\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
108                         if seq_ids:\r
109                             prev_seq = int(self.browse(cr, uid, seq_ids[-1]).reference[12:15])\r
110                             if prev_seq < 999:\r
111                                 seq = '%03d' % (prev_seq + 1)\r
112                             else:\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
128                         else:\r
129                             partner_ref_nr = partner_ref_nr.ljust(7, '0')\r
130                             seq = '001'\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
134                             if seq_ids:\r
135                                 prev_seq = int(self.browse(cr, uid, seq_ids[-1]).reference[12:15])\r
136                                 if prev_seq < 999:\r
137                                     seq = '%03d' % (prev_seq + 1)\r
138                                 else:\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
154                 else:\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
159     \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
166                 else:\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
176                     if same_ids:\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
181 \r
182     def write(self, cr, uid, ids, vals, context={}):\r
183         if isinstance(ids, (int, long)):\r
184             ids = [ids]\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
188             else:    \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
193                 else:\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
201                     if same_ids:\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
206 \r
207     _columns = {\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
210             required=True),\r
211     }\r
212     \r
213     _constraints = [\r
214         (_check_communication, 'Invalid BBA Structured Communication !', ['Communication']),\r
215         ]\r
216 \r
217 account_invoice()\r
218
219 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: