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.
		
		
		
		
		
			
		
			
				
					
					
						
							370 lines
						
					
					
						
							17 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							370 lines
						
					
					
						
							17 KiB
						
					
					
				
								"""Report Wizard for Commission Plan"""
							 | 
						|
								# -*- coding: utf-8 -*-
							 | 
						|
								#############################################################################
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#
							 | 
						|
								#    Copyright (C) 2021-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
							 | 
						|
								#    Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
							 | 
						|
								#
							 | 
						|
								#    You can modify it under the terms of the GNU LESSER
							 | 
						|
								#    GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
							 | 
						|
								#
							 | 
						|
								#    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
							 | 
						|
								#
							 | 
						|
								#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
							 | 
						|
								#    (LGPL v3) along with this program.
							 | 
						|
								#    If not, see <http://www.gnu.org/licenses/>.
							 | 
						|
								#
							 | 
						|
								#############################################################################
							 | 
						|
								import io
							 | 
						|
								import json
							 | 
						|
								from odoo import models, fields, api
							 | 
						|
								from odoo.tools import date_utils
							 | 
						|
								from odoo.exceptions import ValidationError
							 | 
						|
								
							 | 
						|
								try:
							 | 
						|
								    from odoo.tools.misc import xlsxwriter
							 | 
						|
								except ImportError:
							 | 
						|
								    import xlsxwriter
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class CommissionReportWizard(models.TransientModel):
							 | 
						|
								    _name = 'commission.wizard'
							 | 
						|
								    _description = 'Commission Report Wizard'
							 | 
						|
								
							 | 
						|
								    date_from = fields.Date(string="From Date")
							 | 
						|
								    date_to = fields.Date(string="To Date")
							 | 
						|
								    salesperson_ids = fields.Many2many('res.users', string='Salesperson',
							 | 
						|
								                                       domain="[('share','=',False)]")
							 | 
						|
								    sales_team_ids = fields.Many2many('crm.team', string='Sales Team')
							 | 
						|
								    date = fields.Date(string='Date', default=fields.Date.context_today)
							 | 
						|
								    is_sales_person = fields.Boolean(default=False, string="Is sales person")
							 | 
						|
								    is_sales_team = fields.Boolean(default=False, string="Is sales team")
							 | 
						|
								
							 | 
						|
								    @api.onchange('salesperson_ids')
							 | 
						|
								    def onchange_salesperson_ids(self):
							 | 
						|
								        """Function for hide a field base on values"""
							 | 
						|
								        self.is_sales_person = True if self.salesperson_ids else False
							 | 
						|
								
							 | 
						|
								    @api.onchange('sales_team_ids')
							 | 
						|
								    def onchange_sales_team_ids(self):
							 | 
						|
								        self.is_sales_team = True if self.sales_team_ids else False
							 | 
						|
								
							 | 
						|
								    @api.constrains('sales_team_ids', 'salesperson_ids')
							 | 
						|
								    def sales_team_constrains(self):
							 | 
						|
								        """Function for showing validation error"""
							 | 
						|
								        for rec in self:
							 | 
						|
								            if self.sales_team_ids:
							 | 
						|
								                if not rec.sales_team_ids.member_ids:
							 | 
						|
								                    raise ValidationError(
							 | 
						|
								                        "Selected Sales Team haven't any Salespersons")
							 | 
						|
								                if not self.sales_team_ids.member_ids.commission_id and \
							 | 
						|
								                        not self.sales_team_ids.commission_id:
							 | 
						|
								                    raise ValidationError(
							 | 
						|
								                        "Selected Sales Team haven't any Commission Plan")
							 | 
						|
								            elif self.salesperson_ids and not rec.salesperson_ids.commission_id:
							 | 
						|
								                raise ValidationError(
							 | 
						|
								                    "Selected Salesperson haven't any Commission Plan")
							 | 
						|
								
							 | 
						|
								    def print_xls_report(self):
							 | 
						|
								        """Function for printing xlsx report"""
							 | 
						|
								        # sales person's condition starts here #
							 | 
						|
								        user_sale_orders = self.env['sale.order'].search([
							 | 
						|
								            ('user_id', 'in', self.salesperson_ids.ids)])
							 | 
						|
								        user_sale_orders_dict = {}
							 | 
						|
								        total_list = []
							 | 
						|
								        commission_list = []
							 | 
						|
								        user_commission_name = []
							 | 
						|
								        user_commission_salesperson = []
							 | 
						|
								        user_obj = user_sale_orders.mapped('user_id').sorted(key=lambda d: d.id)
							 | 
						|
								        for user in user_obj:
							 | 
						|
								            user_sale_orders_dict.update({
							 | 
						|
								                user: user_sale_orders.filtered(lambda l: l.user_id == user)
							 | 
						|
								            })
							 | 
						|
								        for user, user_sale_orders in user_sale_orders_dict.items():
							 | 
						|
								            commission_id = user.commission_id
							 | 
						|
								            if not commission_id:
							 | 
						|
								                continue
							 | 
						|
								            filtered_order_lines = user_sale_orders.filtered(
							 | 
						|
								                lambda l: self.date_from <= l.date_order.date(
							 | 
						|
								                ) <= self.date_to and l.date_order.date() >= commission_id.date_from
							 | 
						|
								            ).mapped('order_line')
							 | 
						|
								            filtered_order_lines_commission_total = sum(
							 | 
						|
								                filtered_order_lines.mapped('price_subtotal'))
							 | 
						|
								
							 | 
						|
								            if commission_id.type == 'product':
							 | 
						|
								                commission_products = commission_id.product_comm_ids.product_id
							 | 
						|
								                prod_commission = filtered_order_lines.filtered(
							 | 
						|
								                    lambda l: l.product_id in commission_products)
							 | 
						|
								                for rule in commission_id.product_comm_ids.filtered(
							 | 
						|
								                        lambda l: l.product_id in prod_commission.mapped(
							 | 
						|
								                            'product_id')):
							 | 
						|
								                    product_order_line = prod_commission.filtered(
							 | 
						|
								                        lambda l: l.product_id == rule.product_id)
							 | 
						|
								                    total_price = sum(
							 | 
						|
								                        product_order_line.mapped('price_subtotal'))
							 | 
						|
								                    product_commission = (total_price * rule.percentage) / 100
							 | 
						|
								                    total_list.append(total_price)
							 | 
						|
								                    user_commission_name.append(commission_id.name)
							 | 
						|
								                    user_commission_salesperson.append(user.name)
							 | 
						|
								                    commission_list.append(rule.amount) if (
							 | 
						|
								                            product_commission > rule.amount) \
							 | 
						|
								                        else commission_list.append(product_commission)
							 | 
						|
								
							 | 
						|
								            if commission_id.type == 'revenue' and (
							 | 
						|
								                    commission_id.revenue_type == 'graduated'):
							 | 
						|
								                for rule in commission_id.revenue_grd_comm_ids:
							 | 
						|
								                    if rule.amount_from <= filtered_order_lines_commission_total < rule.amount_to:
							 | 
						|
								                        graduated_commission = (filtered_order_lines_commission_total
							 | 
						|
								                                                * rule.graduated_commission_rate) / 100
							 | 
						|
								                        commission_list.append(graduated_commission)
							 | 
						|
								                        user_commission_name.append(commission_id.name)
							 | 
						|
								                        user_commission_salesperson.append(user.name)
							 | 
						|
								                        total_list.append(filtered_order_lines_commission_total)
							 | 
						|
								
							 | 
						|
								            if commission_id.type == 'revenue' and (
							 | 
						|
								                    commission_id.revenue_type == 'straight'):
							 | 
						|
								                straight_commission = (filtered_order_lines_commission_total
							 | 
						|
								                                       * commission_id.straight_commission_rate) / 100
							 | 
						|
								                commission_list.append(straight_commission)
							 | 
						|
								                user_commission_name.append(commission_id.name)
							 | 
						|
								                user_commission_salesperson.append(user.name)
							 | 
						|
								                total_list.append(filtered_order_lines_commission_total)
							 | 
						|
								        # sales person's condition ends here #
							 | 
						|
								
							 | 
						|
								        if not self.sales_team_ids and not self.salesperson_ids:
							 | 
						|
								            self.sales_team_ids = self.env['crm.team'].search([])
							 | 
						|
								
							 | 
						|
								        # sales team's condition starts here #
							 | 
						|
								        team_wizard_persons = self.sales_team_ids.member_ids
							 | 
						|
								        team_sale_orders = self.env['sale.order'].search(
							 | 
						|
								            [('user_id', 'in', team_wizard_persons.ids)])
							 | 
						|
								        team_sale_orders_dict = {}
							 | 
						|
								        commission_total = []
							 | 
						|
								        commission = []
							 | 
						|
								        commission_name = []
							 | 
						|
								        commission_salesperson = []
							 | 
						|
								        commission_sales_team = []
							 | 
						|
								        team_obj = team_sale_orders.mapped('user_id').sorted(key=lambda d: d.id)
							 | 
						|
								
							 | 
						|
								        for team_user in team_obj:
							 | 
						|
								            team_sale_orders_dict.update({
							 | 
						|
								                team_user: team_sale_orders.filtered(
							 | 
						|
								                    lambda l: l.user_id == team_user)
							 | 
						|
								            })
							 | 
						|
								        for team_user, team_sale_orders in team_sale_orders_dict.items():
							 | 
						|
								            commissions_id = team_user.commission_id if team_user.commission_id \
							 | 
						|
								                else team_user.sale_team_id.commission_id
							 | 
						|
								            if commissions_id:
							 | 
						|
								                filtered_order_lines = team_sale_orders.filtered(
							 | 
						|
								                    lambda l: self.date_from <= l.date_order.date(
							 | 
						|
								                    ) <= self.date_to and l.date_order.date() >= commissions_id.date_from
							 | 
						|
								                ).mapped('order_line')
							 | 
						|
								                filtered_order_lines_commission_total = sum(
							 | 
						|
								                    filtered_order_lines.mapped('price_subtotal'))
							 | 
						|
								                if commissions_id.type == 'product':
							 | 
						|
								                    commission_products = commissions_id.product_comm_ids.product_id
							 | 
						|
								                    prod_commission = filtered_order_lines.filtered(
							 | 
						|
								                        lambda l: l.product_id in commission_products)
							 | 
						|
								                    for rules in commissions_id.product_comm_ids.filtered(
							 | 
						|
								                            lambda l: l.product_id in prod_commission.mapped(
							 | 
						|
								                                'product_id')):
							 | 
						|
								                        product_order_line = prod_commission.filtered(
							 | 
						|
								                            lambda l: l.product_id == rules.product_id)
							 | 
						|
								                        total_price = sum(
							 | 
						|
								                            product_order_line.mapped('price_subtotal'))
							 | 
						|
								                        product_commission = (total_price * rules.percentage) / 100
							 | 
						|
								                        commission_total.append(total_price)
							 | 
						|
								                        commission_name.append(commissions_id.name)
							 | 
						|
								                        commission_salesperson.append(team_user.name)
							 | 
						|
								                        commission_sales_team.append(
							 | 
						|
								                            team_user.sale_team_id.name)
							 | 
						|
								                        commission.append(rules.amount) if (
							 | 
						|
								                                product_commission > rules.amount) \
							 | 
						|
								                            else commission.append(product_commission)
							 | 
						|
								
							 | 
						|
								                if commissions_id.type == 'revenue' and (
							 | 
						|
								                        commissions_id.revenue_type == 'graduated'):
							 | 
						|
								                    for rules in commissions_id.revenue_grd_comm_ids:
							 | 
						|
								                        if rules.amount_from <= filtered_order_lines_commission_total \
							 | 
						|
								                                < rules.amount_to:
							 | 
						|
								                            graduated_commission = (filtered_order_lines_commission_total
							 | 
						|
								                                                               * rules.graduated_commission_rate) / 100
							 | 
						|
								                            commission.append(graduated_commission)
							 | 
						|
								                            commission_name.append(commissions_id.name)
							 | 
						|
								                            commission_salesperson.append(team_user.name)
							 | 
						|
								                            commission_sales_team.append(
							 | 
						|
								                                team_user.sale_team_id.name)
							 | 
						|
								                            commission_total.append(
							 | 
						|
								                                filtered_order_lines_commission_total)
							 | 
						|
								
							 | 
						|
								                if commissions_id.type == 'revenue' and (
							 | 
						|
								                        commissions_id.revenue_type == 'straight'):
							 | 
						|
								                    straight_commission = (filtered_order_lines_commission_total
							 | 
						|
								                                           * commissions_id.straight_commission_rate) / 100
							 | 
						|
								                    commission.append(straight_commission)
							 | 
						|
								                    commission_name.append(commissions_id.name)
							 | 
						|
								                    commission_salesperson.append(team_user.name)
							 | 
						|
								                    commission_sales_team.append(team_user.sale_team_id.name)
							 | 
						|
								                    commission_total.append(
							 | 
						|
								                        filtered_order_lines_commission_total)
							 | 
						|
								        # sales team's condition ends here #
							 | 
						|
								
							 | 
						|
								        data = {
							 | 
						|
								            'model_id': self.id,
							 | 
						|
								            'date': self.date,
							 | 
						|
								            'date_from': self.date_from,
							 | 
						|
								            'date_to': self.date_to,
							 | 
						|
								            'sales_team_ids': self.sales_team_ids.ids,
							 | 
						|
								            'salesperson_ids': self.salesperson_ids.ids,
							 | 
						|
								            'commission_list': commission_list,
							 | 
						|
								            'total_list': total_list,
							 | 
						|
								            'commission': commission,
							 | 
						|
								            'commission_total': commission_total,
							 | 
						|
								            'commission_name': commission_name,
							 | 
						|
								            'commission_salesperson': commission_salesperson,
							 | 
						|
								            'commission_sales_team': commission_sales_team,
							 | 
						|
								            'user_commission_name': user_commission_name,
							 | 
						|
								            'user_commission_salesperson': user_commission_salesperson,
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.report',
							 | 
						|
								            'data': {
							 | 
						|
								                'model': 'commission.wizard',
							 | 
						|
								                'options': json.dumps(data, default=date_utils.json_default),
							 | 
						|
								                'output_format': 'xlsx',
							 | 
						|
								                'report_name': 'Commission Plan xlsx report'},
							 | 
						|
								            'report_type': 'xlsx'
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def get_xlsx_report(self, data, response):
							 | 
						|
								        """get_xlsx_report function"""
							 | 
						|
								        date = data['date']
							 | 
						|
								        team = data['sales_team_ids']
							 | 
						|
								        user = data['salesperson_ids']
							 | 
						|
								        commission_list = data['commission_list']
							 | 
						|
								        total_list = data['total_list']
							 | 
						|
								        commission = data['commission']
							 | 
						|
								        commission_total = data['commission_total']
							 | 
						|
								        commission_name = data['commission_name']
							 | 
						|
								        commission_salesperson = data['commission_salesperson']
							 | 
						|
								        commission_sales_team = data['commission_sales_team']
							 | 
						|
								        user_commission_name = data['user_commission_name']
							 | 
						|
								        user_commission_salesperson = data['user_commission_salesperson']
							 | 
						|
								
							 | 
						|
								        output = io.BytesIO()
							 | 
						|
								        workbook = xlsxwriter.Workbook(output, {'in_memory': True})
							 | 
						|
								        sheet = workbook.add_worksheet()
							 | 
						|
								        head = workbook.add_format({'align': 'center', 'bold': True,
							 | 
						|
								                                    'font_size': '15px', 'valign': 'vcenter'})
							 | 
						|
								        format1 = workbook.add_format({'align': 'left', 'font_size': '12px'})
							 | 
						|
								        format2 = workbook.add_format({'align': 'right', 'font_size': '12x'})
							 | 
						|
								        format3 = workbook.add_format(
							 | 
						|
								            {'align': 'right', 'font_size': '12x', 'bold': True})
							 | 
						|
								        heading = workbook.add_format({'align': 'left', 'bold': True,
							 | 
						|
								                                       'font_size': '12px',
							 | 
						|
								                                       'valign': 'vcenter'})
							 | 
						|
								        date_format = workbook.add_format(
							 | 
						|
								            {'num_format': 'dd/mm/yy', 'align': 'left', 'font_size': '10px'})
							 | 
						|
								
							 | 
						|
								        sheet.merge_range('A2:B2', "Printed Date: " + date, date_format)
							 | 
						|
								        sheet.write('A4', 'No.', heading)
							 | 
						|
								        sheet.set_column(5, 1, 25)
							 | 
						|
								        sheet.set_row(0, 25)
							 | 
						|
								        row = 5
							 | 
						|
								        col = 0
							 | 
						|
								        index = 1
							 | 
						|
								        if user:
							 | 
						|
								            sheet.merge_range('A1:E1', 'COMMISSION PLAN REPORT', head)
							 | 
						|
								            sheet.write('D2', 'Date From: ' + data['date_from'], date_format)
							 | 
						|
								            sheet.write('E2', 'Date To: ' + data['date_to'], date_format)
							 | 
						|
								
							 | 
						|
								            sheet.write('B4', 'Sale Persons', heading)
							 | 
						|
								            sheet.write('C4', 'Commission Plan Name', heading)
							 | 
						|
								            sheet.write('D4', 'Total Revenue', heading)
							 | 
						|
								            sheet.write('E4', 'Commission Amount', heading)
							 | 
						|
								
							 | 
						|
								            for j in user_commission_name:
							 | 
						|
								                sheet.write(row, col + 0, index, format2)
							 | 
						|
								                sheet.write(row, col + 1, j, format1)
							 | 
						|
								                row += 1
							 | 
						|
								                index += 1
							 | 
						|
								
							 | 
						|
								            row = 5
							 | 
						|
								            col = 0
							 | 
						|
								            for j in user_commission_salesperson:
							 | 
						|
								                sheet.write(row, col + 2, j, format1)
							 | 
						|
								                row += 1
							 | 
						|
								
							 | 
						|
								            row = 5
							 | 
						|
								            col = 0
							 | 
						|
								            for j in total_list:
							 | 
						|
								                sheet.write(row, col + 3, round(j, 2), format2)
							 | 
						|
								                row += 1
							 | 
						|
								
							 | 
						|
								            row = 5
							 | 
						|
								            col = 0
							 | 
						|
								            for i in commission_list:
							 | 
						|
								                sheet.write(row, col + 4, round(i, 2), format2)
							 | 
						|
								                row += 1
							 | 
						|
								
							 | 
						|
								            sheet.write(row + 1, col + 2, 'Total', format3)
							 | 
						|
								            sheet.write(row + 1, col + 3, round(sum(total_list), 2), format2)
							 | 
						|
								            sheet.write(row + 1, col + 4, round(sum(commission_list), 2),
							 | 
						|
								                        format2)
							 | 
						|
								
							 | 
						|
								        elif team:
							 | 
						|
								            sheet.merge_range('A1:F1', 'COMMISSION PLAN REPORT', head)
							 | 
						|
								            sheet.write('E2', 'Date From: ' + data['date_from'], date_format)
							 | 
						|
								            sheet.write('F2', 'Date To: ' + data['date_to'], date_format)
							 | 
						|
								
							 | 
						|
								            sheet.write('B4', 'Sales Teams', heading)
							 | 
						|
								            sheet.write('C4', 'Sales Person', heading)
							 | 
						|
								            sheet.write('D4', 'Commission Plan Name', heading)
							 | 
						|
								            sheet.write('E4', 'Total Revenue', heading)
							 | 
						|
								            sheet.write('F4', 'Commission Amount', heading)
							 | 
						|
								
							 | 
						|
								            for j in commission_sales_team:
							 | 
						|
								                sheet.write(row, col + 0, index, format2)
							 | 
						|
								                sheet.write(row, col + 1, j, format1)
							 | 
						|
								                row += 1
							 | 
						|
								                index += 1
							 | 
						|
								
							 | 
						|
								            row = 5
							 | 
						|
								            col = 0
							 | 
						|
								            for j in commission_salesperson:
							 | 
						|
								                sheet.write(row, col + 2, j, format1)
							 | 
						|
								                row += 1
							 | 
						|
								
							 | 
						|
								            row = 5
							 | 
						|
								            col = 0
							 | 
						|
								            for j in commission_name:
							 | 
						|
								                sheet.write(row, col + 3, j, format1)
							 | 
						|
								                row += 1
							 | 
						|
								
							 | 
						|
								            row = 5
							 | 
						|
								            col = 0
							 | 
						|
								            for j in commission_total:
							 | 
						|
								                sheet.write(row, col + 4, round(j, 2), format2)
							 | 
						|
								                row += 1
							 | 
						|
								
							 | 
						|
								            row = 5
							 | 
						|
								            col = 0
							 | 
						|
								            for i in commission:
							 | 
						|
								                sheet.write(row, col + 5, round(i, 2), format2)
							 | 
						|
								                row += 1
							 | 
						|
								
							 | 
						|
								            sheet.write(row + 1, col + 3, 'Total:', format3)
							 | 
						|
								            sheet.write(row + 1, col + 4, round(sum(commission_total), 2),
							 | 
						|
								                        format2)
							 | 
						|
								            sheet.write(row + 1, col + 5, round(sum(commission), 2), format2)
							 | 
						|
								
							 | 
						|
								        workbook.close()
							 | 
						|
								        output.seek(0)
							 | 
						|
								        response.stream.write(output.read())
							 | 
						|
								        output.close()
							 | 
						|
								
							 |