Project Revenue and consultant reports updated
This commit is contained in:
parent
8887ddca44
commit
ec7067c6c1
|
@ -21,6 +21,8 @@
|
|||
'report/project_budget_amt_analysis_views.xml',
|
||||
'report/project_timeline_report_views.xml',
|
||||
'report/project_timesheet_report_views.xml',
|
||||
'report/project_revenue_custom_report_views.xml',
|
||||
'report/project_consultant_custom_report_views.xml',
|
||||
],
|
||||
'qweb': [
|
||||
"static/src/xml/base.xml",
|
||||
|
|
|
@ -5,3 +5,5 @@ from . import project_budget_hrs_analysis
|
|||
from . import project_budget_amt_analysis
|
||||
from . import project_timeline_report
|
||||
from . import project_timesheet_report
|
||||
from . import project_revenue_custom_report
|
||||
from . import project_consultant_custom_report
|
|
@ -32,10 +32,6 @@ class BudgetAmtAnalysis(models.Model):
|
|||
end_date = fields.Date(string='End Date', readonly=True)
|
||||
timesheet_date = fields.Date(string='Timesheet Date', readonly=True)
|
||||
timesheet_sdatetime = fields.Datetime(string='Timesheet Start Time', readonly=True)
|
||||
unit_amount = fields.Float('Timesheet Hours')
|
||||
timesheet_cost = fields.Float('Timesheet Cost')
|
||||
profit_per = fields.Float(string='Porfit Percentage', digits=(16, 2))
|
||||
profit_amt = fields.Float(string='Profit Amount', digits=(16, 2))
|
||||
#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")
|
||||
|
||||
|
@ -44,9 +40,7 @@ class BudgetAmtAnalysis(models.Model):
|
|||
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,
|
||||
start_date, end_date, timesheet_date, timesheet_sdatetime, unit_amount, timesheet_cost, partner_id, employee_id, amount_type,
|
||||
profit_per, profit_amt, pricing_type, project_type, revenue from (
|
||||
SELECT ROW_NUMBER() OVER() as id, project_id, parentproject as parent_project, start_date, end_date, timesheet_date, timesheet_sdatetime, partner_id, employee_id, amount_type, pricing_type, project_type, revenue 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,
|
||||
|
@ -55,14 +49,10 @@ class BudgetAmtAnalysis(models.Model):
|
|||
pro.partner_id AS partner_id,
|
||||
pro_emp.employee_id AS employee_id,
|
||||
'Budgeted Revenue' as amount_type,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
pro.pricing_type as pricing_type,
|
||||
pro.project_type as project_type,
|
||||
null::date AS timesheet_date,
|
||||
null::timestamp AS timesheet_sdatetime,
|
||||
0.0 as unit_amount,
|
||||
0.0 as timesheet_cost,
|
||||
pro_emp.cost AS revenue
|
||||
FROM project_project pro
|
||||
Left JOIN project_sale_line_employee_map pro_emp ON pro_emp.project_id = pro.id
|
||||
|
@ -76,23 +66,18 @@ class BudgetAmtAnalysis(models.Model):
|
|||
pro.partner_id AS partner_id,
|
||||
AAL.employee_id AS employee_id,
|
||||
'Actual Cost' as amount_type,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
pro.pricing_type as pricing_type,
|
||||
pro.project_type as project_type,
|
||||
AAL.date AS timesheet_date,
|
||||
AAL.start_datetime AS timesheet_sdatetime,
|
||||
AAL.unit_amount as unit_amount,
|
||||
emp.timesheet_cost as timesheet_cost,
|
||||
(AAL.unit_amount * pro_emp.employee_price) AS revenue
|
||||
(sum(AAL.unit_amount) * pro_emp.employee_price) AS revenue
|
||||
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
|
||||
LEFT JOIN hr_employee emp on AAL.employee_id = emp.id
|
||||
WHERE PRO.active = 't' and AAL.employee_id is not null and PRO.pricing_type = 'employee_rate'
|
||||
and PRO.project_type in ('hours_in_consultant', 'hours_no_limit')
|
||||
--group by pro.id, aal.employee_id, aal.date, aal.start_datetime, pro_emp.employee_price, AAL.unit_amount
|
||||
group by pro.id, aal.employee_id, aal.date, aal.start_datetime, pro_emp.employee_price
|
||||
union
|
||||
SELECT
|
||||
pro.id AS project_id,
|
||||
|
@ -102,21 +87,16 @@ class BudgetAmtAnalysis(models.Model):
|
|||
pro.partner_id AS partner_id,
|
||||
AAL.employee_id AS employee_id,
|
||||
'Actual Revenue' as amount_type,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
pro.pricing_type as pricing_type,
|
||||
pro.project_type as project_type,
|
||||
AAL.date AS timesheet_date,
|
||||
AAL.start_datetime AS timesheet_sdatetime,
|
||||
AAL.unit_amount as unit_amount,
|
||||
emp.timesheet_cost as timesheet_cost,
|
||||
(AAL.unit_amount * pro.hourly_rate) AS revenue
|
||||
(sum(AAL.unit_amount) * pro.hourly_rate) AS revenue
|
||||
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 hr_employee emp on AAL.employee_id = emp.id
|
||||
WHERE PRO.active = 't' and PRO.pricing_type = 'employee_rate' and PRO.project_type = 'hours_no_limit'
|
||||
--group by pro.id, aal.employee_id, aal.date, aal.unit_amount, aal.start_datetime, AAL.unit_amount
|
||||
group by pro.id, aal.employee_id, aal.date, aal.unit_amount, aal.start_datetime
|
||||
union
|
||||
SELECT
|
||||
pro.id AS project_id,
|
||||
|
@ -126,14 +106,10 @@ class BudgetAmtAnalysis(models.Model):
|
|||
pro.partner_id AS partner_id,
|
||||
null::int AS employee_id,
|
||||
'Budgeted Revenue' as amount_type,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
pro.pricing_type as pricing_type,
|
||||
pro.project_type as project_type,
|
||||
null::date AS timesheet_date,
|
||||
null::timestamp AS timesheet_sdatetime,
|
||||
0.0 as unit_amount,
|
||||
0.0 as timesheet_cost,
|
||||
pro.budgeted_revenue AS revenue
|
||||
FROM project_project pro
|
||||
--Left JOIN project_sale_line_employee_map pro_emp ON pro_emp.project_id = pro.id
|
||||
|
@ -147,22 +123,17 @@ class BudgetAmtAnalysis(models.Model):
|
|||
pro.partner_id AS partner_id,
|
||||
AAL.employee_id AS employee_id,
|
||||
'Actual Revenue' as amount_type,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
pro.pricing_type as pricing_type,
|
||||
pro.project_type as project_type,
|
||||
AAL.date AS timesheet_date,
|
||||
AAL.start_datetime AS timesheet_sdatetime,
|
||||
AAL.unit_amount as unit_amount,
|
||||
emp.timesheet_cost as timesheet_cost,
|
||||
(AAL.unit_amount * pro_emp.price_unit) AS revenue
|
||||
(sum(AAL.unit_amount) * pro_emp.price_unit) AS revenue
|
||||
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
|
||||
LEFT JOIN hr_employee emp on AAL.employee_id = emp.id
|
||||
WHERE PRO.active = 't' and AAL.employee_id is not null and PRO.pricing_type = 'employee_rate' and PRO.project_type = 'hours_in_consultant'
|
||||
--group by pro.id, aal.employee_id, aal.date, aal.start_datetime, AAL.unit_amount, pro_emp.price_unit
|
||||
group by pro.id, aal.employee_id, aal.date, aal.start_datetime, pro_emp.price_unit
|
||||
union
|
||||
SELECT
|
||||
pro.id AS project_id,
|
||||
|
@ -172,19 +143,14 @@ class BudgetAmtAnalysis(models.Model):
|
|||
pro.partner_id AS partner_id,
|
||||
AAL.employee_id AS employee_id,
|
||||
'Actual Cost' as amount_type,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
pro.pricing_type as pricing_type,
|
||||
pro.project_type as project_type,
|
||||
AAL.date AS timesheet_date,
|
||||
AAL.start_datetime AS timesheet_sdatetime,
|
||||
AAL.unit_amount as unit_amount,
|
||||
emp.timesheet_cost as timesheet_cost,
|
||||
(AAL.amount * -1) AS revenue
|
||||
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 hr_employee emp on AAL.employee_id = emp.id
|
||||
--and AAL.employee_id = pro_emp.employee_id
|
||||
WHERE PRO.active = 't' and PRO.pricing_type = 'fixed_rate')
|
||||
as res
|
||||
|
@ -192,6 +158,4 @@ class BudgetAmtAnalysis(models.Model):
|
|||
project_id,
|
||||
amount_type desc
|
||||
--group by Pro.id, PRO.partner_id, Pro.budgeted_revenue, AAL.amount
|
||||
)""" % (self._table,))
|
||||
|
||||
|
||||
)""" % (self._table,))
|
|
@ -6,9 +6,8 @@
|
|||
<field name="model">project.budget.amt.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Budget Analysis" disable_linking="True" sample="1"> <!-- display_quantity="true" -->
|
||||
<field name="project_id" type="row"/>
|
||||
<field name="unit_amount" type="measure"/>
|
||||
<field name="timesheet_cost" type="measure"/>
|
||||
<field name="project_id" type="col"/>
|
||||
<field name="amount_type" type="col"/>
|
||||
<field name="revenue" type="measure"/>
|
||||
</pivot>
|
||||
</field>
|
||||
|
@ -20,7 +19,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<graph string="Budget Analysis" type="bar" stacked="False" sample="1" disable_linking="1">
|
||||
<field name="revenue" type="row"/>
|
||||
<field name="project_id" type="col"/>
|
||||
<field name="project_id" type="row"/>
|
||||
<field name="amount_type" type="row"/>
|
||||
<field name="revenue" type="measure"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -35,7 +36,6 @@
|
|||
<field name="end_date"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="timesheet_date" optional="hide"/>
|
||||
<field name="unit_amount"/>
|
||||
<field name="amount_type"/>
|
||||
<field name="revenue"/>
|
||||
<field name="parent_project" optional="hide"/>
|
||||
|
@ -80,7 +80,6 @@
|
|||
<field name="res_model">project.budget.amt.report</field>
|
||||
<field name="view_mode">graph,tree,pivot</field>
|
||||
<field name="search_view_id" ref="project_budget_amt_report_view_search"/>
|
||||
<!--<field name="context">{'default_res_model': 'project.budget.amt.report'}</field>-->
|
||||
<field name="context">{'search_default_group_by_project': 1,'search_default_group_by_amount_type': 1, 'default_res_model': 'project.budget.amt.report', 'search_default_notfixed':1}</field>
|
||||
</record>
|
||||
|
||||
|
@ -90,4 +89,4 @@
|
|||
name="Projects Revenue Acutal Vs Budget"
|
||||
sequence="50"/>
|
||||
|
||||
</odoo>
|
||||
</odoo>
|
|
@ -0,0 +1,58 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, tools
|
||||
|
||||
|
||||
class ProjectConsultantCustomReport(models.Model):
|
||||
|
||||
_name = "project.consultant.custom.report"
|
||||
_description = "Project Consultant Custom Analysis report"
|
||||
#_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)
|
||||
employee_id = fields.Many2one('hr.employee', string='Consultant', readonly=True)
|
||||
start_date = fields.Date(string='Start Date', readonly=True)
|
||||
end_date = fields.Date(string='End Date', readonly=True)
|
||||
percentage = fields.Float("Budgeted Percentage (%)")
|
||||
budgeted_hours = fields.Float("Budgeted Hours for period", compute='_compute_budgeted_hours', store=True)
|
||||
actual_percentage = fields.Float("Actual Percentage (%)", compute='_compute_actual_calc', store=True)
|
||||
actual_hours = fields.Float("Actual Hours for period", compute='_compute_actual_calc', store=True)
|
||||
|
||||
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,
|
||||
employee_id,
|
||||
partner_id,
|
||||
start_date,
|
||||
end_date,
|
||||
percentage,
|
||||
budgeted_hours,
|
||||
actual_percentage,
|
||||
actual_hours
|
||||
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,
|
||||
consult.employee_id AS employee_id,
|
||||
consult.start_date as start_date,
|
||||
consult.end_date as end_date,
|
||||
consult.percentage percentage,
|
||||
consult.budgeted_hours AS budgeted_hours,
|
||||
consult.percentage AS actual_percentage,
|
||||
consult.actual_percentage AS actual_hours
|
||||
FROM project_project PRO
|
||||
right JOIN project_consultant_hrs consult ON PRO.id = consult.project_id
|
||||
WHERE PRO.active = 't' and PRO.pricing_type='employee_rate' and PRO.project_type='hours_in_consultant'
|
||||
) res
|
||||
)""" % (self._table,))
|
||||
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_consultant_custom_report_view_pivot" model="ir.ui.view">
|
||||
<field name="name">project.consultant.custom.report.pivot</field>
|
||||
<field name="model">project.consultant.custom.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Consultant Analysis" disable_linking="True" sample="1">
|
||||
<field name="project_id" type="row"/>
|
||||
<field name="percentage" type="measure"/>
|
||||
<field name="budgeted_hours" type="measure"/>
|
||||
<field name="actual_percentage" type="measure"/>
|
||||
<field name="actual_hours" type="measure"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_consultant_custom_report_view_graph" model="ir.ui.view">
|
||||
<field name="name">project.consultant.custom.report.graph</field>
|
||||
<field name="model">project.consultant.custom.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Consultant Analysis" type="bar" stacked="True" sample="1" disable_linking="1">
|
||||
<field name="project_id" type="col"/>
|
||||
<field name="budgeted_hours" type="row"/>
|
||||
<field name="actual_hours" type="row"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_consultant_custom_report_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.consultant.custom.report.tree</field>
|
||||
<field name="model">project.consultant.custom.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Consultant Analysis" create="false" edit="false" delete="false">
|
||||
<field name="project_id"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="percentage"/>
|
||||
<field name="budgeted_hours"/>
|
||||
<field name="actual_percentage"/>
|
||||
<field name="actual_hours"/>
|
||||
<field name="parent_project" optional="hide"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="project_consultant_custom_report_view_search" model="ir.ui.view">
|
||||
<field name="name">project.consultant.custom.report.search</field>
|
||||
<field name="model">project.consultant.custom.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Consultant Analysis">
|
||||
<field name="project_id"/>
|
||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
||||
<field name="employee_id"/>
|
||||
<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="Start Date" name="group_startdate" domain="[]" context="{'group_by':'start_date:month'}"/>
|
||||
<filter string="End Date" name="group_enddate" domain="[]" context="{'group_by':'end_date:month'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_consultant_custom_report_action" model="ir.actions.act_window">
|
||||
<field name="name">Consultant Allocation Reports</field>
|
||||
<field name="res_model">project.consultant.custom.report</field>
|
||||
<field name="view_mode">pivot,tree,graph</field>
|
||||
<field name="search_view_id" ref="project_consultant_custom_report_view_search"/>
|
||||
<field name="context">{'search_default_group_project': 1,'search_default_group_employee': 1}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_project_consultant_custom_report"
|
||||
parent="project.menu_project_report"
|
||||
action="project_consultant_custom_report_action"
|
||||
name="Consultant Allocation Reports"
|
||||
sequence="50"/>
|
||||
|
||||
</odoo>
|
|
@ -0,0 +1,188 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, tools
|
||||
|
||||
|
||||
class ProjectRevenueCustomReport(models.Model):
|
||||
|
||||
_name = "project.revenue.custom.report"
|
||||
_description = "Project Revenue Custom Analysis report"
|
||||
#_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)
|
||||
#start_date = fields.Date(string='Start Date', readonly=True)
|
||||
#end_date = fields.Date(string='End Date', readonly=True)
|
||||
timesheet_sdatetime = fields.Datetime(string='Timesheet Start Time', readonly=True)
|
||||
unit_amount = fields.Float('Timesheet Hours')
|
||||
timesheet_cost = fields.Float('Timesheet Cost')
|
||||
profit_per = fields.Float(string='Profit Percentage', digits=(16, 2))
|
||||
profit_amt = fields.Float(string='Profit Amount', digits=(16, 2))
|
||||
pro_hourly_rate = fields.Float("Hourly Rate", group_operator="sum")
|
||||
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")
|
||||
|
||||
|
||||
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,
|
||||
employee_id,
|
||||
partner_id,
|
||||
budgeted_revenue,
|
||||
budgeted_hours,
|
||||
pro_hourly_rate,
|
||||
actual_revenue,
|
||||
actual_cost,
|
||||
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,
|
||||
AAL.employee_id AS employee_id,
|
||||
0.0 AS budgeted_revenue,
|
||||
0.0 AS budgeted_hours,
|
||||
0.0 AS pro_hourly_rate,
|
||||
0.0 AS actual_revenue,
|
||||
(AAL.amount * -1) AS actual_cost,
|
||||
0.0 AS profit_amt,
|
||||
0.0 AS profit_per,
|
||||
AAL.unit_amount,
|
||||
((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) as timesheet_cost,
|
||||
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,
|
||||
null::int AS employee_id,
|
||||
pro.budgeted_revenue AS budgeted_revenue,
|
||||
pro.budgeted_hours2 AS budgeted_hours,
|
||||
pro.hourly_rate AS pro_hourly_rate,
|
||||
0.0 AS actual_revenue,
|
||||
0.0 AS actual_cost,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
0.0 as unit_amount,
|
||||
0.0 as timesheet_cost,
|
||||
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,
|
||||
AAL.employee_id AS employee_id,
|
||||
0.0 AS budgeted_revenue,
|
||||
0.0 AS budgeted_hours,
|
||||
0.0 AS pro_hourly_rate,
|
||||
(AAL.unit_amount * pro.hourly_rate) AS actual_revenue,
|
||||
(AAL.amount * -1) AS actual_cost,
|
||||
0.0 AS profit_per,
|
||||
0.0 AS profit_amt,
|
||||
AAL.unit_amount,
|
||||
((AAL.amount * -1)/NULLIF(AAL.unit_amount, 0)) as timesheet_cost,
|
||||
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
|
||||
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_emp.employee_id AS employee_id,
|
||||
pro_emp.cost AS budgeted_revenue,
|
||||
pro_emp.budgeted_qty AS budgeted_hours,
|
||||
0.0 as pro_hourly_rate,
|
||||
0.0 AS actual_revenue,
|
||||
0.0 AS actual_cost,
|
||||
0.0 as profit_per,
|
||||
0.0 as profit_amt,
|
||||
0.0 as unit_amount,
|
||||
0.0 as timesheet_cost,
|
||||
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,
|
||||
null::int AS employee_id,
|
||||
0.0 as pro_hourly_rate,
|
||||
0.0 AS budgeted_revenue,
|
||||
0.0 AS budgeted_hours,
|
||||
0.0 AS actual_revenue,
|
||||
0.0 AS actual_cost,
|
||||
pro.profit_per,
|
||||
pro.profit_amt,
|
||||
0.0 as unit_amount,
|
||||
0.0 as timesheet_cost,
|
||||
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,
|
||||
AAL.employee_id AS employee_id,
|
||||
COALESCE(pro_emp.price_unit, 0) as pro_hourly_rate,
|
||||
0.0 AS budgeted_revenue,
|
||||
0.0 AS budgeted_hours,
|
||||
(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 profit_per,
|
||||
0.0 AS profit_amt,
|
||||
AAL.unit_amount,
|
||||
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.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,))
|
||||
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_revenue_custom_report_view_pivot" model="ir.ui.view">
|
||||
<field name="name">project.revenue.custom.report.pivot</field>
|
||||
<field name="model">project.revenue.custom.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Revenue Analysis" disable_linking="True" sample="1">
|
||||
<field name="project_id" type="row"/>
|
||||
<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="pro_hourly_rate" 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_report_view_graph" model="ir.ui.view">
|
||||
<field name="name">project.revenue.custom.report.graph</field>
|
||||
<field name="model">project.revenue.custom.report</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_report_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.revenue.custom.report.tree</field>
|
||||
<field name="model">project.revenue.custom.report</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_report_view_search" model="ir.ui.view">
|
||||
<field name="name">project.revenue.custom.report.search</field>
|
||||
<field name="model">project.revenue.custom.report</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="[('project_type','=','hours_in_consultant')]"/>
|
||||
<filter string="Total hours are budgeted without division to consultant" name="limit" domain="[('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_report_action" model="ir.actions.act_window">
|
||||
<field name="name">Projects Revenue</field>
|
||||
<field name="res_model">project.revenue.custom.report</field>
|
||||
<field name="view_mode">pivot,tree,graph</field>
|
||||
<field name="search_view_id" ref="project_revenue_custom_report_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_report"
|
||||
parent="project.menu_project_report"
|
||||
action="project_revenue_custom_report_action"
|
||||
name="Projects Revenue"
|
||||
sequence="50"/>
|
||||
|
||||
</odoo>
|
|
@ -8,4 +8,8 @@ access_project_create_expense_user,access_project_create_expense_project_user,mo
|
|||
access_project_timeline_report_manager,project.timeline.report,model_project_timeline_report,project.group_project_manager,1,1,1,1
|
||||
access_project_timeline_report_user,project.timeline.report,model_project_timeline_report,project.group_project_user,1,0,0,0
|
||||
access_project_timesheet_report_manager,project.timesheet.report,model_project_timesheet_report,project.group_project_manager,1,1,1,1
|
||||
access_project_timesheet_report_user,project.timesheet.report,model_project_timesheet_report,project.group_project_user,1,0,0,0
|
||||
access_project_timesheet_report_user,project.timesheet.report,model_project_timesheet_report,project.group_project_user,1,0,0,0
|
||||
access_project_revenue_custom_report_manager,project_revenue_custom_report_manager,model_project_revenue_custom_report,project.group_project_manager,1,1,1,1
|
||||
access_project_revenue_custom_report_user,project_revenue_custom_report_user,model_project_revenue_custom_report,project.group_project_user,1,0,0,0
|
||||
access_project_consultant_custom_report_manager,project_consultant_custom_report_manager,model_project_consultant_custom_report,project.group_project_manager,1,1,1,1
|
||||
access_project_consultant_custom_report_user,project_consultant_custom_report_user,model_project_consultant_custom_report,project.group_project_user,1,0,0,0
|
||||
|
|
|
Loading…
Reference in New Issue