From fea006c468850b8eca5908e10a49e85b7c720b6d Mon Sep 17 00:00:00 2001 From: Fatemi Lokhandwala Date: Mon, 9 Jul 2018 15:53:28 +0530 Subject: [PATCH] [ADD]:Added Upstream Patch for sale_stock --- addons/sale_stock/models/account_invoice.py | 25 ++------------------- addons/sale_stock/models/sale_order.py | 14 +++++------- addons/sale_stock/models/stock.py | 16 ++----------- addons/sale_stock/tests/test_sale_stock.py | 4 ++-- 4 files changed, 11 insertions(+), 48 deletions(-) diff --git a/addons/sale_stock/models/account_invoice.py b/addons/sale_stock/models/account_invoice.py index b47454a6..f620aa87 100644 --- a/addons/sale_stock/models/account_invoice.py +++ b/addons/sale_stock/models/account_invoice.py @@ -25,9 +25,7 @@ class AccountInvoiceLine(models.Model): qty_done = sum([x.uom_id._compute_quantity(x.quantity, x.product_id.uom_id) for x in s_line.invoice_lines if x.invoice_id.state in ('open', 'paid')]) quantity = self.uom_id._compute_quantity(self.quantity, self.product_id.uom_id) # Put moves in fixed order by date executed - moves = self.env['stock.move'] - moves |= s_line.move_ids - moves.sorted(lambda x: x.date) + moves = s_line.move_ids.sorted(lambda x: x.date) # Go through all the moves and do nothing until you get to qty_done # Beyond qty_done we need to calculate the average of the price_unit # on the moves we encounter. @@ -37,23 +35,4 @@ class AccountInvoiceLine(models.Model): return price_unit def _compute_average_price(self, qty_done, quantity, moves): - average_price_unit = 0 - qty_delivered = 0 - invoiced_qty = 0 - for move in moves: - if move.state != 'done': - continue - invoiced_qty += move.product_qty - if invoiced_qty <= qty_done: - continue - qty_to_consider = move.product_qty - if invoiced_qty - move.product_qty < qty_done: - qty_to_consider = invoiced_qty - qty_done - qty_to_consider = min(qty_to_consider, quantity - qty_delivered) - qty_delivered += qty_to_consider - # `move.price_unit` is negative if the move is out and positive if the move is - # dropshipped. Use its absolute value to compute the average price unit. - average_price_unit = (average_price_unit * (qty_delivered - qty_to_consider) + abs(move.price_unit) * qty_to_consider) / qty_delivered - if qty_delivered == quantity: - break - return average_price_unit + return self.env['product.product']._compute_average_price(qty_done, quantity, moves) diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py index 3a74a707..d7d41949 100644 --- a/addons/sale_stock/models/sale_order.py +++ b/addons/sale_stock/models/sale_order.py @@ -137,13 +137,9 @@ class SaleOrderLine(models.Model): @api.multi @api.depends('product_id') def _compute_qty_delivered_updateable(self): - # prefetch field before filtering - self.mapped('product_id') - # on consumable or stockable products, qty_delivered_updateable defaults - # to False; on other lines use the original computation - lines = self.filtered(lambda line: line.product_id.type not in ('consu', 'product')) - lines = lines.with_prefetch(self._prefetch) - super(SaleOrderLine, lines)._compute_qty_delivered_updateable() + for line in self: + if line.product_id.type not in ('consu', 'product'): + super(SaleOrderLine, line)._compute_qty_delivered_updateable() @api.onchange('product_id') def _onchange_product_id_set_customer_lead(self): @@ -343,8 +339,8 @@ class SaleOrderLine(models.Model): raise UserError('You cannot decrease the ordered quantity below the delivered quantity.\n' 'Create a return first.') for line in self: - pickings = self.order_id.picking_ids.filtered(lambda p: p.state not in ('done', 'cancel')) + pickings = line.order_id.picking_ids.filtered(lambda p: p.state not in ('done', 'cancel')) for picking in pickings: picking.message_post("The quantity of %s has been updated from %d to %d in %s" % - (line.product_id.name, line.product_uom_qty, values['product_uom_qty'], self.order_id.name)) + (line.product_id.display_name, line.product_uom_qty, values['product_uom_qty'], line.order_id.name)) super(SaleOrderLine, self)._update_line_quantity(values) diff --git a/addons/sale_stock/models/stock.py b/addons/sale_stock/models/stock.py index 677bff2a..5d7608e8 100644 --- a/addons/sale_stock/models/stock.py +++ b/addons/sale_stock/models/stock.py @@ -28,7 +28,7 @@ class StockMove(models.Model): def _action_done(self): result = super(StockMove, self)._action_done() - for line in result.mapped('sale_line_id'): + for line in result.mapped('sale_line_id').sudo(): line.qty_delivered = line._get_delivered_qty() return result @@ -39,7 +39,7 @@ class StockMove(models.Model): for move in self: if move.state == 'done': sale_order_lines = self.filtered(lambda move: move.sale_line_id and move.product_id.expense_policy == 'no').mapped('sale_line_id') - for line in sale_order_lines: + for line in sale_order_lines.sudo(): line.qty_delivered = line._get_delivered_qty() return res @@ -64,15 +64,3 @@ class StockPicking(models.Model): _inherit = 'stock.picking' sale_id = fields.Many2one(related="group_id.sale_id", string="Sales Order", store=True) - - @api.multi - def _create_backorder(self, backorder_moves=[]): - res = super(StockPicking, self)._create_backorder(backorder_moves) - for picking in self.filtered(lambda pick: pick.picking_type_id.code == 'outgoing'): - backorder = picking.search([('backorder_id', '=', picking.id)]) - if backorder.sale_id: - backorder.message_post_with_view( - 'mail.message_origin_link', - values={'self': backorder, 'origin': backorder.sale_id}, - subtype_id=self.env.ref('mail.mt_note').id) - return res diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index 9af09ec7..af7dabac 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -52,7 +52,7 @@ class TestSaleStock(TestSale): pick_2 = self.so.picking_ids[0] pick_2.force_assign() pick_2.move_lines.write({'quantity_done': 1}) - self.assertIsNone(pick_2.button_validate(), 'Sale Stock: second picking should be final without need for a backorder') + self.assertTrue(pick_2.button_validate(), 'Sale Stock: second picking should be final without need for a backorder') self.assertEqual(self.so.invoice_status, 'to invoice', 'Sale Stock: so invoice_status should be "to invoice" after complete delivery') del_qties = [sol.qty_delivered for sol in self.so.order_line] del_qties_truth = [2.0 if sol.product_id.type in ['product', 'consu'] else 0.0 for sol in self.so.order_line] @@ -104,7 +104,7 @@ class TestSaleStock(TestSale): pick = self.so.picking_ids pick.force_assign() pick.move_lines.write({'quantity_done': 2}) - self.assertIsNone(pick.button_validate(), 'Sale Stock: complete delivery should not need a backorder') + self.assertTrue(pick.button_validate(), 'Sale Stock: complete delivery should not need a backorder') del_qties = [sol.qty_delivered for sol in self.so.order_line] del_qties_truth = [2.0 if sol.product_id.type in ['product', 'consu'] else 0.0 for sol in self.so.order_line] self.assertEqual(del_qties, del_qties_truth, 'Sale Stock: delivered quantities are wrong after partial delivery')