From f7dfcd5d9816a2841c3ab3bb71feb3ab71520ae1 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 22 Jul 2014 16:38:52 +0200 Subject: [PATCH 01/44] [FIX] delivery: use unit of measure and not unit of stock to compute price of delivery The computation expects uom and it was wrongly passing uos qunatities. --- addons/delivery/delivery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py index c6deb3147a3..62d513c8bff 100644 --- a/addons/delivery/delivery.py +++ b/addons/delivery/delivery.py @@ -196,7 +196,7 @@ class delivery_grid(osv.osv): for line in order.order_line: if not line.product_id: continue - q = product_uom_obj._compute_qty(cr, uid, line.product_uom.id, line.product_uos_qty, line.product_id.uom_id.id) + q = product_uom_obj._compute_qty(cr, uid, line.product_uom.id, line.product_uom_qty, line.product_id.uom_id.id) total += line.price_subtotal or 0.0 weight += (line.product_id.weight or 0.0) * q volume += (line.product_id.volume or 0.0) * q From 9a20018166d0633c6b3cee2f13ec5c65c215df60 Mon Sep 17 00:00:00 2001 From: Hardik Ansodariya Date: Wed, 23 Jul 2014 10:03:40 +0200 Subject: [PATCH 02/44] [FIX] stock: allow same serial number for different products Bug lp:1222289, opw 597639 --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 3b1e70646f1..c14819f9f5f 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1487,7 +1487,7 @@ class stock_production_lot(osv.osv): 'product_id': lambda x, y, z, c: c.get('product_id', False), } _sql_constraints = [ - ('name_ref_uniq', 'unique (name, ref)', 'The combination of Serial Number and internal reference must be unique !'), + ('name_ref_uniq', 'unique (name, ref, product_id, company_id)', 'The combination of Serial Number, internal reference, Product and Company must be unique !'), ] def action_traceability(self, cr, uid, ids, context=None): """ It traces the information of a product From f9d43e83c67691f84f352b2594977a05cbf3d50c Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 23 Jul 2014 12:19:51 +0200 Subject: [PATCH 03/44] [FIX] web: correct rev 680f955 Missing backport of commit f652402 for buffered dataset Again, should not be forwardported --- addons/web/static/src/js/data.js | 28 ++++++++++++++++++++++----- addons/web/static/src/js/view_form.js | 15 ++++++-------- addons/web/static/src/js/view_list.js | 9 +++++---- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index ee24c481a3a..6ae69fbe67b 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -430,12 +430,30 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin, read_ids: function (ids, fields, options) { if (_.isEmpty(ids)) return $.Deferred().resolve([]); - + options = options || {}; - // TODO: reorder results to match ids list - return this._model.call('read', - [ids, fields || false], - {context: this.get_context(options.context)}); + var method = 'read'; + var ids_arg = ids; + var context = this.get_context(options.context); + if (options.check_access_rule === true){ + method = 'search_read'; + ids_arg = [['id', 'in', ids]]; + context = new instance.web.CompoundContext(context, {active_test: false}); + } + return this._model.call(method, + [ids_arg, fields || false], + {context: context}) + .then(function (records) { + if (records.length <= 1) { return records; } + var indexes = {}; + for (var i = 0; i < ids.length; i++) { + indexes[ids[i]] = i; + } + records.sort(function (a, b) { + return indexes[a.id] - indexes[b.id]; + }); + return records; + }); }, /** * Read a slice of the records represented by this DataSet, based on its diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 790fa88caa5..e91955e0a4e 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -957,20 +957,17 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } else { var fields = _.keys(self.fields_view.fields); fields.push('display_name'); - // Use of search_read instead of read to check if we can still read the record (security rules) - return self.dataset.call('search_read', [[['id', '=', self.dataset.ids[self.dataset.index]]], fields], + return self.dataset.read_index(fields, { context: { 'bin_size': true, 'future_display_name': true - } + }, + check_access_rule: true }).then(function(r) { - if (_.isEmpty(r)){ - self.do_action('history_back'); - } - else{ - self.trigger('load_record', r[0]); - } + self.trigger('load_record', r); + }).fail(function (){ + self.do_action('history_back'); }); } }); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 9d4c781b785..54f7946a9a3 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -529,13 +529,14 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi reload_record: function (record) { var self = this; // Use of search_read instead of read to check if we can still read the record (security rules) - return this.dataset.call('search_read', [ - [['id', '=', record.get('id')]], + return this.dataset.read_ids( + [record.get('id')], _.pluck(_(this.columns).filter(function (r) { return r.tag === 'field'; - }), 'name')] + }), 'name'), + {check_access_rule: true} ).done(function (records) { - var values = _.isEmpty(records) ? undefined : records[0]; + var values = records[0]; if (!values) { self.records.remove(record); return; From 67cca3f1e5489a81996d1ba20586749490d8665a Mon Sep 17 00:00:00 2001 From: Sandy Carter Date: Tue, 15 Jul 2014 16:17:36 -0400 Subject: [PATCH 04/44] [FIX] mail: display translated model name at record creation When a record is created, if it inherits from mail.thread, a message 'OBJECT created' is posted. 'created' is translated but the name of the model wasn't. This fix uses the name of the linked ir.model which is already a translatable field. lp:1262000, opw 611043 --- addons/mail/mail_thread.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 384fc6d6642..5691cb9ac73 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -253,7 +253,10 @@ class mail_thread(osv.AbstractModel): # automatic logging unless asked not to (mainly for various testing purpose) if not context.get('mail_create_nolog'): - self.message_post(cr, uid, thread_id, body=_('%s created') % (self._description), context=context) + ir_model_pool = self.pool['ir.model'] + ids = ir_model_pool.search(cr, uid, [('model', '=', self._name)], context=context) + name = ir_model_pool.read(cr, uid, ids, ['name'], context=context)[0]['name'] + self.message_post(cr, uid, thread_id, body=_('%s created') % name, context=context) # auto_subscribe: take values and defaults into account create_values = dict(values) From 5ae0b900f7c1fbbcf3a96d4affeac273f291153f Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Wed, 23 Jul 2014 15:43:59 +0200 Subject: [PATCH 05/44] [IMP] website_crm - add kwargs into create_lead function. That allow to get some fields which will be already join in the description from values to custom the behavior from create_lead function --- addons/website_crm/controllers/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website_crm/controllers/main.py b/addons/website_crm/controllers/main.py index c97dcd97c5a..2e24d318b73 100644 --- a/addons/website_crm/controllers/main.py +++ b/addons/website_crm/controllers/main.py @@ -26,7 +26,7 @@ class contactus(http.Controller): values.update(kwargs=kwargs.items()) return request.website.render("website.contactus", values) - def create_lead(self, request, values): + def create_lead(self, request, values, kwargs): """ Allow to be overrided """ return request.registry['crm.lead'].create(request.cr, SUPERUSER_ID, values, request.context) @@ -83,7 +83,7 @@ class contactus(http.Controller): post_description.append("%s: %s" % ("REFERER", environ.get("HTTP_REFERER"))) values['description'] += dict_to_str(_("Environ Fields: "), post_description) - lead_id = self.create_lead(request, values) + lead_id = self.create_lead(request, values, kwargs) if lead_id: for field_value in post_file: attachment_value = { From 330808b2cfadaa922994e92835b6b2df1f05c914 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 23 Jul 2014 16:21:53 +0200 Subject: [PATCH 06/44] [FIX] website.snippet: display snippet editor button inline insead of 2 lines for the small boxes --- addons/website/static/src/css/snippets.css | 7 +++++++ addons/website/static/src/css/snippets.sass | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/addons/website/static/src/css/snippets.css b/addons/website/static/src/css/snippets.css index a19baa33fd6..bd3ca21a367 100644 --- a/addons/website/static/src/css/snippets.css +++ b/addons/website/static/src/css/snippets.css @@ -356,6 +356,13 @@ } .oe_overlay .oe_overlay_options > .btn-group { left: -50%; + white-space: nowrap; +} +.oe_overlay .oe_overlay_options > .btn-group > a { + cursor: pointer; + display: inline-block; + float: none; + margin: 0 -3px; } .oe_overlay .oe_overlay_options .btn, .oe_overlay .oe_overlay_options a { cursor: pointer; diff --git a/addons/website/static/src/css/snippets.sass b/addons/website/static/src/css/snippets.sass index afdb261a2a5..bbdf34c8c61 100644 --- a/addons/website/static/src/css/snippets.sass +++ b/addons/website/static/src/css/snippets.sass @@ -264,6 +264,12 @@ z-index: 1002 > .btn-group left: -50% + white-space: nowrap + > a + cursor: pointer + display: inline-block + float: none + margin: 0 -3px .btn, a cursor: pointer .dropdown From 335e4a8cc34151a0369dc887efa2334f20b5c0b6 Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Wed, 23 Jul 2014 17:10:02 +0200 Subject: [PATCH 07/44] [FIX] website_blog: Add sanitize=False on content of blog to allow writer/author to insert some tricky code like form or JS --- addons/website_blog/models/website_blog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 37678e94aba..51f3ceed8c4 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -58,7 +58,7 @@ class BlogPost(osv.Model): 'tag_ids': fields.many2many( 'blog.tag', string='Tags', ), - 'content': fields.html('Content', translate=True), + 'content': fields.html('Content', translate=True, sanitize=False), # website control 'website_published': fields.boolean( 'Publish', help="Publish on the website" From 3d53306ccc4229ed6b1ee7c908f83c90acf24977 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 24 Jul 2014 08:50:48 +0200 Subject: [PATCH 08/44] [FIX] gamification: why is there a button here ? do you need a button ? I don't think so... --- addons/gamification/views/badge.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/gamification/views/badge.xml b/addons/gamification/views/badge.xml index 0b37e62051d..ad0aee76b07 100644 --- a/addons/gamification/views/badge.xml +++ b/addons/gamification/views/badge.xml @@ -40,7 +40,6 @@
From 1acf76bfc2b89af50ffe7f3e41c0b1c984ee418f Mon Sep 17 00:00:00 2001 From: Ravi Gohil Date: Mon, 9 Jun 2014 12:47:54 +0530 Subject: [PATCH 09/44] [FIX] purchase_analytic_plans: keep reference to analytic distribution Purchase orders created with invoice policy 'Based on incoming shipments' were not keeping the reference to the account analytic distribution when invoiced. opw 607577 --- .../purchase_analytic_plans/purchase_analytic_plans.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/addons/purchase_analytic_plans/purchase_analytic_plans.py b/addons/purchase_analytic_plans/purchase_analytic_plans.py index c80beddd20f..ae359f64b1a 100644 --- a/addons/purchase_analytic_plans/purchase_analytic_plans.py +++ b/addons/purchase_analytic_plans/purchase_analytic_plans.py @@ -42,4 +42,14 @@ class purchase_order(osv.osv): purchase_order() +class stock_picking(osv.osv): + _name='stock.picking' + _inherit='stock.picking' + + def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=None): + res = super(stock_picking, self)._prepare_invoice_line(cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=context) + if move_line.purchase_line_id and move_line.purchase_line_id.analytics_id: + res['analytics_id'] = move_line.purchase_line_id.analytics_id.id + return res + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 951a51df3f7696bf69a5bb0f3fc82a802219bf19 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Thu, 24 Jul 2014 12:21:34 +0200 Subject: [PATCH 10/44] [IMP] account: do not offer closed analytic accounts on invoices lp:1223922, opw 609656 --- addons/account/account_invoice_view.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index 2c768115e2a..f353877dd21 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -61,7 +61,7 @@ - + @@ -95,7 +95,7 @@ - + @@ -200,7 +200,7 @@ domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '=', 'other')]" on_change="onchange_account_id(product_id, parent.partner_id, parent.type, parent.fiscal_position,account_id)"/> + domain="[('type','!=','view'), ('company_id', '=', parent.company_id), ('state','not in',('close','cancelled'))]"/> @@ -357,7 +357,7 @@ domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '=', 'other')]" on_change="onchange_account_id(product_id, parent.partner_id, parent.type, parent.fiscal_position,account_id)"/> + domain="[('type','!=','view'), ('company_id', '=', parent.company_id), ('state','not in',('close','cancelled'))]"/> From 89e8626ab032a24c839ca2d87a3257f01b64d44a Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Thu, 24 Jul 2014 18:12:32 +0200 Subject: [PATCH 11/44] [FIX] website: catch exception on destroy of ckeditor to allow the modifications to be saved anyway --- addons/website/static/src/js/website.editor.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 93d75429352..a05c226a683 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -546,7 +546,13 @@ observer.disconnect(); var editor = this.rte.editor; var root = editor.element.$; - editor.destroy(); + try { + editor.destroy(); + } + catch(err) { + // Hack to avoid the lost of all changes because ckeditor fails in destroy + console.log("Error in editor.destroy() : " + err.toString() + "\n " + err.stack); + } // FIXME: select editables then filter by dirty? var defs = this.rte.fetch_editables(root) .filter('.oe_dirty') From de34d66860a4f586f456819974d0b38c81505cc2 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 24 Jul 2014 19:41:15 +0200 Subject: [PATCH 12/44] [FIX] project: remove state field from task analys The state has been replaced by stage_id in the view, so the state is no longer used Moreover, when doing an advanced search, the field state is visible and if used -> Traceback (because not available in the report sql table) opw-609984 --- addons/project/report/project_report.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/project/report/project_report.py b/addons/project/report/project_report.py index 5a473469b2d..30a61106d76 100644 --- a/addons/project/report/project_report.py +++ b/addons/project/report/project_report.py @@ -50,7 +50,6 @@ class report_project_task_user(osv.osv): 'nbr': fields.integer('# of tasks', readonly=True), 'priority': fields.selection([('4', 'Very Low'), ('3', 'Low'), ('2', 'Medium'), ('1', 'Urgent'), ('0', 'Very urgent')], string='Priority', readonly=True), - 'state': fields.selection([('draft', 'Draft'), ('open', 'In Progress'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')],'Status', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), 'partner_id': fields.many2one('res.partner', 'Contact', readonly=True), 'stage_id': fields.many2one('project.task.type', 'Stage'), From a5531c1d291786e76974e6bd6c2481fa5483e803 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 24 Jul 2014 20:42:21 +0200 Subject: [PATCH 13/44] [FIX] stock: do not set user_id on prepare_invoice_group The user_id is already set by the prepare_invoice method, which is called before the prepare_invoice_group (the user_id is already set, thus) Besides, _prepare_invoice is overriden in sale_stock, to set the picking sale order salesman as user_id, and, without this correct, grouping invoicse by partner re-set the user_id to uid, which is wrong. --- addons/stock/stock.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index c14819f9f5f..d363275b7fa 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1011,7 +1011,6 @@ class stock_picking(osv.osv): 'origin': (invoice.origin or '') + ', ' + (picking.name or '') + (picking.origin and (':' + picking.origin) or ''), 'comment': (comment and (invoice.comment and invoice.comment + "\n" + comment or comment)) or (invoice.comment and invoice.comment or ''), 'date_invoice': context.get('date_inv', False), - 'user_id': uid, } def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None): From e46794678536e3560c73625dbe0033f55498d085 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 25 Jul 2014 09:47:13 +0200 Subject: [PATCH 14/44] [FIX] website: iframe to google maps need the trailing slash, otherwise the path and the id are not separated (e.g.: '/members42') --- .../views/website_crm_partner_assign.xml | 2 +- addons/website_membership/views/website_membership.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml b/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml index 0dd5616070b..fd2aa909edc 100644 --- a/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml +++ b/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml @@ -117,7 +117,7 @@

World Map

diff --git a/addons/website_membership/views/website_membership.xml b/addons/website_membership/views/website_membership.xml index ca38873c0d0..7eccbfe5cee 100644 --- a/addons/website_membership/views/website_membership.xml +++ b/addons/website_membership/views/website_membership.xml @@ -106,7 +106,7 @@ From 10fce02eb0ee8c9eb9fa19c9ab0af8ef19b3ab2e Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 25 Jul 2014 10:57:30 +0200 Subject: [PATCH 15/44] [FIX] website_membership: access rules fixes When searching on memberships, we use domain clauses in the format 'partner.x = y' where partner is a many2one to res.partner. The object res.partner has strict security rules for public users and this search will return zero result if not done with SUPERUSER_ID. In addition, we need to access the list of products (membership_ids) in the domain to be sure we will retrieve only published membership (otherwise it would crash in the sort below). --- addons/website_membership/controllers/main.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/addons/website_membership/controllers/main.py b/addons/website_membership/controllers/main.py index a4932c1b46c..e8787978e43 100644 --- a/addons/website_membership/controllers/main.py +++ b/addons/website_membership/controllers/main.py @@ -50,7 +50,7 @@ class WebsiteMembership(http.Controller): ('partner.website_description', 'ilike', post_name)] # group by country, based on all customers (base domain) - membership_line_ids = membership_line_obj.search(cr, uid, base_line_domain, context=context) + membership_line_ids = membership_line_obj.search(cr, SUPERUSER_ID, base_line_domain, context=context) countries = partner_obj.read_group( cr, uid, [('member_lines', 'in', membership_line_ids), ("website_published", "=", True)], ["id", "country_id"], groupby="country_id", orderby="country_id", context=request.context) @@ -72,8 +72,14 @@ class WebsiteMembership(http.Controller): 'country_id': (0, _("All Countries")) }) + # format domain for group_by and memberships + membership_ids = product_obj.search(cr, uid, [('membership', '=', True)], order="website_sequence", context=context) + memberships = product_obj.browse(cr, uid, membership_ids, context=context) + # make sure we don't access to lines with unpublished membershipts + line_domain.append(('membership_id', 'in', membership_ids)) + # displayed membership lines - membership_line_ids = membership_line_obj.search(cr, uid, line_domain, context=context) + membership_line_ids = membership_line_obj.search(cr, SUPERUSER_ID, line_domain, context=context) membership_lines = membership_line_obj.browse(cr, uid, membership_line_ids, context=context) membership_lines.sort(key=lambda x: x.membership_id.website_sequence) partner_ids = [m.partner and m.partner.id for m in membership_lines] @@ -83,10 +89,6 @@ class WebsiteMembership(http.Controller): for partner in partner_obj.read(cr, openerp.SUPERUSER_ID, partner_ids, request.website.get_partner_white_list_fields(), context=context): partners_data[partner.get("id")] = partner - # format domain for group_by and memberships - membership_ids = product_obj.search(cr, uid, [('membership', '=', True)], order="website_sequence", context=context) - memberships = product_obj.browse(cr, uid, membership_ids, context=context) - # request pager for lines pager = request.website.pager(url="/members/", total=len(membership_line_ids), page=page, step=self._references_per_page, scope=7, url_args=post) From 93127099c9b90964ab1d1b1e99c7fe1532365570 Mon Sep 17 00:00:00 2001 From: dsabrinarg Date: Thu, 24 Jul 2014 22:31:12 -0500 Subject: [PATCH 16/44] [ADD] base_vat: add VAT validation for Peruvian localization. --- addons/base_vat/base_vat.py | 38 ++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index 374e910e6e6..5ecb321d3ba 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -63,6 +63,7 @@ _ref_vat = { 'mx': 'MXABC123456T1B', 'nl': 'NL123456782B90', 'no': 'NO123456785', + 'pe': 'PER10254824220 or PED10254824220', 'pl': 'PL1234567883', 'pt': 'PT123456789', 'ro': 'RO1234567897', @@ -219,7 +220,7 @@ class res_partner(osv.osv): return vat[7] == self._ie_check_char(vat[2:7] + vat[0] + vat[8]) return False - # Mexican VAT verification, contributed by + # Mexican VAT verification, contributed by Vauxoo # and Panos Christeas __check_vat_mx_re = re.compile(r"(?P[A-Za-z\xd1\xf1&]{3,4})" \ r"[ \-_]?" \ @@ -276,6 +277,41 @@ class res_partner(osv.osv): return False return check == int(vat[8]) + # Peruvian VAT validation, contributed by Vauxoo + def check_vat_pe(self, vat): + + vat_type,vat = vat and len(vat)>=2 and (vat[0], vat[1:]) or (False, False) + + if vat_type and vat_type.upper() == 'D': + #DNI + return True + elif vat_type and vat_type.upper() == 'R': + #verify RUC + factor = '5432765432' + sum = 0 + dig_check = False + if len(vat) != 11: + return False + try: + int(vat) + except ValueError: + return False + + for f in range(0,10): + sum += int(factor[f]) * int(vat[f]) + + subtraction = 11 - (sum % 11) + if subtraction == 10: + dig_check = 0 + elif subtraction == 11: + dig_check = 1 + else: + dig_check = subtraction + + return int(vat[10]) == dig_check + else: + return False + res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 133becd966ba1789f323487c4c2c67530965b1e5 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 25 Jul 2014 11:53:30 +0200 Subject: [PATCH 17/44] [FIX] ir_fields: allow accent on selection import If the selection label (not value) had accents, it wasn't possible to import it using the label having accents --- openerp/addons/base/ir/ir_fields.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index 0ed2cb3bf4e..f8a93730430 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -11,7 +11,8 @@ import pytz from openerp.osv import orm from openerp.tools.translate import _ from openerp.tools.misc import DEFAULT_SERVER_DATE_FORMAT,\ - DEFAULT_SERVER_DATETIME_FORMAT + DEFAULT_SERVER_DATETIME_FORMAT,\ + ustr from openerp.tools import html_sanitize REFERENCING_FIELDS = set([None, 'id', '.id']) @@ -256,6 +257,7 @@ class ir_fields_converter(orm.Model): # Or just copy context & remove lang? selection = selection(model, cr, uid, context=None) for item, label in selection: + label = ustr(label) labels = self._get_translations( cr, uid, ('selection', 'model', 'code'), label, context=context) labels.append(label) @@ -264,8 +266,8 @@ class ir_fields_converter(orm.Model): raise ValueError( _(u"Value '%s' not found in selection field '%%(field)s'") % ( value), { - 'moreinfo': [label or unicode(item) for item, label in selection - if label or item] + 'moreinfo': [_label or unicode(item) for item, _label in selection + if _label or item] }) From 46ef1356d6de734b96ab3f1d8a0892044989b5f9 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 25 Jul 2014 13:00:17 +0200 Subject: [PATCH 18/44] [ADD] safe_eval: UNPACK_SEQUENCE and Exception Allowing UNPACK_SEQUENCE allows the use of the "multi" assignation: a, b = [1,2] for a,b in items --- openerp/tools/safe_eval.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openerp/tools/safe_eval.py b/openerp/tools/safe_eval.py index 76987e278e6..0b9b2e7a8a3 100644 --- a/openerp/tools/safe_eval.py +++ b/openerp/tools/safe_eval.py @@ -67,7 +67,7 @@ _SAFE_OPCODES = _EXPR_OPCODES.union(set(opmap[x] for x in [ # New in Python 2.7 - http://bugs.python.org/issue4715 : 'JUMP_IF_FALSE_OR_POP', 'JUMP_IF_TRUE_OR_POP', 'POP_JUMP_IF_FALSE', 'POP_JUMP_IF_TRUE', 'SETUP_EXCEPT', 'END_FINALLY', - 'LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', + 'LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', 'UNPACK_SEQUENCE', 'LOAD_GLOBAL', # Only allows access to restricted globals ] if x in opmap)) @@ -278,7 +278,8 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal 'filter': filter, 'round': round, 'len': len, - 'set' : set + 'set' : set, + 'Exception': Exception, } ) try: From 98ddec4fb80431b3443dacaf6a5b7d9e960b1a56 Mon Sep 17 00:00:00 2001 From: Ravish Date: Fri, 25 Jul 2014 15:41:21 +0530 Subject: [PATCH 19/44] [ADD] sale: validity date in sale order report --- addons/sale/views/report_saleorder.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/sale/views/report_saleorder.xml b/addons/sale/views/report_saleorder.xml index 5c198c635a3..243004869e3 100644 --- a/addons/sale/views/report_saleorder.xml +++ b/addons/sale/views/report_saleorder.xml @@ -45,6 +45,10 @@ Salesperson:

+
+ Validity Date: +

+

Payment Term:

From b7e62ae3dccc825673e993467b251408c62149b8 Mon Sep 17 00:00:00 2001 From: Richard Mathot Date: Wed, 16 Jul 2014 14:50:19 +0200 Subject: [PATCH 20/44] [FIX] survey: minor view fixes --- addons/survey/views/survey_result.xml | 10 ++++------ addons/survey/views/survey_templates.xml | 14 +++++++------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/addons/survey/views/survey_result.xml b/addons/survey/views/survey_result.xml index 40a8a75fc28..c6be07f37d0 100644 --- a/addons/survey/views/survey_result.xml +++ b/addons/survey/views/survey_result.xml @@ -15,7 +15,7 @@

-

+
Filters Clear All Filters
@@ -34,6 +34,7 @@

+

@@ -56,7 +57,7 @@ -
+
@@ -275,10 +276,7 @@ - -
- +
diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml index 9ae973b9345..449a6b159cf 100644 --- a/addons/survey/views/survey_templates.xml +++ b/addons/survey/views/survey_templates.xml @@ -8,7 +8,7 @@

Thank you!

-
+
You scored points.
If you wish, you can review your answers.
@@ -70,7 +70,7 @@

-
+
Start Survey @@ -105,7 +105,7 @@