From b665478fa760909b74d4b4bae69700c796ecb72c Mon Sep 17 00:00:00 2001 From: Thomas Groutars Date: Sun, 29 Mar 2015 16:16:32 +0200 Subject: [PATCH 1/8] [FIX] py.js: unhandled prefix `not` closes #6129 --- addons/web/static/lib/py.js/lib/py.js | 4 ++-- addons/web/static/test/evals.js | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/addons/web/static/lib/py.js/lib/py.js b/addons/web/static/lib/py.js/lib/py.js index ed5657c8f3b..a940299a5c5 100644 --- a/addons/web/static/lib/py.js/lib/py.js +++ b/addons/web/static/lib/py.js/lib/py.js @@ -317,10 +317,10 @@ var py = {}; } else if (token in symbols) { var symbol; // transform 'not in' and 'is not' in a single token - if (token === 'in' && tokens[tokens.length-1].id === 'not') { + if (token === 'in' && tokens.length > 1 && tokens[tokens.length-1].id === 'not') { symbol = symbols['not in']; tokens.pop(); - } else if (token === 'not' && tokens[tokens.length-1].id === 'is') { + } else if (token === 'not' && tokens.length > 1 && tokens[tokens.length-1].id === 'is') { symbol = symbols['is not']; tokens.pop(); } else { diff --git a/addons/web/static/test/evals.js b/addons/web/static/test/evals.js index a85f973e874..ff97086b019 100644 --- a/addons/web/static/test/evals.js +++ b/addons/web/static/test/evals.js @@ -1,3 +1,16 @@ +openerp.testing.section('eval.basics', { + dependencies: ['web.core'], + setup: function (instance) { + instance.session.uid = 42; + } +}, function (test) { + test('not prefix', function (instance) { + ok(py.eval('not False')); + ok(py.eval('not foo', {foo: false})); + ok(py.eval('not a in b', {a: 3, b: [1, 2, 4, 8]})); + }); +}); + openerp.testing.section('eval.types', { dependencies: ['web.core'], setup: function (instance) { From c6d6ae8aec9dbb903c95c0381d940afb6358c66a Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 19 Nov 2015 14:59:44 +0100 Subject: [PATCH 2/8] [FIX] qweb: handle unicode tags and attributes closes #8895 --- addons/web/static/lib/qweb/qweb-test-utf8tags.xml | 8 ++++++++ openerp/addons/base/ir/ir_qweb.py | 11 ++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 addons/web/static/lib/qweb/qweb-test-utf8tags.xml diff --git a/addons/web/static/lib/qweb/qweb-test-utf8tags.xml b/addons/web/static/lib/qweb/qweb-test-utf8tags.xml new file mode 100644 index 00000000000..dd51635bab2 --- /dev/null +++ b/addons/web/static/lib/qweb/qweb-test-utf8tags.xml @@ -0,0 +1,8 @@ + + + + + + + ]]> + diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py index 3fc8313e727..c183a013430 100644 --- a/openerp/addons/base/ir/ir_qweb.py +++ b/openerp/addons/base/ir/ir_qweb.py @@ -116,8 +116,9 @@ class QWeb(orm.AbstractModel): _name = 'ir.qweb' _void_elements = frozenset([ - 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', - 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr']) + u'area', u'base', u'br', u'col', u'embed', u'hr', u'img', u'input', + u'keygen', u'link', u'menuitem', u'meta', u'param', u'source', + u'track', u'wbr']) _format_regex = re.compile( '(?:' # ruby-style pattern @@ -266,7 +267,7 @@ class QWeb(orm.AbstractModel): t_render = None template_attributes = {} for (attribute_name, attribute_value) in element.attrib.iteritems(): - attribute_name = str(attribute_name) + attribute_name = unicode(attribute_name) if attribute_name == "groups": cr = qwebcontext.get('request') and qwebcontext['request'].cr or None uid = qwebcontext.get('request') and qwebcontext['request'].uid or None @@ -325,7 +326,7 @@ class QWeb(orm.AbstractModel): except Exception: template = qwebcontext.get('__template__') raise_qweb_exception(message="Could not render element %r" % element.tag, node=element, template=template) - name = str(element.tag) + name = unicode(element.tag) inner = "".join(g_inner) trim = template_attributes.get("trim", 0) if trim == 0: @@ -344,7 +345,7 @@ class QWeb(orm.AbstractModel): for qwebcontext in (name, generated_attributes, inner, name) ) else: - return "<%s%s/>" % (name, generated_attributes) + return "<%s%s/>" % (name.encode("utf-8"), generated_attributes) def render_attribute(self, element, name, value, qwebcontext): return _build_attribute(name, value) From 8590f0445f6f2f72a7a665db07a572694b08905d Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 20 Nov 2015 11:24:02 +0100 Subject: [PATCH 3/8] [FIX] stock: `partner_id` field in incoming products list `partner_id` is not the `supplier` of the stock move, this is the destination address: `Optional address where goods are to be delivered, specifically used for allotment`. The supplier would be a related to the `partner_id` of the `picking_id`. Nevertheless, displaying the `supplier` in the `stock.move` list is not useful. You should use the pickign list for that matter. opw-656985 Closes #9219 --- addons/stock/stock_view.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 229a3dde9e7..a9de687c688 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1192,7 +1192,6 @@ - From 6188bc6e9d7936c01e70dde7dd3e4b8367010c6f Mon Sep 17 00:00:00 2001 From: Lionel Sausin Date: Fri, 20 Nov 2015 11:02:29 +0100 Subject: [PATCH 4/8] [DOC] Add words of caution about `sudo` Closes #9655 --- openerp/models.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/openerp/models.py b/openerp/models.py index 44f19052d7b..a3284f54093 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -5306,6 +5306,11 @@ class BaseModel(object): """ Returns a new version of this recordset attached to the provided environment + .. warning:: + The new environment will not benefit from the current + environment's data cache, so later data access may incur extra + delays while re-fetching from the database. + :type env: :class:`~openerp.api.Environment` """ return self._browse(env, self._ids) @@ -5315,6 +5320,25 @@ class BaseModel(object): Returns a new version of this recordset attached to the provided user. + + By default this returns a `SUPERUSER` recordset, where access control + and record rules are bypassed. + + .. note:: + Using `sudo` could cause data access to cross the boundaries of + record rules, possibly mixing records that are meant to be + isolated (e.g. records from different companies in multi-company + environments). + + It may lead to un-intuitive results in methods which select one + record among many - for example getting the default company, or + selecting a Bill of Materials. + + .. note:: + Because the record rules and access control will have to be + re-evaluated, the new recordset will not benefit from the current + environment's data cache, so later data access may incur extra + delays while re-fetching from the database. """ return self.with_env(self.env(user=user)) From 777f215edb7a0ce29f6724ad0792eb1d02b7d592 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 20 Nov 2015 14:29:29 +0100 Subject: [PATCH 5/8] [FIX] website_quote: quote email template When there is a quote template set on a sale order, the email sent by default is the email `Sales Order - Send by Email (Online Quote)`, and this since 5153b2d281fd1af5529c6347faf3c95da83571b2. Therefore, there is no point to override the content of the email template `Sales Order - Send by Email` to set the quotation link in the email template, since this is not this email which is being used for sales order with an online quotation template. Nevertheless, the link to the email quotation must be put in the `Sales Order - Send by Email (Online Quote)`, so the customer can access his online quotation directly from the confirmation email, as it was designed and done in the override of the `Sales Order - Send by Email`. opw-657060 --- .../data/website_quotation_data.xml | 123 +++--------------- 1 file changed, 17 insertions(+), 106 deletions(-) diff --git a/addons/website_quote/data/website_quotation_data.xml b/addons/website_quote/data/website_quotation_data.xml index 05802f6a8b7..32728b09f69 100644 --- a/addons/website_quote/data/website_quotation_data.xml +++ b/addons/website_quote/data/website_quotation_data.xml @@ -1,16 +1,24 @@ - - - - - + + + + + Sales Order - Send by Email (Online Quote) + ${(object.user_id.email or '')|safe} + ${object.company_id.name|safe} ${object.state in ('draft', 'sent') and 'Quotation' or 'Order'} (Ref ${object.name or 'n/a' }) + ${object.partner_invoice_id.id} + + + + ${(object.name or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''} + ${object.partner_id.lang} + +

Hello ${object.partner_id.name},

- +

Here is your ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'} from ${object.company_id.name}:

@@ -42,103 +50,6 @@ % endif -
-

If you have any question, do not hesitate to contact us.

-

Thank you for choosing ${object.company_id.name or 'us'}!

-
-
-
-

- ${object.company_id.name}

-
-
- - % if object.company_id.street: - ${object.company_id.street}
- % endif - % if object.company_id.street2: - ${object.company_id.street2}
- % endif - % if object.company_id.city or object.company_id.zip: - ${object.company_id.zip} ${object.company_id.city}
- % endif - % if object.company_id.country_id: - ${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}
- % endif -
- % if object.company_id.phone: -
- Phone:  ${object.company_id.phone} -
- % endif - % if object.company_id.website: - - %endif -

-
-
- ]]>
-
- -
- - - - - - Sales Order - Send by Email (Online Quote) - ${(object.user_id.email or '')|safe} - ${object.company_id.name|safe} ${object.state in ('draft', 'sent') and 'Quotation' or 'Order'} (Ref ${object.name or 'n/a' }) - ${object.partner_invoice_id.id} - - - - ${(object.name or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''} - ${object.partner_id.lang} - - - -

Hello ${object.partner_id.name},

- -

Here is your ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'} from ${object.company_id.name}:

- -

-   REFERENCES
-   Order number: ${object.name}
-   Order total: ${object.amount_total} ${object.pricelist_id.currency_id.name}
-   Order date: ${object.date_order}
- % if object.origin: -   Order reference: ${object.origin}
- % endif - % if object.client_order_ref: -   Your reference: ${object.client_order_ref}
- % endif - % if object.user_id: -   Your contact: ${object.user_id.name} - % endif -

- - % set signup_url = object.get_signup_url() - % if signup_url: -

- You can access this document and pay online via our Customer Portal: -

- View ${object.state in ('draft', 'sent') and 'Quotation' or 'Order'} - % endif - - % if object.paypal_url: -
-

It is also possible to directly pay with Paypal:

- - - - % endif -

If you have any question, do not hesitate to contact us.

Thank you for choosing ${object.company_id.name or 'us'}!

From 4eab4d786805ecfd9bdff0b013ff831c4984cc99 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Fri, 20 Nov 2015 15:18:27 +0100 Subject: [PATCH 6/8] [DOC] reports: clarification about styles * correct xpath to add style in report.styles * informations about style troubleshoot closes #9105 --- doc/howtos/backend.rst | 24 ++++++++++++++++++++++++ doc/reference/reports.rst | 11 ++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/howtos/backend.rst b/doc/howtos/backend.rst index 8c20909e953..ce56c70e975 100644 --- a/doc/howtos/backend.rst +++ b/doc/howtos/backend.rst @@ -1622,6 +1622,30 @@ http://localhost:8069/report/html/account.report_invoice/1 (if ``account`` is installed) and the PDF version through http://localhost:8069/report/pdf/account.report_invoice/1. +.. _reference/backend/reporting/printed-reports/pdf-without-styles: + +.. danger:: + + If it appears that your PDF report is missing the styles (i.e. the text + appears but the style/layout is different from the html version), probably + your wkhtmltopdf_ process cannot reach your web server to download them. + + If you check your server logs and see that the CSS styles are not being + downloaded when generating a PDF report, most surely this is the problem. + + The wkhtmltopdf_ process will use the ``web.base.url`` system parameter as + the *root path* to all linked files, but this parameter is automatically + updated each time the Administrator is logged in. If your server resides + behind some kind of proxy, that could not be reachable. You can fix this by + adding one of these system parameters: + + - ``report.url``, pointing to an URL reachable from your server + (probably ``http://localhost:8069`` or something similar). It will be + used for this particular purpose only. + + - ``web.base.url.freeze``, when set to ``True``, will stop the + automatic updates to ``web.base.url``. + .. exercise:: Create a report for the Session model For each session, it should display session's name, its start and end, diff --git a/doc/reference/reports.rst b/doc/reference/reports.rst index 92760e98e78..44b8741109a 100644 --- a/doc/reference/reports.rst +++ b/doc/reference/reports.rst @@ -205,19 +205,20 @@ Useful Remarks * Twitter Bootstrap and FontAwesome classes can be used in your report template * Local CSS can be put directly in the template - * Global CSS can be inserted in the main report layout by inheriting its template and inserting your CSS:: - +* If it appears that your PDF report is missing the styles, please check + :ref:`these instructions `. .. _reference/reports/paper_formats: From a92b55865296ed600f755f1462297b7e6a596e17 Mon Sep 17 00:00:00 2001 From: Julien Legros Date: Fri, 20 Nov 2015 15:01:42 +0100 Subject: [PATCH 7/8] [FIX] mail: update_notification --- addons/mail/update.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/mail/update.py b/addons/mail/update.py index 5644c45b027..485382f58b1 100644 --- a/addons/mail/update.py +++ b/addons/mail/update.py @@ -53,7 +53,9 @@ class publisher_warranty_contract(AbstractModel): "web_base_url": web_base_url, "apps": [app['name'] for app in apps], } - msg.update(self.pool.get("res.company").read(cr, uid, [1], ["name", "email", "phone"])[0]) + if user.partner_id.company_id: + company_id = user.partner_id.company_id.id + msg.update(self.pool.get("res.company").read(cr, uid, [company_id], ["name", "email", "phone"])[0]) return msg def _get_sys_logs(self, cr, uid): From 6f29cbe3ace5302781aa51d727b4358903efb373 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Mon, 23 Nov 2015 16:52:57 +0100 Subject: [PATCH 8/8] [FIX] website,ir_qweb: prevent inherit_branding for assets The attribute `data-oe-*` (`data-oe-id`, `data-oe-model`, ...) must not be added when rendering the assets, to avoid having different assets content, e.g. a different content for the assets_common, according if the user is signed in or not, if the user can edit the website or not. A different content for an assets according to the users rights or the user being signed in or not means that the assets are permanently re-written in the filestore, which is against the point of the assets. The content of the assets (assets_common) must not be different from time to time, it must always be the same (except when installing a new module, obviously). Adding the `data-oe` attributes was pointless for the assets anyway, and prevented having an identical content all the time, therefore rewritting the assets all the time in the filestore. opw-657046 --- addons/website/models/ir_ui_view.py | 9 +++++---- openerp/addons/base/ir/ir_qweb.py | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 9a3a84a9adb..35ce4cdd6a9 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -158,10 +158,11 @@ class view(osv.osv): qcontext.update(values) # in edit mode ir.ui.view will tag nodes - if qcontext.get('editable'): - context = dict(context, inherit_branding=True) - elif request.registry['res.users'].has_group(cr, uid, 'base.group_website_publisher'): - context = dict(context, inherit_branding_auto=True) + if not qcontext.get('rendering_bundle'): + if qcontext.get('editable'): + context = dict(context, inherit_branding=True) + elif request.registry['res.users'].has_group(cr, uid, 'base.group_website_publisher'): + context = dict(context, inherit_branding_auto=True) view_obj = request.website.get_template(id_or_xml_id) if 'main_object' not in qcontext: diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py index c183a013430..dd043a32a0c 100644 --- a/openerp/addons/base/ir/ir_qweb.py +++ b/openerp/addons/base/ir/ir_qweb.py @@ -1091,6 +1091,7 @@ class AssetsBundle(object): context = self.context.copy() context['inherit_branding'] = False + context['inherit_branding_auto'] = False context['rendering_bundle'] = True self.html = self.registry['ir.ui.view'].render(self.cr, self.uid, xmlid, context=context) self.parse()