From 043263f69e60b64d76d4ea7bb75879fd9eb14e6d Mon Sep 17 00:00:00 2001 From: RisvanaCybro Date: Thu, 9 May 2024 21:46:40 +0530 Subject: [PATCH] May 09: [FIX] Bug Fixed 'stock_last_purchase_price' --- .../models/stock_move.py | 112 +++++++++++------- 1 file changed, 69 insertions(+), 43 deletions(-) diff --git a/stock_last_purchase_price/models/stock_move.py b/stock_last_purchase_price/models/stock_move.py index 8896dbcd2..6dd6df628 100644 --- a/stock_last_purchase_price/models/stock_move.py +++ b/stock_last_purchase_price/models/stock_move.py @@ -30,62 +30,88 @@ class StockMove(models.Model): _inherit = "stock.move" def product_price_update_before_done(self, forced_qty=None): - """ Function to update the price of the product """ + tmpl_dict = defaultdict(lambda: 0.0) - # Adapt standard price on incoming moves if the product cost_method - # is 'average' + # adapt standard price on incomming moves if the product cost_method is 'average' std_price_update = {} - for move in self.filtered(lambda move: move.location_id.usage in ( - 'supplier', 'production') and move.product_id.cost_method in ( - 'average', 'last')): - product_tot_qty_available = move.product_id.qty_available + \ - tmpl_dict[move.product_id.id] + for move in self.filtered( + lambda move: move._is_in() and move.with_company( + move.company_id).product_id.cost_method == 'average'): + product_tot_qty_available = move.product_id.sudo().with_company( + move.company_id).quantity_svl + tmpl_dict[move.product_id.id] rounding = move.product_id.uom_id.rounding - qty_done = 0.0 + + valued_move_lines = move._get_in_move_lines() + qty_done = 0 + for valued_move_line in valued_move_lines: + qty_done += valued_move_line.product_uom_id._compute_quantity( + valued_move_line.qty_done, move.product_id.uom_id) + + qty = forced_qty or qty_done if float_is_zero(product_tot_qty_available, precision_rounding=rounding): new_std_price = move._get_price_unit() elif float_is_zero(product_tot_qty_available + move.product_qty, precision_rounding=rounding) or \ - float_is_zero(product_tot_qty_available + qty_done, + float_is_zero(product_tot_qty_available + qty, precision_rounding=rounding): new_std_price = move._get_price_unit() else: # Get the standard price - if move.product_id.cost_method == 'average': - amount_unit = std_price_update.get( - (move.company_id.id, - move.product_id.id)) or move.product_id.standard_price - qty_done = move.product_uom._compute_quantity( - move.quantity_done, move.product_id.uom_id) - qty = forced_qty or qty_done - new_std_price = ((amount_unit * product_tot_qty_available) - + (move._get_price_unit() * qty)) / ( - product_tot_qty_available + - qty_done) - if (move.product_id.cost_method == 'last' and - move.product_id.valuation == 'real_time' or - move.product_id.valuation == 'manual_periodic'): - new_std_price = move._get_price_unit() - products = self.env['product.product'].browse( - move.product_id.id) - account_id = ( - products.property_account_creditor_price_difference.id - or products.categ_id.property_account_creditor_price_difference_categ.id) - if not account_id: - raise UserError( - _('Configuration error. Please configure the price ' - 'difference account on the product or its category ' - 'to process this operation.')) - products.create_price_change_account_move(new_std_price, - account_id, - move.company_id.id, - move.origin) + amount_unit = std_price_update.get((move.company_id.id, + move.product_id.id)) or move.product_id.with_company( + move.company_id).standard_price + new_std_price = ((amount_unit * product_tot_qty_available) + ( + move._get_price_unit() * qty)) / ( + product_tot_qty_available + qty) + tmpl_dict[move.product_id.id] += qty_done - # Write the standard price, as SUPERUSER_ID because a warehouse - # manager may not have the right to write on products - move.product_id.with_context( - force_company=move.company_id.id).sudo().write( + # Write the standard price, as SUPERUSER_ID because a warehouse manager may not have the right to write on products + move.product_id.with_company(move.company_id.id).with_context( + disable_auto_svl=True).sudo().write( {'standard_price': new_std_price}) std_price_update[ move.company_id.id, move.product_id.id] = new_std_price + + # adapt standard price on incomming moves if the product cost_method + # is 'fifo' + for move in self.filtered(lambda move: + move.with_company( + move.company_id).product_id.cost_method == 'fifo' + and float_is_zero( + move.product_id.sudo().quantity_svl, + precision_rounding=move.product_id.uom_id.rounding)): + move.product_id.with_company(move.company_id.id).sudo().write( + {'standard_price': move._get_price_unit()}) + # Add new costing method for 'last' with real-time or + # manual_periodic valuation + # Filter moves based on conditions + for move in self.filtered(lambda move: move.with_company( + move.company_id).product_id.cost_method == 'last' and + (move.product_id.valuation == 'real_time' or move.product_id.valuation == 'manual_periodic')): + # Get the new standard price for the move + new_std_price = move._get_price_unit() # Presumably retrieves incoming move price + + # Retrieve product details for the move + products = self.env['product.product'].browse(move.product_id.id) + + # Determine the account ID for price differences + account_id = (products.property_account_creditor_price_difference.id + or products.categ_id.property_account_creditor_price_difference_categ.id) + + # Check if account ID is not set, raise an error + if not account_id: + raise UserError( + _('Configuration error. Please configure the price ' + 'difference account on the product or its category ' + 'to process this operation.')) + # products.create_price_change_account_move(new_std_price, + # account_id, + # move.company_id.id, + # move.origin) + # Update the standard price for the product + move.product_id.with_company(move.company_id.id).with_context( + disable_auto_svl=True).sudo().write( + {'standard_price': new_std_price}) + +