From 08416b2335f2657c0202d8879c2cf437b02b072f Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Mon, 23 May 2016 14:29:46 +0200 Subject: [PATCH 01/13] [FIX] account: partner_id set on a bank fee Used case: -Create several customer invoices and validate them -Register a payment without any partner_id and in a bank statement for an amount a bit lower than the total of the invoice (the difference is the paypal fees) -Reconcile the invoices with the payment and create a write-off for the paypal fees -When you close the bank statement, check the journal items, the paypal fees are automatically assigned with a partner. Fix: -When creating the account move line for the fee, if all the account move lines linked to the move are for different partners then you cannot determine the partner of the fee. opw:674822 --- addons/account/account_move_line.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index e7509edecdc..fe893b9ccbe 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -275,8 +275,9 @@ class account_move_line(osv.osv): #we propose to continue the same move by copying the ref, the name, the partner... move = move_obj.browse(cr, uid, move_id, context=context) data.setdefault('name', move.line_id[-1].name) + same_partner = len({l.partner_id for l in move.line_id}) == 1 for l in move.line_id: - data['partner_id'] = data.get('partner_id') or l.partner_id.id + data['partner_id'] = data.get('partner_id') or (same_partner and l.partner_id.id) data['ref'] = data.get('ref') or l.ref total += (l.debit or 0.0) - (l.credit or 0.0) From be48a1402cfcab733ce37910bc1b567b01f72747 Mon Sep 17 00:00:00 2001 From: Joren Van Onder Date: Wed, 25 May 2016 08:53:48 +0200 Subject: [PATCH 02/13] [FIX] hr_payroll: avoid infinite recursion The get_recursive_parent function seemingly depended on the ordering of the rule_categories recordset which happens to work fine in most cases because all data first defines the parent before defining the children rule categories. But if you happen to do it the other way around it won't work and it will infinitely call itself because: if rule_categories[0].parent_id: rule_categories = rule_categories[0].parent_id | rule_categories won't change the value of rule_categories[0]. opw-673222 (loosely related) --- .../hr_payroll/report/report_payslip_details.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/addons/hr_payroll/report/report_payslip_details.py b/addons/hr_payroll/report/report_payslip_details.py index f521cdb320d..7bfa1802ee4 100644 --- a/addons/hr_payroll/report/report_payslip_details.py +++ b/addons/hr_payroll/report/report_payslip_details.py @@ -37,13 +37,16 @@ class payslip_details_report(report_sxw.rml_parse): payslip_line = self.pool.get('hr.payslip.line') rule_cate_obj = self.pool.get('hr.salary.rule.category') - def get_recursive_parent(rule_categories): - if not rule_categories: - return [] - if rule_categories[0].parent_id: - rule_categories = rule_categories[0].parent_id | rule_categories - get_recursive_parent(rule_categories) - return rule_categories + def get_recursive_parent(current_rule_category, rule_categories = None): + if rule_categories: + rule_categories = current_rule_category | rule_categories + else: + rule_categories = current_rule_category + + if current_rule_category.parent_id: + return get_recursive_parent(current_rule_category.parent_id, rule_categories) + else: + return rule_categories res = [] result = {} From 97492a12a9f0975b80ebd43422aeebfb315dacb2 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 25 May 2016 12:34:20 +0200 Subject: [PATCH 03/13] [IMP] gamification: prevent misconfiguration Prevent selecting wrong field or models or computed fields Fixes #8545 --- addons/gamification/i18n/gamification.pot | 44 +++++++++++++++++++++-- addons/gamification/models/goal.py | 17 +++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/addons/gamification/i18n/gamification.pot b/addons/gamification/i18n/gamification.pot index 62def93f0e8..b722d230be8 100644 --- a/addons/gamification/i18n/gamification.pot +++ b/addons/gamification/i18n/gamification.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-01-21 14:08+0000\n" -"PO-Revision-Date: 2015-01-21 14:08+0000\n" +"POT-Creation-Date: 2016-05-25 12:58+0000\n" +"PO-Revision-Date: 2016-05-25 12:58+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -562,6 +562,18 @@ msgstr "" msgid "Display Mode" msgstr "" +#. module: gamification +#: field:gamification.badge,display_name:0 +#: field:gamification.badge.user,display_name:0 +#: field:gamification.badge.user.wizard,display_name:0 +#: field:gamification.challenge,display_name:0 +#: field:gamification.challenge.line,display_name:0 +#: field:gamification.goal,display_name:0 +#: field:gamification.goal.definition,display_name:0 +#: field:gamification.goal.wizard,display_name:0 +msgid "Display Name" +msgstr "" + #. module: gamification #: field:gamification.goal.definition,display_mode:0 msgid "Displayed as" @@ -967,6 +979,18 @@ msgstr "" msgid "Last Message Date" msgstr "" +#. module: gamification +#: field:gamification.badge,__last_update:0 +#: field:gamification.badge.user,__last_update:0 +#: field:gamification.badge.user.wizard,__last_update:0 +#: field:gamification.challenge,__last_update:0 +#: field:gamification.challenge.line,__last_update:0 +#: field:gamification.goal,__last_update:0 +#: field:gamification.goal.definition,__last_update:0 +#: field:gamification.goal.wizard,__last_update:0 +msgid "Last Modified on" +msgstr "" + #. module: gamification #: field:gamification.challenge,last_report_date:0 msgid "Last Report Date" @@ -1585,6 +1609,22 @@ msgstr "" msgid "The maximum number of time this badge can be sent per month per person." msgstr "" +#. module: gamification +#: code:addons/gamification/models/goal.py:160 +#, python-format +msgid "The model configuration for the definition %s seems incorrect, please check it.\n" +"\n" +"%s not found" +msgstr "" + +#. module: gamification +#: code:addons/gamification/models/goal.py:158 +#, python-format +msgid "The model configuration for the definition %s seems incorrect, please check it.\n" +"\n" +"%s not stored" +msgstr "" + #. module: gamification #: help:gamification.goal.definition,model_id:0 msgid "The model object for the field to evaluate" diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index ad37762d10b..a63431a83c4 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -148,18 +148,31 @@ class gamification_goal_definition(osv.Model): raise osv.except_osv(_('Error!'),_("The domain for the definition %s seems incorrect, please check it.\n\n%s" % (definition.name, msg))) return True + def _check_model_validity(self, cr, uid, ids, context=None): + """ make sure the selected field and model are usable""" + for definition in self.browse(cr, uid, ids, context=context): + try: + model = self.pool[definition.model_id.model] + field = model._fields[definition.field_id.name] + if not field.store: + raise UserError(_("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not stored") % (definition.name, definition.field_id.name)) + except KeyError, e: + raise UserError(_("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not found") % (definition.name, e.message)) + def create(self, cr, uid, vals, context=None): res_id = super(gamification_goal_definition, self).create(cr, uid, vals, context=context) if vals.get('computation_mode') in ('count', 'sum'): self._check_domain_validity(cr, uid, [res_id], context=context) - + if vals.get('field_id'): + self._check_model_validity(cr, uid, [res_id], context=context) return res_id def write(self, cr, uid, ids, vals, context=None): res = super(gamification_goal_definition, self).write(cr, uid, ids, vals, context=context) if vals.get('computation_mode', 'count') in ('count', 'sum') and (vals.get('domain') or vals.get('model_id')): self._check_domain_validity(cr, uid, ids, context=context) - + if vals.get('field_id') or vals.get('model_id') or vals.get('batch_mode'): + self._check_model_validity(cr, uid, ids, context=context) return res def on_change_model_id(self, cr, uid, ids, model_id, context=None): From 4c7a9bdac4850674c47253bde432d020953e66de Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Wed, 25 May 2016 14:54:00 +0200 Subject: [PATCH 04/13] [FIX] web: raise a warning for bad domain When a user wrote a wrong value in char_domain field it should raise a warning message instead of a traceback. Backport of b3a88b6ed846a13c0cd07cc25ea49bccbdf84aa8 opw:676783 --- addons/web/i18n/web.pot | 14 ++++++++++++++ addons/web/static/src/js/view_form.js | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/addons/web/i18n/web.pot b/addons/web/i18n/web.pot index 6522ed569ce..3217d20f3fe 100644 --- a/addons/web/i18n/web.pot +++ b/addons/web/i18n/web.pot @@ -1073,6 +1073,13 @@ msgstr "" msgid "Error" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/views/form_widgets.js:2600 +#, python-format +msgid "Error: Bad domain" +msgstr "" + #. module: web #: code:addons/web/controllers/main.py:764 #: code:addons/web/controllers/main.py:805 @@ -2318,6 +2325,13 @@ msgstr "" msgid "The database has been duplicated." msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/views/form_widgets.js:2600 +#, python-format +msgid "The domain is wrong." +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/view_form.js:5637 diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index cdf73ee06ae..6588340e4d7 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2593,7 +2593,13 @@ instance.web.form.FieldCharDomain = instance.web.form.AbstractField.extend(insta this.$el.html(instance.web.qweb.render("FieldCharDomain", {widget: this})); if (this.get('value')) { var model = this.options.model || this.field_manager.get_field_value(this.options.model_field); - var domain = instance.web.pyeval.eval('domain', this.get('value')); + try{ + var domain = pyeval.eval('domain', this.get('value')); + } + catch(e){ + this.do_warn(_t('Error: Bad domain'), _t('The domain is wrong.')); + return; + } var ds = new instance.web.DataSetStatic(self, model, self.build_context()); ds.call('search_count', [domain, self.build_context()]).then(function (results) { $('.oe_domain_count', self.$el).text(results + _t(' records selected')); From 4176030cd3f0ab8895beb7a6634d57a145e44167 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 25 May 2016 18:07:05 +0200 Subject: [PATCH 05/13] [FIX] calandar: all day events email notification When sending a notification email to an event attendee for an all day event, the timezone must be ignored as the `start` and `stop` datetime are stored as the day date + '00:00:00'. If the timezone is applied, for users being in a negative timezone (such as an American timezone), the day displayed would be the day just before. opw-677019 --- addons/calendar/calendar_data.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/addons/calendar/calendar_data.xml b/addons/calendar/calendar_data.xml index 787933610ad..710524b678e 100644 --- a/addons/calendar/calendar_data.xml +++ b/addons/calendar/calendar_data.xml @@ -107,11 +107,11 @@
-
${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz)}
+
${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz if not object.event_id.allday else None)}
- ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz)} + ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz if not object.event_id.allday else None)}
-
${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz)}
+
${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz if not object.event_id.allday else None)}
${not object.event_id.allday and object.event_id.get_interval(object.event_id.start, 'time', tz=object.partner_id.tz) or ''}
@@ -240,11 +240,11 @@
-
${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz)}
+
${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz if not object.event_id.allday else None)}
- ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz)} + ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz if not object.event_id.allday else None)}
-
${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz)}
+
${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz if not object.event_id.allday else None)}
${not object.event_id.allday and object.event_id.get_interval(object.event_id.start, 'time', tz=object.partner_id.tz) or ''}
@@ -372,11 +372,11 @@
-
${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz)}
+
${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz if not object.event_id.allday else None)}
- ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz)} + ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz if not object.event_id.allday else None)}
-
${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz)}
+
${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz if not object.event_id.allday else None)}
${not object.event_id.allday and object.event_id.get_interval(object.event_id.start, 'time', tz=object.partner_id.tz) or ''}
From 9772bbef07e2f13a85faf7f6dc737d7c8be8119c Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Wed, 25 May 2016 23:38:28 +0200 Subject: [PATCH 06/13] [FIX] web: fix backport #4c7a9bd --- addons/web/static/src/js/view_form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 6588340e4d7..27e201b2e3b 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2594,7 +2594,7 @@ instance.web.form.FieldCharDomain = instance.web.form.AbstractField.extend(insta if (this.get('value')) { var model = this.options.model || this.field_manager.get_field_value(this.options.model_field); try{ - var domain = pyeval.eval('domain', this.get('value')); + var domain = instance.web.pyeval.eval('domain', this.get('value')); } catch(e){ this.do_warn(_t('Error: Bad domain'), _t('The domain is wrong.')); From a4687c6e42a7b0ec6b8d98dc2af7fe2d1c3272d0 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 26 May 2016 08:29:39 +0200 Subject: [PATCH 07/13] [FIX] gamification: bad backport to 8.0 UserError was defined in version 9, not 8 --- addons/gamification/models/goal.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index a63431a83c4..969d4321bab 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -155,9 +155,11 @@ class gamification_goal_definition(osv.Model): model = self.pool[definition.model_id.model] field = model._fields[definition.field_id.name] if not field.store: - raise UserError(_("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not stored") % (definition.name, definition.field_id.name)) + raise osv.except_osv(_('Error!'), + _("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not stored") % (definition.name, definition.field_id.name)) except KeyError, e: - raise UserError(_("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not found") % (definition.name, e.message)) + raise osv.except_osv(_('Error!'), + _("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not found") % (definition.name, e.message)) def create(self, cr, uid, vals, context=None): res_id = super(gamification_goal_definition, self).create(cr, uid, vals, context=context) From 37bbe87d5792c879130e5f1e491f743cbc50dc1e Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 26 May 2016 08:33:20 +0200 Subject: [PATCH 08/13] [INP] gamification: skip check for not required fields Could get a definition with a model only --- addons/gamification/models/goal.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 969d4321bab..42fd073b58e 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -152,6 +152,9 @@ class gamification_goal_definition(osv.Model): """ make sure the selected field and model are usable""" for definition in self.browse(cr, uid, ids, context=context): try: + if not definition.model_id or not definition.field_id: + continue + model = self.pool[definition.model_id.model] field = model._fields[definition.field_id.name] if not field.store: From 6c129e99546497b33a3150d6e01647c1dccb4585 Mon Sep 17 00:00:00 2001 From: rocksolidsolutions Date: Wed, 25 May 2016 08:57:33 -0700 Subject: [PATCH 09/13] [CLA] Rock Solid Solutions signs corporate CLA. Closes #12182 --- doc/cla/corporate/rocksolidsolutions.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doc/cla/corporate/rocksolidsolutions.md diff --git a/doc/cla/corporate/rocksolidsolutions.md b/doc/cla/corporate/rocksolidsolutions.md new file mode 100644 index 00000000000..133c19de35c --- /dev/null +++ b/doc/cla/corporate/rocksolidsolutions.md @@ -0,0 +1,15 @@ +United States, 2016-05-25 + +Rock Solid Solutions, LLC agrees to the terms of the Odoo Corporate Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Daniel Kauffman, Manager rocksolidsolutions@users.noreply.github.com + +List of contributors: + +Daniel Kauffman rocksolidsolutions@users.noreply.github.com From 9c28b6fbfa9344f6cd4a1765ef5d2979cc967957 Mon Sep 17 00:00:00 2001 From: 65HQqp5QTq8QwA3f <65HQqp5QTq8QwA3f@users.noreply.github.com> Date: Tue, 10 Nov 2015 10:55:42 -0800 Subject: [PATCH 10/13] [FIX] sale: propagate context Closes #9521 --- addons/sale/sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 67f04c45fc3..29a572c8e0f 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -539,7 +539,7 @@ class sale_order(osv.osv): continue elif (line.state in states): lines.append(line.id) - created_lines = obj_sale_order_line.invoice_line_create(cr, uid, lines) + created_lines = obj_sale_order_line.invoice_line_create(cr, uid, lines, context=context) if created_lines: invoices.setdefault(o.partner_invoice_id.id or o.partner_id.id, []).append((o, created_lines)) if not invoices: From dbdc8e1ceffc11d80dc336ef471eecffdadd5b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Mon, 18 Aug 2014 13:35:58 +0100 Subject: [PATCH 11/13] [FIX] server: Do not listen when --no-xmlrpc is set This is a fix for f04f409943b8bd8f4bd2653e368523d1cc0d8246, which only prevented the workers from being spawned in Prefork mode, while the socket was still being bound to - this is a problem when starting a worker-only server as it cannot coexist with the XMLRPC server on the same machine. Closes #1828 --- openerp/service/server.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/openerp/service/server.py b/openerp/service/server.py index 46c5c15fe1a..f2d67c000ef 100644 --- a/openerp/service/server.py +++ b/openerp/service/server.py @@ -428,7 +428,8 @@ class PreforkServer(CommonServer): """ def __init__(self, app): # config - self.address = (config['xmlrpc_interface'] or '0.0.0.0', config['xmlrpc_port']) + self.address = config['xmlrpc'] and \ + (config['xmlrpc_interface'] or '0.0.0.0', config['xmlrpc_port']) self.population = config['workers'] self.timeout = config['limit_time_real'] self.limit_request = config['limit_request'] @@ -603,12 +604,13 @@ class PreforkServer(CommonServer): signal.signal(signal.SIGQUIT, dumpstacks) signal.signal(signal.SIGUSR1, log_ormcache_stats) - # listen to socket - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.socket.setblocking(0) - self.socket.bind(self.address) - self.socket.listen(8 * self.population) + if self.address: + # listen to socket + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.socket.setblocking(0) + self.socket.bind(self.address) + self.socket.listen(8 * self.population) def stop(self, graceful=True): if self.long_polling_pid is not None: @@ -632,7 +634,8 @@ class PreforkServer(CommonServer): _logger.info("Stopping forcefully") for pid in self.workers.keys(): self.worker_kill(pid, signal.SIGTERM) - self.socket.close() + if self.socket: + self.socket.close() def run(self, preload, stop): self.start() @@ -735,11 +738,13 @@ class Worker(object): _logger.info("Worker %s (%s) alive", self.__class__.__name__, self.pid) # Reseed the random number generator random.seed() - # Prevent fd inherientence close_on_exec - flags = fcntl.fcntl(self.multi.socket, fcntl.F_GETFD) | fcntl.FD_CLOEXEC - fcntl.fcntl(self.multi.socket, fcntl.F_SETFD, flags) - # reset blocking status - self.multi.socket.setblocking(0) + if self.multi.socket: + # Prevent fd inheritance: close_on_exec + flags = fcntl.fcntl(self.multi.socket, fcntl.F_GETFD) | fcntl.FD_CLOEXEC + fcntl.fcntl(self.multi.socket, fcntl.F_SETFD, flags) + # reset blocking status + self.multi.socket.setblocking(0) + signal.signal(signal.SIGINT, self.signal_handler) signal.signal(signal.SIGTERM, signal.SIG_DFL) signal.signal(signal.SIGCHLD, signal.SIG_DFL) @@ -857,7 +862,8 @@ class WorkerCron(Worker): def start(self): os.nice(10) # mommy always told me to be nice with others... Worker.start(self) - self.multi.socket.close() + if self.multi.socket: + self.multi.socket.close() #---------------------------------------------------------- # start/stop public api From 66221968b8024f589d361ead74312a24ae02cd99 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 26 May 2016 11:44:00 +0200 Subject: [PATCH 12/13] [FIX] crm_partner_assign: minimum access rights to employee Give the same as access rights to the employee as for the public user. This patch is needed to allow a user to access the partner form. Same for portal. The list of grades in not a confidential information. Fixes #7719 --- addons/crm_partner_assign/security/ir.model.access.csv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/crm_partner_assign/security/ir.model.access.csv b/addons/crm_partner_assign/security/ir.model.access.csv index 61b35dde142..9aebe66635a 100644 --- a/addons/crm_partner_assign/security/ir.model.access.csv +++ b/addons/crm_partner_assign/security/ir.model.access.csv @@ -3,6 +3,8 @@ access_ crm_lead_report_assign,crm.lead.report.assign,model_crm_lead_report_assi access_ crm_lead_report_assign_all,crm.lead.report.assign.all,model_crm_lead_report_assign,base.group_user,1,0,0,0 access_crm_partner_report,crm.partner.report.assign.all,model_crm_partner_report_assign,base.group_sale_salesman,1,0,0,0 access_res_partner_grade,res.partner.grade,model_res_partner_grade,base.group_sale_salesman,1,1,1,0 +access_res_partner_grade_employee,res.partner.grade,model_res_partner_grade,base.group_user,1,0,0,0 +access_res_partner_grade_portal,res.partner.grade,model_res_partner_grade,base.group_portal,1,0,0,0 access_res_partner_grade_public,res.partner.grade,model_res_partner_grade,base.group_public,1,0,0,0 access_res_partner_grade_manager,res.partner.grade.manager,model_res_partner_grade,base.group_sale_manager,1,1,1,1 access_res_partner_activation_user,res.partner.activation.user,model_res_partner_activation,base.group_user,1,0,0,0 From 6c6a9f3d609765111e50af0656f637b30724de84 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 26 May 2016 13:05:46 +0200 Subject: [PATCH 13/13] [FIX] *: replace uses of `except_osv` with `UserError` that have been forgotten during previous forward-ports --- addons/crm/base_partner_merge.py | 2 +- addons/point_of_sale/point_of_sale.py | 2 +- addons/purchase/purchase.py | 5 ++--- addons/sale_stock/sale_stock.py | 2 +- addons/stock/wizard/stock_return_picking.py | 2 +- addons/stock_account/product.py | 2 +- addons/stock_account/stock_account.py | 2 +- openerp/addons/base/res/res_users.py | 2 +- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py index 8baf69a5a7a..95ad18f044f 100644 --- a/addons/crm/base_partner_merge.py +++ b/addons/crm/base_partner_merge.py @@ -306,7 +306,7 @@ class MergePartnerAutomatic(osv.TransientModel): for partner_id in partner_ids: child_ids = child_ids.union(set(proxy.search(cr, uid, [('id', 'child_of', [partner_id])])) - set([partner_id])) if set(partner_ids).intersection(child_ids): - raise osv.except_osv(_('Error'), _("You cannot merge a contact with one of his parent.")) + raise UserError(_("You cannot merge a contact with one of his parent.")) if openerp.SUPERUSER_ID != uid and len(set(partner.email for partner in proxy.browse(cr, uid, partner_ids, context=context))) > 1: raise UserError(_("All contacts must have the same email. Only the Administrator can merge contacts with different emails.")) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index ead3b4ac119..9ddbc244051 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -1546,7 +1546,7 @@ class product_template(osv.osv): product_ctx = dict(context or {}, active_test=False) if self.search_count(cr, uid, [('id', 'in', ids), ('available_in_pos', '=', True)], context=product_ctx): if self.pool['pos.session'].search_count(cr, uid, [('state', '!=', 'closed')], context=context): - raise osv.except_osv(_('Error!'), + raise UserError( _('You cannot delete a product saleable in point of sale while a session is still opened.')) return super(product_template, self).unlink(cr, uid, ids, context=context) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 446da4cf081..15226a4022b 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -435,7 +435,7 @@ class purchase_order(osv.osv): company_id = context.get('company_id') or self.pool.get('res.users')._get_company(cr, uid, context=context) if not company_id: - raise osv.except_osv(_('Error!'), _('There is no default company for the current user!')) + raise UserError(_('There is no default company for the current user!')) fp = self.pool['account.fiscal.position'].get_fiscal_position(cr, uid, company_id, partner_id, context=context) supplier_address = partner.address_get(cr, uid, [partner_id], ['default'], context=context) supplier = partner.browse(cr, uid, partner_id, context=context) @@ -578,8 +578,7 @@ class purchase_order(osv.osv): if not any(line.state != 'cancel' for line in po.order_line): raise UserError(_('You cannot confirm a purchase order without any purchase order line.')) if po.invoice_method == 'picking' and not any([l.product_id and l.product_id.type in ('product', 'consu') and l.state != 'cancel' for l in po.order_line]): - raise osv.except_osv( - _('Error!'), + raise UserError( _("You cannot confirm a purchase order with Invoice Control Method 'Based on incoming shipments' that doesn't contain any stockable item.")) for line in po.order_line: if line.state=='draft': diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index 65f37e985e3..f3fc9b6d3ee 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -375,7 +375,7 @@ class sale_order_line(osv.osv): for procurement in lines.mapped('procurement_ids'): for move in procurement.move_ids: if move.state == 'done' and not move.scrapped: - raise osv.except_osv(_('Invalid Action!'), _('You cannot cancel a sale order line which is linked to a stock move already done.')) + raise UserError(_('You cannot cancel a sale order line which is linked to a stock move already done.')) return super(sale_order_line, self).button_cancel(cr, uid, ids, context=context) class stock_move(osv.osv): diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py index ce46f07f764..39e588bfd7c 100644 --- a/addons/stock/wizard/stock_return_picking.py +++ b/addons/stock/wizard/stock_return_picking.py @@ -60,7 +60,7 @@ class stock_return_picking(osv.osv_memory): context = {} if context and context.get('active_ids', False): if len(context.get('active_ids')) > 1: - raise osv.except_osv(_('Warning!'), _("You may only return one picking at a time!")) + raise UserError(_("You may only return one picking at a time!")) res = super(stock_return_picking, self).default_get(cr, uid, fields, context=context) record_id = context and context.get('active_id', False) or False uom_obj = self.pool.get('product.uom') diff --git a/addons/stock_account/product.py b/addons/stock_account/product.py index 728ea544a07..fd433279348 100644 --- a/addons/stock_account/product.py +++ b/addons/stock_account/product.py @@ -134,7 +134,7 @@ class product_template(osv.osv): if not counterpart_account: counterpart_account = product.categ_id.property_account_expense_categ and product.categ_id.property_account_expense_categ.id or False if not counterpart_account: - raise osv.except_osv(_('Error!'), _('No expense account defined on the product %s or on its category') % (product.name)) + raise UserError(_('No expense account defined on the product %s or on its category') % (product.name)) if diff * qty > 0: amount_diff = qty * diff debit_account_id = counterpart_account diff --git a/addons/stock_account/stock_account.py b/addons/stock_account/stock_account.py index bee410ae3ca..237da2f677a 100644 --- a/addons/stock_account/stock_account.py +++ b/addons/stock_account/stock_account.py @@ -196,7 +196,7 @@ class stock_quant(osv.osv): :param context: context dictionary that can explicitly mention the company to consider via the 'force_company' key :returns: journal_id, source account, destination account, valuation account - :raise: osv.except_osv() is any mandatory account or journal is not defined. + :raise: openerp.exceptions.UserError if any mandatory account or journal is not defined. """ product_obj = self.pool.get('product.template') accounts = product_obj.get_product_accounts(cr, uid, move.product_id.product_tmpl_id.id, context) diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index dda40e32d7f..38625280089 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -527,7 +527,7 @@ class res_users(osv.osv): :return: True :raise: openerp.exceptions.AccessDenied when old password is wrong - :raise: except_osv when new password is not set or empty + :raise: openerp.exceptions.UserError when new password is not set or empty """ self.check(cr.dbname, uid, old_passwd) if new_passwd: