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