# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, tools

class ProjectRevenueCustomReport3(models.Model):

    _name = "project.revenue.custom.report3"
    _description = "Project Revenue Custom Analysis report3"
    #_order = 'project_id'
    _auto = False

    start_date = fields.Date(string='Start Date', readonly=True)
    #start_datetime = fields.Datetime(string='Start Datetime111111111', readonly=True)
    end_date = fields.Date(string='End Date', readonly=True)
    project_id = fields.Many2one('project.project', string='Project', readonly=True)
    parent_project = fields.Many2one('project.project', string='Parent Project', readonly=True)
    partner_id = fields.Many2one('res.partner', string='Client', readonly=True)
    timesheet_id = fields.Integer(string='Timesheet ID', readonly=True)
    pricing_type = fields.Selection([
        ('fixed_rate', 'Fixed rate'),
        ('employee_rate', 'Consultant rate')
    ], string="Pricing", readonly=True)
    project_type = fields.Selection([
        ('hours_in_consultant', 'Hours are budgeted according to a consultant'),
        ('hours_no_limit', 'Total hours are budgeted without division to consultant'),
    ], string="Project Type", readonly=True)
    employee_id = fields.Many2one('hr.employee', string='Consultant', readonly=True)
    timesheet_sdatetime = fields.Datetime(string='Timesheet Start Time', readonly=True)
    unit_amount = fields.Float('Timesheet Hours', digits=(16, 2))
    timesheet_cost = fields.Float('Hourly Cost', digits=(16, 2))
    profit_per = fields.Float(string='Profit (%)', digits=(16, 2))
    profit_amt = fields.Float(string='Profit Amount', digits=(16, 2))
    expenses_amt = fields.Float(string='Expenses Amount', digits=(16, 2))
    pro_hourly_rate = fields.Float("Hourly Revenue", digits=(16, 2), group_operator="max")
    budgeted_hours = fields.Float("Budgeted Hours", digits=(16, 2), readonly=True, group_operator="sum")
    budgeted_revenue = fields.Float("Budgeted Revenue", digits=(16, 2), readonly=True, group_operator="sum")
    actual_revenue = fields.Float("Actual Revenue", digits=(16, 2), readonly=True, group_operator="sum")
    actual_cost = fields.Float("Actual Cost", digits=(16, 2), readonly=True, group_operator="sum")
    overall_budgeted_revenue = fields.Float("Overall Budgeted Rev.", digits=(16, 2), readonly=True, group_operator="sum")
    overall_hourly_rate = fields.Float("Overall Hourly Rate", digits=(16, 2), group_operator="sum")
    project_active = fields.Boolean('Active')
    tag_name = fields.Char("Tag Name")
    role = fields.Selection([('Manager', 'Manager'), ('Employee', 'Employee')], string="Role")
    #is_sub_project = fields.Boolean("Is Sub Project")
    sub_project = fields.Many2one('project.project', string='Sub Project')


    def init(self):
        '''Create the view'''
        tools.drop_view_if_exists(self._cr, self._table)
        self._cr.execute("""
        CREATE OR REPLACE VIEW %s AS (
with pro_data as (
    SELECT
        PRO.id as pproject_id,
        PRO.date_start as pro_sdate, 
        PRO.date as pro_edate,
        PRO.active as project_active,
        PRO.project_type,
        PRO.pricing_type,
        PRO.is_sub_project,
        (select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parent_project,
     --(select PRO.id from project_subproject_rel as PAR where PRO.id=PAR.project_id limit 1) as parent_project,
        STRING_AGG(distinct tag_master.name, ', ') as tag_name,
        PRO.partner_id AS partner_id,
        PRO.budgeted_revenue as budgeted_revenue,
        PRO.budgeted_hours2 as budgeted_hours,
        PRO.expenses_amt as expenses_amt,
        PRO.hourly_rate AS pro_hourly_rate
    FROM project_project PRO
    LEFT JOIN custom_project_tags_project_project_rel AS cus_pro_tag ON pro.id = cus_pro_tag.project_project_id
    LEFT JOIN custom_project_tags as tag_master ON tag_master.id = cus_pro_tag.custom_project_tags_id
    group by pro.id
),
sub_pro_data as (
    SELECT
        PRO.parent_project as pproject_id,
        PRO.date_start as pro_sdate, 
        PRO.date as pro_edate,
        PRO.active as project_active,
        PRO.project_type,
        PRO.pricing_type,
        PRO.is_sub_project,
        PRO.id as sub_project,
        (select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parent_project,
     --(select PRO.id from project_subproject_rel as PAR where PRO.id=PAR.project_id limit 1) as parent_project,
        STRING_AGG(distinct tag_master.name, ', ') as tag_name,
        PRO.partner_id AS partner_id,
        PRO.budgeted_revenue as budgeted_revenue,
        PRO.budgeted_hours2 as budgeted_hours,
        PRO.expenses_amt as expenses_amt,
        PRO.hourly_rate AS pro_hourly_rate
    FROM project_project PRO
    LEFT JOIN custom_project_tags_project_project_rel AS cus_pro_tag ON pro.id = cus_pro_tag.project_project_id
    LEFT JOIN custom_project_tags as tag_master ON tag_master.id = cus_pro_tag.custom_project_tags_id
    where PRO.is_sub_project=True
    group by pro.id
),
cons_data1 as (
    SELECT
        date_trunc('month', min(PRO_EMP.start_date)) AS min,
        date_trunc('month', coalesce(max(PRO_EMP.end_date), current_date AT TIME ZONE 'UTC')) AS max,
        PRO_EMP.start_date as start_date,
      --PRO_EMP.end_date as end_date,
        coalesce(PRO_EMP.end_date, current_date AT TIME ZONE 'UTC') as end_date,
        PRO_EMP.project_id,
        PRO_EMP.employee_id,
        PRO_EMP.role,
        PRO_EMP.cost as budgeted_revenue,
        PRO_EMP.budgeted_qty as budgeted_hours,
        PRO_EMP.employee_price as cons_timesheet_cost,
        PRO_EMP.price_unit as cons_hourly_cost
    FROM project_sale_line_employee_map PRO_EMP
    group by start_date, end_date, project_id, employee_id, role, budgeted_revenue, budgeted_hours, cons_timesheet_cost, cons_hourly_cost
),
tsheet_data1 as (
    SELECT
        date_trunc('month', min(AAL.start_datetime::date)) AS min,
        date_trunc('month', max(AAL.end_datetime::date)) AS max,
        AAL.project_id,
        AAL.employee_id
    FROM account_analytic_line AAL
    group by AAL.project_id, AAL.employee_id
),
drange_data2 as (
    SELECT
        cons_data1.project_id,
        cons_data1.employee_id,
        generate_series(min, max,'1 month'):: date AS start_date,
        (generate_series(min, max, '1 month'):: date + '1 month' :: interval - '1 day' :: interval):: date AS end_date
    FROM cons_data1
),
invoice_date as (
      SELECT 
        date, 
        project_id, 
        (SELECT id FROM hr_employee WHERE LOWER(name)=LOWER('Fixed amount') limit 1) as employee_id,
        fixed_amount from project_revenue_lines
),
data1 as (
     SELECT 
        TO_CHAR(start_datetime, 'YYYY-MM-01')::date as start_date,
        (date_trunc('month', end_datetime) + interval '1 month' - interval '1 day')::date as end_date,
        pro_data.pproject_id as project_id,
        pro_data.project_active,
        pro_data.project_type,
        pro_data.pricing_type,
        pro_data.parent_project,
        AAL.sub_project,
        null::char as role,
        pro_data.tag_name,
        pro_data.partner_id,
        AAL.employee_id,
        AAL.id as timesheet_id,
        AAL.start_datetime as timesheet_sdatetime,
        0 as overall_budgeted_revenue,
        0 as budgeted_revenue,
        0 as budgeted_hours,
        0 as overall_hourly_rate,
        sum(AAL.unit_amount) as unit_amount, 
        0 AS pro_hourly_rate,
        ((sum(AAL.amount) * -1)/NULLIF(sum(AAL.unit_amount), 0)) as timesheet_cost,
        0.0 AS actual_revenue,
        (sum(AAL.amount) * -1) as actual_cost,
        0.0 AS expenses_amt,
        (0.0 - (sum(AAL.amount) * -1)) AS profit_amt,
        0.0 AS profit_per
        FROM pro_data
        right join account_analytic_line AAL on AAL.project_id=pro_data.pproject_id 
        where pro_data.pricing_type = 'fixed_rate' 
        and AAL.sub_project is null
        and COALESCE(pro_data.is_sub_project, FALSE) = False 
    group by  
        pro_data.pproject_id,
        pro_data.project_active,
        pro_data.project_type,
        pro_data.pricing_type,
        pro_data.parent_project,
        AAL.sub_project,
        pro_data.tag_name,
        pro_data.partner_id,
        AAL.employee_id,
        AAL.id,
        AAL.start_datetime
),
data1_sub as (
     SELECT 
        TO_CHAR(start_datetime, 'YYYY-MM-01')::date as start_date,
        (date_trunc('month', end_datetime) + interval '1 month' - interval '1 day')::date as end_date,
        sub_pro_data.parent_project as project_id,
        sub_pro_data.project_active,
        sub_pro_data.project_type,
        sub_pro_data.pricing_type,
        sub_pro_data.parent_project,
        AAL.sub_project,
        null::char as role,
        sub_pro_data.tag_name,
        sub_pro_data.partner_id,
        AAL.employee_id,
        AAL.id as timesheet_id,
        AAL.start_datetime as timesheet_sdatetime,
        0 as overall_budgeted_revenue,
        0 as budgeted_revenue,
        0 as budgeted_hours,
        0 as overall_hourly_rate,
        sum(AAL.unit_amount) as unit_amount, 
        0 AS pro_hourly_rate,
        ((sum(AAL.amount) * -1)/NULLIF(sum(AAL.unit_amount), 0)) as timesheet_cost,
        0.0 AS actual_revenue,
        (sum(AAL.amount) * -1) as actual_cost,
        0.0 AS expenses_amt,
        (0.0 - (sum(AAL.amount) * -1)) AS profit_amt,
        0.0 AS profit_per
        FROM sub_pro_data
        right join account_analytic_line AAL on AAL.sub_project=sub_pro_data.sub_project  
        where sub_pro_data.pricing_type = 'fixed_rate' 
        and AAL.sub_project is not null
        and sub_pro_data.is_sub_project = TRUE 
    group by  
        sub_pro_data.parent_project,
        sub_pro_data.project_active,
        sub_pro_data.project_type,
        sub_pro_data.pricing_type,
        sub_pro_data.parent_project,
        AAL.sub_project,
        sub_pro_data.tag_name,
        sub_pro_data.partner_id,
        AAL.employee_id,
        AAL.id,
        AAL.start_datetime
),
data2 as (
     SELECT 
        --coalesce(min(pro_data.pro_sdate), min(AAL.start_datetime::date)) as start_date,
        --coalesce(max(pro_data.pro_edate), max(AAL.end_datetime::date)) as end_date,
        null::date as start_date,
        null::date as end_date,
        pro_data.pproject_id as project_id,
        pro_data.project_active,
        pro_data.project_type,
        pro_data.pricing_type,
        pro_data.parent_project,
        null::int as sub_project,
        null::char as role,
        pro_data.tag_name,
        pro_data.partner_id,
        null::int AS employee_id,
        null::int As timesheet_id,
        null::timestamp as timesheet_sdatetime,
        0 as overall_budgeted_revenue,
        pro_data.budgeted_revenue,
        pro_data.budgeted_hours,
        0 as overall_hourly_rate,
        0 as unit_amount, 
        0.0 AS pro_hourly_rate,
        0 as timesheet_cost,
        0.0 AS actual_revenue,
        0 as actual_cost,
        pro_data.expenses_amt,
        0.0 AS profit_amt,
        0.0 AS profit_per
        FROM pro_data
        right join account_analytic_line AAL on AAL.project_id=pro_data.pproject_id
        WHERE pro_data.pricing_type='employee_rate' and pro_data.project_type='hours_no_limit' 
        and AAL.sub_project is null 
        and COALESCE(pro_data.is_sub_project, FALSE) = False 
        and (pro_data.budgeted_revenue>0 or pro_data.budgeted_hours>0)
    group by  
        pro_data.pproject_id,
        pro_data.project_active,
        pro_data.project_type,
        pro_data.pricing_type,
        pro_data.parent_project,
        sub_project,
        pro_data.tag_name,
        pro_data.partner_id,
        pro_data.budgeted_revenue,
        pro_data.budgeted_hours,
        pro_data.expenses_amt
UNION
SELECT 
        TO_CHAR(start_datetime, 'YYYY-MM-01')::date as start_date,
        (date_trunc('month', end_datetime) + interval '1 month' - interval '1 day')::date as end_date,
        pro_data.pproject_id as project_id,
        pro_data.project_active,
        pro_data.project_type,
        pro_data.pricing_type,
        pro_data.parent_project,
        AAL.sub_project,
        null::char as role,
        pro_data.tag_name,
        pro_data.partner_id,
        AAL.employee_id,
        AAL.id as timesheet_id,
        AAL.start_datetime as timesheet_sdatetime,
        0 as overall_budgeted_revenue,
        0 as budgeted_revenue,
        0 as budgeted_hours,
        0 as overall_hourly_rate,
        AAL.unit_amount as unit_amount,
        pro_data.pro_hourly_rate as pro_hourly_rate,
        ((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) as timesheet_cost,
        (AAL.unit_amount * pro_data.pro_hourly_rate) AS actual_revenue,
        (AAL.amount * -1) as actual_cost,
        0 AS expenses_amt,
        ((AAL.unit_amount * pro_data.pro_hourly_rate) - (AAL.amount * -1)) AS profit_amt,
        ((AAL.unit_amount * pro_data.pro_hourly_rate) - (AAL.amount * -1))/NULLIF((AAL.unit_amount * pro_data.pro_hourly_rate),0) AS profit_per
        FROM pro_data
        right join account_analytic_line AAL on AAL.project_id=pro_data.pproject_id 
        WHERE pro_data.pricing_type='employee_rate' and pro_data.project_type='hours_no_limit'
        AND AAL.sub_project is null 
        AND COALESCE(pro_data.is_sub_project, FALSE) = False 
    group by  
        pro_data.pro_sdate,
        pro_data.pro_edate,
        pro_data.pproject_id,
        pro_data.project_active,
        pro_data.project_type,
        pro_data.pricing_type,
        pro_data.parent_project,
        AAL.sub_project,
        pro_data.tag_name,
        pro_data.partner_id,
        AAL.employee_id,
        AAL.id,
        AAL.start_datetime,
        pro_data.pro_hourly_rate,
        AAL.unit_amount,
        AAL.amount,
        pro_data.budgeted_hours,
        pro_data.expenses_amt        
),
data2_sub_project as (
     SELECT 
        --min(sub_pro_data.pro_sdate) as start_date,
        --max(sub_pro_data.pro_edate)as end_date,
        null::date as start_date,
        null::date as end_date,
        sub_pro_data.parent_project as project_id,
        sub_pro_data.project_active,
        sub_pro_data.project_type,
        sub_pro_data.pricing_type,
        sub_pro_data.parent_project,
        sub_pro_data.sub_project,
        null::char as role,
        sub_pro_data.tag_name,
        sub_pro_data.partner_id,
        null::int AS employee_id,
        null::int As timesheet_id,
        null::timestamp as timesheet_sdatetime,
        0 as overall_budgeted_revenue,
        sub_pro_data.budgeted_revenue,
        sub_pro_data.budgeted_hours,
        0 as overall_hourly_rate,
        0 as unit_amount, 
        0.0 AS pro_hourly_rate,
        0 as timesheet_cost,
        0.0 AS actual_revenue,
        0 as actual_cost,
        sub_pro_data.expenses_amt,
        0.0 AS profit_amt,
        0.0 AS profit_per
        FROM sub_pro_data
        WHERE sub_pro_data.pricing_type='employee_rate' and sub_pro_data.project_type='hours_no_limit' 
        and sub_pro_data.is_sub_project = TRUE
        and (sub_pro_data.budgeted_revenue>0 or sub_pro_data.budgeted_hours>0)
    group by  
        sub_pro_data.parent_project,
        sub_pro_data.project_active,
        sub_pro_data.project_type,
        sub_pro_data.pricing_type,
        sub_pro_data.parent_project,
        sub_pro_data.sub_project,
        sub_pro_data.tag_name,
        sub_pro_data.partner_id,
        sub_pro_data.budgeted_revenue,
        sub_pro_data.budgeted_hours,
        sub_pro_data.expenses_amt     
UNION
SELECT 
        TO_CHAR(start_datetime, 'YYYY-MM-01')::date as start_date,
        (date_trunc('month', end_datetime) + interval '1 month' - interval '1 day')::date as end_date,
        sub_pro_data.pproject_id as project_id,
        sub_pro_data.project_active,
        sub_pro_data.project_type,
        sub_pro_data.pricing_type,
        sub_pro_data.parent_project,
        AAL.sub_project,
        null::char as role,
        sub_pro_data.tag_name,
        sub_pro_data.partner_id,
        AAL.employee_id,
        AAL.id as timesheet_id,
        AAL.start_datetime as timesheet_sdatetime,
        0 as overall_budgeted_revenue,
        0 as budgeted_revenue,
        0 as budgeted_hours,
        0 as overall_hourly_rate,
        AAL.unit_amount as unit_amount,
        sub_pro_data.pro_hourly_rate as pro_hourly_rate,
        ((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) as timesheet_cost,
        (AAL.unit_amount * sub_pro_data.pro_hourly_rate) AS actual_revenue,
        (AAL.amount * -1) as actual_cost,
        0 AS expenses_amt,
        ((AAL.unit_amount * sub_pro_data.pro_hourly_rate) - (AAL.amount * -1)) AS profit_amt,
        ((AAL.unit_amount * sub_pro_data.pro_hourly_rate) - (AAL.amount * -1))/NULLIF((AAL.unit_amount * sub_pro_data.pro_hourly_rate),0) AS profit_per
        FROM sub_pro_data
        right join account_analytic_line AAL on AAL.sub_project=sub_pro_data.sub_project
        WHERE sub_pro_data.pricing_type='employee_rate' and sub_pro_data.project_type='hours_no_limit'
        and AAL.sub_project is not null 
        and sub_pro_data.is_sub_project = TRUE 
    group by  
        sub_pro_data.pro_sdate,
        sub_pro_data.pro_edate,
        sub_pro_data.pproject_id,
        sub_pro_data.project_active,
        sub_pro_data.project_type,
        sub_pro_data.pricing_type,
        sub_pro_data.parent_project,
        AAL.sub_project,
        sub_pro_data.tag_name,
        sub_pro_data.partner_id,
        AAL.employee_id,
        AAL.id,
        AAL.start_datetime,
        sub_pro_data.pro_hourly_rate,
        AAL.unit_amount,
        AAL.amount,
        sub_pro_data.budgeted_hours,
        sub_pro_data.expenses_amt            
),
data3 as (
SELECT
    --coalesce(min(pro_data.pro_sdate), min(AAL.start_datetime::date)) as start_date,
    --coalesce(max(pro_data.pro_edate), max(AAL.end_datetime::date)) as end_date,
    null::date as start_date,
    null::date as end_date,
    pro_data.pproject_id as project_id,
    pro_data.project_active,
    pro_data.project_type,
    pro_data.pricing_type,
    pro_data.parent_project,
    null::int as sub_project,
    null::char as role,
    pro_data.tag_name,
    pro_data.partner_id,
    null::int as employee_id,
    null::int As timesheet_id,
    null::timestamp as timesheet_sdatetime,
    pro_data.budgeted_revenue AS overall_budgeted_revenue,
    0 as budgeted_revenue,
    0 as budgeted_hours,
    pro_data.pro_hourly_rate AS overall_hourly_rate,
    0.0 as unit_amount,
    0.0 as pro_hourly_rate,
    0.0 as timesheet_cost,
    0.0 as actual_revenue,
    0.0 as actual_cost,
    pro_data.expenses_amt,
    0.0 as profit_amt,
    0.0 as profit_per
    FROM pro_data
    right join account_analytic_line AAL on AAL.project_id=pro_data.pproject_id 
    where pro_data.pricing_type='employee_rate' and  pro_data.project_type='hours_in_consultant' 
    and AAL.sub_project is null
    and COALESCE(pro_data.is_sub_project, FALSE) = False 
    and (pro_data.budgeted_revenue>0 or pro_data.pro_hourly_rate>0 or pro_data.expenses_amt>0)
    group by
    pro_data.pproject_id,
    pro_data.project_active,
    pro_data.project_type,
    pro_data.parent_project,
    pro_data.budgeted_revenue,
    pro_data.tag_name,
    pro_data.pricing_type,
    pro_data.partner_id,
    pro_data.pro_hourly_rate,
    pro_data.expenses_amt
UNION
SELECT
    null::date as start_date,
    null::date as end_date,
    cons_data1.project_id,
    pro_data.project_active,
    pro_data.project_type,
    pro_data.pricing_type,
    pro_data.parent_project,
    null::int as sub_project,
    cons_data1.role,
    pro_data.tag_name,
    pro_data.partner_id,
    cons_data1.employee_id,
    null::int As timesheet_id,
    null::timestamp as timesheet_sdatetime,
    0 as overall_budgeted_revenue,
    sum(cons_data1.budgeted_revenue) as budgeted_revenue,
    sum(cons_data1.budgeted_hours) as budgeted_hours,
    0 as overall_hourly_rate,
    0 as unit_amount,
    0 as pro_hourly_rate,
    0 as timesheet_cost,
    0 as actual_revenue,
    0  as actual_cost,
    0 as expenses_amt,
    0 as profit_amt,
    0 as profit_per
    FROM pro_data
    left join cons_data1 on cons_data1.project_id = pro_data.pproject_id 
    where pro_data.pricing_type='employee_rate' and  pro_data.project_type='hours_in_consultant' 
    and COALESCE(pro_data.is_sub_project, FALSE) = False 
    and (cons_data1.budgeted_revenue>0 or cons_data1.budgeted_hours>0)
    group by
    cons_data1.project_id,
    cons_data1.employee_id,
    pro_data.project_active,
    pro_data.project_type,
    pro_data.parent_project,
    cons_data1.role,
    pro_data.tag_name,
    pro_data.pricing_type,
    pro_data.partner_id
UNION        
SELECT
    TO_CHAR(start_datetime, 'YYYY-MM-01')::date as start_date,
    (date_trunc('month', end_datetime) + interval '1 month' - interval '1 day')::date as end_date,
    pro_data.pproject_id as project_id,
    pro_data.project_active,
    pro_data.project_type,
    pro_data.pricing_type,
    pro_data.parent_project,
    AAL.sub_project,
    cons_data1.role,
    pro_data.tag_name,
    pro_data.partner_id,
    AAL.employee_id,
    AAL.id as timesheet_id,
    AAL.start_datetime as timesheet_sdatetime,
    0 as overall_budgeted_revenue,
    0 as budgeted_revenue,
    0 as budgeted_hours,
    0 as overall_hourly_rate,
    AAL.unit_amount as unit_amount,
    COALESCE(cons_data1.cons_hourly_cost, 0) as pro_hourly_rate,
    case when cons_data1.cons_timesheet_cost is null then  ((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) else cons_data1.cons_timesheet_cost 
    end as timesheet_cost,
    --coalesce(((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)), cons_data1.cons_timesheet_cost) as timesheet_cost,
    (AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)) as actual_revenue,
    case when cons_data1.cons_timesheet_cost is null then (AAL.amount * -1) else (AAL.unit_amount * cons_data1.cons_timesheet_cost) 
    end as actual_cost,  
    0 as expenses_amt,
    (AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)) - case when cons_data1.cons_timesheet_cost is null 
    then (AAL.amount * -1) else (AAL.unit_amount * cons_data1.cons_timesheet_cost) end as profit_amt,   
    (((AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)) - case when cons_data1.cons_timesheet_cost is null then (AAL.amount * -1)
    else (AAL.unit_amount * cons_data1.cons_timesheet_cost) end) / NULLIF((AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)), 0)) * 100 as profit_per 		                           
    FROM pro_data
    right join account_analytic_line AAL on AAL.project_id=pro_data.pproject_id 
    left join cons_data1 on cons_data1.project_id=AAL.project_id and cons_data1.employee_id=AAL.employee_id
    --and (AAL.start_datetime, AAL.end_datetime) OVERLAPS (cons_data1.start_date::date, cons_data1.end_date::date)
    and AAL.start_datetime --at time zone 'utc' at time zone (select tz from res_partner where id=3)
        >= cons_data1.start_date::date + '00:00:00'::time AT TIME ZONE 'UTC'
    and AAL.end_datetime --at time zone 'utc' at time zone (select tz from res_partner where id=3)
        <= cons_data1.end_date::date + '23:59:59'::time AT TIME ZONE 'UTC'
    where pro_data.pricing_type='employee_rate' and  pro_data.project_type='hours_in_consultant' 
    AND AAL.sub_project is null
    AND COALESCE(pro_data.is_sub_project, FALSE) = False 
    group by
    pro_data.pproject_id,
    AAL.employee_id,
    AAL.id,
    AAL.start_datetime,
    pro_data.project_active,
    pro_data.project_type,
    pro_data.parent_project,
    AAL.sub_project,
    cons_data1.role,
    pro_data.tag_name,
    pro_data.pricing_type,
    pro_data.partner_id,
    AAL.unit_amount,
    AAL.amount,
    cons_data1.cons_timesheet_cost,
    cons_data1.cons_hourly_cost
),
data3_sub_project as (
SELECT
    --min(sub_pro_data.pro_sdate) as start_date,
    --max(sub_pro_data.pro_edate) as end_date,
    null::date as start_date,
    null::date as end_date,
    --sub_pro_data.parent_project as project_id,
    sub_pro_data.pproject_id as project_id,
    sub_pro_data.project_active,
    sub_pro_data.project_type,
    sub_pro_data.pricing_type,
    sub_pro_data.parent_project,
    sub_pro_data.sub_project,
    null::char as role,
    sub_pro_data.tag_name,
    sub_pro_data.partner_id,
    null::int as employee_id,
    null::int As timesheet_id,
    null::timestamp as timesheet_sdatetime,
    sub_pro_data.budgeted_revenue AS overall_budgeted_revenue,
    0 as budgeted_revenue,
    0 as budgeted_hours,
    sub_pro_data.pro_hourly_rate AS overall_hourly_rate,
    0.0 as unit_amount,
    0.0 as pro_hourly_rate,
    0.0 as timesheet_cost,
    0.0 as actual_revenue,
    0.0 as actual_cost,
    sub_pro_data.expenses_amt,
    0.0 as profit_amt,
    0.0 as profit_per
    FROM sub_pro_data
    where sub_pro_data.pricing_type='employee_rate' and sub_pro_data.project_type='hours_in_consultant' 
    and sub_pro_data.is_sub_project = True
    and (sub_pro_data.budgeted_revenue>0 or sub_pro_data.pro_hourly_rate>0 or sub_pro_data.expenses_amt>0)
    group by
    sub_pro_data.pproject_id,
    sub_pro_data.project_active,
    sub_pro_data.project_type,
    sub_pro_data.parent_project,
    sub_pro_data.sub_project,
    sub_pro_data.budgeted_revenue,
    sub_pro_data.tag_name,
    sub_pro_data.pricing_type,
    sub_pro_data.partner_id,
    sub_pro_data.pro_hourly_rate,
    sub_pro_data.expenses_amt
UNION
SELECT
    null::date as start_date,
    null::date as end_date,
    sub_pro_data.pproject_id as project_id,
    sub_pro_data.project_active,
    sub_pro_data.project_type,
    sub_pro_data.pricing_type,
    sub_pro_data.parent_project,
    sub_pro_data.sub_project,
    cons_data1.role,
    sub_pro_data.tag_name,
    sub_pro_data.partner_id,
    cons_data1.employee_id,
    null::int As timesheet_id,
    null::timestamp as timesheet_sdatetime,
    0 as overall_budgeted_revenue,
    sum(cons_data1.budgeted_revenue) as budgeted_revenue,
    sum(cons_data1.budgeted_hours) as budgeted_hours,
    0 as overall_hourly_rate,
    0 as unit_amount,
    0 as pro_hourly_rate,
    0 as timesheet_cost,
    0 as actual_revenue,
    0  as actual_cost,
    0 as expenses_amt,
    0 as profit_amt,
    0 as profit_per
    FROM sub_pro_data
    left join cons_data1 on cons_data1.project_id = sub_pro_data.sub_project
    where sub_pro_data.pricing_type='employee_rate' and sub_pro_data.project_type='hours_in_consultant' 
    and sub_pro_data.is_sub_project = True
    and (cons_data1.budgeted_revenue>0 or  cons_data1.budgeted_hours>0)
    group by
    sub_pro_data.pproject_id,
    cons_data1.employee_id,
    sub_pro_data.project_active,
    sub_pro_data.project_type,
    sub_pro_data.parent_project,
    sub_pro_data.sub_project,
    cons_data1.role,
    sub_pro_data.tag_name,
    sub_pro_data.pricing_type,
    sub_pro_data.partner_id
UNION
SELECT
    TO_CHAR(start_datetime, 'YYYY-MM-01')::date as start_date,
    (date_trunc('month', end_datetime) + interval '1 month' - interval '1 day')::date as end_date,
    sub_pro_data.pproject_id as project_id,
    sub_pro_data.project_active,
    sub_pro_data.project_type,
    sub_pro_data.pricing_type,
    sub_pro_data.parent_project,
    sub_pro_data.sub_project,
    cons_data1.role,
    sub_pro_data.tag_name,
    sub_pro_data.partner_id,
    AAL.employee_id,
    AAL.id as timesheet_id,
    AAL.start_datetime as timesheet_sdatetime,
    0 as overall_budgeted_revenue,
    0 as budgeted_revenue,
    0 as budgeted_hours,
    0 as overall_hourly_rate,
    AAL.unit_amount as unit_amount,
    COALESCE(cons_data1.cons_hourly_cost, 0) as pro_hourly_rate,
    case when cons_data1.cons_timesheet_cost is null then  ((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) else cons_data1.cons_timesheet_cost 
    end as timesheet_cost,
    --coalesce(((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)), cons_data1.cons_timesheet_cost) as timesheet_cost,
    (AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)) as actual_revenue,
    case when cons_data1.cons_timesheet_cost is null then (AAL.amount * -1) else (AAL.unit_amount * cons_data1.cons_timesheet_cost) 
    end as actual_cost,  
    0 as expenses_amt,
    (AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)) - case when cons_data1.cons_timesheet_cost is null 
    then (AAL.amount * -1) else (AAL.unit_amount * cons_data1.cons_timesheet_cost) end as profit_amt,   
    (((AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)) - case when cons_data1.cons_timesheet_cost is null then (AAL.amount * -1)
    else (AAL.unit_amount * cons_data1.cons_timesheet_cost) end) / NULLIF((AAL.unit_amount * COALESCE(cons_data1.cons_hourly_cost, 0)), 0)) * 100 as profit_per 		                           
    FROM sub_pro_data
    right join account_analytic_line AAL on AAL.sub_project=sub_pro_data.sub_project
    left join cons_data1 on cons_data1.project_id=AAL.sub_project and cons_data1.employee_id=AAL.employee_id
    --and (AAL.start_datetime, AAL.end_datetime) OVERLAPS (cons_data1.start_date::date, cons_data1.end_date::date)
    and AAL.start_datetime --at time zone 'utc' at time zone (select tz from res_partner where id=3)
        >= cons_data1.start_date::date + '00:00:00'::time AT TIME ZONE 'UTC'
    and AAL.end_datetime --at time zone 'utc' at time zone (select tz from res_partner where id=3)
        <= cons_data1.end_date::date + '23:59:59'::time AT TIME ZONE 'UTC'
    where sub_pro_data.pricing_type='employee_rate' and  sub_pro_data.project_type='hours_in_consultant' 
    AND AAL.sub_project is not null
    AND sub_pro_data.is_sub_project = True
    group by
    sub_pro_data.pproject_id,
    AAL.employee_id,
    AAL.id,
    AAL.start_datetime,
    sub_pro_data.project_active,
    sub_pro_data.project_type,
    sub_pro_data.parent_project,
    sub_pro_data.sub_project,
    cons_data1.role,
    sub_pro_data.tag_name,
    sub_pro_data.pricing_type,
    sub_pro_data.partner_id,
    AAL.unit_amount,
    AAL.amount,
    cons_data1.cons_timesheet_cost,
    cons_data1.cons_hourly_cost
),
invoice_data as (SELECT
    invoice_date.date as start_date,
    invoice_date.date as end_date,
    invoice_date.project_id,
    pro_data.project_active,
    pro_data.project_type,
    pro_data.pricing_type,
    pro_data.parent_project,
    null::int as sub_project,
    null::char as role,
    pro_data.tag_name,
    pro_data.partner_id,
    invoice_date.employee_id,
    null::int As timesheet_id,
    null::timestamp as timesheet_sdatetime,
    0 as overall_budgeted_revenue,
    0 as budgeted_revenue,
    0 as budgeted_hours,
    0 as overall_hourly_rate,
    0 as unit_amount,
    0 as pro_hourly_rate,
    0 as timesheet_cost,
    invoice_date.fixed_amount as actual_revenue,
    0 as actual_cost,
    0.0 AS expenses_amt,
    0.0 AS profit_amt,
    0.0 AS profit_per
    from invoice_date
    left join pro_data on pro_data.pproject_id = invoice_date.project_id --and pro_data.employee_id = invoice_date.employee_id
    where COALESCE(pro_data.is_sub_project, FALSE) = False
    ),
invoice_data_sub as (SELECT
    invoice_date.date as start_date,
    invoice_date.date as end_date,
    --invoice_date.project_id,
    sub_pro_data.parent_project as project_id,
    sub_pro_data.project_active,
    sub_pro_data.project_type,
    sub_pro_data.pricing_type,
    sub_pro_data.parent_project,
    sub_pro_data.sub_project,
    null::char as role,
    sub_pro_data.tag_name,
    sub_pro_data.partner_id,
    invoice_date.employee_id,
    null::int As timesheet_id,
    null::timestamp as timesheet_sdatetime,
    0 as overall_budgeted_revenue,
    0 as budgeted_revenue,
    0 as budgeted_hours,
    0 as overall_hourly_rate,
    0 as unit_amount,
    0 as pro_hourly_rate,
    0 as timesheet_cost,
    invoice_date.fixed_amount as actual_revenue,
    0 as actual_cost,
    0.0 AS expenses_amt,
    0.0 AS profit_amt,
    0.0 AS profit_per
    from invoice_date
    left join sub_pro_data on sub_pro_data.sub_project = invoice_date.project_id 
    where sub_pro_data.is_sub_project = True
    ),
res as (
select * from data1
UNION
select * from data1_sub
UNION
select * from data2
UNION
select * from data2_sub_project
UNION
select * from data3
UNION
select * from data3_sub_project
UNION
select * from invoice_data
UNION
select * from invoice_data_sub
)
select 
    ROW_NUMBER() OVER() as id,
    start_date,
    end_date,
    project_id,
    project_active,
    project_type,
    pricing_type,
    parent_project,
    sub_project,
    role,
    tag_name,
    partner_id,
    employee_id,
    timesheet_id,
    timesheet_sdatetime,
    overall_budgeted_revenue,
    budgeted_revenue,
    budgeted_hours,
    overall_hourly_rate,
    unit_amount,
    pro_hourly_rate,
    timesheet_cost,
    actual_revenue,
    actual_cost,
    expenses_amt,
    profit_amt,
    profit_per
    from res 
group by
    start_date,
    end_date,
    project_id,
    project_active,
    project_type,
    pricing_type,
    parent_project,
    sub_project,
    role,
    tag_name,
    partner_id,
    employee_id,
    timesheet_id,
    timesheet_sdatetime,
    overall_budgeted_revenue,
    budgeted_revenue,
    budgeted_hours,
    overall_hourly_rate,
    unit_amount,
    pro_hourly_rate,
    timesheet_cost,
    actual_revenue,
    actual_cost,
    expenses_amt,
    profit_amt,
    profit_per    
)""" % (self._table,))

    @api.model
    def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
        res = super(ProjectRevenueCustomReport3, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
        pro_hourly_rate = 0
        actual_cost = 0
        for line in res:
            try:
                if 'actual_cost' in line:
                    actual_cost = line['actual_cost']
                if 'overall_budgeted_revenue' in line and 'budgeted_hours' in line:
                    if line['budgeted_hours'] > 0:
                        line['overall_hourly_rate'] = line['overall_budgeted_revenue'] / line['budgeted_hours']
                if 'pro_hourly_rate' in line and 'budgeted_hours' in line:
                    if line['budgeted_hours'] > 0:
                        line['pro_hourly_rate'] = line['budgeted_revenue'] / line['budgeted_hours']
                if 'actual_revenue' in line and 'actual_cost' in line and not 'expenses_amt' in line:
                    line['profit_amt'] = line['actual_revenue'] - line['actual_cost']
                if 'actual_revenue' in line and 'actual_cost' in line and 'expenses_amt' in line:
                    line['profit_amt'] = line['actual_revenue'] - line['actual_cost'] - line['expenses_amt']
                if 'profit_amt' in line and 'actual_revenue' in line:
                    try:
                        line['profit_per'] = (line['profit_amt'] / line['actual_revenue']) * 100
                    except ZeroDivisionError:
                        pass
                if 'unit_amount' in line:
                    try:
                        line['timesheet_cost'] = actual_cost / line['unit_amount']
                    except ZeroDivisionError:
                        pass
            except Exception:
                pass
        return res

