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.
		
		
		
		
		
			
		
			
				
					
					
						
							185 lines
						
					
					
						
							8.7 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							185 lines
						
					
					
						
							8.7 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| ################################################################################ | |
| # | |
| #    Cybrosys Technologies Pvt. Ltd. | |
| #    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |
| #    Author: Bhagyadev KP (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 datetime import datetime | |
| from odoo import fields, models, _ | |
| from odoo.exceptions import UserError | |
| 
 | |
| 
 | |
| class SaleOrderLine(models.Model): | |
|     """Inherits Sale order line to add the functions for checking the | |
|     visibility of the pricelists in order lines and also apply the | |
|     pricelist to order lines""" | |
|     _inherit = 'sale.order.line' | |
| 
 | |
|     pricelist_visibility = fields.Boolean( | |
|         compute="_compute_pricelist_visibility", string="Pricelist Visible", | |
|         help="Multi Pricelist enabled or not") | |
|     applied_pricelist_id = fields.Many2one('product.pricelist', | |
|                                            string="PriceList", | |
|                                            help="Price lists that is applied to" | |
|                                                 "the order line.") | |
| 
 | |
|     def _get_pricelist_price(self): | |
|         # Overriding the _get_pricelist_price method to apply multiple pricelist | |
|         self.ensure_one() | |
|         self.product_id.ensure_one() | |
|         if self.applied_pricelist_id: | |
|             for line in self: | |
|                 line.pricelist_item_id = line.applied_pricelist_id._get_product_rule( | |
|                     line.product_id, | |
|                     quantity=line.product_uom_qty or 1.0, | |
|                     uom=line.product_uom, | |
|                     date=line.order_id.date_order, | |
|                 ) | |
|             price = self.pricelist_item_id._compute_price( | |
|                 product=self.product_id.with_context( | |
|                     **self._get_product_price_context()), | |
|                 quantity=self.product_uom_qty or 1.0, | |
|                 uom=self.product_uom, | |
|                 date=self.order_id.date_order, | |
|                 currency=self.currency_id, | |
|             ) | |
|             return price | |
|         else: | |
|             price = self.pricelist_item_id._compute_price( | |
|                 product=self.product_id.with_context( | |
|                     **self._get_product_price_context()), | |
|                 quantity=self.product_uom_qty or 1.0, | |
|                 uom=self.product_uom, | |
|                 date=self.order_id.date_order, | |
|                 currency=self.currency_id, | |
|             ) | |
|             return price | |
| 
 | |
|     def apply_pricelist(self): | |
|         """This function will help to select all the pricelists | |
|         for a product in order line and apply it""" | |
|         for rec in self: | |
|             date_time_today = datetime.today().strftime("%Y-%m-%d %H:%M:%S") | |
|             # find the matching price list for a product | |
|             price_ids = self.env['product.pricelist.item'].search( | |
|                 ['|', '|', ('product_tmpl_id', '=', False), | |
|                  ('categ_id', '=', rec.product_id.categ_id.id), | |
|                  ('product_tmpl_id', '=', rec.product_id.product_tmpl_id.id), | |
|                  ('min_quantity', '<=', rec.product_uom_qty),'|', | |
|                  ('date_start', '<=', date_time_today), | |
|                  ('date_start', '=', False), '|', | |
|                  ('date_end', '>=', date_time_today), | |
|                  ('date_end', '=', False), | |
|                  ]) | |
|             variant_ids = self.env['product.pricelist.item'].search( | |
|                 [ | |
|                     ('product_id', '=', rec.product_id.id), | |
|                     ('min_quantity', '<=', rec.product_uom_qty), | |
|                     '|', ('date_start', '<=', date_time_today), | |
|                     ('date_start', '=', False), '|', | |
|                     ('date_end', '>=', date_time_today), | |
|                     ('date_end', '=', False), | |
|                 ]) | |
|             combined_ids = price_ids + variant_ids | |
|             if combined_ids: | |
|                 pricelist_wizard = self.env['pricelist.product'].create({ | |
|                     'order_line_id': rec.id, | |
|                     'line_ids': [(0, 0, { | |
|                         'pricelist_id': price.pricelist_id.id, | |
|                         'product_id': rec.product_id.id, | |
|                         'unit_price': self.unit_price(price), | |
|                         'unit_cost': rec.product_id.standard_price, | |
|                         'uom_id': rec.product_id.uom_id.id | |
|                     }) for price in combined_ids], | |
|                 }) | |
|             else: | |
|                 raise UserError(_( | |
|                     "No price list is configured for this product!")) | |
|         return { | |
|             'type': 'ir.actions.act_window', | |
|             'target': 'new', | |
|             'name': 'Select Pricelist', | |
|             'view_mode': 'form', | |
|             'view_id': self.env.ref( | |
|                 "multi_pricelist.pricelist_wizard_view_form", False).id, | |
|             'res_model': 'pricelist.product', | |
|             'res_id': pricelist_wizard.id, | |
|         } | |
| 
 | |
