| 
						
						
							
								
							
						
						
					 | 
					@ -19,100 +19,112 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#    If not, see <http://www.gnu.org/licenses/>. | 
					 | 
					 | 
					#    If not, see <http://www.gnu.org/licenses/>. | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					# | 
					 | 
					 | 
					# | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					############################################################################# | 
					 | 
					 | 
					############################################################################# | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from datetime import timedelta, date | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import dateutil.relativedelta | 
					 | 
					 | 
					import dateutil.relativedelta | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from dateutil.relativedelta import relativedelta | 
					 | 
					 | 
					from dateutil.relativedelta import relativedelta | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					from datetime import timedelta, date | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					from odoo import models | 
					 | 
					 | 
					from odoo import models | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					class CustomReport(models.AbstractModel): | 
					 | 
					 | 
					class CustomReport(models.AbstractModel): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    """The CustomReport abstract Model is used to generate a top-selling | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    products report based on various date options.""" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    _name = "report.top_selling_product_report.top_selling_reports" | 
					 | 
					 | 
					    _name = "report.top_selling_product_report.top_selling_reports" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    _description = "Top selling products report" | 
					 | 
					 | 
					    _description = "Top selling products report" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def _get_report_values(self, docids, data=None): | 
					 | 
					 | 
					    def _get_report_values(self, docids, data=None): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        limit_value = data['period'] if data['period'] else None | 
					 | 
					 | 
					        """Generate the data for the top-selling products report. | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        Args: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            data (dict): A dictionary containing the parameters for the report. | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        Returns: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            dict: A dictionary containing the data and other details of the | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            top-selling products report.""" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        limit_value = int(data['period']) if data['period'] else None | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        date_option = data['date'] | 
					 | 
					 | 
					        date_option = data['date'] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        date_selected_from = None | 
					 | 
					 | 
					        date_selected_from = None | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        date_selected = None | 
					 | 
					 | 
					        date_selected = None | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        date_selected_to = None | 
					 | 
					 | 
					        date_selected_to = None | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        other_details = {} | 
					 | 
					 | 
					        other_details = {} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        company_id = data['company'] | 
					 | 
					 | 
					        company_id = data['company'] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        warehouse_id = data['warehouse'] | 
					 | 
					 | 
					        warehouse_id = data['warehouse'] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        from_date = date.today() - dateutil.relativedelta.relativedelta(years=100) | 
					 | 
					 | 
					        from_date = date.today() - dateutil.relativedelta.relativedelta( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            years=100) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        to_date = date.today() + dateutil.relativedelta.relativedelta(days=1) | 
					 | 
					 | 
					        to_date = date.today() + dateutil.relativedelta.relativedelta(days=1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if date_option == 'days': | 
					 | 
					 | 
					        if date_option == 'days': | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					            from_date = date.today() - dateutil.relativedelta.relativedelta( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            from_date = date.today() - dateutil.relativedelta.relativedelta(days=11) | 
					 | 
					 | 
					                days=11) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            to_date = date.today() + dateutil.relativedelta.relativedelta(days=1) | 
					 | 
					 | 
					            to_date = date.today() + dateutil.relativedelta.relativedelta( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                days=1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_selected = "Last 10 Days" | 
					 | 
					 | 
					            date_selected = "Last 10 Days" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        elif date_option == 'last_month': | 
					 | 
					 | 
					        elif date_option == 'last_month': | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					            date_limit = date.today() - dateutil.relativedelta.relativedelta( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            date_limit = date.today() - dateutil.relativedelta.relativedelta(months=1) | 
					 | 
					 | 
					                months=1) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            from_date = date_limit.replace(day=1) | 
					 | 
					 | 
					            from_date = date_limit.replace(day=1) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            to_date = (date_limit + relativedelta(months=1, day=1)) - timedelta(1) | 
					 | 
					 | 
					            to_date = (date_limit + relativedelta(months=1, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                                  day=1)) - timedelta(1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_selected = "Last Month" | 
					 | 
					 | 
					            date_selected = "Last Month" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        elif date_option == 'curr_month': | 
					 | 
					 | 
					        elif date_option == 'curr_month': | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            from_date = date.today().replace(day=1) | 
					 | 
					 | 
					            from_date = date.today().replace(day=1) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            to_date = date.today() + dateutil.relativedelta.relativedelta(days=1) | 
					 | 
					 | 
					            to_date = date.today() + dateutil.relativedelta.relativedelta( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                days=1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_selected = "Current Month" | 
					 | 
					 | 
					            date_selected = "Current Month" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        elif date_option == 'last_year': | 
					 | 
					 | 
					        elif date_option == 'last_year': | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					            date_limit = date.today() - dateutil.relativedelta.relativedelta( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            date_limit = date.today() - dateutil.relativedelta.relativedelta(years=1) | 
					 | 
					 | 
					                years=1) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            from_date = date_limit.replace(day=1) | 
					 | 
					 | 
					            from_date = date_limit.replace(day=1) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            to_date = (date_limit + relativedelta(months=12, day=1)) - timedelta(1) | 
					 | 
					 | 
					            to_date = (date_limit + relativedelta(months=12, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                                  day=1)) - timedelta(1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_selected = "Last Year" | 
					 | 
					 | 
					            date_selected = "Last Year" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        elif date_option == 'curr_year': | 
					 | 
					 | 
					        elif date_option == 'curr_year': | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_limit = date.today() - dateutil.relativedelta.relativedelta(years=1) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            from_date = date.today().replace(month=1, day=1) | 
					 | 
					 | 
					            from_date = date.today().replace(month=1, day=1) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            to_date = date.today() + dateutil.relativedelta.relativedelta(days=1) | 
					 | 
					 | 
					            to_date = date.today() + dateutil.relativedelta.relativedelta( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                days=1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_selected = "Current Year" | 
					 | 
					 | 
					            date_selected = "Current Year" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        elif date_option == 'select_period': | 
					 | 
					 | 
					        elif date_option == 'select_period': | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            from_date = data['from_date'] | 
					 | 
					 | 
					            from_date = data['from_date'] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            to_date = data['to_date'] | 
					 | 
					 | 
					            to_date = data['to_date'] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_selected_from = from_date | 
					 | 
					 | 
					            date_selected_from = from_date | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            date_selected_to = to_date | 
					 | 
					 | 
					            date_selected_to = to_date | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        other_details.update({ | 
					 | 
					 | 
					        other_details.update({ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            'limit': limit_value, | 
					 | 
					 | 
					            'limit': limit_value, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            'least': data['least'], | 
					 | 
					 | 
					            'least': data['least'], | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            'range': date_selected, | 
					 | 
					 | 
					            'range': date_selected, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            'date_selected_from': date_selected_from, | 
					 | 
					 | 
					            'date_selected_from': date_selected_from, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            'date_selected_to': date_selected_to, | 
					 | 
					 | 
					            'date_selected_to': date_selected_to, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        }) | 
					 | 
					 | 
					        }) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					        sale_report_model = self.env['sale.report'] | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        cr = self._cr | 
					 | 
					 | 
					        states = sale_report_model._get_done_states() | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        order = 'asc' if data['least'] else 'desc' | 
					 | 
					 | 
					        data_domain = [('state', 'in', states), ('date', '>=', from_date), | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        company_id = str(tuple(company_id)) if len(company_id) > 1 else "(" + str(company_id[0]) + ")" | 
					 | 
					 | 
					                       ('date', '<=', to_date), | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        warehouse_id = str(tuple(warehouse_id)) if len(warehouse_id) > 1 else "(" + str(warehouse_id[0]) + ")" | 
					 | 
					 | 
					                       ('company_id', 'in', company_id)] | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        limit_clause = " limit'%s'" % limit_value if limit_value else "" | 
					 | 
					 | 
					        if warehouse_id: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					            data_domain.append(('warehouse_id', 'in', warehouse_id)) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        query = ("""select sl.name as product_name,sum(product_uom_qty),pu.name from sale_order_line sl  | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                   JOIN sale_order so ON sl.order_id = so.id  | 
					 | 
					 | 
					        sale_data = sale_report_model.search(data_domain) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                   JOIN uom_uom pu on sl.product_uom = pu.id | 
					 | 
					 | 
					        product_dict = {} | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                   where so.date_order::DATE >= '%s'::DATE and  | 
					 | 
					 | 
					        for record in sale_data: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                   so.date_order::DATE <= '%s'::DATE and  | 
					 | 
					 | 
					            product_name = record.product_id.display_name | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                   sl.state = 'sale' and so.company_id in %s  | 
					 | 
					 | 
					            if product_name in product_dict: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                   and so.warehouse_id in %s | 
					 | 
					 | 
					                product_dict[product_name][ | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                   group by sl.name,pu.name order by sum %s""" % ( | 
					 | 
					 | 
					                    'sold_quantity'] += record.product_uom_qty | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            from_date, to_date, company_id, warehouse_id, order)) + limit_clause | 
					 | 
					 | 
					            else: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        cr.execute(query) | 
					 | 
					 | 
					                product_dict[product_name] = { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        dat = cr.dictfetchall() | 
					 | 
					 | 
					                    'product_name': product_name, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					                    'sold_quantity': record.product_uom_qty, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    'uom': record.product_uom.name, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        sorted_products = sorted(product_dict.values(), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                 key=lambda x: x['sold_quantity'], | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                 reverse=not data['least']) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        limit_products = sorted_products[:limit_value] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        return { | 
					 | 
					 | 
					        return { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            'data': dat, | 
					 | 
					 | 
					            'data': limit_products, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            'other': other_details, | 
					 | 
					 | 
					            'other': other_details, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					
  |