You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							112 lines
						
					
					
						
							5.9 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							112 lines
						
					
					
						
							5.9 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| ################################################################################ | |
| # | |
| #    Cybrosys Technologies Pvt. Ltd. | |
| #    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |
| #    Author: Ammu Raj (odoo@cybrosys.com) | |
| # | |
| #    This program is free software: you can modify | |
| #    it under the terms of the GNU Affero General Public License (AGPL) as | |
| #    published by the Free Software Foundation, either version 3 of the | |
| #    License, or (at your option) any later version. | |
| # | |
| #    This program is distributed in the hope that it will be useful, | |
| #    but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | |
| #    GNU Affero General Public License for more details. | |
| # | |
| #    You should have received a copy of the GNU Affero General Public License | |
| #    along with this program.  If not, see <https://www.gnu.org/licenses/>. | |
| # | |
| ################################################################################ | |
| from collections import defaultdict | |
| from odoo import models, _ | |
| from odoo.exceptions import UserError | |
| from odoo.tools import float_is_zero | |
| 
 | |
| 
 | |
| class StockMove(models.Model): | |
|     """ Class to inherit stock_move to update the product price """ | |
|     _inherit = "stock.move" | |
| 
 | |
|     def product_price_update_before_done(self, forced_qty=None): | |
|         tmpl_dict = defaultdict(lambda: 0.0) | |
|         # adapt standard price on incoming moves if the product cost_method is | |
|         # 'average' | |
|         std_price_update = {} | |
|         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 | |
| 
 | |
|             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.quantity, 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, | |
|                                   precision_rounding=rounding): | |
|                 new_std_price = move._get_price_unit() | |
|             else: | |
|                 # Get the standard price | |
|                 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_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()[self.env['stock.lot']] | |
|             # 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.')) | |
|             move.product_id.with_company(move.company_id.id).with_context( | |
|                 disable_auto_svl=True).sudo().write( | |
|                 {'standard_price': new_std_price})
 | |
| 
 |