From 494f1686c3127658b38c845da3ffe0f6b634fa28 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Tue, 13 May 2014 17:56:10 +0200 Subject: [PATCH 001/119] Use NamedTemporaryFile instead of file and of deprecated mktemp. That way we ensure 2 files created at the exact same time will have a unique name --- addons/report_webkit/webkit_report.py | 44 +++++++++++---------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/addons/report_webkit/webkit_report.py b/addons/report_webkit/webkit_report.py index c6a30f5e579..20c71e3acbd 100644 --- a/addons/report_webkit/webkit_report.py +++ b/addons/report_webkit/webkit_report.py @@ -105,9 +105,10 @@ class WebKitParser(report_sxw): """Call webkit in order to generate pdf""" if not webkit_header: webkit_header = report_xml.webkit_header - tmp_dir = tempfile.gettempdir() - out_filename = tempfile.mktemp(suffix=".pdf", prefix="webkit.tmp.") - file_to_del = [out_filename] + out_filename = tempfile.NamedTemporaryFile(suffix=".pdf", + prefix="webkit.tmp.", + delete=False) + file_to_del = [out_filename.name] if comm_path: command = [comm_path] else: @@ -117,25 +118,15 @@ class WebKitParser(report_sxw): # default to UTF-8 encoding. Use to override. command.extend(['--encoding', 'utf-8']) if header : - head_file = file( os.path.join( - tmp_dir, - str(time.time()) + '.head.html' - ), - 'w' - ) - head_file.write(self._sanitize_html(header)) - head_file.close() + with tempfile.NamedTemporaryFile(suffix=".head.html", + delete=False) as head_file: + head_file.write(self._sanitize_html(header)) file_to_del.append(head_file.name) command.extend(['--header-html', head_file.name]) if footer : - foot_file = file( os.path.join( - tmp_dir, - str(time.time()) + '.foot.html' - ), - 'w' - ) - foot_file.write(self._sanitize_html(footer)) - foot_file.close() + with tempfile.NamedTemporaryFile(suffix=".foot.html", + delete=False) as foot_file: + foot_file.write(self._sanitize_html(footer)) file_to_del.append(foot_file.name) command.extend(['--footer-html', foot_file.name]) @@ -153,13 +144,13 @@ class WebKitParser(report_sxw): command.extend(['--page-size', str(webkit_header.format).replace(',', '.')]) count = 0 for html in html_list : - html_file = file(os.path.join(tmp_dir, str(time.time()) + str(count) +'.body.html'), 'w') - count += 1 - html_file.write(self._sanitize_html(html)) - html_file.close() + with tempfile.NamedTemporaryFile(suffix="%d.body.html" %count, + delete=False) as html_file: + count += 1 + html_file.write(self._sanitize_html(html)) file_to_del.append(html_file.name) command.append(html_file.name) - command.append(out_filename) + command.append(out_filename.name) stderr_fd, stderr_path = tempfile.mkstemp(text=True) file_to_del.append(stderr_path) try: @@ -176,9 +167,8 @@ class WebKitParser(report_sxw): if status : raise except_osv(_('Webkit error' ), _("The command 'wkhtmltopdf' failed with error code = %s. Message: %s") % (status, error_message)) - pdf_file = open(out_filename, 'rb') - pdf = pdf_file.read() - pdf_file.close() + with out_filename as pdf_file: + pdf = pdf_file.read() finally: if stderr_fd is not None: os.close(stderr_fd) From 4ed343455c3fb396e2a77630ec604cbeee5ce37e Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Wed, 14 May 2014 13:22:42 +0200 Subject: [PATCH 002/119] Fix incompatibility with Windows using tempfile. --- addons/report_webkit/webkit_report.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/report_webkit/webkit_report.py b/addons/report_webkit/webkit_report.py index 20c71e3acbd..e6ed123b8ad 100644 --- a/addons/report_webkit/webkit_report.py +++ b/addons/report_webkit/webkit_report.py @@ -105,10 +105,9 @@ class WebKitParser(report_sxw): """Call webkit in order to generate pdf""" if not webkit_header: webkit_header = report_xml.webkit_header - out_filename = tempfile.NamedTemporaryFile(suffix=".pdf", - prefix="webkit.tmp.", - delete=False) - file_to_del = [out_filename.name] + fd, out_filename = tempfile.mkstemp(suffix=".pdf", + prefix="webkit.tmp.") + file_to_del = [out_filename] if comm_path: command = [comm_path] else: @@ -150,7 +149,7 @@ class WebKitParser(report_sxw): html_file.write(self._sanitize_html(html)) file_to_del.append(html_file.name) command.append(html_file.name) - command.append(out_filename.name) + command.append(out_filename) stderr_fd, stderr_path = tempfile.mkstemp(text=True) file_to_del.append(stderr_path) try: @@ -167,8 +166,9 @@ class WebKitParser(report_sxw): if status : raise except_osv(_('Webkit error' ), _("The command 'wkhtmltopdf' failed with error code = %s. Message: %s") % (status, error_message)) - with out_filename as pdf_file: + with open(out_filename, 'rb') as pdf_file: pdf = pdf_file.read() + os.close(fd) finally: if stderr_fd is not None: os.close(stderr_fd) From 5597c25acf0b98b6e73f5e305c268c2a4da88d79 Mon Sep 17 00:00:00 2001 From: Sandy Carter Date: Fri, 16 May 2014 16:43:38 -0400 Subject: [PATCH 003/119] [FIX] Fix account_budget name unicode error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix bug https://bugs.launchpad.net/openobject-addons/+bug/1292245: Invoice budget's warning when crossovered budget lines are not related to any account will cause a UnicodeEncodeError if the account has unicode-only characters such as é. Make sure that the budget name is a unicode to avoid UnicodeEncodeError which happens when budget name contains UTF-8 characters. Signed-off-by: Sandy Carter --- addons/account_budget/account_budget.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/account_budget/account_budget.py b/addons/account_budget/account_budget.py index daec4ea0a2f..c20871ed65e 100644 --- a/addons/account_budget/account_budget.py +++ b/addons/account_budget/account_budget.py @@ -22,6 +22,7 @@ import datetime from openerp.osv import fields, osv +from openerp.tools import ustr from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp @@ -116,7 +117,7 @@ class crossovered_budget_lines(osv.osv): for line in self.browse(cr, uid, ids, context=context): acc_ids = [x.id for x in line.general_budget_id.account_ids] if not acc_ids: - raise osv.except_osv(_('Error!'),_("The Budget '%s' has no accounts!") % str(line.general_budget_id.name)) + raise osv.except_osv(_('Error!'),_("The Budget '%s' has no accounts!") % ustr(line.general_budget_id.name)) date_to = line.date_to date_from = line.date_from if context.has_key('wizard_date_from'): From 93238cd1cb68fcfc27fd6be8fd7d9a4eca1f2d0e Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 20 May 2014 20:23:25 +0200 Subject: [PATCH 004/119] [FIX] website: respect max_{width,height} for /website/image route --- addons/website/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 460f64147e8..ab6f6f08564 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -381,7 +381,7 @@ class Website(openerp.addons.web.controllers.main.Home): """ response = werkzeug.wrappers.Response() return request.registry['website']._image( - request.cr, request.uid, model, id, field, response) + request.cr, request.uid, model, id, field, response, max_width, max_height) #------------------------------------------------------ From 49657b28e6915c46342a509e7b4c1e62645e16d4 Mon Sep 17 00:00:00 2001 From: etenesaca Date: Tue, 20 May 2014 14:58:40 -0500 Subject: [PATCH 005/119] Now when a search is conducted in the fields and not m2o results have a message saying "No results to show" since the show nothing will display the user is confused --- addons/web/static/src/js/view_form.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 4c4ba6f004c..582ddd7597e 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3394,6 +3394,11 @@ instance.web.form.CompletionFieldMixin = { classname: 'oe_m2o_dropdown_option' }); } + else if (values.length == 0) + values.push({ + label: "
" + _t("No results to show...") + "
", + action: function() {}, + }); return values; }); From bd8b2e9002194c08f4828c9a29ef8af3bc2f64e1 Mon Sep 17 00:00:00 2001 From: etenesaca Date: Tue, 20 May 2014 21:16:52 -0500 Subject: [PATCH 006/119] Optimized search fields from m2o Added translation of the message Now this style of message in a CSS class and not use HTML tags --- addons/web/i18n/es.po | 7 +++++++ addons/web/static/src/css/base.css | 4 ++++ addons/web/static/src/js/view_form.js | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/addons/web/i18n/es.po b/addons/web/i18n/es.po index b43baf25b21..9be938168dc 100644 --- a/addons/web/i18n/es.po +++ b/addons/web/i18n/es.po @@ -1292,6 +1292,13 @@ msgstr "Agrupar por: %s" msgid "No data provided." msgstr "No se han facilitado datos" +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/view_form.js:3399 +#, python-format +msgid "No results to show..." +msgstr "No hay resultados para mostrar..." + #. module: web #. openerp-web #: code:addons/web/static/src/js/view_list.js:345 diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index f02dc3c7fd7..b6d12b38688 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -2409,6 +2409,10 @@ .openerp .oe_form_field_many2one input { padding-right: 13px; } +.openerp.ui-autocomplete li.oe_m2o_dropdown_option_no_results_to_show a { + font-style: italic; + text-align: center; +} .openerp.ui-autocomplete li.oe_m2o_dropdown_option a { font-style: italic; padding-left: 2em; diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 582ddd7597e..14cd0551fd4 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3396,8 +3396,9 @@ instance.web.form.CompletionFieldMixin = { } else if (values.length == 0) values.push({ - label: "
" + _t("No results to show...") + "
", + label: _t("No results to show..."), action: function() {}, + classname: 'oe_m2o_dropdown_option_no_results_to_show' }); return values; From f1a6ab5070226c1af615079c0b434c8c3b4dcbd3 Mon Sep 17 00:00:00 2001 From: Richard Mathot Date: Wed, 21 May 2014 10:00:08 +0200 Subject: [PATCH 007/119] [FIX] website_hr_recruitment: Hide unpublished job offers to portal users and employees --- .../website_hr_recruitment_security.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/addons/website_hr_recruitment/security/website_hr_recruitment_security.xml b/addons/website_hr_recruitment/security/website_hr_recruitment_security.xml index 792995ca606..5d47e69fead 100644 --- a/addons/website_hr_recruitment/security/website_hr_recruitment_security.xml +++ b/addons/website_hr_recruitment/security/website_hr_recruitment_security.xml @@ -11,6 +11,26 @@ + + Job Positions: Portal + + [('website_published', '=', True)] + + + + + + + + Job Positions: HR Officer + + [(1, '=', 1)] + + + + + + Job department: Public From b6a7402fdbddfe817fa36292e6f89e8659f9bdea Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 21 May 2014 11:20:37 +0200 Subject: [PATCH 008/119] [FIX] report: correct page numbering --- openerp/report/render/rml2pdf/trml2pdf.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index 91dfc9dd79b..00b119ac61f 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -104,7 +104,7 @@ class NumberedCanvas(canvas.Canvas): self.setFont("Helvetica", 8) self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40), " %(this)i / %(total)i" % { - 'this': self._pageNumber+1, + 'this': self._pageNumber, 'total': page_count, } ) @@ -1001,8 +1001,6 @@ class _rml_template(object): if story_cnt > 0: fis.append(platypus.PageBreak()) fis += r.render(node_story) - # Reset Page Number with new story tag - fis.append(PageReset()) story_cnt += 1 try: if self.localcontext and self.localcontext.get('internal_header',False): From 35c5e56718e1ce8ca3747f90ba5c06d8f9d20b1c Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 11:57:45 +0200 Subject: [PATCH 009/119] [FIX] address div more to the left on external reports --- addons/account/views/report_invoice.xml | 2 +- addons/account/views/report_overdue.xml | 2 +- addons/account_followup/views/report_followup.xml | 2 +- addons/hr_payroll/views/report_payslip.xml | 2 +- addons/lunch/views/report_lunchorder.xml | 2 +- addons/mrp_repair/views/report_mrprepairorder.xml | 2 +- addons/purchase/views/report_purchaseorder.xml | 2 +- addons/purchase/views/report_purchasequotation.xml | 2 +- addons/report/data/report_paperformat.xml | 2 +- addons/report_intrastat/views/report_intrastatinvoice.xml | 2 +- addons/sale/views/report_saleorder.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index 6c4b701c6cf..a250eb9ebf7 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -5,7 +5,7 @@
-
+
diff --git a/addons/account/views/report_overdue.xml b/addons/account/views/report_overdue.xml index bc522aa8b9d..df3934ff0de 100644 --- a/addons/account/views/report_overdue.xml +++ b/addons/account/views/report_overdue.xml @@ -5,7 +5,7 @@
-
+

diff --git a/addons/account_followup/views/report_followup.xml b/addons/account_followup/views/report_followup.xml index 6c79fe4cc55..c0d98e7bb28 100644 --- a/addons/account_followup/views/report_followup.xml +++ b/addons/account_followup/views/report_followup.xml @@ -7,7 +7,7 @@
-
+
diff --git a/addons/hr_payroll/views/report_payslip.xml b/addons/hr_payroll/views/report_payslip.xml index 5ac9dfa557e..b30cb089d1a 100644 --- a/addons/hr_payroll/views/report_payslip.xml +++ b/addons/hr_payroll/views/report_payslip.xml @@ -19,7 +19,7 @@ Address -
diff --git a/addons/lunch/views/report_lunchorder.xml b/addons/lunch/views/report_lunchorder.xml index 93d43f6521d..30401bc142b 100644 --- a/addons/lunch/views/report_lunchorder.xml +++ b/addons/lunch/views/report_lunchorder.xml @@ -8,7 +8,7 @@
-
+
diff --git a/addons/mrp_repair/views/report_mrprepairorder.xml b/addons/mrp_repair/views/report_mrprepairorder.xml index 0ea3f22167c..2897fee1fd9 100644 --- a/addons/mrp_repair/views/report_mrprepairorder.xml +++ b/addons/mrp_repair/views/report_mrprepairorder.xml @@ -22,7 +22,7 @@

