From 51d072db444bfd2dcad18122b502a4d3a98627f4 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Mon, 26 Jun 2017 10:38:04 +0200 Subject: [PATCH 1/9] [FIX] stock_account: Invalid product price history breaks stock valuation Steps to reproduce: 1. Create a new Stockable Product 2. Set cost price to 2.00 3. Adjust stock to 10 pcs 4. Enable developer mode 5. Go to Inventory > Reports > Inventory at Date 6. Select current time and retrieve the inventory value Bug: The stock valuation for the product was 0.0. Reason: When creating a stockable product, Odoo creates two price history entries with the same datetime but different cost. The stock valuation report only takes one of them into account. Fixes #14889 opw:747857 --- addons/stock_account/report/stock_history.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock_account/report/stock_history.py b/addons/stock_account/report/stock_history.py index ccf150954dc..4d5d4045dfb 100644 --- a/addons/stock_account/report/stock_history.py +++ b/addons/stock_account/report/stock_history.py @@ -41,7 +41,7 @@ class StockHistory(models.Model): self._cr.execute("""SELECT DISTINCT ON (product_id, company_id) product_id, company_id, cost FROM product_price_history WHERE product_id in %s AND datetime <= %s - ORDER BY product_id, company_id, datetime DESC""", (tuple(not_real_cost_method_products.ids), date)) + ORDER BY product_id, company_id, datetime DESC, id DESC""", (tuple(not_real_cost_method_products.ids), date)) for history in self._cr.dictfetchall(): histories_dict[(history['product_id'], history['company_id'])] = history['cost'] From d86f134abd70c4742c3234c14f0f8ab08a9fb39b Mon Sep 17 00:00:00 2001 From: Pieczynski Marcin Date: Sun, 25 Jun 2017 13:49:35 +0200 Subject: [PATCH 2/9] [CLA] signature for piemar1 Done at #17817 --- doc/cla/individual/piemar1.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/cla/individual/piemar1.md diff --git a/doc/cla/individual/piemar1.md b/doc/cla/individual/piemar1.md new file mode 100644 index 00000000000..06c857427ca --- /dev/null +++ b/doc/cla/individual/piemar1.md @@ -0,0 +1,9 @@ +Poland, 2017-06-25 + +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, + +Marcin PieczyƄski marcin-pieczynski@wp.pl https://github.com/piemar1 From 831744684c3a23c1024714b380438b30a1c92099 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Mon, 26 Jun 2017 14:02:46 +0200 Subject: [PATCH 3/9] [FIX] stock: empty state - Update view with external_id=stock.view_move_picking_tree and remove editable attribute on the tree view. - Create a new picking - Add a line (form view will open) and click on "Save and close" => A traceback show up since 'scrapped' was not in the form view. - The picking location fields become readonly, and the status bar disappears - Save the picking => Error: "creation/update: a mandatory field is not correctly set : [object with reference: location_id - location.id]" Courtesy of @benwillig Closes #17738 opw-748353 --- addons/stock/models/stock_picking.py | 4 ++-- addons/stock/views/stock_move_views.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 40121b2aae5..401258e5aed 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -325,11 +325,11 @@ class Picking(models.Model): .filtered(lambda move: move.state not in ['cancel', 'done'])\ .sorted(key=lambda move: (move.state == 'assigned' and 2) or (move.state == 'waiting' and 1) or 0) if self.move_type == 'one': - self.state = moves_todo[0].state + self.state = moves_todo[0].state or 'draft' elif moves_todo[0].state != 'assigned' and any(x.partially_available or x.state == 'assigned' for x in moves_todo): self.state = 'partially_available' else: - self.state = moves_todo[-1].state + self.state = moves_todo[-1].state or 'draft' @api.one @api.depends('move_lines.priority') diff --git a/addons/stock/views/stock_move_views.xml b/addons/stock/views/stock_move_views.xml index a49dc87dd7c..3d92f99a3b4 100644 --- a/addons/stock/views/stock_move_views.xml +++ b/addons/stock/views/stock_move_views.xml @@ -157,6 +157,7 @@
+ From d6909f42ad23840ba7a670aad7195c5df06401c9 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Mon, 26 Jun 2017 12:55:38 +0200 Subject: [PATCH 4/9] [FIX] stock: incorrect ordered quantity - Create a stockable product, get 61 units in stock - Create a SO of 75 units, validate - In the picking, transfer only 50 units, validate and create a backorder - Print the Delivery Slip of the picking: it shows 61 units ordered - Print the Delivery Slip of the backorder: it shows 61 units ordered - Receive the 14 missing units, recheck availability on the backorder: it shows 25 units ordered The quantity ordered should be recomputed from the stock moves when a partial transfer is done. opw-747983 --- addons/stock/models/stock_picking.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 401258e5aed..65aa42b69a5 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -612,9 +612,13 @@ class Picking(models.Model): forced_qties[move.product_id] = forced_qty for vals in picking._prepare_pack_ops(picking_quants, forced_qties): vals['fresh_record'] = False - PackOperation.create(vals) + PackOperation |= PackOperation.create(vals) # recompute the remaining quantities all at once self.do_recompute_remaining_quantities() + for pack in PackOperation: + pack.ordered_qty = sum( + pack.mapped('linked_move_operation_ids').mapped('move_id').filtered(lambda r: r.state != 'cancel').mapped('ordered_qty') + ) self.write({'recompute_pack_op': False}) @api.multi From d37ef94c4b836a36b59426fe8448b1497d794823 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Mon, 26 Jun 2017 11:54:46 +0200 Subject: [PATCH 5/9] [FIX] mrp: Post inventory button without finished product" This fix 2e18070a66595a72a9a626a196c97a689832f667 has been done in stable and some customers wants to keep the button "Post Inventory" available all the time. Now the button is just visible in developper mode. opw:748347 --- addons/mrp/models/mrp_production.py | 7 ++----- addons/mrp/views/mrp_production_views.xml | 2 +- addons/stock/models/product.py | 3 --- addons/stock_account/models/product.py | 3 --- 4 files changed, 3 insertions(+), 12 deletions(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 904eba16eb0..b9a37b99f5b 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -208,11 +208,8 @@ class MrpProduction(models.Model): @api.depends('move_raw_ids.quantity_done', 'move_finished_ids.quantity_done') def _compute_post_visible(self): for order in self: - if order.product_tmpl_id._is_cost_method_standard(): - order.post_visible = any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_raw_ids) or \ - any((x.quantity_done > 0 and x.state not in ['done' 'cancel']) for x in order.move_finished_ids) - else: - order.post_visible = any((x.quantity_done > 0 and x.state not in ['done' 'cancel']) for x in order.move_finished_ids) + order.post_visible = any(order.move_raw_ids.filtered(lambda x: (x.quantity_done) > 0 and (x.state not in ['done', 'cancel']))) or \ + any(order.move_finished_ids.filtered(lambda x: (x.quantity_done) > 0 and (x.state not in ['done', 'cancel']))) @api.multi @api.depends('workorder_ids.state', 'move_finished_ids') diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml index 6c8ffea7fa7..c35a5e13cfe 100644 --- a/addons/mrp/views/mrp_production_views.xml +++ b/addons/mrp/views/mrp_production_views.xml @@ -48,7 +48,7 @@