bzr revid: hda@tinyerp.com-20091102091524-8sen0rrm3r50qo90
This commit is contained in:
HDA (OpenERP) 2009-11-02 14:45:24 +05:30
commit 69036a94e0
9 changed files with 302 additions and 96 deletions

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@ -129,7 +129,7 @@ class report_xml(osv.osv):
('sxw', 'sxw'),
('odt', 'odt'),
('html2html','HTML from HTML'),
('mako2html','Mako from HTML'),
('mako2html','HTML from HTML(Mako)'),
], string='Type', required=True),
'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'),
'attachment': fields.char('Save As Attachment Prefix', size=128, help='This is the filename of the attachment used to store the printing result. Keep empty to not save the printed reports. You can use a python expression with the object and time variables.'),
@ -151,7 +151,7 @@ class act_window(osv.osv):
_name = 'ir.actions.act_window'
_table = 'ir_act_window'
_sequence = 'ir_actions_id_seq'
def _check_model(self, cr, uid, ids, context={}):
for action in self.browse(cr, uid, ids, context):
if not self.pool.get(action.res_model):
@ -252,7 +252,7 @@ class act_window(osv.osv):
'filter': fields.boolean('Filter'),
'default_user_ids': fields.many2many('res.users', 'ir_act_window_user_rel', 'act_id', 'uid', 'Users'),
'search_view' : fields.function(_search_view, type='text', method=True, string='Search View'),
'menus': fields.char('Menus', size=4096)
'menus': fields.char('Menus', size=4096)
}
_defaults = {
'type': lambda *a: 'ir.actions.act_window',
@ -547,10 +547,10 @@ class actions_server(osv.osv):
if result in (None, False):
return str("--------")
return str(result)
com = re.compile('(\[\[.+?\]\])')
message = com.sub(merge, keystr)
return message
# Context should contains:
@ -559,16 +559,16 @@ class actions_server(osv.osv):
# OUT:
# False : Finnished correctly
# ACTION_ID : Action to launch
def run(self, cr, uid, ids, context={}):
logger = netsvc.Logger()
for action in self.browse(cr, uid, ids, context):
obj_pool = self.pool.get(action.model_id.model)
obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
cxt = {
'context':context,
'object': obj,
'context':context,
'object': obj,
'time':time,
'cr': cr,
'pool' : self.pool,
@ -577,10 +577,10 @@ class actions_server(osv.osv):
expr = eval(str(action.condition), cxt)
if not expr:
continue
if action.state=='client_action':
if not action.action_id:
raise osv.except_osv(_('Error'), _("Please specify an action to launch !"))
raise osv.except_osv(_('Error'), _("Please specify an action to launch !"))
result = self.pool.get(action.action_id.type).read(cr, uid, action.action_id.id, context=context)
return result
@ -605,16 +605,16 @@ class actions_server(osv.osv):
address = eval(str(action.email), cxt)
except:
pass
if not address:
logger.notifyChannel('email', netsvc.LOG_INFO, 'Partner Email address not Specified!')
continue
if not user:
raise osv.except_osv(_('Error'), _("Please specify server option --smtp-from !"))
subject = self.merge_message(cr, uid, str(action.subject), action, context)
body = self.merge_message(cr, uid, str(action.message), action, context)
if tools.email_send(user, [address], subject, body, debug=False, subtype='html') == True:
logger.notifyChannel('email', netsvc.LOG_INFO, 'Email successfully send to : %s' % (address))
else:
@ -639,7 +639,7 @@ class actions_server(osv.osv):
logger.notifyChannel('sms', netsvc.LOG_INFO, 'SMS successfully send to : %s' % (action.address))
else:
logger.notifyChannel('sms', netsvc.LOG_ERROR, 'Failed to send SMS to : %s' % (action.address))
if action.state == 'other':
res = []
for act in action.child_ids:
@ -647,15 +647,15 @@ class actions_server(osv.osv):
result = self.run(cr, uid, [act.id], context)
if result:
res.append(result)
return res
if action.state == 'loop':
obj_pool = self.pool.get(action.model_id.model)
obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
cxt = {
'context':context,
'object': obj,
'context':context,
'object': obj,
'time':time,
'cr': cr,
'pool' : self.pool,
@ -666,7 +666,7 @@ class actions_server(osv.osv):
for i in expr:
context['active_id'] = i.id
result = self.run(cr, uid, [action.loop_action.id], context)
if action.state == 'object_write':
res = {}
for exp in action.fields_lines:
@ -688,7 +688,7 @@ class actions_server(osv.osv):
write_id = context.get('active_id')
obj_pool = self.pool.get(action.srcmodel_id.model)
obj_pool.write(cr, uid, [write_id], res)
elif action.write_id:
obj_pool = self.pool.get(action.srcmodel_id.model)
rec = self.pool.get(action.model_id.model).browse(cr, uid, context.get('active_id'))
@ -697,7 +697,7 @@ class actions_server(osv.osv):
id = int(id)
except:
raise osv.except_osv(_('Error'), _("Problem in configuration `Record Id` in Server Action!"))
if type(id) != type(1):
raise osv.except_osv(_('Error'), _("Problem in configuration `Record Id` in Server Action!"))
write_id = id
@ -741,9 +741,9 @@ act_window_close()
# if action type is 'service',
# - if start_type= 'at once', it will be start at one time on start date
# - if start_type='auto', it will be start on auto starting from start date, and stop on stop date
# - if start_type="manual", it will start and stop on manually
# - if start_type="manual", it will start and stop on manually
class ir_actions_todo(osv.osv):
_name = 'ir.actions.todo'
_name = 'ir.actions.todo'
_columns={
'name':fields.char('Name',size=64,required=True, select=True),
'note':fields.text('Text', translate=True),
@ -778,7 +778,7 @@ class ir_actions_configuration_wizard(osv.osv_memory):
return item
return False
def _get_action_name(self, cr, uid, context={}):
next_action=self.next_configuration_action(cr,uid,context=context)
next_action=self.next_configuration_action(cr,uid,context=context)
if next_action:
return next_action.note
else:

View File

@ -1,13 +1,30 @@
<hr width="100%" height="27.7">
<address>
% if company['rml_footer1']:
<p align = "center"><small><b>${company.rml_footer1}</b></small></br></p>
%endif
% if company['rml_footer2']:
<p><small><b>${company.rml_footer2}</b></small></br></p>
%endif
% if user['name']:
<p align="center"><small><b>Contact : ${user.name}</b></small></p>
%endif
</address>
<footer>
<table width="400" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<hr width="100%" height="27.7">
</td>
</tr>
<tr>
<td>
% if company['rml_footer1']:
<p align = "center"><small><b>${company.rml_footer1}</b></small></br></p>
%endif
</td>
</tr>
<tr>
<td>
% if company['rml_footer2']:
<p align = "center"><small><b>${company.rml_footer2}</b></small></br></p>
%endif
</td>
</tr>
<tr>
<td>
% if user['name']:
<p align="center"><small><b>Contact : ${user.name}</b></small></p>
%endif
</td>
</tr>
</table>
</footer>

View File

@ -1,34 +1,62 @@
## -*- coding: utf-8 -*-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<header>
<link type="text/css" rel="stylesheet" href="${css_path}/mako_template.css" media="print,screen"></link>
% if company.logo:
<img src ="data:image/gif;base64,${company.logo}" border="0"/>
%endif
<table width="400" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
% if company['partner_id']['name']:
<small>${company.partner_id.name}</small></br>
%endif
</td>
</tr>
<html>
<head>
<link type="text/css" rel="stylesheet" href="${css_path}/mako_template.css" media="print,screen"></link>
</head>
<body>
% if company.logo:
<img src ="data:image/gif;base64,${company.logo}" border="0"/>
%endif
<address>
% if company['partner_id']['name']:
<small>${company.partner_id.name}</small></br>
%endif
% if company['partner_id']['address'] and company['partner_id']['address'][0]['street']:
<small>${company.partner_id.address[0].street}</small></br>
%endif
% if company['partner_id']['address'] and company['partner_id']['address'][0]['zip']:
<small>${company.partner_id.address[0].zip}
${company.partner_id.address[0].city}-${company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name}</small></br>
%endif
% if company['partner_id']['address'] and company['partner_id']['address'][0]['phone']:
<small><b>Phone:</b>${company.partner_id.address and company.partner_id.address[0].phone}</small></br>
%endif
% if company['partner_id']['address'] and company['partner_id']['address'][0]['email']:
<small><b>Mail:</b>${company.partner_id.address and company.partner_id.address[0].email}</small></br></<address>
%endif
% if company['rml_header1']:
<p align="right"><small>${company.rml_header1}</small></br></p>
%endif
<hr width="100%" height="27.7">
</body>
</html>
<tr>
<td>
% if company['partner_id']['address'] and company['partner_id']['address'][0]['street']:
<small>${company.partner_id.address[0].street}</small></br>
%endif
</td>
</tr>
<tr>
<td>
% if company['partner_id']['address'] and company['partner_id']['address'][0]['zip']:
<small>${company.partner_id.address[0].zip}
${company.partner_id.address[0].city}-${company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name}</small></br>
%endif
</td>
</tr>
<tr>
<td>
% if company['partner_id']['address'] and company['partner_id']['address'][0]['phone']:
<small><b>Phone:</b>${company.partner_id.address and company.partner_id.address[0].phone}</small></br>
%endif
</td>
</tr>
<tr>
<td>
% if company['partner_id']['address'] and company['partner_id']['address'][0]['email']:
<small><b>Mail:</b>${company.partner_id.address and company.partner_id.address[0].email}</small></br></<address>
%endif
</td>
</tr>
<tr>
<td>
% if company['rml_header1']:
<small><p align="right"><small>${company.rml_header1}</small></br></p></small>
%endif
</td>
</tr>
<tr>
<td>
<small><hr width="100%" height="27.7"></small>
</td>
</tr>
</table>
</header>

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@ -82,6 +82,7 @@ class report_rml(report_int):
'sxw': self.create_sxw,
'odt': self.create_odt,
'html2html' : self.create_html2html,
'makohtml2html' :self.create_makohtml2html,
}
def create(self, cr, uid, ids, datas, context):
@ -223,6 +224,11 @@ class report_rml(report_int):
obj.render()
return obj.get()
def create_makohtml2html(self,html,localcontext = None):
obj = render.makohtml2html(html,localcontext)
obj.render()
return obj.get()
from report_sxw import report_sxw
def register_all(db):

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@ -15,12 +15,12 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from simple import simple
from rml import rml, rml2html, odt2odt , html2html
from rml import rml, rml2html, odt2odt, html2html, makohtml2html
from render import render
try:

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from makohtml2html import parseNode

View File

@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from lxml import etree
from mako.template import Template
from mako.lookup import TemplateLookup
import netsvc
import traceback, sys, os
class makohtml2html(object):
def __init__(self, html, localcontext):
self.localcontext = localcontext
self.html = html
def format_header(self, html):
head = html.findall('head')
header = ''
for node in head:
header += etree.tostring(node)
return header
def format_footer(self, footer):
html_footer = ''
for node in footer[0].getchildren():
html_footer += etree.tostring(node)
return html_footer
def format_body(self, html):
body = html.findall('body')
body_list = []
footer = self.format_footer(body[-1].getchildren())
for b in body[:-1]:
body_list.append(etree.tostring(b).replace('\t', '').replace('\n',''))
html_body ='''
<script type="text/javascript">
var indexer = 0;
var aryTest = %s ;
function nextData()
{
if(indexer < aryTest.length -1)
{
indexer += 1;
document.forms[0].prev.disabled = false;
document.getElementById("openerp_data").innerHTML=aryTest[indexer];
document.getElementById("counter").innerHTML= indexer + 1 + ' / ' + aryTest.length;
}
else
{
document.forms[0].next.disabled = true;
}
}
function prevData()
{
if (indexer > 0)
{
indexer -= 1;
document.forms[0].next.disabled = false;
document.getElementById("openerp_data").innerHTML=aryTest[indexer];
document.getElementById("counter").innerHTML= indexer + 1 + ' / ' + aryTest.length;
}
else
{
document.forms[0].prev.disabled = true;
}
}
</script>
</head>
<body>
<div id="openerp_data">
%s
</div>
<div>
%s
</div>
<br>
<form>
<table>
<tr>
<td td align="left">
<input name = "prev" type="button" value="Previous" onclick="prevData();">
</td>
<td>
<div id = "counter">%s / %s</div>
</td>
<td align="right">
<input name = "next" type="button" value="Next" onclick="nextData();">
</td>
</tr>
</table>
</form>
</body></html>'''%(body_list,body_list[0],footer,'1',len(body_list))
return html_body
def render(self):
path = os.path.realpath('addons/base/report')
temp_lookup = TemplateLookup(directories=[path],output_encoding='utf-8', encoding_errors='replace')
template = Template(self.html, lookup=temp_lookup)
self.localcontext.update({'css_path':path})
final_html ='''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>'''
try:
html = template.render_unicode(**self.localcontext)
etree_obj = etree.HTML(html)
final_html += self.format_header(etree_obj)
final_html += self.format_body(etree_obj)
return final_html
except Exception,e:
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
netsvc.Logger().notifyChannel('report', netsvc.LOG_ERROR,
'report :\n%s\n%s\n' % (tb_s, str(e)))
def parseNode(html, localcontext = {}):
r = makohtml2html(html, localcontext)
return r.render()

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@ -24,6 +24,7 @@ import rml2pdf
import rml2html as htmlizer
import odt2odt as odt
import html2html as html
import makohtml2html as makohtml
class rml(render.render):
@ -56,7 +57,6 @@ class odt2odt(render.render):
self.localcontext = localcontext
self.output_type = 'odt'
def _render(self):
return odt.parseNode(self.rml_dom,self.localcontext)
@ -66,9 +66,19 @@ class html2html(render.render):
self.rml_dom = rml
self.localcontext = localcontext
self.output_type = 'html'
def _render(self):
return html.parseString(self.rml_dom,self.localcontext)
class makohtml2html(render.render):
def __init__(self, html, localcontext = None):
render.render.__init__(self)
self.html = html
self.localcontext = localcontext
self.output_type = 'html'
def _render(self):
return makohtml.parseNode(self.html,self.localcontext)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,10 +19,7 @@
#
##############################################################################
from lxml import etree
from mako.template import Template
from mako.lookup import TemplateLookup
from mako import exceptions
import traceback, sys
import StringIO
import cStringIO
import base64
@ -567,17 +564,10 @@ class report_sxw(report_rml, preprocess.report):
def create_single_mako2html(self, cr, uid, ids, data, report_xml, context=None):
mako_html = report_xml.report_rml_content
path = os.path.realpath('addons/base/report')
report_type = report_xml.report_type
html_parser = self.parser(cr, uid, self.name2, context)
objs = self.getObjects(cr, uid, ids, context)
html_parser.set_context(objs, data, ids, report_type)
temp_lookup = TemplateLookup(directories=[path],output_encoding='utf-8', encoding_errors='replace')
template = Template(tools.ustr(mako_html), lookup=temp_lookup)
html_parser.localcontext.update({'css_path':path})
try:
html = template.render_unicode(**html_parser.localcontext)
except:
return(exceptions.html_error_template().render(),'html')
html_parser.set_context(objs, data, ids, 'html')
create_doc = self.generators['makohtml2html']
html = create_doc(mako_html,html_parser.localcontext)
return (html,'html')