VAT:

-
+
diff --git a/addons/purchase/views/report_purchaseorder.xml b/addons/purchase/views/report_purchaseorder.xml index c03e535ff75..bd1f1846cd5 100644 --- a/addons/purchase/views/report_purchaseorder.xml +++ b/addons/purchase/views/report_purchaseorder.xml @@ -23,7 +23,7 @@

VAT:

-
+
diff --git a/addons/purchase/views/report_purchasequotation.xml b/addons/purchase/views/report_purchasequotation.xml index 68e8995ddd8..7f6c8f5bb78 100644 --- a/addons/purchase/views/report_purchasequotation.xml +++ b/addons/purchase/views/report_purchasequotation.xml @@ -23,7 +23,7 @@

VAT:

-
+
diff --git a/addons/report/data/report_paperformat.xml b/addons/report/data/report_paperformat.xml index 275d65edd13..f05e0afb6f0 100644 --- a/addons/report/data/report_paperformat.xml +++ b/addons/report/data/report_paperformat.xml @@ -9,7 +9,7 @@ 0 Portrait 40 - 20 + 23 7 7 diff --git a/addons/report_intrastat/views/report_intrastatinvoice.xml b/addons/report_intrastat/views/report_intrastatinvoice.xml index c534f808c95..abf4bdd56ba 100644 --- a/addons/report_intrastat/views/report_intrastatinvoice.xml +++ b/addons/report_intrastat/views/report_intrastatinvoice.xml @@ -5,7 +5,7 @@
-
+
diff --git a/addons/sale/views/report_saleorder.xml b/addons/sale/views/report_saleorder.xml index c23e680e664..5c198c635a3 100644 --- a/addons/sale/views/report_saleorder.xml +++ b/addons/sale/views/report_saleorder.xml @@ -19,7 +19,7 @@

VAT:

-
+
From 4019b2b3345c044e41492404a2322c169b75a23e Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 12:56:56 +0200 Subject: [PATCH 010/119] [FIX] Report: do not raise when wkhtmltopdf returns a code 1. In most cases, it is due to some http requests which did not success *but* the pdf is still acceptable. Far from the best commit ever, but it avoids to completely crash when just a link to an image is wrong --- addons/report/models/report.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index fed6a2335ee..d744c917343 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -353,8 +353,6 @@ class Report(osv.Model): if paperformat: command_args.extend(self._build_wkhtmltopdf_args(paperformat, spec_paperformat_args)) - command_args.extend(['--load-error-handling', 'ignore']) - if landscape and '--orientation' in command_args: command_args_copy = list(command_args) for index, elem in enumerate(command_args_copy): @@ -417,7 +415,7 @@ class Report(osv.Model): if config['workers'] == 1: os.kill(ppid, signal.SIGTTOU) - if process.returncode != 0: + if process.returncode not in [0, 1]: raise osv.except_osv(_('Report (PDF)'), _('wkhtmltopdf failed with error code = %s. ' 'Message: %s') % (str(process.returncode), err)) From 6958d47694df0a5397b07c40b061c41e43046941 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 21 May 2014 12:57:28 +0200 Subject: [PATCH 011/119] [FIX] account_analytic_analysis: recurring invoices prepare and product_id_change product_id_change set the description with the same behavior as sale orders product_id_change set the price unit according to the pricelist _prepare_invoice is split into two sub methods, _prepare_invoice_data and _prepare_invoice_line _prepare_invoice actually prepare the invoice values instead of directly creating the invoice --- .../account_analytic_analysis.py | 62 ++++++++++++------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index 9f110ed78e6..76b68a7b1fa 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -62,22 +62,33 @@ class account_analytic_invoice_line(osv.osv): context = context or {} uom_obj = self.pool.get('product.uom') company_id = company_id or False - context.update({'company_id': company_id, 'force_company': company_id, 'pricelist_id': pricelist_id}) + local_context = dict(context, company_id=company_id, force_company=company_id, pricelist=pricelist_id) if not product: return {'value': {'price_unit': 0.0}, 'domain':{'product_uom':[]}} if partner_id: - part = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context) + part = self.pool.get('res.partner').browse(cr, uid, partner_id, context=local_context) if part.lang: - context.update({'lang': part.lang}) + local_context.update({'lang': part.lang}) result = {} - res = self.pool.get('product.product').browse(cr, uid, product, context=context) - result.update({'name': name or res.description or False,'uom_id': uom_id or res.uom_id.id or False, 'price_unit': price_unit or res.list_price or 0.0}) + res = self.pool.get('product.product').browse(cr, uid, product, context=local_context) + if price_unit is not False: + price = price_unit + elif pricelist_id: + price = res.price + else: + price = res.list_price + if not name: + name = self.pool.get('product.product').name_get(cr, uid, [res.id], context=local_context)[0][1] + if res.description_sale: + result['name'] += '\n'+res.description_sale + + result.update({'name': name or False,'uom_id': uom_id or res.uom_id.id or False, 'price_unit': price}) res_final = {'value':result} if result['uom_id'] != res.uom_id.id: - selected_uom = uom_obj.browse(cr, uid, result['uom_id'], context=context) + selected_uom = uom_obj.browse(cr, uid, result['uom_id'], context=local_context) new_price = uom_obj._compute_price(cr, uid, res.uom_id.id, res_final['value']['price_unit'], result['uom_id']) res_final['value']['price_unit'] = new_price return res_final @@ -645,12 +656,10 @@ class account_analytic_account(osv.osv): 'nodestroy': True, } - def _prepare_invoice(self, cr, uid, contract, context=None): + def _prepare_invoice_data(self, cr, uid, contract, context=None): context = context or {} - inv_obj = self.pool.get('account.invoice') journal_obj = self.pool.get('account.journal') - fpos_obj = self.pool.get('account.fiscal.position') if not contract.partner_id: raise osv.except_osv(_('No Customer Defined!'),_("You must first select a Customer for Contract %s!") % contract.name ) @@ -671,33 +680,36 @@ class account_analytic_account(osv.osv): elif contract.company_id: currency_id = contract.company_id.currency_id.id - inv_data = { - 'reference': contract.code or False, + invoice = { 'account_id': contract.partner_id.property_account_receivable.id, 'type': 'out_invoice', 'partner_id': contract.partner_id.id, 'currency_id': currency_id, 'journal_id': len(journal_ids) and journal_ids[0] or False, 'date_invoice': contract.recurring_next_date, - 'origin': contract.name, + 'origin': contract.code, 'fiscal_position': fpos and fpos.id, 'payment_term': partner_payment_term, 'company_id': contract.company_id.id or False, } - invoice_id = inv_obj.create(cr, uid, inv_data, context=context) + return invoice + def _prepare_invoice_lines(self, cr, uid, contract, fiscal_position_id, context=None): + fpos_obj = self.pool.get('account.fiscal.position') + fiscal_position = fpos_obj.browse(cr, uid, fiscal_position_id, context=context) + invoice_lines = [] for line in contract.recurring_invoice_line_ids: res = line.product_id account_id = res.property_account_income.id if not account_id: account_id = res.categ_id.property_account_income_categ.id - account_id = fpos_obj.map_account(cr, uid, fpos, account_id) + account_id = fpos_obj.map_account(cr, uid, fiscal_position, account_id) taxes = res.taxes_id or False - tax_id = fpos_obj.map_tax(cr, uid, fpos, taxes) + tax_id = fpos_obj.map_tax(cr, uid, fiscal_position, taxes) - invoice_line_vals = { + invoice_lines.append((0, 0, { 'name': line.name, 'account_id': account_id, 'account_analytic_id': contract.id, @@ -705,13 +717,14 @@ class account_analytic_account(osv.osv): 'quantity': line.quantity, 'uos_id': line.uom_id.id or False, 'product_id': line.product_id.id or False, - 'invoice_id' : invoice_id, 'invoice_line_tax_id': [(6, 0, tax_id)], - } - self.pool.get('account.invoice.line').create(cr, uid, invoice_line_vals, context=context) + })) + return invoice_lines - inv_obj.button_compute(cr, uid, [invoice_id], context=context) - return invoice_id + def _prepare_invoice(self, cr, uid, contract, context=None): + invoice = self._prepare_invoice_data(cr, uid, contract, context=context) + invoice['invoice_line'] = self._prepare_invoice_lines(cr, uid, contract, invoice['fiscal_position'], context=context) + return invoice def recurring_create_invoice(self, cr, uid, ids, context=None): return self._recurring_create_invoice(cr, uid, ids, context=context) @@ -721,6 +734,7 @@ class account_analytic_account(osv.osv): def _recurring_create_invoice(self, cr, uid, ids, automatic=False, context=None): context = context or {} + invoice_ids = [] current_date = time.strftime('%Y-%m-%d') if ids: contract_ids = ids @@ -728,8 +742,8 @@ class account_analytic_account(osv.osv): contract_ids = self.search(cr, uid, [('recurring_next_date','<=', current_date), ('state','=', 'open'), ('recurring_invoices','=', True), ('type', '=', 'contract')]) for contract in self.browse(cr, uid, contract_ids, context=context): try: - invoice_id = self._prepare_invoice(cr, uid, contract, context=context) - + invoice_values = self._prepare_invoice(cr, uid, contract, context=context) + invoice_ids.append(self.pool['account.invoice'].create(cr, uid, invoice_values, context=context)) next_date = datetime.datetime.strptime(contract.recurring_next_date or current_date, "%Y-%m-%d") interval = contract.recurring_interval if contract.recurring_rule_type == 'daily': @@ -747,7 +761,7 @@ class account_analytic_account(osv.osv): _logger.error(traceback.format_exc()) else: raise - return True + return invoice_ids class account_analytic_account_summary_user(osv.osv): _name = "account_analytic_analysis.summary.user" From 1745c738eeac326a06f31d2fc4ecd0e0f71d5f86 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 12:59:05 +0200 Subject: [PATCH 012/119] [FIX] Report: double the default height/width of barcode image to avoid a blurred/unusable barcode once integrated in a report --- addons/report/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/report/controllers/main.py b/addons/report/controllers/main.py index d3a683cccdc..800c10140b6 100644 --- a/addons/report/controllers/main.py +++ b/addons/report/controllers/main.py @@ -64,7 +64,7 @@ class ReportController(Controller): # Misc. route utils #------------------------------------------------------ @route(['/report/barcode', '/report/barcode//'], type='http', auth="user") - def report_barcode(self, type, value, width=300, height=50): + def report_barcode(self, type, value, width=600, height=100): """Contoller able to render barcode images thanks to reportlab. Samples: From 226579a80deac960b2345a8a7b47b683994deff8 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 13:01:42 +0200 Subject: [PATCH 013/119] [FIX] Report: removed psutil/signal/openerp worker crap --- addons/report/models/report.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index d744c917343..89979bb7220 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -20,15 +20,11 @@ ############################################################################## from openerp.osv import osv -from openerp.tools import config from openerp.tools.translate import _ from openerp.addons.web.http import request from openerp.tools.safe_eval import safe_eval as eval -import os import time -import psutil -import signal import base64 import logging import tempfile @@ -399,25 +395,15 @@ class Report(osv.Model): content_file.seek(0) try: - # If the server is running with only one worker, ask to create a secund to be able - # to serve the http request of wkhtmltopdf subprocess. - if config['workers'] == 1: - ppid = psutil.Process(os.getpid()).ppid - os.kill(ppid, signal.SIGTTIN) - wkhtmltopdf = command + command_args + command_arg_local wkhtmltopdf += [content_file.name] + [pdfreport.name] - process = subprocess.Popen(wkhtmltopdf, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + process = subprocess.Popen(wkhtmltopdf, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() - if config['workers'] == 1: - os.kill(ppid, signal.SIGTTOU) - if process.returncode not in [0, 1]: raise osv.except_osv(_('Report (PDF)'), - _('wkhtmltopdf failed with error code = %s. ' + _('Wkhtmltopdf failed with error code = %s. ' 'Message: %s') % (str(process.returncode), err)) # Save the pdf in attachment if marked From 654df600c1c2ec398506058ae6a0e83fa0555627 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 13:02:59 +0200 Subject: [PATCH 014/119] [FIX] Report: less verbose error message --- addons/report/models/report.py | 40 ++++++++++++++++------------------ 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index 89979bb7220..c76a6b72e0e 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -338,17 +338,20 @@ class Report(osv.Model): command_args = [] tmp_dir = tempfile.gettempdir() - # Passing the cookie to wkhtmltopdf in order to resolve URL. + # Passing the cookie to wkhtmltopdf in order to resolve internal links. try: if request: command_args.extend(['--cookie', 'session_id', request.session.sid]) except AttributeError: pass - # Display arguments + # Wkhtmltopdf arguments + command_args.extend(['--quiet']) # Less verbose error messages if paperformat: + # Convert the paperformat record into arguments command_args.extend(self._build_wkhtmltopdf_args(paperformat, spec_paperformat_args)) + # Force the landscape orientation if necessary if landscape and '--orientation' in command_args: command_args_copy = list(command_args) for index, elem in enumerate(command_args_copy): @@ -359,43 +362,38 @@ class Report(osv.Model): elif landscape and not '--orientation' in command_args: command_args.extend(['--orientation', 'landscape']) + # Execute WKhtmltopdf pdfdocuments = [] - # HTML to PDF thanks to WKhtmltopdf for index, reporthtml in enumerate(bodies): - command_arg_local = [] - pdfreport = tempfile.NamedTemporaryFile(suffix='.pdf', prefix='report.tmp.', - mode='w+b') - # Directly load the document if we have it + local_command_args = [] + pdfreport = tempfile.NamedTemporaryFile(suffix='.pdf', prefix='report.tmp.', mode='w+b') + + # Directly load the document if we already have it if save_in_attachment and save_in_attachment['loaded_documents'].get(reporthtml[0]): pdfreport.write(save_in_attachment['loaded_documents'].get(reporthtml[0])) pdfreport.seek(0) pdfdocuments.append(pdfreport) continue - # Header stuff + # Wkhtmltopdf handles header/footer as separate pages. Create them if necessary. if headers: - head_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.header.tmp.', - dir=tmp_dir, mode='w+') + head_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.header.tmp.', dir=tmp_dir, mode='w+') head_file.write(headers[index]) head_file.seek(0) - command_arg_local.extend(['--header-html', head_file.name]) - - # Footer stuff + local_command_args.extend(['--header-html', head_file.name]) if footers: - foot_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.footer.tmp.', - dir=tmp_dir, mode='w+') + foot_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.footer.tmp.', dir=tmp_dir, mode='w+') foot_file.write(footers[index]) foot_file.seek(0) - command_arg_local.extend(['--footer-html', foot_file.name]) + local_command_args.extend(['--footer-html', foot_file.name]) # Body stuff - content_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.body.tmp.', - dir=tmp_dir, mode='w+') + content_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.body.tmp.', dir=tmp_dir, mode='w+') content_file.write(reporthtml[1]) content_file.seek(0) try: - wkhtmltopdf = command + command_args + command_arg_local + wkhtmltopdf = command + command_args + local_command_args wkhtmltopdf += [content_file.name] + [pdfreport.name] process = subprocess.Popen(wkhtmltopdf, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -403,7 +401,7 @@ class Report(osv.Model): if process.returncode not in [0, 1]: raise osv.except_osv(_('Report (PDF)'), - _('Wkhtmltopdf failed with error code = %s. ' + _('Wkhtmltopdf failed (error code: %s). ' 'Message: %s') % (str(process.returncode), err)) # Save the pdf in attachment if marked @@ -429,7 +427,7 @@ class Report(osv.Model): except: raise - # Get and return the full pdf + # Return the entire document if len(pdfdocuments) == 1: content = pdfdocuments[0].read() pdfdocuments[0].close() From 58d3a6f3f7bf295a2328b557f8094811a67c9942 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 13:06:31 +0200 Subject: [PATCH 015/119] [FIX] Report: inform the user that he may not print a pdf report while his openerp is running with only one worker; adapt method to extract wkhtmltopdf version to also work on mac where the ouput of '--version' is different from gnu/linux binary --- addons/report/models/report.py | 23 +++++--- .../report/static/src/js/qwebactionmanager.js | 53 ++++++++++--------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index c76a6b72e0e..32752fa6e33 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -20,6 +20,7 @@ ############################################################################## from openerp.osv import osv +from openerp.tools import config from openerp.tools.translate import _ from openerp.addons.web.http import request from openerp.tools.safe_eval import safe_eval as eval @@ -48,15 +49,23 @@ try: ['wkhtmltopdf', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) except OSError: - _logger.error('You need wkhtmltopdf to print a pdf version of the reports.') + _logger.info('You need wkhtmltopdf to print a pdf version of the reports.') else: out, err = process.communicate() - version = out.splitlines()[1].strip() - version = version.split(' ')[1] - if LooseVersion(version) < LooseVersion('0.12.0'): - _logger.warning('Upgrade wkhtmltopdf to (at least) 0.12.0') - wkhtmltopdf_state = 'upgrade' - wkhtmltopdf_state = 'ok' + + for line in out.splitlines(): + line = line.strip() + if line.startswith('wkhtmltopdf 0.'): + version = line.split(' ')[1] + if LooseVersion(version) < LooseVersion('0.12.0'): + _logger.info('Upgrade wkhtmltopdf to (at least) 0.12.0') + wkhtmltopdf_state = 'upgrade' + else: + wkhtmltopdf_state = 'ok' + + if config['workers'] == 1: + _logger.info('You need to start OpenERP with at least two workers to print a pdf version of the reports.') + wkhtmltopdf_state = 'workers' class Report(osv.Model): diff --git a/addons/report/static/src/js/qwebactionmanager.js b/addons/report/static/src/js/qwebactionmanager.js index 7e55661be86..cb0f3921482 100644 --- a/addons/report/static/src/js/qwebactionmanager.js +++ b/addons/report/static/src/js/qwebactionmanager.js @@ -54,34 +54,35 @@ openerp.report = function(instance) { if (action.report_type == 'qweb-html') { window.open(report_url, '_blank', 'height=900,width=1280'); instance.web.unblockUI(); - } else { + } else if (action.report_type === 'qweb-pdf') { // Trigger the download of the pdf/controller report - - if (action.report_type == 'qweb-pdf') { - (wkhtmltopdf_state = wkhtmltopdf_state || openerp.session.rpc('/report/check_wkhtmltopdf')).then(function (presence) { - // Fallback of qweb-pdf if wkhtmltopdf is not installed - if (presence == 'install' && action.report_type == 'qweb-pdf') { - self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \ - system. The report will be shown in html.

\ - wkhtmltopdf.org'), true); - report_url = report_url.substring(12) - window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024'); - instance.web.unblockUI(); - return; - } else { - if (presence == 'upgrade') { - self.do_notify(_t('Report'), _t('You should upgrade your version of\ - Wkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\ - support for table-breaking between pages.

wkhtmltopdf.org'), true); - } - } - return trigger_download(self.session, response, c); - }); - } - else if (action.report_type == 'controller') { + (wkhtmltopdf_state = wkhtmltopdf_state || openerp.session.rpc('/report/check_wkhtmltopdf')).then(function (presence) { + // Fallback on html if wkhtmltopdf is not installed or if OpenERP is started with one worker + if (presence === 'install') { + self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \ +system. The report will be shown in html.

\ +wkhtmltopdf.org'), true); + report_url = report_url.substring(12) + window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024'); + instance.web.unblockUI(); + return; + } else if (presence === 'workers') { + self.do_notify(_t('Report'), _t('You need to start OpenERP with at least two \ +workers to print a pdf version of the reports.'), true); + report_url = report_url.substring(12) + window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024'); + instance.web.unblockUI(); + return; + } else if (presence === 'upgrade') { + self.do_notify(_t('Report'), _t('You should upgrade your version of\ + Wkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\ + support for table-breaking between pages.

wkhtmltopdf.org'), true); + } return trigger_download(self.session, response, c); - } + }); + } else if (action.report_type === 'controller') { + return trigger_download(self.session, response, c); } } else { return self._super(action, options); From b50421e551ef120e0fa77cddec9247fd1ac982ed Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 13:11:27 +0200 Subject: [PATCH 016/119] [FIX] ir_actions: adapt render_report when called in a tests/qweb report context to generate the pdf only if a directory has been provided --- openerp/addons/base/ir/ir_actions.py | 16 ++++++++++------ openerp/tools/test_reports.py | 3 +-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 4e177959792..8aa968a3b3a 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -41,6 +41,7 @@ import openerp.workflow _logger = logging.getLogger(__name__) + class actions(osv.osv): _name = 'ir.actions.actions' _table = 'ir_actions' @@ -129,9 +130,15 @@ class ir_actions_report_xml(osv.osv): Look up a report definition and render the report for the provided IDs. """ new_report = self._lookup_report(cr, name) - # in order to use current yml test files with qweb reports - if isinstance(new_report, (str, unicode)): - return self.pool['report'].get_pdf(cr, uid, res_ids, new_report, data=data, context=context), 'pdf' + + if isinstance(new_report, (str, unicode)): # Qweb report + # The only case where a QWeb report is rendered with this method occurs when running + # yml tests originally written for RML reports. + if openerp.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(cr, uid, res_ids, new_report, data=data, context=context), 'html' + else: + return self.pool['report'].get_pdf(cr, uid, res_ids, new_report, data=data, context=context), 'pdf' else: return new_report.create(cr, uid, res_ids, data, context) @@ -1170,7 +1177,4 @@ class ir_actions_act_client(osv.osv): } - - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py index c008c20ae29..305d2b0f115 100644 --- a/openerp/tools/test_reports.py +++ b/openerp/tools/test_reports.py @@ -87,8 +87,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, re if ('[[' in line) or ('[ [' in line): _logger.error("Report %s may have bad expression near: \"%s\".", rname, line[80:]) # TODO more checks, what else can be a sign of a faulty report? - elif res_format == 'foobar': - # TODO + elif res_format == 'html': pass else: _logger.warning("Report %s produced a \"%s\" chunk, cannot examine it", rname, res_format) From 2e760407e4df1d0f239c1bc3ad3f2517ce5014fd Mon Sep 17 00:00:00 2001 From: Richard Mathot Date: Wed, 21 May 2014 13:42:17 +0200 Subject: [PATCH 017/119] [FIX] survey: enable survey access to portal users instead of 404 --- addons/survey/security/ir.model.access.csv | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/survey/security/ir.model.access.csv b/addons/survey/security/ir.model.access.csv index 89c001ce44e..e49c976ea1f 100644 --- a/addons/survey/security/ir.model.access.csv +++ b/addons/survey/security/ir.model.access.csv @@ -1,11 +1,11 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_survey_public,survey.survey public,model_survey_survey,base.group_public,1,0,0,0 -access_survey_page_public,survey.page public,model_survey_page,base.group_public,1,0,0,0 -access_survey_question_public,survey.question public,model_survey_question,base.group_public,1,0,0,0 -access_survey_label_public,survey.label public,model_survey_label,base.group_public,1,0,0,0 -access_survey_user_input_public,survey.user_input public,model_survey_user_input,base.group_public,1,1,1,0 -access_survey_user_input_line_public,survey.user_input_line public,model_survey_user_input_line,base.group_public,1,1,1,0 -access_survey_stage_public,survey.stage public,model_survey_stage,base.group_public,1,0,0,0 +access_survey_public,survey.survey public,model_survey_survey,,1,0,0,0 +access_survey_page_public,survey.page public,model_survey_page,,1,0,0,0 +access_survey_question_public,survey.question public,model_survey_question,,1,0,0,0 +access_survey_label_public,survey.label public,model_survey_label,,1,0,0,0 +access_survey_user_input_public,survey.user_input public,model_survey_user_input,,1,1,1,0 +access_survey_user_input_line_public,survey.user_input_line public,model_survey_user_input_line,,1,1,1,0 +access_survey_stage_public,survey.stage public,model_survey_stage,,1,0,0,0 access_survey_user,survey.survey user,model_survey_survey,base.group_survey_user,1,0,0,0 access_survey_page_user,survey.page user,model_survey_page,base.group_survey_user,1,0,0,0 access_survey_question_user,survey.question user,model_survey_question,base.group_survey_user,1,0,0,0 From 1f97c40c9c109165caef58ee1a87f925b5c7d884 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 21 May 2014 14:05:18 +0200 Subject: [PATCH 018/119] [FIX] Report: get the wkhtmltopdf version in a cleaner way with a simple regex --- addons/report/models/report.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index 32752fa6e33..6d118021775 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -25,6 +25,7 @@ from openerp.tools.translate import _ from openerp.addons.web.http import request from openerp.tools.safe_eval import safe_eval as eval +import re import time import base64 import logging @@ -52,16 +53,12 @@ except OSError: _logger.info('You need wkhtmltopdf to print a pdf version of the reports.') else: out, err = process.communicate() - - for line in out.splitlines(): - line = line.strip() - if line.startswith('wkhtmltopdf 0.'): - version = line.split(' ')[1] - if LooseVersion(version) < LooseVersion('0.12.0'): - _logger.info('Upgrade wkhtmltopdf to (at least) 0.12.0') - wkhtmltopdf_state = 'upgrade' - else: - wkhtmltopdf_state = 'ok' + version = re.search('([0-9.]+)', out).group(0) + if LooseVersion(version) < LooseVersion('0.12.0'): + _logger.info('Upgrade wkhtmltopdf to (at least) 0.12.0') + wkhtmltopdf_state = 'upgrade' + else: + wkhtmltopdf_state = 'ok' if config['workers'] == 1: _logger.info('You need to start OpenERP with at least two workers to print a pdf version of the reports.') From abe5c803a0e36f18aec4cc56abc289f66329a749 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 21 May 2014 15:44:46 +0200 Subject: [PATCH 019/119] [IMP] account: support for partial reconciliation in aged partner balance When computing the aged partner balance, the partial reconciliation was not handled correctly. The reconciled amount should be removed from the original remaining amount instead of displaying two entries in the journal. eg: if invocie of 1000 in period 1 and payment of 300 in period 2, should only display +700 in period 1 instead of two entries --- .../report/account_aged_partner_balance.py | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/addons/account/report/account_aged_partner_balance.py b/addons/account/report/account_aged_partner_balance.py index 3b000e40592..b7c26120b48 100644 --- a/addons/account/report/account_aged_partner_balance.py +++ b/addons/account/report/account_aged_partner_balance.py @@ -159,7 +159,7 @@ class aged_trial_report(report_sxw.rml_parse, common_report_header): dates_query += ' < %s)' args_list += (form[str(i)]['stop'],) args_list += (self.date_from,) - self.cr.execute('''SELECT l.partner_id, SUM(l.debit-l.credit) + self.cr.execute('''SELECT l.partner_id, SUM(l.debit-l.credit), l.reconcile_partial_id FROM account_move_line AS l, account_account, account_move am WHERE (l.account_id = account_account.id) AND (l.move_id=am.id) AND (am.state IN %s) @@ -171,12 +171,24 @@ class aged_trial_report(report_sxw.rml_parse, common_report_header): AND account_account.active AND ''' + dates_query + ''' AND (l.date <= %s) - GROUP BY l.partner_id''', args_list) - t = self.cr.fetchall() - d = {} - for i in t: - d[i[0]] = i[1] - history.append(d) + GROUP BY l.partner_id, l.reconcile_partial_id''', args_list) + partners_partial = self.cr.fetchall() + partners_amount = dict((i[0],0) for i in partners_partial) + for partner_info in partners_partial: + if partner_info[2]: + # in case of partial reconciliation, we want to keep the left amount in the oldest period + self.cr.execute('''SELECT MIN(COALESCE(date_maturity,date)) FROM account_move_line WHERE reconcile_partial_id = %s''', (partner_info[2],)) + date = self.cr.fetchall() + if date and args_list[-3] <= date[0][0] <= args_list[-2]: + # partial reconcilation + self.cr.execute('''SELECT SUM(l.debit-l.credit) + FROM account_move_line AS l + WHERE l.reconcile_partial_id = %s''', (partner_info[2],)) + unreconciled_amount = self.cr.fetchall() + partners_amount[partner_info[0]] += unreconciled_amount[0][0] + else: + partners_amount[partner_info[0]] += partner_info[1] + history.append(partners_amount) for partner in partners: values = {} From b7c6b1cbca9a3ae0043bed40018bb88a8ebbb184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 21 May 2014 16:27:17 +0200 Subject: [PATCH 020/119] [FIX] website_mail: message description should effectively be limited to the first 30 characters. --- addons/website_mail/models/mail_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_mail/models/mail_message.py b/addons/website_mail/models/mail_message.py index 1e50611fa00..cff950f2962 100644 --- a/addons/website_mail/models/mail_message.py +++ b/addons/website_mail/models/mail_message.py @@ -34,7 +34,7 @@ class MailMessage(osv.Model): res[message.id] = message.subject else: plaintext_ct = html2plaintext(message.body) - res[message.id] = plaintext_ct + '%s' % (' [...]' if len(plaintext_ct) >= 20 else '') + res[message.id] = plaintext_ct[:30] + '%s' % (' [...]' if len(plaintext_ct) >= 30 else '') return res _columns = { From 52eb9cba89cc0d057f65b3f20e551ba6559226ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 21 May 2014 16:32:31 +0200 Subject: [PATCH 021/119] [IMP] website_mail_group: refactored layout of displayed mailing lists and their archive. Should be a bit more easy to use and understand. Todo: fix number of displayed thread / replies, and probably re-do the layout once somebody decides to change everything. --- addons/website_mail_group/controllers/main.py | 26 +- .../views/website_mail_group.xml | 376 +++++++++++------- 2 files changed, 261 insertions(+), 141 deletions(-) diff --git a/addons/website_mail_group/controllers/main.py b/addons/website_mail_group/controllers/main.py index 88eb1a7e9b7..4449a38f999 100644 --- a/addons/website_mail_group/controllers/main.py +++ b/addons/website_mail_group/controllers/main.py @@ -9,7 +9,8 @@ from openerp.addons.web.http import request class MailGroup(http.Controller): - _thread_per_page = 10 + _thread_per_page = 5 + _replies_per_page = 1 def _get_archives(self, group_id): MailMessage = request.registry['mail.message'] @@ -27,7 +28,7 @@ class MailGroup(http.Controller): def view(self, **post): cr, uid, context = request.cr, request.uid, request.context group_obj = request.registry.get('mail.group') - group_ids = group_obj.search(cr, uid, [], context=context) + group_ids = group_obj.search(cr, uid, [('alias_id', '!=', False), ('alias_id.alias_name', '!=', False)], context=context) values = {'groups': group_obj.browse(cr, uid, group_ids, context)} return request.website.render('website_mail_group.mail_groups', values) @@ -85,7 +86,28 @@ class MailGroup(http.Controller): 'message': message, 'group': group, 'mode': mode, + 'archives': self._get_archives(group.id), 'date_begin': date_begin, 'date_end': date_end, } return request.website.render('website_mail_group.group_message', values) + + @http.route( + '''/groups// - - - -