[MERGE] report: Migration to new API
This commit is contained in:
@@ -18,9 +18,10 @@ class PayslipLinesContributionRegister(models.TransientModel):
|
||||
|
||||
@api.multi
|
||||
def print_report(self):
|
||||
active_ids = self.env.context.get('active_ids', [])
|
||||
datas = {
|
||||
'ids': self.env.context.get('active_ids', []),
|
||||
'ids': active_ids,
|
||||
'model': 'hr.contribution.register',
|
||||
'form': self.read()[0]
|
||||
}
|
||||
return self.env['report'].get_action(self.browse(), 'hr_payroll.report_contributionregister', data=datas)
|
||||
return self.env['report'].get_action(self.browse(active_ids), 'hr_payroll.report_contributionregister', data=datas)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
from odoo import api
|
||||
|
||||
class product_price_list(osv.osv_memory):
|
||||
_name = 'product.price_list'
|
||||
@@ -24,16 +24,15 @@ class product_price_list(osv.osv_memory):
|
||||
'qty5': 0,
|
||||
}
|
||||
|
||||
def print_report(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def print_report(self):
|
||||
"""
|
||||
To get the date and print the report
|
||||
@return : return report
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
datas = {'ids': context.get('active_ids', [])}
|
||||
res = self.read(cr, uid, ids, ['price_list','qty1', 'qty2','qty3','qty4','qty5'], context=context)
|
||||
datas = {'ids': self.env.context.get('active_ids', [])}
|
||||
res = self.read(['price_list', 'qty1', 'qty2', 'qty3', 'qty4', 'qty5'])
|
||||
res = res and res[0] or {}
|
||||
res['price_list'] = res['price_list'][0]
|
||||
datas['form'] = res
|
||||
return self.pool['report'].get_action(cr, uid, [], 'product.report_pricelist', data=datas, context=context)
|
||||
return self.env['report'].get_action(self, 'product.report_pricelist', data=datas)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import controllers
|
||||
import models
|
||||
import tests
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Report',
|
||||
'category': 'Base',
|
||||
'summary': 'Hidden',
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
Report
|
||||
""",
|
||||
'depends': ['base', 'web'],
|
||||
'data': [
|
||||
'views/layouts.xml',
|
||||
'views/views.xml',
|
||||
'data/report_paperformat.xml',
|
||||
'data/report_paperformat_data.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'views/report.xml',
|
||||
'views/ir_actions.xml',
|
||||
'views/layout_templates.xml',
|
||||
'views/report_paperformat_views.xml',
|
||||
'views/report_templates.xml',
|
||||
'views/res_company_views.xml',
|
||||
'views/ir_actions_report_views.xml',
|
||||
],
|
||||
'qweb' : [
|
||||
'static/src/xml/*.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': True,
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import main
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.addons.web.http import Controller, route, request
|
||||
from openerp.addons.web.controllers.main import _serialize_exception, content_disposition
|
||||
from openerp.tools import html_escape
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
|
||||
import json
|
||||
import time
|
||||
from werkzeug import exceptions, url_decode
|
||||
from werkzeug.datastructures import Headers
|
||||
from werkzeug.test import Client
|
||||
from werkzeug.wrappers import BaseResponse
|
||||
from werkzeug.datastructures import Headers
|
||||
from reportlab.graphics.barcode import createBarcodeDrawing
|
||||
|
||||
from odoo.http import Controller, route, request
|
||||
from odoo.tools import html_escape
|
||||
from odoo.addons.web.controllers.main import _serialize_exception, content_disposition
|
||||
from odoo.tools.safe_eval import safe_eval as eval
|
||||
|
||||
|
||||
class ReportController(Controller):
|
||||
@@ -25,8 +24,8 @@ class ReportController(Controller):
|
||||
'/report/<converter>/<reportname>/<docids>',
|
||||
], type='http', auth='user', website=True)
|
||||
def report_routes(self, reportname, docids=None, converter=None, **data):
|
||||
report_obj = request.registry['report']
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
report_obj = request.env['report']
|
||||
context = dict(request.env.context)
|
||||
|
||||
if docids:
|
||||
docids = [int(i) for i in docids.split(',')]
|
||||
@@ -39,12 +38,11 @@ class ReportController(Controller):
|
||||
if data['context'].get('lang'):
|
||||
del data['context']['lang']
|
||||
context.update(data['context'])
|
||||
|
||||
if converter == 'html':
|
||||
html = report_obj.get_html(cr, uid, docids, reportname, data=data, context=context)
|
||||
html = report_obj.with_context(context).get_html(docids, reportname, data=data)
|
||||
return request.make_response(html)
|
||||
elif converter == 'pdf':
|
||||
pdf = report_obj.get_pdf(cr, uid, docids, reportname, data=data, context=context)
|
||||
pdf = report_obj.with_context(context).get_pdf(docids, reportname, data=data)
|
||||
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
||||
return request.make_response(pdf, headers=pdfhttpheaders)
|
||||
else:
|
||||
@@ -56,9 +54,9 @@ class ReportController(Controller):
|
||||
@route(['/report/barcode', '/report/barcode/<type>/<path:value>'], type='http', auth="user")
|
||||
def report_barcode(self, type, value, width=600, height=100, humanreadable=0):
|
||||
"""Contoller able to render barcode images thanks to reportlab.
|
||||
Samples:
|
||||
Samples:
|
||||
<img t-att-src="'/report/barcode/QR/%s' % o.name"/>
|
||||
<img t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' %
|
||||
<img t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' %
|
||||
('QR', o.name, 200, 200)"/>
|
||||
|
||||
:param type: Accepted types: 'Codabar', 'Code11', 'Code128', 'EAN13', 'EAN8', 'Extended39',
|
||||
@@ -68,7 +66,7 @@ class ReportController(Controller):
|
||||
at the bottom of the output image
|
||||
"""
|
||||
try:
|
||||
barcode = request.registry['report'].barcode(type, value, width=width, height=height, humanreadable=humanreadable)
|
||||
barcode = request.env['report'].barcode(type, value, width=width, height=height, humanreadable=humanreadable)
|
||||
except (ValueError, AttributeError):
|
||||
raise exceptions.HTTPException(description='Cannot convert into barcode.')
|
||||
|
||||
@@ -101,8 +99,7 @@ class ReportController(Controller):
|
||||
data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON
|
||||
response = self.report_routes(reportname, converter='pdf', **dict(data))
|
||||
|
||||
cr, uid = request.cr, request.uid
|
||||
report = request.registry['report']._get_report_from_name(cr, uid, reportname)
|
||||
report = request.env['report']._get_report_from_name(reportname)
|
||||
filename = "%s.%s" % (report.name, "pdf")
|
||||
if docids:
|
||||
ids = [int(x) for x in docids.split(",")]
|
||||
@@ -112,7 +109,7 @@ class ReportController(Controller):
|
||||
response.headers.add('Content-Disposition', content_disposition(filename))
|
||||
response.set_cookie('fileToken', token)
|
||||
return response
|
||||
elif type =='controller':
|
||||
elif type == 'controller':
|
||||
reqheaders = Headers(request.httprequest.headers)
|
||||
response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
|
||||
response.set_cookie('fileToken', token)
|
||||
@@ -130,4 +127,4 @@ class ReportController(Controller):
|
||||
|
||||
@route(['/report/check_wkhtmltopdf'], type='json', auth="user")
|
||||
def check_wkhtmltopdf(self):
|
||||
return request.registry['report']._check_wkhtmltopdf()
|
||||
return request.env['report']._check_wkhtmltopdf()
|
||||
|
||||
+2
-4
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record id="paperformat_euro" model="report.paperformat">
|
||||
<field name="name">European A4</field>
|
||||
<field name="default" eval="True" />
|
||||
@@ -32,5 +31,4 @@
|
||||
<field name="header_spacing">35</field>
|
||||
<field name="dpi">90</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,8 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import abstract_report
|
||||
import ir_actions
|
||||
import ir_actions_report_xml
|
||||
import ir_http
|
||||
import ir_qweb
|
||||
import report
|
||||
import report_paperformat
|
||||
import abstract_report
|
||||
import ir_qweb
|
||||
import res_company
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import osv
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class AbstractReport(osv.AbstractModel):
|
||||
class AbstractReport(models.AbstractModel):
|
||||
"""Model used to embed old style reports"""
|
||||
_name = 'report.abstract_report'
|
||||
_template = None
|
||||
_wrapped_report_class = None
|
||||
|
||||
def render_html(self, cr, uid, ids, data=None, context=None):
|
||||
context = dict(context or {})
|
||||
@api.multi
|
||||
def render_html(self, data=None):
|
||||
context = dict(self.env.context or {})
|
||||
|
||||
# If the key 'landscape' is present in data['form'], passing it into the context
|
||||
if data and data.get('form', {}).get('landscape'):
|
||||
@@ -20,18 +21,18 @@ class AbstractReport(osv.AbstractModel):
|
||||
if context and context.get('active_ids'):
|
||||
# Browse the selected objects via their reference in context
|
||||
model = context.get('active_model') or context.get('model')
|
||||
objects_model = self.pool[model]
|
||||
objects = objects_model.browse(cr, uid, context['active_ids'], context=context)
|
||||
objects_model = self.env[model]
|
||||
objects = objects_model.with_context(context).browse(context['active_ids'])
|
||||
else:
|
||||
# If no context is set (for instance, during test execution), build one
|
||||
model = self.pool['report']._get_report_from_name(cr, uid, self._template).model
|
||||
objects_model = self.pool[model]
|
||||
objects = objects_model.browse(cr, uid, ids, context=context)
|
||||
model = self.env['report']._get_report_from_name(self._template).model
|
||||
objects_model = self.env[model]
|
||||
objects = objects_model.with_context(context).browse(self.ids)
|
||||
context['active_model'] = model
|
||||
context['active_ids'] = ids
|
||||
context['active_ids'] = self.ids
|
||||
|
||||
# Generate the old style report
|
||||
wrapped_report = self._wrapped_report_class(cr, uid, '', context=context)
|
||||
wrapped_report = self.with_context(context)._wrapped_report_class(self.env.cr, self.env.uid, '', context=self.env.context)
|
||||
wrapped_report.set_context(objects, data, context['active_ids'])
|
||||
|
||||
# Rendering self._template with the wrapped report instance localcontext as
|
||||
@@ -45,4 +46,4 @@ class AbstractReport(osv.AbstractModel):
|
||||
docargs['doc_ids'] = context['active_ids']
|
||||
docargs['doc_model'] = model
|
||||
|
||||
return self.pool['report'].render(cr, uid, [], self._template, docargs, context=context)
|
||||
return self.env['report'].with_context(context).render(self._template, docargs)
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
from openerp import models, fields
|
||||
|
||||
class Actions(models.Model):
|
||||
_inherit = 'ir.actions.report.xml'
|
||||
|
||||
print_report_name = fields.Char('Printed Report Name', help="This is the filename of the report going to download. Keep empty to not change the report filename. You can use a python expression with the object and time variables.")
|
||||
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
class ir_actions_report(models.Model):
|
||||
_inherit = 'ir.actions.report.xml'
|
||||
|
||||
paperformat_id = fields.Many2one('report.paperformat', 'Paper format')
|
||||
print_report_name = fields.Char('Printed Report Name',
|
||||
help="This is the filename of the report going to download. Keep empty to not change the report filename. You can use a python expression with the object and time variables.")
|
||||
|
||||
@api.multi
|
||||
def associated_view(self):
|
||||
"""Used in the ir.actions.report.xml form view in order to search naively after the view(s)
|
||||
used in the rendering.
|
||||
"""
|
||||
self.ensure_one()
|
||||
action_ref = self.env.ref('base.action_ui_view')
|
||||
if not action_ref:
|
||||
return False
|
||||
action_data = action_ref.read()[0]
|
||||
action_data['domain'] = [('name', 'ilike', self.report_name.split('.')[1]), ('type', '=', 'qweb')]
|
||||
return action_data
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from reportlab.graphics.barcode import createBarcodeDrawing
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import osv
|
||||
from openerp.addons.base.ir.ir_qweb import unicodifier
|
||||
from odoo import api, models
|
||||
from odoo.addons.base.ir.ir_qweb import unicodifier
|
||||
|
||||
|
||||
class BarcodeConverter(osv.AbstractModel):
|
||||
class IrQwebFieldBarcode(models.AbstractModel):
|
||||
""" ``barcode`` widget rendering, inserts a data:uri-using image tag in the
|
||||
document. May be overridden by e.g. the website module to generate links
|
||||
instead.
|
||||
@@ -12,14 +13,15 @@ class BarcodeConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.barcode'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, options, context=None):
|
||||
options = options or {}
|
||||
@api.model
|
||||
def value_to_html(self, value, options=None):
|
||||
barcode_type = options.get('type', 'Code128')
|
||||
barcode = self.pool['report'].barcode(
|
||||
barcode = self.env['report'].barcode(
|
||||
barcode_type,
|
||||
value,
|
||||
**dict((key, value) for key, value in options.items() if key in ['width', 'height', 'humanreadable']))
|
||||
return unicodifier('<img src="data:%s;base64,%s">' % ('png', barcode.encode('base64')))
|
||||
|
||||
def from_html(self, cr, uid, model, field, element, context=None):
|
||||
@api.model
|
||||
def from_html(self, model, field, element):
|
||||
return None
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import api
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.exceptions import AccessError
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.sql_db import TestCursor
|
||||
from openerp.tools import config
|
||||
from openerp.tools.misc import find_in_path
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
from openerp.exceptions import UserError
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.sql_db import TestCursor
|
||||
from odoo.tools import config
|
||||
from odoo.tools.misc import find_in_path
|
||||
from odoo.addons.web.http import request
|
||||
from odoo.tools.safe_eval import safe_eval as eval
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
import re
|
||||
import time
|
||||
import base64
|
||||
import logging
|
||||
import tempfile
|
||||
import lxml.html
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
from contextlib import closing
|
||||
from distutils.version import LooseVersion
|
||||
from functools import partial
|
||||
@@ -73,7 +71,7 @@ else:
|
||||
wkhtmltopdf_state = 'workers'
|
||||
|
||||
|
||||
class Report(osv.Model):
|
||||
class Report(models.Model):
|
||||
_name = "report"
|
||||
_description = "Report"
|
||||
|
||||
@@ -83,7 +81,8 @@ class Report(osv.Model):
|
||||
# Extension of ir_ui_view.render with arguments frequently used in reports
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
def render(self, cr, uid, ids, template, values=None, context=None):
|
||||
@api.multi
|
||||
def render(self, template, values=None):
|
||||
"""Allow to render a QWeb template python-side. This function returns the 'ir.ui.view'
|
||||
render but embellish it with some variables/methods used in reports.
|
||||
|
||||
@@ -93,14 +92,11 @@ class Report(osv.Model):
|
||||
if values is None:
|
||||
values = {}
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
context = dict(self.env.context, inherit_branding=True) # Tell QWeb to brand the generated html
|
||||
|
||||
context = dict(context, inherit_branding=True) # Tell QWeb to brand the generated html
|
||||
|
||||
view_obj = self.pool['ir.ui.view']
|
||||
|
||||
user = self.pool['res.users'].browse(cr, uid, uid, context=context)
|
||||
view_obj = self.env['ir.ui.view']
|
||||
# Browse the user instead of using the sudo self.env.user
|
||||
user = self.env['res.users'].browse(self.env.uid)
|
||||
website = None
|
||||
if request and hasattr(request, 'website'):
|
||||
if request.website is not None:
|
||||
@@ -109,51 +105,42 @@ class Report(osv.Model):
|
||||
|
||||
values.update(
|
||||
time=time,
|
||||
context_timestamp=lambda t: fields.datetime.context_timestamp(cr, uid, t, context),
|
||||
context_timestamp=lambda t: fields.Datetime.context_timestamp(self.with_context(tz=user.tz), t),
|
||||
editable=True,
|
||||
user=user,
|
||||
res_company=user.company_id,
|
||||
website=website,
|
||||
web_base_url=self.pool['ir.config_parameter'].get_param(cr, SUPERUSER_ID, 'web.base.url', default='')
|
||||
web_base_url=self.env['ir.config_parameter'].get_param('web.base.url', default='')
|
||||
)
|
||||
return view_obj.render_template(cr, uid, template, values, context=context)
|
||||
return view_obj.render_template(template, values)
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Main report methods
|
||||
#--------------------------------------------------------------------------
|
||||
@api.v7
|
||||
def get_html(self, cr, uid, ids, report_name, data=None, context=None):
|
||||
@api.model
|
||||
def get_html(self, docids, report_name, data=None):
|
||||
"""This method generates and returns html version of a report.
|
||||
"""
|
||||
# If the report is using a custom model to render its html, we must use it.
|
||||
# Otherwise, fallback on the generic html rendering.
|
||||
report_model_name = 'report.%s' % report_name
|
||||
particularreport_obj = self.pool.get(report_model_name)
|
||||
if particularreport_obj is not None:
|
||||
return particularreport_obj.render_html(cr, uid, ids, data=data, context=context)
|
||||
report_model = self.env.get(report_model_name)
|
||||
if report_model is not None:
|
||||
return report_model.render_html(data=data)
|
||||
else:
|
||||
report = self._get_report_from_name(cr, uid, report_name)
|
||||
report_obj = self.pool[report.model]
|
||||
docs = report_obj.browse(cr, uid, ids, context=context)
|
||||
report = self._get_report_from_name(report_name)
|
||||
docs = self.env[report.model].browse(docids)
|
||||
docargs = {
|
||||
'doc_ids': ids,
|
||||
'doc_ids': docids,
|
||||
'doc_model': report.model,
|
||||
'docs': docs,
|
||||
}
|
||||
return self.render(cr, uid, [], report.report_name, docargs, context=context).encode('utf-8')
|
||||
return self.render(report.report_name, docargs).encode('utf-8')
|
||||
|
||||
@api.v8
|
||||
def get_html(self, records, report_name, data=None):
|
||||
return Report.get_html(self._model, self._cr, self._uid, records.ids,
|
||||
report_name, data=data, context=self._context)
|
||||
|
||||
@api.v7
|
||||
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None, context=None):
|
||||
@api.model
|
||||
def get_pdf(self, docids, report_name, html=None, data=None):
|
||||
"""This method generates and returns pdf version of a report.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
# As the assets are generated during the same transaction as the rendering of the
|
||||
# templates calling them, there is a scenario where the assets are unreachable: when
|
||||
# you make a request to read the assets while the transaction creating them is not done.
|
||||
@@ -162,8 +149,9 @@ class Report(osv.Model):
|
||||
# This scenario happens when you want to print a PDF report for the first time, as the
|
||||
# assets are not in cache and must be generated. To workaround this issue, we manually
|
||||
# commit the writes in the `ir.attachment` table. It is done thanks to a key in the context.
|
||||
context = dict(self.env.context)
|
||||
if not config['test_enable']:
|
||||
context = dict(context, commit_assetsbundle=True)
|
||||
context['commit_assetsbundle'] = True
|
||||
|
||||
# Disable the debug mode in the PDF rendering in order to not split the assets bundle
|
||||
# into separated files to load. This is done because of an issue in wkhtmltopdf
|
||||
@@ -171,25 +159,25 @@ class Report(osv.Model):
|
||||
# Without this, the header/footer of the reports randomly disapear
|
||||
# because the resources files are not loaded in time.
|
||||
# https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2083
|
||||
context = dict(context, debug=False)
|
||||
context['debug'] = False
|
||||
|
||||
if html is None:
|
||||
html = self.get_html(cr, uid, ids, report_name, data=data, context=context)
|
||||
html = self.get_html(docids, report_name, data=data)
|
||||
|
||||
# The test cursor prevents the use of another environnment while the current
|
||||
# transaction is not finished, leading to a deadlock when the report requests
|
||||
# an asset bundle during the execution of test scenarios. In this case, return
|
||||
# the html version.
|
||||
if isinstance(cr, TestCursor):
|
||||
if isinstance(self.env.cr, TestCursor):
|
||||
return html
|
||||
|
||||
# Get the ir.actions.report.xml record we are working on.
|
||||
report = self._get_report_from_name(cr, uid, report_name)
|
||||
report = self._get_report_from_name(report_name)
|
||||
# Check if we have to save the report or if we have to get one from the db.
|
||||
save_in_attachment = self._check_attachment_use(cr, uid, ids, report)
|
||||
save_in_attachment = self._check_attachment_use(docids, report)
|
||||
# Get the paperformat associated to the report, otherwise fallback on the company one.
|
||||
if not report.paperformat_id:
|
||||
user = self.pool['res.users'].browse(cr, uid, uid)
|
||||
user = self.env['res.users'].browse(self.env.uid) # Rebrowse to avoid sudo user from self.env.user
|
||||
paperformat = user.company_id.paperformat_id
|
||||
else:
|
||||
paperformat = report.paperformat_id
|
||||
@@ -198,12 +186,12 @@ class Report(osv.Model):
|
||||
headerhtml = []
|
||||
contenthtml = []
|
||||
footerhtml = []
|
||||
irconfig_obj = self.pool['ir.config_parameter']
|
||||
base_url = irconfig_obj.get_param(cr, SUPERUSER_ID, 'report.url') or irconfig_obj.get_param(cr, SUPERUSER_ID, 'web.base.url')
|
||||
irconfig_obj = self.env['ir.config_parameter'].sudo()
|
||||
base_url = irconfig_obj.get_param('report.url') or irconfig_obj.get_param('web.base.url')
|
||||
|
||||
# Minimal page renderer
|
||||
view_obj = self.pool['ir.ui.view']
|
||||
render_minimal = partial(view_obj.render_template, cr, uid, 'report.minimal_layout', context=context)
|
||||
view_obj = self.env['ir.ui.view']
|
||||
render_minimal = partial(view_obj.render_template, 'report.minimal_layout')
|
||||
|
||||
# The received html report must be simplified. We convert it in a xml tree
|
||||
# in order to extract headers, bodies and footers.
|
||||
@@ -226,8 +214,8 @@ class Report(osv.Model):
|
||||
# must set a relation between report ids and report's content. We use the QWeb
|
||||
# branding in order to do so: searching after a node having a data-oe-model
|
||||
# attribute with the value of the current report model and read its oe-id attribute
|
||||
if ids and len(ids) == 1:
|
||||
reportid = ids[0]
|
||||
if docids and len(docids) == 1:
|
||||
reportid = docids[0]
|
||||
else:
|
||||
oemodelnode = node.find(".//*[@data-oe-model='%s']" % report.model)
|
||||
if oemodelnode is not None:
|
||||
@@ -257,33 +245,26 @@ class Report(osv.Model):
|
||||
|
||||
# Run wkhtmltopdf process
|
||||
return self._run_wkhtmltopdf(
|
||||
cr, uid, headerhtml, footerhtml, contenthtml, context.get('landscape'),
|
||||
headerhtml, footerhtml, contenthtml, context.get('landscape'),
|
||||
paperformat, specific_paperformat_args, save_in_attachment,
|
||||
context.get('set_viewport_size')
|
||||
)
|
||||
|
||||
@api.v8
|
||||
def get_pdf(self, records, report_name, html=None, data=None):
|
||||
return Report.get_pdf(self._model, self._cr, self._uid, records.ids,
|
||||
report_name, html=html, data=data, context=self._context)
|
||||
|
||||
@api.v7
|
||||
def get_action(self, cr, uid, ids, report_name, data=None, context=None):
|
||||
@api.model
|
||||
def get_action(self, docids, report_name, data=None):
|
||||
"""Return an action of type ir.actions.report.xml.
|
||||
|
||||
:param ids: Ids of the records to print (if not used, pass an empty list)
|
||||
:param report_name: Name of the template to generate an action for
|
||||
"""
|
||||
if ids:
|
||||
if not isinstance(ids, list):
|
||||
ids = [ids]
|
||||
context = dict(context or {}, active_ids=ids)
|
||||
if isinstance(docids, list):
|
||||
active_ids = docids
|
||||
else:
|
||||
active_ids = docids.ids
|
||||
|
||||
report_obj = self.pool['ir.actions.report.xml']
|
||||
idreport = report_obj.search(cr, uid, [('report_name', '=', report_name)], context=context)
|
||||
try:
|
||||
report = report_obj.browse(cr, uid, idreport[0], context=context)
|
||||
except IndexError:
|
||||
context = dict(self.env.context, active_ids=active_ids)
|
||||
report = self.env['ir.actions.report.xml'].with_context(context).search([('report_name', '=', report_name)])
|
||||
if not report:
|
||||
raise UserError(_("Bad Report Reference") + _("This report is not loaded into the database: %s.") % report_name)
|
||||
|
||||
return {
|
||||
@@ -296,16 +277,11 @@ class Report(osv.Model):
|
||||
'context': context,
|
||||
}
|
||||
|
||||
@api.v8
|
||||
def get_action(self, records, report_name, data=None):
|
||||
return Report.get_action(self._model, self._cr, self._uid, records.ids,
|
||||
report_name, data=data, context=self._context)
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Report generation helpers
|
||||
#--------------------------------------------------------------------------
|
||||
@api.v7
|
||||
def _check_attachment_use(self, cr, uid, ids, report):
|
||||
@api.model
|
||||
def _check_attachment_use(self, docids, report):
|
||||
""" Check attachment_use field. If set to true and an existing pdf is already saved, load
|
||||
this one now. Else, mark save it.
|
||||
"""
|
||||
@@ -314,12 +290,12 @@ class Report(osv.Model):
|
||||
save_in_attachment['loaded_documents'] = {}
|
||||
|
||||
if report.attachment:
|
||||
records = self.pool[report.model].browse(cr, uid, ids)
|
||||
filenames = self._attachment_filename(cr, uid, records, report)
|
||||
records = self.env[report.model].browse(docids)
|
||||
filenames = self._attachment_filename(records, report)
|
||||
attachments = None
|
||||
if report.attachment_use:
|
||||
attachments = self._attachment_stored(cr, uid, records, report, filenames=filenames)
|
||||
for record_id in ids:
|
||||
attachments = self._attachment_stored(records, report, filenames=filenames)
|
||||
for record_id in docids:
|
||||
filename = filenames[record_id]
|
||||
|
||||
# If the user has checked 'Reload from Attachment'
|
||||
@@ -344,11 +320,6 @@ class Report(osv.Model):
|
||||
|
||||
return save_in_attachment
|
||||
|
||||
@api.v8
|
||||
def _check_attachment_use(self, records, report):
|
||||
return Report._check_attachment_use(
|
||||
self._model, self._cr, self._uid, records.ids, report, context=self._context)
|
||||
|
||||
@api.model
|
||||
def _attachment_filename(self, records, report):
|
||||
return dict((record.id, eval(report.attachment, {'object': record, 'time': time})) for record in records)
|
||||
@@ -366,7 +337,8 @@ class Report(osv.Model):
|
||||
def _check_wkhtmltopdf(self):
|
||||
return wkhtmltopdf_state
|
||||
|
||||
def _run_wkhtmltopdf(self, cr, uid, headers, footers, bodies, landscape, paperformat, spec_paperformat_args=None, save_in_attachment=None, set_viewport_size=False):
|
||||
@api.model
|
||||
def _run_wkhtmltopdf(self, headers, footers, bodies, landscape, paperformat, spec_paperformat_args=None, save_in_attachment=None, set_viewport_size=False):
|
||||
"""Execute wkhtmltopdf as a subprocess in order to convert html given in input into a pdf
|
||||
document.
|
||||
|
||||
@@ -469,7 +441,7 @@ class Report(osv.Model):
|
||||
'res_id': reporthtml[0],
|
||||
}
|
||||
try:
|
||||
self.pool['ir.attachment'].create(cr, uid, attachment)
|
||||
self.env['ir.attachment'].create(attachment)
|
||||
except AccessError:
|
||||
_logger.info("Cannot save PDF report %r as attachment", attachment['name'])
|
||||
else:
|
||||
@@ -499,16 +471,16 @@ class Report(osv.Model):
|
||||
|
||||
return content
|
||||
|
||||
def _get_report_from_name(self, cr, uid, report_name):
|
||||
@api.model
|
||||
def _get_report_from_name(self, report_name):
|
||||
"""Get the first record of ir.actions.report.xml having the ``report_name`` as value for
|
||||
the field report_name.
|
||||
"""
|
||||
report_obj = self.pool['ir.actions.report.xml']
|
||||
report_obj = self.env['ir.actions.report.xml']
|
||||
qwebtypes = ['qweb-pdf', 'qweb-html']
|
||||
conditions = [('report_type', 'in', qwebtypes), ('report_name', '=', report_name)]
|
||||
context = self.pool['res.users'].context_get(cr, uid)
|
||||
idreport = report_obj.search(cr, uid, conditions, context=context)[0]
|
||||
return report_obj.browse(cr, uid, idreport, context=context)
|
||||
context = self.env['res.users'].context_get()
|
||||
return report_obj.with_context(context).search(conditions, limit=1)
|
||||
|
||||
def _build_wkhtmltopdf_args(self, paperformat, specific_paperformat_args=None):
|
||||
"""Build arguments understandable by wkhtmltopdf from a report.paperformat record.
|
||||
|
||||
@@ -1,137 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from functools import partial
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
|
||||
class report_paperformat(osv.Model):
|
||||
class report_paperformat(models.Model):
|
||||
_name = "report.paperformat"
|
||||
_description = "Allows customization of a report."
|
||||
|
||||
_columns = {'name': fields.char('Name', required=True),
|
||||
'default': fields.boolean('Default paper format ?'),
|
||||
'format': fields.selection([('A0', 'A0 5 841 x 1189 mm'),
|
||||
('A1', 'A1 6 594 x 841 mm'),
|
||||
('A2', 'A2 7 420 x 594 mm'),
|
||||
('A3', 'A3 8 297 x 420 mm'),
|
||||
('A4', 'A4 0 210 x 297 mm, 8.26 x 11.69 inches'),
|
||||
('A5', 'A5 9 148 x 210 mm'),
|
||||
('A6', 'A6 10 105 x 148 mm'),
|
||||
('A7', 'A7 11 74 x 105 mm'),
|
||||
('A8', 'A8 12 52 x 74 mm'),
|
||||
('A9', 'A9 13 37 x 52 mm'),
|
||||
('B0', 'B0 14 1000 x 1414 mm'),
|
||||
('B1', 'B1 15 707 x 1000 mm'),
|
||||
('B2', 'B2 17 500 x 707 mm'),
|
||||
('B3', 'B3 18 353 x 500 mm'),
|
||||
('B4', 'B4 19 250 x 353 mm'),
|
||||
('B5', 'B5 1 176 x 250 mm, 6.93 x 9.84 inches'),
|
||||
('B6', 'B6 20 125 x 176 mm'),
|
||||
('B7', 'B7 21 88 x 125 mm'),
|
||||
('B8', 'B8 22 62 x 88 mm'),
|
||||
('B9', 'B9 23 33 x 62 mm'),
|
||||
('B10', ':B10 16 31 x 44 mm'),
|
||||
('C5E', 'C5E 24 163 x 229 mm'),
|
||||
('Comm10E', 'Comm10E 25 105 x 241 mm, U.S. '
|
||||
'Common 10 Envelope'),
|
||||
('DLE', 'DLE 26 110 x 220 mm'),
|
||||
('Executive', 'Executive 4 7.5 x 10 inches, '
|
||||
'190.5 x 254 mm'),
|
||||
('Folio', 'Folio 27 210 x 330 mm'),
|
||||
('Ledger', 'Ledger 28 431.8 x 279.4 mm'),
|
||||
('Legal', 'Legal 3 8.5 x 14 inches, '
|
||||
'215.9 x 355.6 mm'),
|
||||
('Letter', 'Letter 2 8.5 x 11 inches, '
|
||||
'215.9 x 279.4 mm'),
|
||||
('Tabloid', 'Tabloid 29 279.4 x 431.8 mm'),
|
||||
('custom', 'Custom')],
|
||||
'Paper size',
|
||||
help="Select Proper Paper size"),
|
||||
'margin_top': fields.float('Top Margin (mm)'),
|
||||
'margin_bottom': fields.float('Bottom Margin (mm)'),
|
||||
'margin_left': fields.float('Left Margin (mm)'),
|
||||
'margin_right': fields.float('Right Margin (mm)'),
|
||||
'page_height': fields.integer('Page height (mm)'),
|
||||
'page_width': fields.integer('Page width (mm)'),
|
||||
'orientation': fields.selection([('Landscape', 'Landscape'),
|
||||
('Portrait', 'Portrait')],
|
||||
'Orientation'),
|
||||
'header_line': fields.boolean('Display a header line'),
|
||||
'header_spacing': fields.integer('Header spacing'),
|
||||
'dpi': fields.integer('Output DPI', required=True),
|
||||
'report_ids': fields.one2many('ir.actions.report.xml',
|
||||
'paperformat_id',
|
||||
'Associated reports',
|
||||
help="Explicitly associated reports")
|
||||
}
|
||||
name = fields.Char('Name', required=True)
|
||||
default = fields.Boolean('Default paper format ?')
|
||||
format = fields.Selection([
|
||||
('A0', 'A0 5 841 x 1189 mm'),
|
||||
('A1', 'A1 6 594 x 841 mm'),
|
||||
('A2', 'A2 7 420 x 594 mm'),
|
||||
('A3', 'A3 8 297 x 420 mm'),
|
||||
('A4', 'A4 0 210 x 297 mm, 8.26 x 11.69 inches'),
|
||||
('A5', 'A5 9 148 x 210 mm'),
|
||||
('A6', 'A6 10 105 x 148 mm'),
|
||||
('A7', 'A7 11 74 x 105 mm'),
|
||||
('A8', 'A8 12 52 x 74 mm'),
|
||||
('A9', 'A9 13 37 x 52 mm'),
|
||||
('B0', 'B0 14 1000 x 1414 mm'),
|
||||
('B1', 'B1 15 707 x 1000 mm'),
|
||||
('B2', 'B2 17 500 x 707 mm'),
|
||||
('B3', 'B3 18 353 x 500 mm'),
|
||||
('B4', 'B4 19 250 x 353 mm'),
|
||||
('B5', 'B5 1 176 x 250 mm, 6.93 x 9.84 inches'),
|
||||
('B6', 'B6 20 125 x 176 mm'),
|
||||
('B7', 'B7 21 88 x 125 mm'),
|
||||
('B8', 'B8 22 62 x 88 mm'),
|
||||
('B9', 'B9 23 33 x 62 mm'),
|
||||
('B10', ':B10 16 31 x 44 mm'),
|
||||
('C5E', 'C5E 24 163 x 229 mm'),
|
||||
('Comm10E', 'Comm10E 25 105 x 241 mm, U.S. '
|
||||
'Common 10 Envelope'),
|
||||
('DLE', 'DLE 26 110 x 220 mm'),
|
||||
('Executive', 'Executive 4 7.5 x 10 inches, '
|
||||
'190.5 x 254 mm'),
|
||||
('Folio', 'Folio 27 210 x 330 mm'),
|
||||
('Ledger', 'Ledger 28 431.8 x 279.4 mm'),
|
||||
('Legal', 'Legal 3 8.5 x 14 inches, '
|
||||
'215.9 x 355.6 mm'),
|
||||
('Letter', 'Letter 2 8.5 x 11 inches, '
|
||||
'215.9 x 279.4 mm'),
|
||||
('Tabloid', 'Tabloid 29 279.4 x 431.8 mm'),
|
||||
('custom', 'Custom')
|
||||
], 'Paper size', default='A4', help="Select Proper Paper size")
|
||||
margin_top = fields.Float('Top Margin (mm)', default=40)
|
||||
margin_bottom = fields.Float('Bottom Margin (mm)', default=20)
|
||||
margin_left = fields.Float('Left Margin (mm)', default=7)
|
||||
margin_right = fields.Float('Right Margin (mm)', default=7)
|
||||
page_height = fields.Integer('Page height (mm)', default=False)
|
||||
page_width = fields.Integer('Page width (mm)', default=False)
|
||||
orientation = fields.Selection([
|
||||
('Landscape', 'Landscape'),
|
||||
('Portrait', 'Portrait')
|
||||
], 'Orientation', default='Landscape')
|
||||
header_line = fields.Boolean('Display a header line', default=False)
|
||||
header_spacing = fields.Integer('Header spacing', default=35)
|
||||
dpi = fields.Integer('Output DPI', required=True, default=90)
|
||||
report_ids = fields.One2many('ir.actions.report.xml', 'paperformat_id', 'Associated reports', help="Explicitly associated reports")
|
||||
|
||||
def _check_format_or_page(self, cr, uid, ids, context=None):
|
||||
for paperformat in self.browse(cr, uid, ids, context=context):
|
||||
if paperformat.format != 'custom' and (paperformat.page_width or paperformat.page_height):
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_format_or_page, 'Error ! You cannot select a format AND specific '
|
||||
'page width/height.', ['format']),
|
||||
]
|
||||
|
||||
_defaults = {
|
||||
'format': 'A4',
|
||||
'margin_top': 40,
|
||||
'margin_bottom': 20,
|
||||
'margin_left': 7,
|
||||
'margin_right': 7,
|
||||
'page_height': False,
|
||||
'page_width': False,
|
||||
'orientation': 'Landscape',
|
||||
'header_line': False,
|
||||
'header_spacing': 35,
|
||||
'dpi': 90,
|
||||
}
|
||||
|
||||
|
||||
class res_company(osv.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
_columns = {'paperformat_id': fields.many2one('report.paperformat', 'Paper format')}
|
||||
|
||||
def init(self, cr):
|
||||
# set a default paperformat based on rml one.
|
||||
ref = partial(self.pool['ir.model.data'].xmlid_to_res_id, cr, SUPERUSER_ID)
|
||||
|
||||
ids = self.search(cr, SUPERUSER_ID, [('paperformat_id', '=', False)])
|
||||
for company in self.browse(cr, SUPERUSER_ID, ids):
|
||||
paperformat_id = {
|
||||
'a4': ref('report.paperformat_euro'),
|
||||
'us_letter': ref('report.paperformat_us'),
|
||||
}.get(company.rml_paper_format) or ref('report.paperformat_euro')
|
||||
|
||||
if paperformat_id:
|
||||
company.write({'paperformat_id': paperformat_id})
|
||||
|
||||
sup = super(res_company, self)
|
||||
if hasattr(sup, 'init'):
|
||||
sup.init(cr)
|
||||
|
||||
|
||||
class ir_actions_report(osv.Model):
|
||||
_inherit = 'ir.actions.report.xml'
|
||||
|
||||
def associated_view(self, cr, uid, ids, context):
|
||||
"""Used in the ir.actions.report.xml form view in order to search naively after the view(s)
|
||||
used in the rendering.
|
||||
"""
|
||||
try:
|
||||
report_name = self.browse(cr, uid, ids[0], context).report_name
|
||||
act_window_obj = self.pool.get('ir.actions.act_window')
|
||||
view_action = act_window_obj.for_xml_id(cr, uid, 'base', 'action_ui_view', context=context)
|
||||
view_action['domain'] = [('name', 'ilike', report_name.split('.')[1]), ('type', '=', 'qweb')]
|
||||
return view_action
|
||||
except:
|
||||
return False
|
||||
|
||||
_columns = {'paperformat_id': fields.many2one('report.paperformat', 'Paper format')}
|
||||
@api.constrains('format')
|
||||
def _check_format_or_page(self):
|
||||
if self.filtered(lambda x: x.format != 'custom' and (x.page_width or x.page_height)):
|
||||
raise ValidationError(_('Error ! You cannot select a format AND specific page width/height.'))
|
||||
|
||||
@@ -1,14 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import osv
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class ResCompany(osv.Model):
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
def _prepare_report_view_action(self, cr, uid, template):
|
||||
template_id = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, template)
|
||||
paperformat_id = fields.Many2one('report.paperformat', 'Paper format')
|
||||
|
||||
@api.model_cr
|
||||
def init(self):
|
||||
|
||||
# set a default paperformat based on rml one.
|
||||
|
||||
for company in self.search([('paperformat_id', '=', False)]):
|
||||
paperformat_euro = self.env.ref('report.paperformat_euro', False)
|
||||
paperformat_us = self.env.ref('report.paperformat_us', False)
|
||||
paperformat_id = {
|
||||
'a4': paperformat_euro and paperformat_euro.id or False,
|
||||
'us_letter': paperformat_us and paperformat_us.id or False,
|
||||
}.get(company.rml_paper_format) or paperformat_euro
|
||||
|
||||
if paperformat_id:
|
||||
company.write({'paperformat_id': paperformat_id})
|
||||
|
||||
sup = super(ResCompany, self)
|
||||
if hasattr(sup, 'init'):
|
||||
sup.init()
|
||||
|
||||
@api.model
|
||||
def _prepare_report_view_action(self, template):
|
||||
template_id = self.env.ref(template)
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'ir.ui.view',
|
||||
@@ -17,12 +39,14 @@ class ResCompany(osv.Model):
|
||||
'res_id': template_id,
|
||||
}
|
||||
|
||||
def edit_external_header(self, cr, uid, ids, context=None):
|
||||
return self._prepare_report_view_action(cr, uid, 'report.external_layout_header')
|
||||
@api.multi
|
||||
def edit_external_header(self):
|
||||
return self._prepare_report_view_action('report.external_layout_header')
|
||||
|
||||
def edit_external_footer(self, cr, uid, ids, context=None):
|
||||
return self._prepare_report_view_action(cr, uid, 'report.external_layout_footer')
|
||||
|
||||
def edit_internal_header(self, cr, uid, ids, context=None):
|
||||
return self._prepare_report_view_action(cr, uid, 'report.internal_layout')
|
||||
@api.multi
|
||||
def edit_external_footer(self):
|
||||
return self._prepare_report_view_action('report.external_layout_footer')
|
||||
|
||||
@api.multi
|
||||
def edit_internal_header(self):
|
||||
return self._prepare_report_view_action('report.internal_layout')
|
||||
|
||||
@@ -2,35 +2,33 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import logging
|
||||
|
||||
import openerp
|
||||
import openerp.tests
|
||||
import odoo
|
||||
import odoo.tests
|
||||
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@openerp.tests.common.at_install(False)
|
||||
@openerp.tests.common.post_install(True)
|
||||
class TestReports(openerp.tests.TransactionCase):
|
||||
@odoo.tests.common.at_install(False)
|
||||
@odoo.tests.common.post_install(True)
|
||||
class TestReports(odoo.tests.TransactionCase):
|
||||
def test_reports(self):
|
||||
registry, cr, uid = self.registry, self.cr, self.uid
|
||||
r_model = registry('ir.actions.report.xml')
|
||||
domain = [('report_type', 'like', 'qweb')]
|
||||
for r in r_model.browse(cr, uid, r_model.search(cr, uid, domain)):
|
||||
report_model = 'report.%s' % r.report_name
|
||||
for report in self.env['ir.actions.report.xml'].search(domain):
|
||||
report_model = 'report.%s' % report.report_name
|
||||
try:
|
||||
registry(report_model)
|
||||
self.env[report_model]
|
||||
except KeyError:
|
||||
# Only test the generic reports here
|
||||
_logger.info("testing report %s", r.report_name)
|
||||
report_model = registry(r.model)
|
||||
report_model_ids = report_model.search(cr, uid, [], limit=10)
|
||||
if not report_model_ids:
|
||||
_logger.info("no record found skipping report %s", r.report_name)
|
||||
if not r.multi:
|
||||
report_model_ids = report_model_ids[:1]
|
||||
# Only test the generic reports here
|
||||
_logger.info("testing report %s", report.report_name)
|
||||
report_model = self.env[report.model]
|
||||
report_records = report_model.search([], limit=10)
|
||||
if not report_records:
|
||||
_logger.info("no record found skipping report %s", report.report_name)
|
||||
if not report.multi:
|
||||
report_records = report_records[:1]
|
||||
|
||||
# Test report generation
|
||||
registry('report').get_html(cr, uid, report_model_ids, r.report_name)
|
||||
self.env['report'].get_html(report_records.ids, report.report_name)
|
||||
else:
|
||||
continue
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Adding a print_report_name field inside to the report action form view -->
|
||||
<record id="act_report_xml_view_inherit_report" model="ir.ui.view">
|
||||
<field name="name">ir.actions.report.xml.form.inherit</field>
|
||||
<field name="inherit_id" ref="base.act_report_xml_view" />
|
||||
<field name="model">ir.actions.report.xml</field>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='report_name']" position="after">
|
||||
<field name="print_report_name" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Adding a print_report_name field inside to the report action form view -->
|
||||
<record id="act_report_xml_view_inherit_report" model="ir.ui.view">
|
||||
<field name="name">ir.actions.report.xml.form.inherit</field>
|
||||
<field name="inherit_id" ref="base.act_report_xml_view" />
|
||||
<field name="model">ir.actions.report.xml</field>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='report_name']" position="after">
|
||||
<field name="print_report_name" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Add a paperformat and web button to the report form view -->
|
||||
<record id="act_report_xml_view_inherit" model="ir.ui.view">
|
||||
<field name="name">act_report_xml_view_inherit</field>
|
||||
<field name="inherit_id" ref="base.act_report_xml_view" />
|
||||
<field name="model">ir.actions.report.xml</field>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='attachment']" position="after">
|
||||
<field name="paperformat_id" attrs="{'invisible':[('report_type','not in',['qweb-pdf'])]}"/>
|
||||
<button
|
||||
type="object"
|
||||
class="oe_link"
|
||||
string="Search associated QWeb views"
|
||||
name="associated_view"
|
||||
attrs="{'invisible':[('report_type', 'not in', ['qweb-pdf', 'qweb-html'])]}"
|
||||
/>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="report.assets_common">
|
||||
<t t-call="web.less_helpers"/>
|
||||
|
||||
@@ -213,5 +212,4 @@
|
||||
</html>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
|
||||
<!-- report.paperformat -->
|
||||
<record id="paperformat_view_tree" model="ir.ui.view">
|
||||
@@ -71,26 +70,6 @@
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
|
||||
<!-- Add a paperformat and web button to the report form view -->
|
||||
<record id="act_report_xml_view_inherit" model="ir.ui.view">
|
||||
<field name="name">act_report_xml_view_inherit</field>
|
||||
<field name="inherit_id" ref="base.act_report_xml_view" />
|
||||
<field name="model">ir.actions.report.xml</field>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='attachment']" position="after">
|
||||
<field name="paperformat_id" attrs="{'invisible':[('report_type','not in',['qweb-pdf'])]}"/>
|
||||
<button
|
||||
type="object"
|
||||
class="oe_link"
|
||||
string="Search associated QWeb views"
|
||||
name="associated_view"
|
||||
attrs="{'invisible':[('report_type', 'not in', ['qweb-pdf', 'qweb-html'])]}"
|
||||
/>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Customize the company form view by adding paperformat field as well as demo reports -->
|
||||
<!-- Demo reports definition -->
|
||||
@@ -125,27 +104,4 @@
|
||||
string="Preview External Report"
|
||||
report_type="qweb-pdf"/>
|
||||
|
||||
<record id="reporting_settings_form_inherited" model="ir.ui.view">
|
||||
<field name="name">view_company_form_inherited</field>
|
||||
<field name="inherit_id" ref="base.view_company_form" />
|
||||
<field name="model">res.company</field>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//page[@name='report']/group[1]" position="inside">
|
||||
<group col="2" colspan="2">
|
||||
<field name="paperformat_id" />
|
||||
</group>
|
||||
<group col="1" colspan="2" groups="base.group_no_one">
|
||||
<button name="%(action_report_internalpreview)d" string="Preview Internal Report" type="action"/>
|
||||
<button name="%(action_report_externalpreview)d" string="Preview External Report" type="action"/>
|
||||
<button name="edit_external_header" string="Edit external header" type="object" class="oe_link"/>
|
||||
<button name="edit_external_footer" string="Edit external footer" type="object" class="oe_link"/>
|
||||
<button name="edit_internal_header" string="Edit internal header" type="object" class="oe_link"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="assets_backend" name="report assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/report/static/src/js/qwebactionmanager.js"></script>
|
||||
@@ -9,5 +8,4 @@
|
||||
<link rel="stylesheet" type="text/less" href="/report/static/src/less/report_backend.less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="reporting_settings_form_inherited" model="ir.ui.view">
|
||||
<field name="name">view_company_form_inherited</field>
|
||||
<field name="inherit_id" ref="base.view_company_form" />
|
||||
<field name="model">res.company</field>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//page[@name='report']/group[1]" position="inside">
|
||||
<group col="2" colspan="2">
|
||||
<field name="paperformat_id" />
|
||||
</group>
|
||||
<group col="1" colspan="2" groups="base.group_no_one">
|
||||
<button name="%(action_report_internalpreview)d" string="Preview Internal Report" type="action"/>
|
||||
<button name="%(action_report_externalpreview)d" string="Preview External Report" type="action"/>
|
||||
<button name="edit_external_header" string="Edit external header" type="object" class="oe_link"/>
|
||||
<button name="edit_external_footer" string="Edit external footer" type="object" class="oe_link"/>
|
||||
<button name="edit_internal_header" string="Edit internal header" type="object" class="oe_link"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -68,9 +68,6 @@ TODO:
|
||||
'demo': [
|
||||
"report/webkit_report_demo.xml",
|
||||
],
|
||||
'test': [
|
||||
"test/print.yml",
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
-
|
||||
Print the report_webkit demo report.
|
||||
-
|
||||
!python {model: ir.actions.report.xml}: |
|
||||
import os
|
||||
from openerp import tools
|
||||
from openerp.report import render_report
|
||||
ids = self.pool['ir.actions.report.xml'].search(cr, uid, [], {})
|
||||
data, format = render_report(cr, uid, ids, 'webkit.ir.actions.report.xml', {})
|
||||
if tools.config['test_report_directory']:
|
||||
file(os.path.join(tools.config['test_report_directory'], 'report_webkit_demo_report.'+format), 'wb+').write(data)
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import test_report_webkit
|
||||
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import os
|
||||
import odoo.tests
|
||||
from odoo import tools
|
||||
from odoo.report import render_report
|
||||
|
||||
class TestReportsWebkit(odoo.tests.TransactionCase):
|
||||
|
||||
def test_report_webkit(self):
|
||||
report_ids = self.env['ir.actions.report.xml'].search([]).ids
|
||||
data, format = render_report(self.env.cr, self.env.uid, report_ids, 'webkit.ir.actions.report.xml', {}, context=self.env.context)
|
||||
if tools.config['test_report_directory']:
|
||||
file(os.path.join(tools.config['test_report_directory'], 'report_webkit_demo_report.' + format), 'wb+').write(data)
|
||||
@@ -227,9 +227,9 @@ class IrActionsReportXml(models.Model):
|
||||
# yml tests originally written for RML reports.
|
||||
if tools.config['test_enable'] and not tools.config['test_report_directory']:
|
||||
# Only generate the pdf when a destination folder has been provided.
|
||||
return self.pool['report'].get_html(self._cr, self._uid, res_ids, report, data=data, context=self._context), 'html'
|
||||
return self.env['report'].get_html(res_ids, report, data=data), 'html'
|
||||
else:
|
||||
return self.pool['report'].get_pdf(self._cr, self._uid, res_ids, report, data=data, context=self._context), 'pdf'
|
||||
return self.env['report'].get_pdf(res_ids, report, data=data), 'pdf'
|
||||
else:
|
||||
return report.create(self._cr, self._uid, res_ids, data, context=self._context)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import openerp
|
||||
|
||||
from openerp import api
|
||||
import interface
|
||||
import print_xml
|
||||
import print_fnc
|
||||
@@ -18,5 +18,5 @@ def render_report(cr, uid, ids, name, data, context=None):
|
||||
"""
|
||||
Helper to call ``ir.actions.report.xml.render_report()``.
|
||||
"""
|
||||
registry = openerp.modules.registry.RegistryManager.get(cr.dbname)
|
||||
return registry['ir.actions.report.xml'].render_report(cr, uid, ids, name, data, context)
|
||||
env = api.Environment(cr, uid, context or {})
|
||||
return env['ir.actions.report.xml'].render_report(ids, name, data)
|
||||
|
||||
@@ -34,7 +34,8 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, re
|
||||
else:
|
||||
rname_s = rname
|
||||
_test_logger.info(" - Trying %s.create(%r)", rname, ids)
|
||||
res = openerp.report.render_report(cr, uid, ids, rname_s, data, context)
|
||||
|
||||
res = openerp.report.render_report(cr, uid, ids, rname_s, data, context=context)
|
||||
if not isinstance(res, tuple):
|
||||
raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \
|
||||
(rname, type(res)))
|
||||
|
||||
Reference in New Issue
Block a user