2010-10-07 07:45:18 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
##############################################################################
|
|
|
|
#
|
2011-09-21 08:14:51 +00:00
|
|
|
# Copyright (c) 2010 Camptocamp SA (http://www.camptocamp.com)
|
2010-10-07 07:45:18 +00:00
|
|
|
# All Right Reserved
|
|
|
|
#
|
|
|
|
# Author : Nicolas Bessi (Camptocamp)
|
2011-03-22 14:01:20 +00:00
|
|
|
# Contributor(s) : Florent Xicluna (Wingo SA)
|
2010-10-07 07:45:18 +00:00
|
|
|
#
|
|
|
|
# WARNING: This program as such is intended to be used by professional
|
|
|
|
# programmers who take the whole responsability of assessing all potential
|
|
|
|
# consequences resulting from its eventual inadequacies and bugs
|
|
|
|
# End users who are looking for a ready-to-use solution with commercial
|
|
|
|
# garantees and support are strongly adviced to contract a Free Software
|
|
|
|
# Service Company
|
|
|
|
#
|
|
|
|
# This program is Free Software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation; either version 2
|
|
|
|
# of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
#
|
|
|
|
##############################################################################
|
|
|
|
|
2011-04-04 16:33:07 +00:00
|
|
|
import subprocess
|
2010-10-07 07:45:18 +00:00
|
|
|
import os
|
|
|
|
import report
|
2010-10-08 14:30:50 +00:00
|
|
|
import tempfile
|
2010-10-07 07:45:18 +00:00
|
|
|
import time
|
2011-09-21 07:49:42 +00:00
|
|
|
import logging
|
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
from mako.template import Template
|
2010-11-15 10:17:59 +00:00
|
|
|
from mako import exceptions
|
2011-09-21 07:49:42 +00:00
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
import netsvc
|
|
|
|
import pooler
|
2010-10-08 14:30:50 +00:00
|
|
|
from report_helper import WebKitHelper
|
|
|
|
from report.report_sxw import *
|
2010-10-26 13:22:54 +00:00
|
|
|
import addons
|
2011-04-30 01:56:46 +00:00
|
|
|
import tools
|
2010-10-08 14:30:50 +00:00
|
|
|
from tools.translate import _
|
|
|
|
from osv.osv import except_osv
|
2010-10-07 07:45:18 +00:00
|
|
|
|
2011-09-21 07:49:42 +00:00
|
|
|
logger = logging.getLogger('report_webkit')
|
2011-03-14 17:14:29 +00:00
|
|
|
|
|
|
|
def mako_template(text):
|
|
|
|
"""Build a Mako template.
|
|
|
|
|
|
|
|
This template uses UTF-8 encoding
|
|
|
|
"""
|
|
|
|
# default_filters=['unicode', 'h'] can be used to set global filters
|
|
|
|
return Template(text, input_encoding='utf-8', output_encoding='utf-8')
|
|
|
|
|
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
class WebKitParser(report_sxw):
|
|
|
|
"""Custom class that use webkit to render HTML reports
|
|
|
|
Code partially taken from report openoffice. Thanks guys :)
|
|
|
|
"""
|
2011-09-21 08:14:51 +00:00
|
|
|
|
|
|
|
def __init__(self, name, table, rml=False, parser=False,
|
2010-10-07 07:45:18 +00:00
|
|
|
header=True, store=False):
|
|
|
|
self.parser_instance = False
|
|
|
|
self.localcontext={}
|
2011-09-21 08:14:51 +00:00
|
|
|
report_sxw.__init__(self, name, table, rml, parser,
|
2010-10-07 07:45:18 +00:00
|
|
|
header, store)
|
|
|
|
|
|
|
|
def get_lib(self, cursor, uid, company) :
|
|
|
|
"""Return the lib wkhtml path"""
|
|
|
|
#TODO Detect lib in system first
|
|
|
|
path = self.pool.get('res.company').read(cursor, uid, company, ['lib_path',])
|
2010-10-13 12:07:37 +00:00
|
|
|
path = path['lib_path']
|
|
|
|
if not path:
|
|
|
|
raise except_osv(
|
|
|
|
_('Wkhtmltopdf library path is not set in company'),
|
|
|
|
_('Please install executable on your system'+
|
|
|
|
' (sudo apt-get install wkhtmltopdf) or download it from here:'+
|
|
|
|
' http://code.google.com/p/wkhtmltopdf/downloads/list and set the'+
|
2011-03-22 13:40:40 +00:00
|
|
|
' path to the executable on the Company form.'+
|
|
|
|
'Minimal version is 0.9.9')
|
2011-09-21 08:14:51 +00:00
|
|
|
)
|
2010-10-13 12:07:37 +00:00
|
|
|
if os.path.isabs(path) :
|
|
|
|
if (os.path.exists(path) and os.access(path, os.X_OK)\
|
|
|
|
and os.path.basename(path).startswith('wkhtmltopdf')):
|
|
|
|
return path
|
|
|
|
else:
|
2010-10-08 14:30:50 +00:00
|
|
|
raise except_osv(
|
2010-10-13 12:07:37 +00:00
|
|
|
_('Wrong Wkhtmltopdf path set in company'+
|
|
|
|
'Given path is not executable or path is wrong'),
|
|
|
|
'for path %s'%(path)
|
|
|
|
)
|
|
|
|
else :
|
|
|
|
raise except_osv(
|
|
|
|
_('path to Wkhtmltopdf is not absolute'),
|
|
|
|
'for path %s'%(path)
|
|
|
|
)
|
2010-10-22 13:34:02 +00:00
|
|
|
def generate_pdf(self, comm_path, report_xml, header, footer, html_list, webkit_header=False):
|
2010-10-07 07:45:18 +00:00
|
|
|
"""Call webkit in order to generate pdf"""
|
2010-10-22 13:34:02 +00:00
|
|
|
if not webkit_header:
|
|
|
|
webkit_header = report_xml.webkit_header
|
2010-10-07 07:45:18 +00:00
|
|
|
tmp_dir = tempfile.gettempdir()
|
|
|
|
out = report_xml.name+str(time.time())+'.pdf'
|
|
|
|
out = os.path.join(tmp_dir, out.replace(' ',''))
|
|
|
|
files = []
|
|
|
|
file_to_del = []
|
2010-10-08 14:30:50 +00:00
|
|
|
if comm_path:
|
|
|
|
command = [comm_path]
|
|
|
|
else:
|
2010-10-13 12:07:37 +00:00
|
|
|
command = ['wkhtmltopdf']
|
2010-12-07 18:21:54 +00:00
|
|
|
|
2011-03-14 17:14:29 +00:00
|
|
|
command.append('--quiet')
|
|
|
|
# default to UTF-8 encoding. Use <meta charset="latin-1"> to override.
|
2011-04-07 08:38:13 +00:00
|
|
|
command.extend(['--encoding', 'utf-8'])
|
2010-10-08 14:30:50 +00:00
|
|
|
if header :
|
|
|
|
head_file = file( os.path.join(
|
|
|
|
tmp_dir,
|
|
|
|
str(time.time()) + '.head.html'
|
2011-09-21 08:14:51 +00:00
|
|
|
),
|
2010-10-08 14:30:50 +00:00
|
|
|
'w'
|
|
|
|
)
|
|
|
|
head_file.write(header)
|
|
|
|
head_file.close()
|
|
|
|
file_to_del.append(head_file.name)
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--header-html', head_file.name])
|
2010-10-08 14:30:50 +00:00
|
|
|
if footer :
|
|
|
|
foot_file = file( os.path.join(
|
|
|
|
tmp_dir,
|
|
|
|
str(time.time()) + '.foot.html'
|
2011-09-21 08:14:51 +00:00
|
|
|
),
|
2010-10-08 14:30:50 +00:00
|
|
|
'w'
|
|
|
|
)
|
|
|
|
foot_file.write(footer)
|
|
|
|
foot_file.close()
|
|
|
|
file_to_del.append(foot_file.name)
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--footer-html', foot_file.name])
|
2011-09-21 08:14:51 +00:00
|
|
|
|
2010-10-22 13:34:02 +00:00
|
|
|
if webkit_header.margin_top :
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--margin-top', str(webkit_header.margin_top).replace(',', '.')])
|
2010-10-22 13:34:02 +00:00
|
|
|
if webkit_header.margin_bottom :
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--margin-bottom', str(webkit_header.margin_bottom).replace(',', '.')])
|
2010-10-22 13:34:02 +00:00
|
|
|
if webkit_header.margin_left :
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--margin-left', str(webkit_header.margin_left).replace(',', '.')])
|
2010-10-22 13:34:02 +00:00
|
|
|
if webkit_header.margin_right :
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--margin-right', str(webkit_header.margin_right).replace(',', '.')])
|
2010-10-22 13:34:02 +00:00
|
|
|
if webkit_header.orientation :
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--orientation', str(webkit_header.orientation).replace(',', '.')])
|
2010-10-22 13:34:02 +00:00
|
|
|
if webkit_header.format :
|
2011-04-04 16:33:07 +00:00
|
|
|
command.extend(['--page-size', str(webkit_header.format).replace(',', '.')])
|
2010-10-22 13:34:02 +00:00
|
|
|
count = 0
|
2010-10-08 14:30:50 +00:00
|
|
|
for html in html_list :
|
2010-10-22 13:34:02 +00:00
|
|
|
html_file = file(os.path.join(tmp_dir, str(time.time()) + str(count) +'.body.html'), 'w')
|
|
|
|
count += 1
|
2010-10-08 14:30:50 +00:00
|
|
|
html_file.write(html)
|
|
|
|
html_file.close()
|
|
|
|
file_to_del.append(html_file.name)
|
|
|
|
command.append(html_file.name)
|
|
|
|
command.append(out)
|
|
|
|
generate_command = ' '.join(command)
|
|
|
|
try:
|
2011-04-05 07:45:59 +00:00
|
|
|
status = subprocess.call(command, stderr=subprocess.PIPE) # ignore stderr
|
2011-04-04 16:33:07 +00:00
|
|
|
if status :
|
2010-10-08 14:30:50 +00:00
|
|
|
raise except_osv(
|
2011-09-21 08:14:51 +00:00
|
|
|
_('Webkit raise an error' ),
|
2011-04-04 16:33:07 +00:00
|
|
|
status
|
2010-10-08 14:30:50 +00:00
|
|
|
)
|
|
|
|
except Exception:
|
2010-10-07 07:45:18 +00:00
|
|
|
for f_to_del in file_to_del :
|
|
|
|
os.unlink(f_to_del)
|
2010-10-13 12:07:37 +00:00
|
|
|
|
2011-04-04 16:33:07 +00:00
|
|
|
pdf = file(out, 'rb').read()
|
2010-10-13 12:07:37 +00:00
|
|
|
for f_to_del in file_to_del :
|
|
|
|
os.unlink(f_to_del)
|
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
os.unlink(out)
|
|
|
|
return pdf
|
2011-09-21 08:14:51 +00:00
|
|
|
|
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
def setLang(self, lang):
|
|
|
|
if not lang:
|
|
|
|
lang = 'en_US'
|
|
|
|
self.localcontext['lang'] = lang
|
2010-10-08 14:30:50 +00:00
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
def translate_call(self, src):
|
|
|
|
"""Translate String."""
|
|
|
|
ir_translation = self.pool.get('ir.translation')
|
2011-09-21 07:49:42 +00:00
|
|
|
res = ir_translation._get_source(self.parser_instance.cr, self.parser_instance.uid,
|
|
|
|
self.name, 'report', self.localcontext.get('lang', 'en_US'), src)
|
2010-10-22 13:34:02 +00:00
|
|
|
if not res :
|
|
|
|
return src
|
2011-09-21 08:14:51 +00:00
|
|
|
return res
|
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False):
|
|
|
|
"""format using the know cursor, language from localcontext"""
|
|
|
|
if digits is None:
|
|
|
|
digits = self.parser_instance.get_digits(value)
|
|
|
|
if isinstance(value, (str, unicode)) and not value:
|
|
|
|
return ''
|
|
|
|
pool_lang = self.pool.get('res.lang')
|
|
|
|
lang = self.localcontext['lang']
|
2011-09-21 08:14:51 +00:00
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
lang_ids = pool_lang.search(self.parser_instance.cr, self.parser_instance.uid, [('code','=',lang)])[0]
|
|
|
|
lang_obj = pool_lang.browse(self.parser_instance.cr, self.parser_instance.uid, lang_ids)
|
|
|
|
|
|
|
|
if date or date_time:
|
|
|
|
if not str(value):
|
|
|
|
return ''
|
|
|
|
|
|
|
|
date_format = lang_obj.date_format
|
|
|
|
parse_format = '%Y-%m-%d'
|
|
|
|
if date_time:
|
|
|
|
value=value.split('.')[0]
|
|
|
|
date_format = date_format + " " + lang_obj.time_format
|
|
|
|
parse_format = '%Y-%m-%d %H:%M:%S'
|
|
|
|
if not isinstance(value, time.struct_time):
|
|
|
|
return time.strftime(date_format, time.strptime(value, parse_format))
|
|
|
|
|
|
|
|
else:
|
|
|
|
date = datetime(*value.timetuple()[:6])
|
|
|
|
return date.strftime(date_format)
|
|
|
|
|
|
|
|
return lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
|
|
|
|
|
2011-09-21 07:49:42 +00:00
|
|
|
# override needed to keep the attachments storing procedure
|
2010-10-08 14:30:50 +00:00
|
|
|
def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
|
2010-10-07 07:45:18 +00:00
|
|
|
"""generate the PDF"""
|
2011-09-21 08:14:51 +00:00
|
|
|
|
2010-10-18 14:33:42 +00:00
|
|
|
if context is None:
|
2010-10-07 07:45:18 +00:00
|
|
|
context={}
|
2011-09-21 07:49:42 +00:00
|
|
|
htmls = []
|
2010-10-13 12:07:37 +00:00
|
|
|
if report_xml.report_type != 'webkit':
|
|
|
|
return super(WebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context)
|
|
|
|
|
2011-09-21 07:49:42 +00:00
|
|
|
self.parser_instance = self.parser(cursor,
|
|
|
|
uid,
|
|
|
|
self.name2,
|
|
|
|
context=context)
|
2010-10-08 14:30:50 +00:00
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
self.pool = pooler.get_pool(cursor.dbname)
|
|
|
|
objs = self.getObjects(cursor, uid, ids, context)
|
|
|
|
self.parser_instance.set_context(objs, data, ids, report_xml.report_type)
|
|
|
|
|
|
|
|
template = False
|
2010-10-14 13:38:14 +00:00
|
|
|
|
2010-10-08 14:30:50 +00:00
|
|
|
if report_xml.report_file :
|
2010-10-26 13:22:54 +00:00
|
|
|
path = addons.get_module_resource(report_xml.report_file)
|
2010-10-07 07:45:18 +00:00
|
|
|
if os.path.exists(path) :
|
|
|
|
template = file(path).read()
|
|
|
|
if not template and report_xml.report_webkit_data :
|
|
|
|
template = report_xml.report_webkit_data
|
|
|
|
if not template :
|
2011-03-05 22:15:52 +00:00
|
|
|
raise except_osv(_('Error!'), _('Webkit Report template not found !'))
|
2010-10-07 07:45:18 +00:00
|
|
|
header = report_xml.webkit_header.html
|
|
|
|
footer = report_xml.webkit_header.footer_html
|
|
|
|
if not header and report_xml.header:
|
2011-09-21 08:14:51 +00:00
|
|
|
raise except_osv(
|
|
|
|
_('No header defined for this Webkit report!'),
|
|
|
|
_('Please set a header in company settings')
|
|
|
|
)
|
2010-10-07 07:45:18 +00:00
|
|
|
if not report_xml.header :
|
2011-09-21 07:49:42 +00:00
|
|
|
header = ''
|
|
|
|
defaut_head = addons.get_module_resource('report_webkit', 'default_header.html')
|
|
|
|
with open(defaut_head,'r') as f:
|
|
|
|
header = f.read()
|
2010-10-07 07:45:18 +00:00
|
|
|
css = report_xml.webkit_header.css
|
|
|
|
if not css :
|
|
|
|
css = ''
|
|
|
|
user = self.pool.get('res.users').browse(cursor, uid, uid)
|
|
|
|
company= user.company_id
|
2011-09-21 08:14:51 +00:00
|
|
|
|
2010-10-07 07:45:18 +00:00
|
|
|
#default_filters=['unicode', 'entity'] can be used to set global filter
|
2011-03-14 17:14:29 +00:00
|
|
|
body_mako_tpl = mako_template(template)
|
2010-10-07 07:45:18 +00:00
|
|
|
helper = WebKitHelper(cursor, uid, report_xml.id, context)
|
2011-09-21 07:49:42 +00:00
|
|
|
if report_xml.precise_mode:
|
|
|
|
for obj in objs:
|
|
|
|
self.parser_instance.localcontext['objects'] = [obj]
|
|
|
|
try :
|
|
|
|
html = body_mako_tpl.render(helper=helper,
|
|
|
|
css=css,
|
|
|
|
_=self.translate_call,
|
|
|
|
**self.parser_instance.localcontext)
|
|
|
|
htmls.append(html)
|
|
|
|
except Exception, e:
|
|
|
|
msg = exceptions.text_error_template().render()
|
|
|
|
logger.error(msg)
|
|
|
|
raise except_osv(_('Webkit render'), msg)
|
|
|
|
else:
|
|
|
|
try :
|
|
|
|
html = body_mako_tpl.render(helper=helper,
|
|
|
|
css=css,
|
|
|
|
_=self.translate_call,
|
|
|
|
**self.parser_instance.localcontext)
|
|
|
|
htmls.append(html)
|
|
|
|
except Exception, e:
|
|
|
|
msg = exceptions.text_error_template().render()
|
|
|
|
logger.error(msg)
|
|
|
|
raise except_osv(_('Webkit render'), msg)
|
2011-03-14 17:14:29 +00:00
|
|
|
head_mako_tpl = mako_template(header)
|
2010-11-15 10:17:59 +00:00
|
|
|
try :
|
2011-09-09 10:49:27 +00:00
|
|
|
head = head_mako_tpl.render(helper=helper,
|
2010-11-15 10:17:59 +00:00
|
|
|
css=css,
|
2010-10-07 07:45:18 +00:00
|
|
|
_=self.translate_call,
|
2011-09-09 10:49:27 +00:00
|
|
|
_debug=False,
|
|
|
|
**self.parser_instance.localcontext)
|
2010-11-25 15:50:35 +00:00
|
|
|
except Exception, e:
|
2010-11-25 16:46:14 +00:00
|
|
|
raise except_osv(_('Webkit render'),
|
|
|
|
exceptions.text_error_template().render())
|
2010-11-15 10:17:59 +00:00
|
|
|
foot = False
|
|
|
|
if footer :
|
2011-03-14 17:14:29 +00:00
|
|
|
foot_mako_tpl = mako_template(footer)
|
2010-11-15 10:17:59 +00:00
|
|
|
try :
|
2011-09-09 10:49:27 +00:00
|
|
|
foot = foot_mako_tpl.render(helper=helper,
|
2010-12-07 18:21:54 +00:00
|
|
|
css=css,
|
2010-11-15 10:17:59 +00:00
|
|
|
_=self.translate_call,
|
2011-09-09 10:49:27 +00:00
|
|
|
**self.parser_instance.localcontext)
|
2010-11-15 10:17:59 +00:00
|
|
|
except:
|
2010-11-25 16:46:14 +00:00
|
|
|
msg = exceptions.text_error_template().render()
|
2011-09-21 07:49:42 +00:00
|
|
|
logger.error(msg)
|
2010-11-25 16:46:14 +00:00
|
|
|
raise except_osv(_('Webkit render'), msg)
|
2010-10-07 07:45:18 +00:00
|
|
|
if report_xml.webkit_debug :
|
2010-11-15 10:17:59 +00:00
|
|
|
try :
|
2011-09-09 10:49:27 +00:00
|
|
|
deb = head_mako_tpl.render(helper=helper,
|
|
|
|
css=css,
|
2011-09-21 08:14:51 +00:00
|
|
|
_debug=tools.ustr("\n".join(htmls)),
|
2011-09-09 10:49:27 +00:00
|
|
|
_=self.translate_call,
|
|
|
|
**self.parser_instance.localcontext)
|
2010-11-25 15:50:35 +00:00
|
|
|
except Exception, e:
|
2010-11-25 16:46:14 +00:00
|
|
|
msg = exceptions.text_error_template().render()
|
2011-09-21 07:49:42 +00:00
|
|
|
logger.error(msg)
|
2010-11-25 16:46:14 +00:00
|
|
|
raise except_osv(_('Webkit render'), msg)
|
2010-10-07 07:45:18 +00:00
|
|
|
return (deb, 'html')
|
|
|
|
bin = self.get_lib(cursor, uid, company.id)
|
2011-09-21 07:49:42 +00:00
|
|
|
pdf = self.generate_pdf(bin, report_xml, head, foot, htmls)
|
2010-10-07 07:45:18 +00:00
|
|
|
return (pdf, 'pdf')
|
|
|
|
|
|
|
|
|
|
|
|
def create(self, cursor, uid, ids, data, context=None):
|
|
|
|
"""We override the create function in order to handle generator
|
|
|
|
Code taken from report openoffice. Thanks guys :) """
|
|
|
|
pool = pooler.get_pool(cursor.dbname)
|
|
|
|
ir_obj = pool.get('ir.actions.report.xml')
|
|
|
|
report_xml_ids = ir_obj.search(cursor, uid,
|
|
|
|
[('report_name', '=', self.name[7:])], context=context)
|
|
|
|
if report_xml_ids:
|
2011-09-21 08:14:51 +00:00
|
|
|
|
|
|
|
report_xml = ir_obj.browse(cursor,
|
|
|
|
uid,
|
|
|
|
report_xml_ids[0],
|
2011-09-21 07:49:42 +00:00
|
|
|
context=context)
|
2010-10-07 07:45:18 +00:00
|
|
|
report_xml.report_rml = None
|
|
|
|
report_xml.report_rml_content = None
|
|
|
|
report_xml.report_sxw_content_data = None
|
|
|
|
report_rml.report_sxw_content = None
|
|
|
|
report_rml.report_sxw = None
|
|
|
|
else:
|
|
|
|
return super(WebKitParser, self).create(cursor, uid, ids, data, context)
|
|
|
|
if report_xml.report_type != 'webkit' :
|
|
|
|
return super(WebKitParser, self).create(cursor, uid, ids, data, context)
|
2010-10-08 14:30:50 +00:00
|
|
|
result = self.create_source_pdf(cursor, uid, ids, data, report_xml, context)
|
|
|
|
if not result:
|
2010-10-07 07:45:18 +00:00
|
|
|
return (False,False)
|
2010-10-08 14:30:50 +00:00
|
|
|
return result
|