[REF] l10n_ch - refactor bank.py
[odoo/odoo.git] / addons / l10n_ch / report / report_webkit_html.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    Author: Nicolas Bessi. Copyright Camptocamp SA
5 #    Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 import time
23 import sys
24 import os
25 import re
26
27 from mako.template import Template
28 from mako.lookup import TemplateLookup
29 from mako import exceptions
30
31
32 from report import report_sxw
33 from report_webkit import webkit_report
34 from report_webkit import report_helper
35
36 from osv import osv
37 from osv.osv import except_osv
38
39 from tools import mod10r
40 from tools.translate import _
41 from tools.config import config
42
43 import wizard
44 import addons
45 import pooler
46
47
48
49
50 class l10n_ch_report_webkit_html(report_sxw.rml_parse):
51     def __init__(self, cr, uid, name, context):
52         super(l10n_ch_report_webkit_html, self).__init__(cr, uid, name, context=context)
53         self.localcontext.update({
54             'time': time,
55             'cr': cr,
56             'uid': uid,
57             'user':self.pool.get("res.users").browse(cr, uid, uid),
58             'mod10r': mod10r,
59             '_space': self._space,
60             '_get_ref': self._get_ref,
61             'comma_me': self.comma_me,
62             'police_absolute_path': self.police_absolute_path,
63             'bvr_absolute_path': self.bvr_absolute_path,
64             'headheight': self.headheight
65         })
66
67     _compile_get_ref = re.compile('[^0-9]')
68     _compile_comma_me = re.compile("^(-?\d+)(\d{3})")
69     _compile_check_bvr = re.compile('[0-9][0-9]-[0-9]{3,6}-[0-9]')
70     _compile_check_bvr_add_num = re.compile('[0-9]*$')
71
72     def set_context(self, objects, data, ids, report_type=None):
73         user = self.pool.get('res.users').browse(self.cr, self.uid, self.uid)
74         company = user.company_id
75         if not company.invoice_only:
76             self._check(ids)
77         return super(l10n_ch_report_webkit_html, self).set_context(objects, data, ids, report_type=report_type)
78
79     def police_absolute_path(self, inner_path) :
80         """Will get the ocrb police absolute path"""
81         path = addons.get_module_resource(os.path.join('l10n_ch', 'report', inner_path))
82         return  path
83
84     def bvr_absolute_path(self) :
85         """Will get the ocrb police absolute path"""
86         path = addons.get_module_resource(os.path.join('l10n_ch', 'report', 'bvr1.jpg'))
87         return  path
88
89     def headheight(self):
90         report_id = self.pool.get('ir.actions.report.xml').search(self.cr, self.uid, [('name','=', 'BVR invoice')])[0]
91         report = self.pool.get('ir.actions.report.xml').browse(self.cr, self.uid, report_id)
92         return report.webkit_header.margin_top
93
94     def comma_me(self, amount):
95         """Fast swiss number formatting"""
96         if  isinstance(amount, float):
97             amount = str('%.2f'%amount)
98         else :
99             amount = str(amount)
100         orig = amount
101         new = self._compile_comma_me.sub("\g<1>'\g<2>", amount)
102         if orig == new:
103             return new
104         else:
105             return self.comma_me(new)
106
107     def _space(self, nbr, nbrspc=5):
108         """Spaces * 5.
109
110         Example:
111             >>> self._space('123456789012345')
112             '12 34567 89012 345'
113         """
114         return ''.join([' '[(i - 2) % nbrspc:] + c for i, c in enumerate(nbr)])
115
116
117     def _get_ref(self, inv):
118         """Retrieve ESR/BVR reference form invoice in order to print it"""
119         res = ''
120         if inv.partner_bank_id.bvr_adherent_num:
121             res = inv.partner_bank_id.bvr_adherent_num
122         invoice_number = ''
123         if inv.number:
124             invoice_number = self._compile_get_ref.sub('', inv.number)
125         return mod10r(res + invoice_number.rjust(26-len(res), '0'))
126
127     def _check(self, invoice_ids):
128         """Check if the invoice is ready to be printed"""
129         if not invoice_ids:
130             invoice_ids = []
131         cursor = self.cr
132         pool = self.pool
133         invoice_obj = pool.get('account.invoice')
134         ids = invoice_ids
135         for invoice in invoice_obj.browse(cursor, self.uid, ids):
136             invoice_name = "%s %s" %(invoice.name, invoice.number)
137             if not invoice.partner_bank_id:
138                 raise except_osv(_('UserError'),
139                         _('No bank specified on invoice:\n%s' %(invoice_name)))
140             if not self._compile_check_bvr.match(
141                     invoice.partner_bank_id.post_number or ''):
142                 raise except_osv(_('UserError'),
143                         _(('Your bank BVR number should be of the form 0X-XXX-X! '
144                           'Please check your company '
145                           'information for the invoice:\n%s')
146                           %(invoice_name)))
147             if invoice.partner_bank_id.bvr_adherent_num \
148                     and not self._compile_check_bvr_add_num.match(
149                             invoice.partner_bank_id.bvr_adherent_num):
150                 raise except_osv(_('UserError'),
151                         _(('Your bank BVR adherent number must contain only '
152                           'digits!\nPlease check your company '
153                           'information for the invoice:\n%s') %(invoice_name)))
154         return ''
155
156 def mako_template(text):
157     """Build a Mako template.
158
159     This template uses UTF-8 encoding
160     """
161     tmp_lookup  = TemplateLookup() #we need it in order to allow inclusion and inheritance
162     return Template(text, input_encoding='utf-8', output_encoding='utf-8', lookup=tmp_lookup)
163
164 class BVRWebKitParser(webkit_report.WebKitParser):
165
166     bvr_file_path = os.path.join('l10n_ch','report','bvr.mako')
167
168     def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
169         """generate the PDF"""
170         context = context or {}
171         if report_xml.report_type != 'webkit':
172             return super(WebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context)
173         self.parser_instance = self.parser(cursor,
174                                             uid,
175                                             self.name2,
176                                             context=context)
177         self.pool = pooler.get_pool(cursor.dbname)
178         objs = self.getObjects(cursor, uid, ids, context)
179         self.parser_instance.set_context(objs, data, ids, report_xml.report_type)
180         template =  False
181         if report_xml.report_file :
182             path = addons.get_module_resource(report_xml.report_file)
183             if os.path.exists(path) :
184                 template = file(path).read()
185         if not template and report_xml.report_webkit_data :
186             template =  report_xml.report_webkit_data
187         if not template :
188             raise except_osv(_('Error'),_('Webkit Report template not found !'))
189         header = report_xml.webkit_header.html
190         footer = report_xml.webkit_header.footer_html
191         if not header and report_xml.header:
192           raise except_osv(
193                 _('No header defined for this Webkit report!'),
194                 _('Please set a header in company settings')
195             )
196         if not report_xml.header :
197             header = ''
198             default_head = addons.get_module_resource('report_webkit', 'default_header.html')
199             with open(default_head,'r') as f:
200                 header = f.read()
201         css = report_xml.webkit_header.css
202         if not css :
203             css = ''
204         user = self.pool.get('res.users').browse(cursor, uid, uid)
205         company = user.company_id
206         body_mako_tpl = mako_template(template)
207         #BVR specific
208         bvr_path = addons.get_module_resource(self.bvr_file_path)
209         body_bvr_tpl = mako_template(file(bvr_path).read())
210         helper = report_helper.WebKitHelper(cursor, uid, report_xml.id, context)
211         ##BVR Specific
212         htmls = []
213         for obj in objs :
214             self.parser_instance.localcontext['objects'] = [obj]
215             if not company.bvr_only:
216                 try:
217                     html = body_mako_tpl.render(helper=helper,
218                                                 css=css,
219                                                 _=self.translate_call,
220                                                 **self.parser_instance.localcontext)
221                 except Exception, e:
222                    raise Exception(exceptions.text_error_template().render())
223                 htmls.append(html)
224             if not company.invoice_only:
225                 try:
226                     bvr = body_bvr_tpl.render(helper=helper,
227                                               css=css,
228                                               _=self.translate_call,
229                                               **self.parser_instance.localcontext)
230                 except Exception, e:
231                    raise Exception(exceptions.text_error_template().render())
232                 htmls.append(bvr)
233         head_mako_tpl = Template(header, input_encoding='utf-8', output_encoding='utf-8')
234         try:
235             head = head_mako_tpl.render(helper=helper,
236                                         css=css,
237                                         _debug=False,
238                                         _=self.translate_call,
239                                         **self.parser_instance.localcontext)
240         except Exception, e:
241            raise Exception(exceptions.text_error_template().render())
242         foot = False
243         if footer and company.invoice_only :
244             foot_mako_tpl = Template(footer, input_encoding='utf-8', output_encoding='utf-8')
245             try:
246                 foot = foot_mako_tpl.render(helper=helper,
247                                             css=css,
248                                             _=self.translate_call,
249                                             **self.parser_instance.localcontext)
250             except Exception, e:
251                raise Exception(exceptions.text_error_template().render())
252         if report_xml.webkit_debug :
253             try:
254                 deb = head_mako_tpl.render(helper=helper,
255                                             css=css,
256                                             _debug=html,
257                                             _=self.translate_call,
258                                             **self.parser_instance.localcontext)
259             except Exception, e:
260                raise Exception(exceptions.text_error_template().render())
261             return (deb, 'html')
262         bin = self.get_lib(cursor, uid)
263         pdf = self.generate_pdf(bin, report_xml, head, foot, htmls)
264         return (pdf, 'pdf')
265
266
267 BVRWebKitParser('report.invoice_web_bvr',
268                'account.invoice',
269                'addons/l10n_ch/report/report_webkit_html.mako',
270                parser=l10n_ch_report_webkit_html)
271
272 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: