Merge commit 'origin/master' into mdv-gpl3-py26
[odoo/odoo.git] / bin / report / printscreen / ps_list.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 from report.interface import report_int
24 import pooler
25 import tools
26
27 from report import render
28
29 from xml.dom import minidom
30 import libxml2
31 import libxslt
32
33 import time, os
34
35 class report_printscreen_list(report_int):
36     def __init__(self, name):
37         report_int.__init__(self, name)
38
39     def _parse_node(self, root_node):
40         result = []
41         for node in root_node.childNodes:
42             if node.localName == 'field':
43                 attrsa = node.attributes
44                 attrs = {}
45                 if not attrsa is None:
46                     for i in range(attrsa.length):
47                         attrs[attrsa.item(i).localName] = attrsa.item(i).nodeValue
48                 result.append(attrs['name'])
49             else:
50                 result.extend(self._parse_node(node))
51         return result
52
53     def _parse_string(self, view):
54         dom = minidom.parseString(unicode(view, 'utf-8').encode('utf-8'))
55         return self._parse_node(dom)
56
57     def create(self, cr, uid, ids, datas, context=None):
58         if not context:
59             context={}
60         pool = pooler.get_pool(cr.dbname)
61         model = pool.get(datas['model'])
62         model_id = pool.get('ir.model').search(cr, uid, [('model','=',model._name)])
63         if model_id:
64             model_desc = pool.get('ir.model').browse(cr, uid, model_id[0], context).name
65             self.title = model_desc
66         else:
67             model_desc = model._description
68             self.title = model_desc
69
70         datas['ids'] = ids
71         model = pooler.get_pool(cr.dbname).get(datas['model'])
72
73         result = model.fields_view_get(cr, uid, view_type='tree', context=context)
74         fields_order = self._parse_string(result['arch'])
75         rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context )
76         res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc)
77         return (self.obj.get(), 'pdf')
78
79
80     def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
81         pageSize=[297.0, 210.0]
82
83         impl = minidom.getDOMImplementation()
84         new_doc = impl.createDocument(None, "report", None)
85
86         # build header
87         config = new_doc.createElement("config")
88
89         def _append_node(name, text):
90             n = new_doc.createElement(name)
91             t = new_doc.createTextNode(text)
92             n.appendChild(t)
93             config.appendChild(n)
94
95         _append_node('date', time.strftime('%d/%m/%Y'))
96         _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
97         _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
98         _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
99
100         _append_node('report-header', title)
101         l = []
102         t = 0
103         rowcount=0;
104         strmax = (pageSize[0]-40) * 2.8346
105         temp = []
106         count = len(fields_order)
107         for i in range(0,count):
108             temp.append(0)
109
110         ince = -1;
111         for f in fields_order:
112             s = 0
113             ince += 1
114             if fields[f]['type'] in ('date','time','float','integer'):
115                 s = 60
116                 strmax -= s
117                 if fields[f]['type'] in ('float','integer'):
118                     temp[ince]=1;
119             else:
120                 t += fields[f].get('size', 80) / 28 + 1
121
122             l.append(s)
123         for pos in range(len(l)):
124             if not l[pos]:
125                 s = fields[fields_order[pos]].get('size', 80) / 28 + 1
126                 l[pos] = strmax * s / t
127
128         _append_node('tableSize', ','.join(map(str,l)) )
129         new_doc.childNodes[0].appendChild(config)
130         header = new_doc.createElement("header")
131
132
133         for f in fields_order:
134             field = new_doc.createElement("field")
135             field_txt = new_doc.createTextNode(fields[f]['string'] or '')
136             field.appendChild(field_txt)
137             header.appendChild(field)
138
139         new_doc.childNodes[0].appendChild(header)
140
141         lines = new_doc.createElement("lines")
142
143         tsum = []
144         count = len(fields_order)
145         for i in range(0,count):
146             tsum.append(0)
147
148
149         for line in results:
150             node_line = new_doc.createElement("row")
151             count = -1
152             for f in fields_order:
153
154                 count += 1
155
156                 if fields[f]['type']=='many2one' and line[f]:
157                     line[f]= line[f][1]
158
159                 if fields[f]['type']=='selection' and line[f]:
160                     for key, value in fields[f]['selection']:
161                         if key == line[f]:
162                             line[f] = value
163                             break
164
165                 if fields[f]['type'] in ('one2many','many2many') and line[f]:
166                     line[f] = '( '+tools.ustr(len(line[f])) + ' )'
167
168                 if fields[f]['type'] == 'float':
169                     precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
170                     line[f]='%.2f'%(line[f])
171
172                 col = new_doc.createElement("col")
173                 col.setAttribute('para','yes')
174                 col.setAttribute('tree','no')
175                 if line[f] != None:
176                     txt = new_doc.createTextNode(tools.ustr(line[f] or ''))
177                     if temp[count] == 1:
178                         tsum[count] = float(tsum[count])  + float(line[f]);
179
180                 else:
181                     txt = new_doc.createTextNode('/')
182                 col.appendChild(txt)
183                 node_line.appendChild(col)
184             lines.appendChild(node_line)
185         node_line = new_doc.createElement("row")
186         lines.appendChild(node_line)
187         node_line = new_doc.createElement("row")
188         count = len(tsum)
189         for f in range(0,count):
190             col = new_doc.createElement("col")
191             col.setAttribute('para','yes')
192             col.setAttribute('tree','no')
193             if tsum[f] != None:
194                if tsum[f] >= 0.01 :
195                   total = '%.2f'%(tsum[f])
196                   txt = new_doc.createTextNode(str(total or ''))
197                else :
198                    txt = new_doc.createTextNode(str(tsum[f] or ''))
199             else:
200                 txt = new_doc.createTextNode('/')
201             if f == 0:
202                 txt = new_doc.createTextNode('Total')
203
204             col.appendChild(txt)
205             node_line.appendChild(col)
206
207         lines.appendChild(node_line)
208
209
210         new_doc.childNodes[0].appendChild(lines)
211
212         styledoc = libxml2.parseFile(os.path.join(tools.config['root_path'],'addons/base/report/custom_new.xsl'))
213         style = libxslt.parseStylesheetDoc(styledoc)
214         doc = libxml2.parseDoc(new_doc.toxml(encoding='utf-8'))
215         rml_obj = style.applyStylesheet(doc, None)
216         rml = style.saveResultToString(rml_obj)
217         self.obj = render.rml(rml, title=self.title)
218         self.obj.render()
219         return True
220 report_printscreen_list('report.printscreen.list')
221
222
223 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: