[FIXES] after review

bzr revid: nicolas.bessi@camptocamp.com-20101013120737-c6uveg1uxl27p1y1
This commit is contained in:
nicolas.bessi@camptocamp.com 2010-10-13 14:07:37 +02:00
parent ce2538a160
commit 8d3892f645
19 changed files with 283 additions and 820 deletions

View File

@ -34,3 +34,4 @@ import company
import report_helper
import webkit_report
import ir_report
import wizard

View File

@ -71,11 +71,13 @@ Web client WYSIWYG
"author" : "Camptocamp SA - NBessi",
"category": "Reports/Webkit",
"url": "http://http://www.camptocamp.com/",
"data": [
"company_view.xml",
"header_view.xml",
"ir_report_view.xml",
],
"data": [ "security/ir.model.access.csv",
"data.xml",
"wizard/report_webkit_actions_view.xml",
"company_view.xml",
"header_view.xml",
"ir_report_view.xml",
],
"installable" : True,
"active" : False,
}

View File

@ -29,10 +29,8 @@
#
##############################################################################
import netsvc
from osv import fields, osv
class ResCompany(osv.osv):
"""Override company to add Header object link a company can have many header and logos"""
@ -43,17 +41,19 @@ class ResCompany(osv.osv):
'company_img_rel',
'company_id',
'img_id',
'Available Images'
'Available Images',
),
'header_webkit' : fields.many2many(
'ir.header_webkit',
'company_html_rel',
'company_id',
'html_id',
'Available html'
'Available html',
),
'lib_path' : fields.char('Webkit Executable Path', size=264, help="Complete path to the wkhtmltopdf executable."),
'lib_path' : fields.char('Webkit Executable Path', size=264, help="Complete (Abolute) path to the wkhtmltopdf executable."),
}
_defaults = {
'lib_path': lambda *a: 'wkhtmltopdf-0.9.9'
}
ResCompany()

View File

@ -1,102 +1,6 @@
<?xml version="1.0" ?>
<openerp>
<data noupdate="1">
<record id="ir_actions_report_xml_webkitinvoice0" model="ir.actions.report.xml">
<field eval="[(6,0,[])]" name="groups_id"/>
<field eval="0" name="multi"/>
<field eval="&quot;&quot;&quot;webkit&quot;&quot;&quot;" name="report_type"/>
<field eval="0" name="auto"/>
<field name="report_webkit_data"> <![CDATA[<html>
<head>
<style type="text/css">
${css}
</style>
</head>
<body>
%for inv in objects :
<% setLang(inv.partner_id.lang) %>
<table class="dest_address">
<tr><td ><b>${inv.partner_id.title or ''|entity} ${inv.partner_id.name |entity}</b></td></tr>
<tr><td>${inv.address_invoice_id.street or ''|entity}</td></tr>
<tr><td>${inv.address_invoice_id.street2 or ''|entity}</td></tr>
<tr><td>${inv.address_invoice_id.zip or ''|entity} ${inv.address_invoice_id.city or ''|entity}</td></tr>
%if inv.address_invoice_id.country_id :
<tr><td>${inv.address_invoice_id.country_id.name or ''|entity} </td></tr>
%endif
%if inv.address_invoice_id.phone :
<tr><td>Tel: ${inv.address_invoice_id.phone|entity}</td></tr>
%endif
%if inv.address_invoice_id.fax :
<tr><td>Fax: ${inv.address_invoice_id.fax|entity}</td></tr>
%endif
%if inv.address_invoice_id.email :
<tr><td>E-mail: ${inv.address_invoice_id.email|entity}</td></tr>
%endif
%if inv.partner_id.vat :
<tr><td>VAT: ${inv.partner_id.vat|entity}</td></tr>
%endif
</table>
<br />
%if inv.type == 'out_invoice' :
<span class="title">${_("Invoice")} ${inv.number or ''|entity}</span>
%elif inv.type == 'in_invoice' :
<span class="title">Supplier Invoice ${inv.number or ''|entity}</span>
%elif inv.type == 'out_refund' :
<span class="title">Refund ${inv.number or ''|entity}</span>
%elif inv.type == 'in_refund' :
<span class="title">Supplier Refund ${inv.number or ''|entity}</span>
%endif
<br/>
<br/>
<table class="basic_table" width="90%">
<tr><td>Document</td><td>${_("Invoice Date")}</td><td>Partner Ref.</td></tr>
<tr><td>${inv.name}</td><td>${formatLang(inv.date_invoice, date=True)|entity}</td><td>&nbsp;</td></tr>
</table>
<h1><br /></h1>
<table class="list_table" width="90%">
<thead><tr><th>${_("Description")}</th><th class>Taxes</th><th class>QTY</th><th>Unit Price</th><th >Disc.(%)</th><th>Price</th></tr></thead>
%for line in inv.invoice_line :
<tbody>
<tr><td>${line.name|entity}</td><td>${ ', '.join([ tax.name or '' for tax in line.invoice_line_tax_id ])|entity}</td><td>${line.quantity}</td><td style="text-align:right;">${formatLang(line.price_unit)}</td><td style="text-align:center;">${line.discount|entity}</td><td style="text-align:right;">${formatLang(line.price_subtotal)}</td></tr>
%if line.note :
<tr><td colspan="6" style="border-style:none"><pre style="font-family:Helvetica;padding-left:20px">${line.note |entity}</pre></td></tr>
%endif
%endfor
<tr><td style="border-style:none"/><td style="border-style:none"/><td style="border-style:none"/><td style="border-style:none"/><td style="border-top:2px solid"><b>Net Total:</b></td><td style="border-top:2px solid;text-align:right">${formatLang(inv.amount_untaxed)}</td></tr>
<tr><td style="border-style:none"/><td style="border-style:none"/><td style="border-style:none"/><td style="border-style:none"/><td style="border-style:none"><b>Taxes:</b></td><td style="text-align:right">${formatLang(inv.amount_tax)}</td></tr>
<tr><td style="border-style:none"/><td style="border-style:none"/><td style="border-style:none"/><td style="border-style:none"/><td style="border-top:2px solid"><b>Total:</b></td><td style="border-top:2px solid;text-align:right">${formatLang(inv.amount_total)}</td></tr>
</tbody>
</table>
<table class="list_table" width="40%">
<tr><th>Tax</th><th>Base</th><th>Amount</th></tr>
%if inv.tax_line :
%for t in inv.tax_line :
<tr>
<td>${ t.name|entity } </td>
<td>${ t.base|entity}</td>
<td>${ formatLang(t.amount) }</td>
</tr>
%endfor
%endif
<tr>
<td style="border-style:none"/>
<td style="border-top:2px solid"><b>Total</b></td>
<td style="border-top:2px solid">${ formatLang(inv.amount_tax) }</td>
</tr>
</table>
<p style="page-break-after:always"></p>
%endfor
<body>
</html>]]></field>
<field eval="&quot;&quot;&quot;webkitaccount.invoice&quot;&quot;&quot;" name="report_name"/>
<field eval="0" name="attachment_use"/>
<field eval="1" name="header"/>
<field eval="0" name="webkit_debug"/>
<field eval="&quot;&quot;&quot;account.invoice&quot;&quot;&quot;" name="model"/>
<field eval="&quot;&quot;&quot;ir.actions.report.xml&quot;&quot;&quot;" name="type"/>
<field eval="&quot;&quot;&quot;WebKit invoice&quot;&quot;&quot;" name="name"/>
</record>
<record id="ir_property_webkitheaderdefault0" model="ir.property">
<field name="fields_id" ref="field_ir_act_report_xml_webkit_header"/>
<field eval="&quot;&quot;&quot;webkit_header_default&quot;&quot;&quot;" name="name"/>
@ -149,7 +53,7 @@
<body style="border:0; margin: 0;" onload="subst()">
<table class="header" style="border-bottom: 0px solid black; width: 100%">
<tr>
<td>${helper.embeed_logo_by_name('camptocamp_logo')}</td>
<td>${helper.embed_logo_by_name('camptocamp_logo')}</td>
<td style="text-align:right"> </td>
</tr>
<tr>
@ -262,7 +166,7 @@ width:50%;
<field eval="&quot;&quot;&quot;Base Sample&quot;&quot;&quot;" name="name"/>
</record>
<record id="ir_header_img_camptocamplogo0" model="ir.header_img">
<field eval="&quot;&quot;&quot;png&quot;&quot;&quot;" name="extention"/>
<field eval="&quot;&quot;&quot;png&quot;&quot;&quot;" name="type"/>
<field eval="&quot;&quot;&quot;iVBORw0KGgoAAAANSUhEUgAAAH4AAABaCAYAAAB+HuKoAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz
AAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAArWSURB
VHic7Z17cFTVHcc/dzebTciTkDcBDElAhAJahCKoRUWrqOgoiNrxUUcRX1Ar0lLLKKPio6PVGUd0

View File

@ -29,22 +29,22 @@
#
##############################################################################
import netsvc
from osv import fields, osv
class HeaderHTML(osv.osv):
"""HTML Header alos you to define HTML CSS and Page format"""
"""HTML Header allows you to define HTML CSS and Page format"""
_name = "ir.header_webkit"
_columns = {
'company_id' : fields.many2one('res.company', 'Company'),
'html' : fields.text('webkit header'),
'footer_html' : fields.text('webkit footer'),
'html' : fields.text('webkit header', help="Set Webkit Report Header"),
'footer_html' : fields.text('webkit footer', help="Set Webkit Report Footer."),
'css' : fields.text('Header CSS'),
'name' : fields.char('Name', size=128, required=True),
'margin_top' : fields.float('Top Margin (mm)'),
'magrin_bottom' : fields.float('Bottom Margin (mm)'),
'magrin_left' : fields.float('Left Margin (mm)'),
'magrin_right' : fields.float('Right Margin (mm)'),
'margin_bottom' : fields.float('Bottom Margin (mm)'),
'margin_left' : fields.float('Left Margin (mm)'),
'margin_right' : fields.float('Right Margin (mm)'),
'orientation' : fields.selection(
[('Landscape','Landscape'),('Portrait', 'Portrait')],
'Orientation'
@ -84,17 +84,18 @@ class HeaderHTML(osv.osv):
],
'Paper size',
required=True,
help="Select Proper Paper size"
)
}
HeaderHTML()
class HeaderImage(osv.osv):
"""Logo alos you to define multiple logo per company"""
"""Logo allows you to define multiple logo per company"""
_name = "ir.header_img"
_columns = {
'company_id' : fields.many2one('res.company', 'Company'),
'img' : fields.binary('Image'),
'name' : fields.char('Name', size=128, required =True),
'extention' : fields.char('extention', size=32, required =True)
'name' : fields.char('Name', size=128, required =True, help="Name of Image"),
'type' : fields.char('Type', size=32, required =True, help="Image type(png,gif,jpeg)")
}
HeaderImage()

View File

@ -9,7 +9,7 @@
<field name='company_id' />
<newline />
<field name="name"/>
<field name="extention"/>
<field name="type"/>
<field name="img" widget="image" colspan="4"/>
</form>
</field>
@ -34,9 +34,9 @@
<field name="orientation" />
<field name="format" />
<field name="margin_top" />
<field name="magrin_bottom" />
<field name="magrin_left" />
<field name="magrin_right" />
<field name="margin_bottom" />
<field name="margin_left" />
<field name="margin_right" />
</page>
</notebook>
</form>

View File

@ -33,10 +33,7 @@ from osv import osv, fields
import netsvc
from webkit_report import WebKitParser
from report.report_sxw import rml_parse
import base64
import tools
from tools.translate import _
import os
def register_report(name, model, tmpl_path, parser):
"Register the report into the services"
@ -85,7 +82,6 @@ class ReportXML(osv.osv):
)
return res
def create(self, cursor, user, vals, context=None):
"Create report and register it"
res = super(ReportXML, self).create(cursor, user, vals, context)

View File

@ -29,7 +29,6 @@
#
##############################################################################
import netsvc
from osv import fields, osv
import pooler
import base64
@ -43,26 +42,23 @@ class WebKitHelper(object):
self.pool = pooler.get_pool(self.cursor.dbname)
self.report_id = report_id
def embeed_image(self, extention, img, width=0, height=0) :
"Transform a DB image into an embeeded HTML image"
try:
if width :
width = 'width="%spx"'%(width)
else :
width = ' '
if height :
height = 'width="%spx"'%(height)
else :
height = ' '
toreturn = '<img %s %s src="data:image/%s;base64,%s">'%(
width,
height,
extention,
str(img))
return toreturn
except Exception, exp:
print exp
return 'No image'
def embed_image(self, type, img, width=0, height=0) :
"Transform a DB image into an embedded HTML image"
if width :
width = 'width="%spx"'%(width)
else :
width = ' '
if height :
height = 'width="%spx"'%(height)
else :
height = ' '
toreturn = '<img %s %s src="data:image/%s;base64,%s">'%(
width,
height,
type,
str(img))
return toreturn
def get_logo_by_name(self, name):
@ -79,10 +75,10 @@ class WebKitHelper(object):
header_img_id = header_img_id[0]
head = header_obj.browse(self.cursor, self.uid, header_img_id)
return (head.img, head.extention)
return (head.img, head.type)
def embeed_logo_by_name(self, name, width=0, height=0) :
"""Return HTML embeeded logo by name"""
img, extention = self.get_logo_by_name(name)
return self.embeed_image(extention, img, width, height)
def embed_logo_by_name(self, name, width=0, height=0) :
"""Return HTML embedded logo by name"""
img, type = self.get_logo_by_name(name)
return self.embed_image(type, img, width, height)

View File

@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_ir_header_webkit","ir.header_webkit","model_ir_header_webkit",,,,,
"access_ir_header_img","ir.header_img","model_ir_header_img",,,,,
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_ir_header_webkit ir.header_webkit model_ir_header_webkit
3 access_ir_header_img ir.header_img model_ir_header_img

View File