|     def _compute_pricelist_visibility(self): | |
|         """ Computes pricelist_visibility by checking the config parameter.""" | |
|         for rec in self: | |
|             rec.pricelist_visibility = self.env[ | |
|                 'ir.config_parameter'].sudo().get_param( | |
|                 'multi_pricelist.multi_pricelist') | |
|             if rec.order_id.state in ['sale', 'done', 'cancel']: | |
|                 rec.pricelist_visibility = False | |
| 
 | |
|     def unit_price(self, price): | |
|         """Compute the unit price of the product according to the | |
|         price_list_item""" | |
|         if price.compute_price == 'fixed': | |
|             unt_price = price.fixed_price | |
|         elif price.compute_price == 'percentage' and price.percent_price != 0: | |
|             unt_price = self.product_id.list_price * ( | |
|                     1 - price.percent_price / 100) | |
|         elif price.compute_price == 'formula' and price.base == 'list_price': | |
|             unt_price = (self.product_id.list_price * ( | |
|                     1 - price.price_discount / 100) + price.price_surcharge) | |
|             if price.price_min_margin or price.price_max_margin: | |
|                 if (unt_price < price.price_min_margin + | |
|                         self.product_id.list_price): | |
|                     unt_price = (price.price_min_margin + | |
|                                  self.product_id.list_price) | |
|                 elif (unt_price > price.price_max_margin + | |
|                       self.product_id.list_price): | |
|                     unt_price = (price.price_max_margin + | |
|                                  self.product_id.list_price) | |
|                 else: | |
|                     unt_price = unt_price | |
|         elif price.compute_price == 'formula' and price.base == 'standard_price': | |
|             unt_price = (self.product_id.standard_price * ( | |
|                     1 - price.price_discount / 100) + price.price_surcharge) | |
|             if price.price_min_margin or price.price_max_margin: | |
|                 if (unt_price < price.price_min_margin + | |
|                         self.product_id.list_price): | |
|                     unt_price = (price.price_min_margin + | |
|                                  self.product_id.list_price) | |
|                 elif (unt_price > price.price_max_margin + | |
|                       self.product_id.list_price): | |
|                     unt_price = (price.price_max_margin + | |
|                                  self.product_id.list_price) | |
|                 else: | |
|                     unt_price = unt_price | |
|         elif price.compute_price == 'formula' and price.base == 'pricelist': | |
|             unt_price = (self.unit_price(price.base_pricelist_id.item_ids) * ( | |
|                     1 - price.price_discount / 100) + price.price_surcharge) | |
|             if price.price_min_margin or price.price_max_margin: | |
|                 if (unt_price < price.price_min_margin + | |
|                         self.product_id.list_price): | |
|                     unt_price = (price.price_min_margin + | |
|                                  self.product_id.list_price) | |
|                 elif (unt_price > price.price_max_margin + | |
|                       self.product_id.list_price): | |
|                     unt_price = (price.price_max_margin + | |
|                                  self.product_id.list_price) | |
|                 else: | |
|                     unt_price = unt_price | |
|         else: | |
|             unt_price = self.product_id.list_price | |
|         return unt_price
 | |
| 
 |