| 
						
						
							
								
							
						
						
					 | 
					@ -30,62 +30,88 @@ class StockMove(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    _inherit = "stock.move" | 
					 | 
					 | 
					    _inherit = "stock.move" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def product_price_update_before_done(self, forced_qty=None): | 
					 | 
					 | 
					    def product_price_update_before_done(self, forced_qty=None): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        """ Function to update the price of the product """ | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        tmpl_dict = defaultdict(lambda: 0.0) | 
					 | 
					 | 
					        tmpl_dict = defaultdict(lambda: 0.0) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        # Adapt standard price on incoming moves if the product cost_method | 
					 | 
					 | 
					        # adapt standard price on incomming moves if the product cost_method is 'average' | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					        # is 'average' | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        std_price_update = {} | 
					 | 
					 | 
					        std_price_update = {} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        for move in self.filtered(lambda move: move.location_id.usage in ( | 
					 | 
					 | 
					        for move in self.filtered( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                'supplier', 'production') and move.product_id.cost_method in ( | 
					 | 
					 | 
					                lambda move: move._is_in() and move.with_company( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                                       'average', 'last')): | 
					 | 
					 | 
					                        move.company_id).product_id.cost_method == 'average'): | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            product_tot_qty_available = move.product_id.qty_available + \ | 
					 | 
					 | 
					            product_tot_qty_available = move.product_id.sudo().with_company( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                        tmpl_dict[move.product_id.id] | 
					 | 
					 | 
					                move.company_id).quantity_svl + tmpl_dict[move.product_id.id] | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            rounding = move.product_id.uom_id.rounding | 
					 | 
					 | 
					            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, | 
					 | 
					 | 
					            if float_is_zero(product_tot_qty_available, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                             precision_rounding=rounding): | 
					 | 
					 | 
					                             precision_rounding=rounding): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                new_std_price = move._get_price_unit() | 
					 | 
					 | 
					                new_std_price = move._get_price_unit() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            elif float_is_zero(product_tot_qty_available + move.product_qty, | 
					 | 
					 | 
					            elif float_is_zero(product_tot_qty_available + move.product_qty, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                               precision_rounding=rounding) or \ | 
					 | 
					 | 
					                               precision_rounding=rounding) or \ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    float_is_zero(product_tot_qty_available + qty_done, | 
					 | 
					 | 
					                    float_is_zero(product_tot_qty_available + qty, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                                  precision_rounding=rounding): | 
					 | 
					 | 
					                                  precision_rounding=rounding): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                new_std_price = move._get_price_unit() | 
					 | 
					 | 
					                new_std_price = move._get_price_unit() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            else: | 
					 | 
					 | 
					            else: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                # Get the standard price | 
					 | 
					 | 
					                # Get the standard price | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                if move.product_id.cost_method == 'average': | 
					 | 
					 | 
					                amount_unit = std_price_update.get((move.company_id.id, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    amount_unit = std_price_update.get( | 
					 | 
					 | 
					                                                    move.product_id.id)) or move.product_id.with_company( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                        (move.company_id.id, | 
					 | 
					 | 
					                    move.company_id).standard_price | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                         move.product_id.id)) or move.product_id.standard_price | 
					 | 
					 | 
					                new_std_price = ((amount_unit * product_tot_qty_available) + ( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    qty_done = move.product_uom._compute_quantity( | 
					 | 
					 | 
					                            move._get_price_unit() * qty)) / ( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                        move.quantity_done, move.product_id.uom_id) | 
					 | 
					 | 
					                                            product_tot_qty_available + qty) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    qty = forced_qty or qty_done | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    new_std_price = ((amount_unit * product_tot_qty_available) | 
					 | 
					 | 
					            tmpl_dict[move.product_id.id] += qty_done | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                     + (move._get_price_unit() * qty)) / ( | 
					 | 
					 | 
					            # Write the standard price, as SUPERUSER_ID because a warehouse manager may not have the right to write on products | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                            product_tot_qty_available + | 
					 | 
					 | 
					            move.product_id.with_company(move.company_id.id).with_context( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                            qty_done) | 
					 | 
					 | 
					                disable_auto_svl=True).sudo().write( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            if (move.product_id.cost_method == 'last' and | 
					 | 
					 | 
					                {'standard_price': new_std_price}) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    move.product_id.valuation == 'real_time' or | 
					 | 
					 | 
					            std_price_update[ | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    move.product_id.valuation == 'manual_periodic'): | 
					 | 
					 | 
					                move.company_id.id, move.product_id.id] = new_std_price | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                new_std_price = move._get_price_unit() | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                products = self.env['product.product'].browse( | 
					 | 
					 | 
					        # adapt standard price on incomming moves if the product cost_method | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    move.product_id.id) | 
					 | 
					 | 
					        # is 'fifo' | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                account_id = ( | 
					 | 
					 | 
					        for move in self.filtered(lambda move: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                        products.property_account_creditor_price_difference.id | 
					 | 
					 | 
					                                  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) | 
					 | 
					 | 
					                          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: | 
					 | 
					 | 
					            if not account_id: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                raise UserError( | 
					 | 
					 | 
					                raise UserError( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    _('Configuration error. Please configure the price ' | 
					 | 
					 | 
					                    _('Configuration error. Please configure the price ' | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                      'difference account on the product or its category ' | 
					 | 
					 | 
					                      'difference account on the product or its category ' | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                      'to process this operation.')) | 
					 | 
					 | 
					                      'to process this operation.')) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                products.create_price_change_account_move(new_std_price, | 
					 | 
					 | 
					            # products.create_price_change_account_move(new_std_price, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                                          account_id, | 
					 | 
					 | 
					            #                                                       account_id, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                                          move.company_id.id, | 
					 | 
					 | 
					            #                                                       move.company_id.id, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                                          move.origin) | 
					 | 
					 | 
					            #                                                       move.origin) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            tmpl_dict[move.product_id.id] += qty_done | 
					 | 
					 | 
					            # Update the standard price for the product | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            # Write the standard price, as SUPERUSER_ID because a warehouse | 
					 | 
					 | 
					            move.product_id.with_company(move.company_id.id).with_context( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            # manager may not have the right to write on products | 
					 | 
					 | 
					                disable_auto_svl=True).sudo().write( | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					            move.product_id.with_context( | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                force_company=move.company_id.id).sudo().write( | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                {'standard_price': new_std_price}) | 
					 | 
					 | 
					                {'standard_price': new_std_price}) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            std_price_update[ | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                move.company_id.id, move.product_id.id] = new_std_price | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					
  |