@ -30,9 +30,8 @@
##############################################################################
import commands
import logging
import os
import platform
#import platform
import report
import sys
import tempfile
@ -63,21 +62,30 @@ class WebKitParser(report_sxw):
"""Return the lib wkhtml path"""
#TODO Detect lib in system first
path = self.pool.get('res.company').read(cursor, uid, company, ['lib_path',])
if path['lib_path']:
return path['lib_path']
else:
try:
status = commands.getstatusoutput('wkhtmltopdf')
if status[0]:
raise
except Exception:
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'+
' path to the executable on the Company form.')
)
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:
raise except_osv(
_('Please install wkhtmltopdf library'),
_('Please install it on you system (sudo apt-get install wkhtmltopdf) or download it from here: http://code.google.com/p/wkhtmltopdf/downloads/list and set the path to the executable on the Company form.')
)
return False
_('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)
)
def generate_pdf(self, comm_path, report_xml, header, footer, html_list):
"""Call webkit in order to generate pdf"""
tmp_dir = tempfile.gettempdir()
@ -88,7 +96,7 @@ class WebKitParser(report_sxw):
if comm_path:
command = [comm_path]
else:
command = 'wkhtmltopdf'
command = ['wkhtmltopdf']
command.append('-q')
if header :
@ -116,12 +124,12 @@ class WebKitParser(report_sxw):
if report_xml.webkit_header.margin_top :
command.append('--margin-top %s'%(report_xml.webkit_header.margin_top))
if report_xml.webkit_header.magrin_bottom :
command.append('--margin-bottom %s'%(report_xml.webkit_header.magrin_bottom))
if report_xml.webkit_header.magrin_left :
command.append('--margin-left %s'%(report_xml.webkit_header.magrin_left))
if report_xml.webkit_header.magrin_right :
command.append('--margin-right %s'%(report_xml.webkit_header.magrin_right))
if report_xml.webkit_header.margin_bottom :
command.append('--margin-bottom %s'%(report_xml.webkit_header.margin_bottom))
if report_xml.webkit_header.margin_left :
command.append('--margin-left %s'%(report_xml.webkit_header.margin_left))
if report_xml.webkit_header.margin_right :
command.append('--margin-right %s'%(report_xml.webkit_header.margin_right))
if report_xml.webkit_header.orientation :
command.append("--orientation '%s'"%(report_xml.webkit_header.orientation))
if report_xml.webkit_header.format :
@ -142,18 +150,13 @@ class WebKitParser(report_sxw):
status[1]
)
except Exception:
try:
for f_to_del in file_to_del :
os.unlink(f_to_del)
except Exception:
pass
pdf = file(out).read()
try:
for f_to_del in file_to_del :
os.unlink(f_to_del)
except Exception, exc:
pass
pdf = file(out).read()
for f_to_del in file_to_del :
os.unlink(f_to_del)
os.unlink(out)
return pdf
@ -203,11 +206,13 @@ class WebKitParser(report_sxw):
# override needed to keep the attachments' storing procedure
def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
"""generate the PDF"""
if report_xml.report_type != 'webkit':
return super(WebKitParser,self).create_single_pdf(self, cursor, uid, ids, data, report_xml, context=context)
if not context:
context={}
if report_xml.report_type != 'webkit':
return super(WebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context)
self.parser_instance = self.parser(
cursor,
uid,
@ -224,6 +229,7 @@ class WebKitParser(report_sxw):
template = False
if report_xml.report_file :
path = os.path.join(config['addons_path'], report_xml.report_file)
if os.path.exists(path) :
@ -235,7 +241,7 @@ class WebKitParser(report_sxw):
header = report_xml.webkit_header.html
footer = report_xml.webkit_header.footer_html
if not header and report_xml.header:
raise except_osv(
raise except_osv(
_('No header defined for this Webkit report!'),
_('Please set a header in company settings')
)
@ -272,12 +278,11 @@ class WebKitParser(report_sxw):
#default_filters=['unicode', 'entity'] can be used to set global filter
body_mako_tpl = Template(template ,input_encoding='utf-8')
helper = WebKitHelper(cursor, uid, report_xml.id, context)
html = body_mako_tpl.render(
helper=helper,
css=css,
_=self.translate_call,
**self.parser_instance.localcontext
)
html = body_mako_tpl.render( helper=helper,
css=css,
_=self.translate_call,
**self.parser_instance.localcontext
)
head_mako_tpl = Template(header, input_encoding='utf-8')
head = head_mako_tpl.render(
company=company,

View File

@ -29,4 +29,4 @@
#
##############################################################################
import report_actions
import report_webkit_actions

View File

@ -1,177 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Camptocamp SA (http://www.camptocamp.com)
# All Right Reserved
#
# Author : Vincent Renaville
#
# 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.
#
##############################################################################
import wizard
import pooler
import ir
from tools.translate import _
class report_actions_wizard(wizard.interface):
'''
Add Print Buttons
'''
form = '''<?xml version="1.0"?>
<form string="Add Print Buttons">
<field name="print_button"/>
<field name="open_action"/>
</form>'''
ex_form = '''<?xml version="1.0"?>
<form string="Add Print Buttons">
<label string="Report Action already exist for this report."/>
</form>'''
fields = {
'print_button':
{
'string': 'Add print button',
'type': 'boolean',
'default': True,
'help':'Add action to menu context in print button.'
},
'open_action':
{
'string': 'Open added action',
'type': 'boolean',
'default': False
},
}
def _do_action(self, cursor, uid, data, context):
"""Called in wizard init"""
pool = pooler.get_pool(cursor.dbname)
report = pool.get(data['model']).browse(
cursor,
uid,
data['id'],
context=context
)
if data['form']['print_button']:
res = ir.ir_set(
cursor,
uid,
'action',
'client_print_multi',
report.report_name,
[report.model],
'ir.actions.report.xml,%d' % data['id'],
isobject=True
)
else:
res = ir.ir_set(
cursor,
uid,
'action',
'client_print_multi',
report.report_name,
[report.model,0],
'ir.actions.report.xml,%d' % data['id'],
isobject=True
)
return {'value_id':res[0]}
def _check(self, cursor, uid, data, context):
"""Check if button exist"""
pool = pooler.get_pool(cursor.dbname)
report = pool.get(data['model']).browse(
cursor,
uid,
data['id'],
context=context
)
ids = pool.get('ir.values').search(
cursor,
uid,
[('value','=',report.type+','+str(data['id']))]
)
if not ids:
return 'add'
else:
return 'exist'
def _action_open_window(self, cursor, uid, data, context):
"""Open a windows in client"""
form=data['form']
if not form['open_action']:
return {}
return {
'domain':"[('id','=',%d)]" % (form['value_id']),
'name': _('Client Actions Connections'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'ir.values',
'view_id': False,
'type': 'ir.actions.act_window',
}
states = {
'init': {
'actions': [],
'result': {
'type':'choice',
'next_state':_check
}
},
'add': {
'actions': [],
'result': {
'type': 'form',
'arch': form,
'fields': fields,
'state': (('end', '_Cancel'), ('process', '_Ok'))
},
},
'exist': {
'actions': [],
'result': {
'type': 'form',
'arch': ex_form,
'fields': {},
'state': (('end', '_Close'),)
},
},
'process': {
'actions': [_do_action],
'result': {
'type': 'state',
'state': 'exit'
},
},
'exit': {
'actions': [],
'result': {
'type': 'action',
'action': _action_open_window,
'state': 'end'
},
},
}
report_actions_wizard('ir.report_actions')

View File

@ -0,0 +1,143 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Camptocamp SA (http://www.camptocamp.com)
# All Right Reserved
#
# Author : Vincent Renaville
#
# 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.
#
##############################################################################
import wizard
import pooler
import ir
from tools.translate import _
from osv import fields, osv
class report_webkit_actions(osv.osv_memory):
_name = "report.webkit.actions"
_description = "Webkit Actions"
_columns = {
'print_button':fields.boolean('Add print button',help="Add action to menu context in print button."),
'open_action':fields.boolean('Open added action'),
}
_defaults = {
'print_button': lambda *a: True,
'open_action': lambda *a: False,
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
""" Changes the view dynamically
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param context: A standard dictionary
@return: New arch of view.
"""
res = super(report_webkit_actions, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
record_id = context and context.get('active_id', False) or False
active_model = context.get('active_model')
if not record_id or (active_model and active_model != 'ir.actions.report.xml'):
return res
report = self.pool.get('ir.actions.report.xml').browse(
cr,
uid,
context.get('active_id'),
context=context
)
ids = self.pool.get('ir.values').search(
cr,
uid,
[('value','=',report.type+','+str(context.get('active_id')))]
)
if ids:
res['arch'] = '''<form string="Add Print Buttons">
<label string="Report Action already exist for this report."/>
<separator colspan="4"/>
<group col="2" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="_Cancel" />
</group>
</form>
'''
return res
def do_action(self, cr, uid, ids, context):
""" This Function Open added Action.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of report.webkit.actions's ID
@param context: A standard dictionary
@return: Dictionary of ir.values form.
"""
report_obj = self.pool.get('ir.actions.report.xml')
for current in self.browse(cr, uid, ids):
report = report_obj.browse(
cr,
uid,
context.get('active_id'),
context=context
)
if current.print_button:
res = ir.ir_set(
cr,
uid,
'action',
'client_print_multi',
report.report_name,
[report.model],
'ir.actions.report.xml,%d' % context.get('active_id', False),
isobject=True
)
else:
res = ir.ir_set(
cr,
uid,
'action',
'client_print_multi',
report.report_name,
[report.model,0],
'ir.actions.report.xml,%d' % context.get('active_id', False),
isobject=True
)
if res[0]:
if not current.open_action:
return {}
return {
'domain':"[('id','=',%d)]" % (res[0]),
'name': _('Client Actions Connections'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'ir.values',
'view_id': False,
'type': 'ir.actions.act_window',
}
report_webkit_actions()

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_report_webkit_actions">
<field name="name">Report Webkit actions wizard</field>
<field name="model">report.webkit.actions</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Add Print Buttons" col="4">
<field name="print_button"/>
<field name="open_action"/>
<separator string="" colspan="6"/>
<group colspan="6" col="4" >
<button string="_Cancel" icon="gtk-close" special="cancel" />
<button name="do_action" type="object" string="_Ok" icon="gtk-ok" />
</group>
</form>
</field>
</record>
<act_window name="Add Print Buttons"
res_model="report.webkit.actions"
src_model="ir.actions.report.xml"
view_mode="form"
view_type="form"
key2="client_print_multi"
target="new"
id="wizard_ofdo_report_actions"/>
</data>
</openerp>

View File

@ -44,9 +44,8 @@
"category": "Reports/Webkit",
"author" : "Camptocamp SA - NBessi",
"url": "http://www.camptocamp.com/",
"data": [ 'data.xml',
"wizard_report_actions_view.xml",
"report_webkit_html_view.xml",
"data": ["report_webkit_html_view.xml",
],
"installable" : True,
"active" : False,

View File

@ -1,225 +0,0 @@
<?xml version="1.0" ?>
<openerp>
<data noupdate="1">
<record id="ir_property_webkitheaderdefault0" model="ir.property">
<field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
<field eval="&quot;&quot;&quot;webkit_header_default&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;ir.header_webkit,1&quot;&quot;&quot;" name="value"/>
</record>
<record id="ir_header_webkit_basesample0" model="ir.header_webkit">
<field name="footer_html"><![CDATA[<html>
<head>
<script>
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for(var i in x) {
var y = document.getElementsByClassName(x[i]);
for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
}
}
</script>
</head>
<body style="border:0; margin: 0;" onload="subst()">
<table style="border-top: 1px solid black; width: 100%">
<tr >
<td style="text-align:right;font-size:12;" width="95%">Page <span class="page"/></td><td style="text-align:left;font-size:12;"> of <span class="topage"/></td>
</tr>
</table>
</body>
</html>]]></field>
<field eval="&quot;&quot;&quot;Portrait&quot;&quot;&quot;" name="orientation"/>
<field eval="&quot;&quot;&quot;A4&quot;&quot;&quot;" name="format"/>
<field name="html"><![CDATA[<html>
<head>
<script>
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for(var i in x) {
var y = document.getElementsByClassName(x[i]);
for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
}
}
</script>
<style type="text/css">
${css}
</style>
</head>
<body style="border:0; margin: 0;" onload="subst()">
<table class="header" style="border-bottom: 0px solid black; width: 100%">
<tr>
<td>${helper.embeed_logo_by_name('camptocamp_logo')}</td>
<td style="text-align:right"> </td>
</tr>
<tr>
<td><br/></td>
<td style="text-align:right"> </td>
</tr>
<tr>
<td>${company.partner_id.name |entity}</td>
<td/>
</tr>
<tr>
<td >${company.partner_id.address and company.partner_id.address[0].street or ''|entity}</td>
<td/>
</tr>
<tr>
<td>Phone: ${company.partner_id.address and company.partner_id.address[0].phone or ''|entity} </td>
<td/>
</tr>
<tr>
<td>Mail: ${company.partner_id.address and company.partner_id.address[0].email or ''|entity}<br/></td>
</tr>
</table> ${_debug or ''} </body>
</html>]]>
</field>
<field eval="55.0" name="margin_top"/>
<field name="css" ><![CDATA[
body {
font-family:helvetica;
font-size:12;
}
.dest_address {
margin-left:60%;
font-size:12;
}
.header {
margin-left:0;
text-align:left;
width:300px;
font-size:12;
}
.title {
font-size:16;
font-weight: bold;
}
.basic_table{
text-align:center;
border:1px solid lightGrey;
border-collapse: collapse;
}
.basic_table td {
border:1px solid lightGrey;
font-size:12;
}
.list_table {
border-color:black;
text-align:center;
border-collapse: collapse;
}
.list_table td {
border-color:gray;
border-top:1px solid gray;
text-align:left;
font-size:12;
padding-right:3px
padding-left:3px
padding-top:3px
padding-bottom:3px
}
.list_table th {
border-bottom:2px solid black;
text-align:left;
font-size:12;
font-weight:bold;
padding-right:3px
padding-left:3px
}
.list_tabe thead {
display:table-header-group;
}
.total {
width:100%;
}
.lib {
width:10.3%;
}
.tot {
text-align:right;
width:15%;
}
.lefttot {
width:74%;
}
.tax {
width:50%;
}]]> </field>
<field eval="&quot;&quot;&quot;Base Sample&quot;&quot;&quot;" name="name"/>
</record>
<record id="ir_header_img_camptocamplogo0" model="ir.header_img">
<field eval="&quot;&quot;&quot;png&quot;&quot;&quot;" name="extention"/>
<field eval="&quot;&quot;&quot;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
&quot;&quot;&quot;" name="img"/>
<field eval="&quot;&quot;&quot;camptocamp_logo&quot;&quot;&quot;" name="name"/>
</record>
</data>
</openerp>

View File

@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Camptocamp SA (http://www.camptocamp.com)
# All Right Reserved
#
# Author : Vincent Renaville
#
# 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.
#
##############################################################################
import report_actions

View File

@ -1,177 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Camptocamp SA (http://www.camptocamp.com)
# All Right Reserved
#
# Author : Vincent Renaville
#
# 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.
#
##############################################################################
import wizard
import pooler
import ir
from tools.translate import _
class report_actions_wizard(wizard.interface):
'''
Add Print Buttons
'''
form = '''<?xml version="1.0"?>
<form string="Add Print Buttons">
<field name="print_button"/>
<field name="open_action"/>
</form>'''
ex_form = '''<?xml version="1.0"?>
<form string="Add Print Buttons">
<label string="Report Action already exist for this report."/>
</form>'''
fields = {
'print_button':
{
'string': 'Add print button',
'type': 'boolean',
'default': True,
'help':'Add action to menu context in print button.'
},
'open_action':
{
'string': 'Open added action',
'type': 'boolean',
'default': False
},
}
def _do_action(self, cursor, uid, data, context):
"""Called in wizard init"""
pool = pooler.get_pool(cursor.dbname)
report = pool.get(data['model']).browse(
cursor,
uid,
data['id'],
context=context
)
if data['form']['print_button']:
res = ir.ir_set(
cursor,
uid,
'action',
'client_print_multi',
report.report_name,
[report.model],
'ir.actions.report.xml,%d' % data['id'],
isobject=True
)
else:
res = ir.ir_set(
cursor,
uid,
'action',
'client_print_multi',
report.report_name,
[report.model,0],
'ir.actions.report.xml,%d' % data['id'],
isobject=True
)
return {'value_id':res[0]}
def _check(self, cursor, uid, data, context):
"""Check if button exist"""
pool = pooler.get_pool(cursor.dbname)
report = pool.get(data['model']).browse(
cursor,
uid,
data['id'],
context=context
)
ids = pool.get('ir.values').search(
cursor,
uid,
[('value','=',report.type+','+str(data['id']))]
)
if not ids:
return 'add'
else:
return 'exist'
def _action_open_window(self, cursor, uid, data, context):
"""Open a windows in client"""
form=data['form']
if not form['open_action']:
return {}
return {
'domain':"[('id','=',%d)]" % (form['value_id']),
'name': _('Client Actions Connections'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'ir.values',
'view_id': False,
'type': 'ir.actions.act_window',
}
states = {
'init': {
'actions': [],
'result': {
'type':'choice',
'next_state':_check
}
},
'add': {
'actions': [],
'result': {
'type': 'form',
'arch': form,
'fields': fields,
'state': (('end', '_Cancel'), ('process', '_Ok'))
},
},
'exist': {
'actions': [],
'result': {
'type': 'form',
'arch': ex_form,
'fields': {},
'state': (('end', '_Close'),)
},
},
'process': {
'actions': [_do_action],
'result': {
'type': 'state',
'state': 'exit'
},
},
'exit': {
'actions': [],
'result': {
'type': 'action',
'action': _action_open_window,
'state': 'end'
},
},
}
report_actions_wizard('ir.report_actions')

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<wizard string="Add Print Buttons" model="ir.actions.report.xml" name="ir.report_actions" menu="True" id="wizard_oo_report_actions" />
</data>
</openerp>