1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
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.
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.
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/>.
20 ##############################################################################
22 from openerp.report.interface import report_int
23 import openerp.pooler as pooler
24 import openerp.tools as tools
25 from openerp.tools.safe_eval import safe_eval as eval
26 from lxml import etree
27 from openerp.report import render, report_sxw
31 from operator import itemgetter
32 from datetime import datetime
34 #.apidoc title: Printscreen for List Views
36 class report_printscreen_list(report_int):
37 def __init__(self, name):
38 report_int.__init__(self, name)
43 def _parse_node(self, root_node):
45 for node in root_node:
46 field_name = node.get('name')
47 if not eval(str(node.attrib.get('invisible',False)),{'context':self.context}):
48 if node.tag == 'field':
49 if field_name in self.groupby:
51 result.append(field_name)
53 result.extend(self._parse_node(node))
56 def _parse_string(self, view):
58 dom = etree.XML(view.encode('utf-8'))
61 return self._parse_node(dom)
63 def create(self, cr, uid, ids, datas, context=None):
67 self.context = context
68 self.groupby = context.get('group_by',[])
69 self.groupby_no_leaf = context.get('group_by_no_leaf',False)
70 pool = pooler.get_pool(cr.dbname)
71 model = pool.get(datas['model'])
72 model_id = pool.get('ir.model').search(cr, uid, [('model','=',model._name)])
73 model_desc = model._description
75 model_desc = pool.get('ir.model').browse(cr, uid, model_id[0], context).name
76 self.title = model_desc
78 result = model.fields_view_get(cr, uid, view_type='tree', context=context)
79 fields_order = self.groupby + self._parse_string(result['arch'])
82 def get_groupby_data(groupby = [], domain = []):
83 records = model.read_group(cr, uid, domain, fields_order, groupby , 0, None, context)
86 rec['__no_leaf'] = self.groupby_no_leaf
87 rec['__grouped_by'] = groupby[0] if (isinstance(groupby, list) and groupby) else groupby
88 for f in fields_order:
91 elif isinstance(rec[f], tuple):
94 inner_groupby = (rec.get('__context', {})).get('group_by',[])
95 inner_domain = rec.get('__domain', [])
97 get_groupby_data(inner_groupby, inner_domain)
99 if self.groupby_no_leaf:
101 child_ids = model.search(cr, uid, inner_domain)
102 res = model.read(cr, uid, child_ids, result['fields'].keys(), context)
103 res.sort(lambda x,y: cmp(ids.index(x['id']), ids.index(y['id'])))
105 dom = [('id','in',ids)]
106 if self.groupby_no_leaf and len(ids) and not ids[0]:
107 dom = datas.get('_domain',[])
108 get_groupby_data(self.groupby, dom)
110 rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context)
111 ids2 = map(itemgetter('id'), rows) # getting the ids from read result
112 if datas['ids'] != ids2: # sorted ids were not taken into consideration for print screen
114 for id in datas['ids']:
115 rows_new += [elem for elem in rows if elem['id'] == id]
117 res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc)
118 return self.obj.get(), 'pdf'
121 def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
122 pageSize=[297.0, 210.0]
124 new_doc = etree.Element("report")
125 config = etree.SubElement(new_doc, 'config')
127 def _append_node(name, text):
128 n = etree.SubElement(config, name)
131 #_append_node('date', time.strftime('%d/%m/%Y'))
132 _append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))))
133 _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
134 _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
135 _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
136 _append_node('report-header', title)
138 _append_node('company', pooler.get_pool(self.cr.dbname).get('res.users').browse(self.cr,uid,uid).company_id.name)
139 rpt_obj = pooler.get_pool(self.cr.dbname).get('res.users')
140 rml_obj=report_sxw.rml_parse(self.cr, uid, rpt_obj._name,context)
141 _append_node('header-date', str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")))
144 strmax = (pageSize[0]-40) * 2.8346
147 for i in range(0, len(fields_order)):
151 for f in fields_order:
154 if fields[f]['type'] in ('date','time','datetime','float','integer'):
157 if fields[f]['type'] in ('float','integer'):
160 t += fields[f].get('size', 80) / 28 + 1
163 for pos in range(len(l)):
165 s = fields[fields_order[pos]].get('size', 80) / 28 + 1
166 l[pos] = strmax * s / t
168 _append_node('tableSize', ','.join(map(str,l)) )
170 header = etree.SubElement(new_doc, 'header')
171 for f in fields_order:
172 field = etree.SubElement(header, 'field')
173 field.text = tools.ustr(fields[f]['string'] or '')
175 lines = etree.SubElement(new_doc, 'lines')
177 node_line = etree.SubElement(lines, 'row')
179 for f in fields_order:
182 if fields[f]['type']=='many2one' and line[f]:
183 if not line.get('__group'):
185 if fields[f]['type']=='selection' and line[f]:
186 for key, value in fields[f]['selection']:
190 if fields[f]['type'] in ('one2many','many2many') and line[f]:
191 line[f] = '( '+tools.ustr(len(line[f])) + ' )'
192 if fields[f]['type'] == 'float' and line[f]:
193 precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
194 prec ='%.' + str(precision) +'f'
195 line[f]=prec%(line[f])
198 if fields[f]['type'] == 'date' and line[f]:
200 if not line.get('__group'):
201 format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))
202 d1 = datetime.strptime(line[f],'%Y-%m-%d')
203 new_d1 = d1.strftime(format)
206 if fields[f]['type'] == 'time' and line[f]:
208 if not line.get('__group'):
209 format = str(locale.nl_langinfo(locale.T_FMT))
210 d1 = datetime.strptime(line[f], '%H:%M:%S')
211 new_d1 = d1.strftime(format)
214 if fields[f]['type'] == 'datetime' and line[f]:
216 if not line.get('__group'):
217 format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))+' '+str(locale.nl_langinfo(locale.T_FMT))
218 d1 = datetime.strptime(line[f], '%Y-%m-%d %H:%M:%S')
219 new_d1 = d1.strftime(format)
223 if line.get('__group'):
224 col = etree.SubElement(node_line, 'col', para='group', tree='no')
226 col = etree.SubElement(node_line, 'col', para='yes', tree='no')
228 # Prevent empty labels in groups
229 if f == line.get('__grouped_by') and line.get('__group') and not line[f] and not float_flag and not temp[count]:
230 col.text = line[f] = 'Undefined'
231 col.set('tree', 'undefined')
233 if line[f] is not None:
234 col.text = tools.ustr(line[f] or '')
236 col.set('tree','float')
237 if line.get('__no_leaf') and temp[count] == 1 and f != 'id' and not line['__context']['group_by']:
238 tsum[count] = float(tsum[count]) + float(line[f])
239 if not line.get('__group') and f != 'id' and temp[count] == 1:
240 tsum[count] = float(tsum[count]) + float(line[f])
244 node_line = etree.SubElement(lines, 'row')
245 for f in range(0, len(fields_order)):
246 col = etree.SubElement(node_line, 'col', para='group', tree='no')
247 col.set('tree', 'float')
248 if tsum[f] is not None:
250 digits = fields[fields_order[f]].get('digits', (16, 2))
251 prec = '%%.%sf' % (digits[1], )
252 total = prec % (tsum[f], )
253 txt = str(total or '')
255 txt = str(tsum[f] or '')
261 col.text = tools.ustr(txt or '')
263 transform = etree.XSLT(
264 etree.parse(os.path.join(tools.config['root_path'],
265 'addons/base/report/custom_new.xsl')))
266 rml = etree.tostring(transform(new_doc))
267 self.obj = render.rml(rml, title=self.title)
270 report_printscreen_list('report.printscreen.list')
273 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: