From e402c89bcc54d2dd471b08d9ca59ffc73657bf01 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 9 Apr 2019 12:14:49 +0000 Subject: [PATCH 1/6] [FIX] stock_account: price unit is zero - Set a product P to average valuation, real time - Create a PO for 1 unit @ 100, validate the picking - Create a PO for 1 unit @ 0 (e.g. you receive a free product) You cannot validate the picking because of the message 'The cost of P is currently equal to 0...' This error message is historical, to prevent users from an incorrect configuration. Since we still want to prevent misconfiguration, but support the mentioned use case, we introduce an `ir._config_parameter` for people who 'know what they are doing'. opw-1962249 closes odoo/odoo#32550 Signed-off-by: Nicolas Martinelli (nim) --- addons/stock_account/models/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock_account/models/stock.py b/addons/stock_account/models/stock.py index 1b544c5559d..7204e532c7e 100644 --- a/addons/stock_account/models/stock.py +++ b/addons/stock_account/models/stock.py @@ -562,7 +562,7 @@ class StockMove(models.Model): debit_value = self.company_id.currency_id.round(valuation_amount) # check that all data is correct - if self.company_id.currency_id.is_zero(debit_value): + if self.company_id.currency_id.is_zero(debit_value) and not self.env['ir.config_parameter'].sudo().get_param('stock_account.allow_zero_cost'): raise UserError(_("The cost of %s is currently equal to 0. Change the cost or the configuration of your product to avoid an incorrect valuation.") % (self.product_id.display_name,)) credit_value = debit_value From 5a83cd264999c588d2a980ac5ae972343619f255 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Wed, 10 Apr 2019 13:36:39 +0000 Subject: [PATCH 2/6] [FIX]sale_stock: Issue when clicking on "No backorder" Steps to reproduce the bug: - Create a SO with no salesperson - Add a SO line with 2 storable product - Confirm the SO and deliver only one product - Click on "No backorder" Bug: A error was raised because the function "_log_activity"(called by _log_less_quantities_than_expected) requires a responsible Partial Backport: https://github.com/odoo/odoo/commit/e1f9499d2672fb0a346f8ac74552f038f5204a64 opw:1950968 closes odoo/odoo#32592 Signed-off-by: Simon Goffin (sig) --- addons/stock/models/stock_picking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index b4d120ce53b..004b085f6ba 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -7,7 +7,7 @@ import time from datetime import date from itertools import groupby -from odoo import api, fields, models, _ +from odoo import api, fields, models, _, SUPERUSER_ID from odoo.osv import expression from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT from odoo.tools.float_utils import float_compare, float_is_zero, float_round @@ -931,7 +931,7 @@ class Picking(models.Model): 'mail.mail_activity_data_warning', date.today(), note=note, - user_id=responsible.id + user_id=responsible.id or SUPERUSER_ID ) def _log_less_quantities_than_expected(self, moves): From 6bd9e71d9d54ea541a107846543e4de463be7132 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 11 Apr 2019 06:26:17 +0000 Subject: [PATCH 3/6] [FIX] SSF: misinterpretation of onchange command (4) From an onchange, at this point, (4) doesn't mean "no change" it means "reset to database values". Through the interplay of client and server reverse-engineering one another at this point the client (is supposed to) assume the o2m results are "complete" and a diff from the current *in-database* values rather than the in-client (sent to the server) ones. So a (1) should completely replace all existing values, and a (4) should just remove all of them (but keep the record linked). closes odoo/odoo#32617 Signed-off-by: Xavier Morel (xmo) --- odoo/tests/common.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 507d023fc98..df6c626906b 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -1461,12 +1461,13 @@ class Form(object): return [] v = [] - c = {t[1]: t[2] for t in current if t[0] in (1, 2)} if current else {} + c = {t[1] for t in current if t[0] in (1, 2)} if current else set() # which view should this be??? subfields = descr['views']['edition']['fields'] + # TODO: simplistic, unlikely to work if e.g. there's a 5 inbetween other commands for command in value: if command[0] in (0, 1): - c.pop(command[1], None) # remove record from currents + c.discard(command[1]) v.append((command[0], command[1], { k: self._cleanup_onchange( subfields[k], v, None @@ -1475,9 +1476,11 @@ class Form(object): if k in subfields })) elif command[0] == 2: + c.discard(command[1]) v.append((2, command[1], False)) elif command[0] == 4: - v.append((1, command[1], c.pop(command[1], {}))) + c.discard(command[1]) + v.append((1, command[1], {})) elif command[0] == 5: v = [] # explicitly mark all non-relinked (or modified) records as deleted From 9365dc5d17b89a44c1d84313d7228c9f7b7f4efd Mon Sep 17 00:00:00 2001 From: Nans Lefebvre Date: Thu, 11 Apr 2019 10:16:31 +0000 Subject: [PATCH 4/6] [FIX] account: better message on user group error The validation error introduced in 552da8dc can pop up in contexts where it is not expected; e.g. not in editing user rights but while upgrading a module. Therefore we make it more explicit, giving the user a way to resolve the error. closes odoo/odoo#32623 Signed-off-by: Nans Lefebvre (len) --- addons/account/i18n/account.pot | 6 +++++- addons/account/models/res_users.py | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/addons/account/i18n/account.pot b/addons/account/i18n/account.pot index 7d790411b5d..8af8a88254a 100644 --- a/addons/account/i18n/account.pot +++ b/addons/account/i18n/account.pot @@ -657,7 +657,11 @@ msgstr "" #. module: account #: code:addons/account/models/res_users.py:17 #, python-format -msgid "A user cannot have both Tax B2B and Tax B2C" +msgid "A user cannot have both Tax B2B and Tax B2C.\n" +"Problematic user(s): %s\n" +"You should go in General Settings, and choose to display Product Prices\n" +"either in 'Tax-Included' or in 'Tax-Excluded' mode\n" +"(or switch twice the mode if you are already in the desired one)." msgstr "" #. module: account diff --git a/addons/account/models/res_users.py b/addons/account/models/res_users.py index 3e6fd163482..ab85e359d22 100644 --- a/addons/account/models/res_users.py +++ b/addons/account/models/res_users.py @@ -12,7 +12,15 @@ class Users(models.Model): @api.constrains('groups_id') def _check_one_user_type(self): super(Users, self)._check_one_user_type() - for user in self: - if (user.user_has_groups('account.group_show_line_subtotals_tax_included') and - user.user_has_groups('account.group_show_line_subtotals_tax_excluded')): - raise ValidationError(_('A user cannot have both Tax B2B and Tax B2C')) + + users_with_both_groups = self.filtered(lambda user: + user.user_has_groups('account.group_show_line_subtotals_tax_included') and + user.user_has_groups('account.group_show_line_subtotals_tax_excluded') + ) + if users_with_both_groups: + names = ", ".join(users_with_both_groups.mapped('name')) + raise ValidationError(_("A user cannot have both Tax B2B and Tax B2C.\n" + "Problematic user(s): %s\n" + "You should go in General Settings, and choose to display Product Prices\n" + "either in 'Tax-Included' or in 'Tax-Excluded' mode\n" + "(or switch twice the mode if you are already in the desired one).") % names) From 2a88e0197aa6d7fbe86b50a380d75608fe6f6ecc Mon Sep 17 00:00:00 2001 From: Hugo Vinicius Garcia Razera Date: Wed, 10 Apr 2019 13:38:13 +0000 Subject: [PATCH 5/6] [CLA] Sign Odoo CLA for hviniciusg closes odoo/odoo#32591 Signed-off-by: Martin Trigaux (mat) --- doc/cla/individual/hviniciusg.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 doc/cla/individual/hviniciusg.md diff --git a/doc/cla/individual/hviniciusg.md b/doc/cla/individual/hviniciusg.md new file mode 100644 index 00000000000..d98b0703a49 --- /dev/null +++ b/doc/cla/individual/hviniciusg.md @@ -0,0 +1,11 @@ +Bolivia, 2019-03-31 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Hugo Vinicius Garcia Razeara hviniciusg@gmail.com https://github.com/hviniciusg From c9d3653f486f6c22b47c91f9dc7583219fffc47b Mon Sep 17 00:00:00 2001 From: Arnold Moyaux Date: Thu, 11 Apr 2019 12:54:25 +0000 Subject: [PATCH 6/6] [FIX] mrp: state on workorder with 0 batch size Usecase: - Go on a BoM with a routing. Go on the first operation and set the next operation(batch field) as 'Once a minimum number of products is processed'. - Set the batch size (minimum operation) to 0. - Create a MO and plan it. - The second work order has state 'pending' instead of 'ready' It happens because the system automatically set the first wo as 'ready' and the following as 'pending' and don't check the batch and batch_size. closes odoo/odoo#32628 Signed-off-by: Simon Lejeune (sle) --- addons/mrp/models/mrp_production.py | 2 +- addons/mrp/models/mrp_workorder.py | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 94c4577b87b..5710d9b572f 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -583,7 +583,7 @@ class MrpProduction(models.Model): }) if workorders: workorders[-1].next_work_order_id = workorder.id - workorders[-1]._init_nextworkorder_states() + workorders[-1]._start_nextworkorder() workorders += workorder # assign moves; last operation receive all unassigned moves (which case ?) diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index e0b993c2215..f1544ab0e44 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -337,9 +337,6 @@ class MrpWorkorder(models.Model): move_line.lot_produced_id = self.final_lot_id.id move_line.done_wo = True - # One a piece is produced, you can launch the next work order - self._start_nextworkorder() - self.move_line_ids.filtered( lambda move_line: not move_line.done_move and not move_line.lot_produced_id and move_line.qty_done > 0 ).write({ @@ -390,6 +387,9 @@ class MrpWorkorder(models.Model): self.final_lot_id.use_next_on_work_order_id = self.next_work_order_id self.final_lot_id = False + # One a piece is produced, you can launch the next work order + self._start_nextworkorder() + # Set a qty producing rounding = self.production_id.product_uom_id.rounding if float_compare(self.qty_produced, self.production_id.product_qty, precision_rounding=rounding) >= 0: @@ -411,12 +411,13 @@ class MrpWorkorder(models.Model): @api.multi def _start_nextworkorder(self): - for record in self: - if record.next_work_order_id.state == 'pending': - record.next_work_order_id.state = 'ready' - - def _init_nextworkorder_states(self): - return 'pending' + rounding = self.product_id.uom_id.rounding + if self.next_work_order_id.state == 'pending' and ( + (self.operation_id.batch == 'no' and + float_compare(self.qty_production, self.qty_produced, precision_rounding=rounding) <= 0) or + (self.operation_id.batch == 'yes' and + float_compare(self.operation_id.batch_size, self.qty_produced, precision_rounding=rounding) <= 0)): + self.next_work_order_id.state = 'ready' @api.multi def button_start(self):