New report file updated

This commit is contained in:
prakash 2022-05-02 07:18:50 +05:30
parent 5d46a570c8
commit 6065b2f4b2
2 changed files with 352 additions and 0 deletions

View File

@ -0,0 +1,255 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, tools
class ProjectRevenueCustomReport2(models.Model):
_name = "project.revenue.custom.report2"
_description = "Project Revenue Custom Analysis report2"
#_order = 'project_id'
_auto = False
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)
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('Consultant Price', 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 Rate", 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")
def init(self):
'''Create the view'''
tools.drop_view_if_exists(self._cr, self._table)
self._cr.execute("""
CREATE OR REPLACE VIEW %s AS (
SELECT ROW_NUMBER() OVER() as id,
project_id,
parentproject as parent_project,
project_type,
pricing_type,
employee_id,
overall_budgeted_revenue,
partner_id,
budgeted_revenue,
budgeted_hours,
pro_hourly_rate,
overall_hourly_rate,
actual_revenue,
actual_cost,
expenses_amt,
profit_amt,
profit_per,
unit_amount,
timesheet_cost,
timesheet_sdatetime
from (
select pro.id AS project_id,
(select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parentproject,
pro.partner_id AS partner_id,
pro.project_type AS project_type,
pro.pricing_type as pricing_type,
AAL.employee_id AS employee_id,
0.0 AS overall_budgeted_revenue,
0.0 AS budgeted_revenue,
0.0 AS budgeted_hours,
0.0 AS overall_hourly_rate,
AAL.unit_amount,
0.0 AS pro_hourly_rate,
((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) as timesheet_cost,
0.0 AS actual_revenue,
(AAL.amount * -1) AS actual_cost,
0.0 AS expenses_amt,
0.0 - (AAL.amount * -1) AS profit_amt,
0.0 AS profit_per,
AAL.start_datetime AS timesheet_sdatetime
FROM project_project PRO
RIGHT JOIN account_analytic_account AA ON PRO.analytic_account_id = AA.id
RIGHT JOIN account_analytic_line AAL ON AAL.account_id = AA.id and AAL.project_id = PRO.id
WHERE PRO.active = 't' and PRO.pricing_type = 'fixed_rate'
UNION
select
pro.id AS project_id,
(select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parentproject,
pro.partner_id AS partner_id,
pro.project_type AS project_type,
pro.pricing_type as pricing_type,
null::int AS employee_id,
0.0 AS overall_budgeted_revenue,
pro.budgeted_revenue AS budgeted_revenue,
pro.budgeted_hours2 AS budgeted_hours,
0.0 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.expenses_amt AS expenses_amt,
0.0 AS profit_amt,
0.0 AS profit_per,
null::timestamp as timesheet_sdatetime
FROM project_project PRO
WHERE PRO.active = 't' and PRO.pricing_type = 'employee_rate' and PRO.project_type='hours_no_limit'
UNION
select
pro.id AS project_id,
(select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parentproject,
pro.partner_id AS partner_id,
pro.project_type AS project_type,
pro.pricing_type as pricing_type,
AAL.employee_id AS employee_id,
0.0 AS overall_budgeted_revenue,
0.0 AS budgeted_revenue,
0.0 AS budgeted_hours,
0.0 AS overall_hourly_rate,
AAL.unit_amount,
pro.hourly_rate AS pro_hourly_rate,
((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) as timesheet_cost,
(AAL.unit_amount * pro.hourly_rate) AS actual_revenue,
(AAL.amount * -1) AS actual_cost,
0.0 AS expenses_amt,
((AAL.unit_amount * pro.hourly_rate) - (AAL.amount * -1)) AS profit_amt,
((AAL.unit_amount * pro.hourly_rate) - (AAL.amount * -1))/NULLIF((AAL.unit_amount * pro.hourly_rate),0) AS profit_per,
AAL.start_datetime AS timesheet_sdatetime
FROM project_project PRO
RIGHT JOIN account_analytic_account AA ON PRO.analytic_account_id = AA.id
RIGHT JOIN account_analytic_line AAL ON AAL.account_id = AA.id and AAL.project_id = PRO.id
WHERE PRO.active = 't' and PRO.pricing_type = 'employee_rate' and PRO.project_type='hours_no_limit'
UNION
select
pro.id AS project_id,
(select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parentproject,
pro.partner_id AS partner_id,
pro.project_type AS project_type,
pro.pricing_type as pricing_type,
pro_emp.employee_id AS employee_id,
0.0 AS overall_budgeted_revenue,
pro_emp.cost AS budgeted_revenue,
0.0 as timesheet_cost,
pro_emp.budgeted_qty AS budgeted_hours,
0.0 AS overall_hourly_rate,
0.0 as unit_amount,
0.0 AS pro_hourly_rate,
0.0 AS actual_revenue,
0.0 AS actual_cost,
0.0 AS expenses_amt,
0.0 as profit_amt,
0.0 as profit_per,
null::timestamp as timesheet_sdatetime
FROM project_project PRO
Left JOIN project_sale_line_employee_map pro_emp ON pro_emp.project_id = pro.id
LEFT JOIN account_analytic_account AA ON PRO.analytic_account_id = AA.id
LEFT JOIN account_analytic_line AAL ON AAL.account_id = AA.id and AAL.project_id = PRO.id and AAL.employee_id = pro_emp.employee_id
WHERE PRO.active = 't' and PRO.pricing_type='employee_rate' and PRO.project_type='hours_in_consultant'
UNION
select
pro.id AS project_id,
(select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parentproject,
pro.partner_id AS partner_id,
pro.project_type AS project_type,
pro.pricing_type as pricing_type,
null::int AS employee_id,
pro.budgeted_revenue AS overall_budgeted_revenue,
0.0 AS budgeted_revenue,
0.0 AS budgeted_hours,
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.expenses_amt AS expenses_amt,
0.0 as profit_amt,
0.0 as profit_per,
null::timestamp as timesheet_sdatetime
FROM project_project PRO
WHERE PRO.active = 't' and PRO.pricing_type='employee_rate' and PRO.project_type='hours_in_consultant'
UNION
select
pro.id AS project_id,
(select project_id from project_subproject_rel as par where pro.id=par.id limit 1) as parentproject,
pro.partner_id AS partner_id,
pro.project_type AS project_type,
pro.pricing_type as pricing_type,
AAL.employee_id AS employee_id,
0.0 AS overall_budgeted_revenue,
0.0 AS budgeted_revenue,
0.0 AS budgeted_hours,
0.0 AS overall_hourly_rate,
AAL.unit_amount,
COALESCE(pro_emp.price_unit, 0) as pro_hourly_rate,
case when pro_emp.employee_price is null then ((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) else pro_emp.employee_price end as timesheet_cost,
(AAL.unit_amount * pro_emp.price_unit) AS actual_revenue,
case when pro_emp.employee_price is null then (AAL.amount * -1) else (AAL.unit_amount * pro_emp.employee_price) end as actual_cost,
0.0 AS expenses_amt,
(AAL.unit_amount * pro_emp.price_unit) - case when pro_emp.employee_price is null then (AAL.amount * -1) else (AAL.unit_amount * pro_emp.employee_price) end
as profit_amt,
(((AAL.unit_amount * pro_emp.price_unit) - case when pro_emp.employee_price is null then (AAL.amount * -1) else (AAL.unit_amount * pro_emp.employee_price) end)
/ NULLIF((AAL.unit_amount * pro_emp.price_unit), 0)) * 100 as profit_per,
AAL.start_datetime AS timesheet_sdatetime
FROM project_project PRO
LEFT JOIN account_analytic_account AA ON PRO.analytic_account_id = AA.id
LEFT JOIN account_analytic_line AAL ON AAL.account_id = AA.id and AAL.project_id = PRO.id
Left JOIN project_sale_line_employee_map pro_emp ON pro_emp.project_id = pro.id and AAL.employee_id = pro_emp.employee_id
LEFT JOIN hr_employee EMP ON AAL.employee_id = EMP.id
WHERE PRO.active = 't' and PRO.pricing_type='employee_rate' and PRO.project_type='hours_in_consultant'
) res
)""" % (self._table,))
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
res = super(ProjectRevenueCustomReport2, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
hourly_rate = 0
actual_cost = 0
for line in res:
try:
if 'actual_cost' in line:
actual_cost = line['actual_cost']
"""if 'pro_hourly_rate' in line:
hourly_rate = line['pro_hourly_rate']
if 'unit_amount' in line: # and 'pro_hourly_rate' in line and 'id' in line
if hourly_rate != 0:
line['actual_revenue'] = hourly_rate * line['unit_amount']
if 'unit_amount' in line and 'timesheet_cost' in line:
line['actual_cost'] = line['timesheet_cost'] * line['unit_amount']"""
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 '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

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="project_revenue_custom_report2_view_pivot" model="ir.ui.view">
<field name="name">project.revenue.custom.report2.pivot</field>
<field name="model">project.revenue.custom.report2</field>
<field name="arch" type="xml">
<pivot string="Revenue Analysis" disable_linking="True" sample="1">
<field name="project_id" type="row"/>
<field name="overall_budgeted_revenue" type="measure"/>
<field name="budgeted_revenue" type="measure"/>
<field name="actual_revenue" type="measure"/>
<field name="actual_cost" type="measure"/>
<field name="budgeted_hours" type="measure"/>
<field name="overall_hourly_rate" type="measure"/>
<field name="pro_hourly_rate" type="measure"/>
<field name="expenses_amt" type="measure"/>
<field name="profit_amt" type="measure"/>
<field name="profit_per" type="measure"/>
<field name="unit_amount" type="measure"/>
<field name="timesheet_cost" type="measure"/>
</pivot>
</field>
</record>
<record id="project_revenue_custom_report2_view_graph" model="ir.ui.view">
<field name="name">project.revenue.custom.report2.graph</field>
<field name="model">project.revenue.custom.report2</field>
<field name="arch" type="xml">
<graph string="Revenue Analysis" type="bar" stacked="True" sample="1" disable_linking="1">
<field name="project_id" type="col"/>
<field name="budgeted_revenue" type="row"/>
<field name="actual_revenue" type="row"/>
<field name="actual_cost" type="row"/>
</graph>
</field>
</record>
<record id="project_revenue_custom_report2_view_tree" model="ir.ui.view">
<field name="name">project.revenue.custom.report2.tree</field>
<field name="model">project.revenue.custom.report2</field>
<field name="arch" type="xml">
<tree string="Revenue Analysis" create="false" edit="false" delete="false">
<field name="project_id"/>
<field name="employee_id"/>
<field name="budgeted_revenue"/>
<field name="actual_revenue"/>
<field name="actual_cost"/>
<field name="budgeted_hours"/>
<field name="pro_hourly_rate"/>
<field name="profit_amt"/>
<field name="profit_per"/>
<field name="unit_amount"/>
<field name="timesheet_cost"/>
<field name="parent_project" optional="hide"/>
</tree>
</field>
</record>
<record id="project_revenue_custom_report2_view_search" model="ir.ui.view">
<field name="name">project.revenue.custom.report2.search</field>
<field name="model">project.revenue.custom.report2</field>
<field name="arch" type="xml">
<search string="Revenue Analysis">
<field name="project_id"/>
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
<field name="employee_id"/>
<filter string="Fixed rate" name="fixed" domain="[('pricing_type','=','fixed_rate')]"/>
<filter string="Hours are budgeted according to a consultant" name="cons" domain="[('pricing_type','=','employee_rate'),('project_type','=','hours_in_consultant')]"/>
<filter string="Total hours are budgeted without division to consultant" name="limit" domain="[('pricing_type','=','employee_rate'),('project_type','=','hours_no_limit')]"/>
<filter string="Not Fixed rate" name="notfixed" domain="[('pricing_type','!=','fixed_rate')]"/>
<group expand="1" string="Group By">
<filter string="Project" name="group_project" context="{'group_by':'project_id'}"/>
<filter string="Consultant" name="group_employee" context="{'group_by':'employee_id'}"/>
<filter string="Client" name="group_partner_id" context="{'group_by':'partner_id'}"/>
<filter string="Timesheet Date" name="group_t_starttime" domain="[]" context="{'group_by':'timesheet_sdatetime:month'}"/>
</group>
</search>
</field>
</record>
<record id="project_revenue_custom_report2_action" model="ir.actions.act_window">
<field name="name">Projects Revenue</field>
<field name="res_model">project.revenue.custom.report2</field>
<field name="view_mode">pivot,tree,graph</field>
<field name="search_view_id" ref="project_revenue_custom_report2_view_search"/>
<field name="context">{'search_default_group_project': 1,'search_default_group_employee': 1,'search_default_group_t_starttime': 1}</field>
</record>
<menuitem id="menu_project_revenue_custom_report2"
parent="project.menu_project_report"
action="project_revenue_custom_report2_action"
name="Projects Revenue (1.1)"
sequence="50"/>
</odoo>