Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.0][WIP] Added Earned Value Management Report #107

Merged
2 changes: 1 addition & 1 deletion business_requirement_deliverable_cost/models/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def _compute_resource_task_total(self):
br.mapped('deliverable_lines').mapped(
'resource_ids').filtered(
lambda r: r.resource_type == 'task').mapped(
'price_total'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

irrelevant

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't make this change in the PR.

'price_total'))

@api.multi
@api.depends('deliverable_lines')
Expand Down
4 changes: 4 additions & 0 deletions business_requirement_earned_value/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# © 2017 Elico Corp (https://www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import report
23 changes: 23 additions & 0 deletions business_requirement_earned_value/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# © 2017 Elico Corp (https://www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': ' Earned Value Management',
'category': 'Business Requirements Management',
'summary': 'Manage the Business Requirement Deliverables and \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BI report for the based on Earned Value Management

Resources for your customers',
'version': '8.0.1.0.0',
'website': 'https://www.elico-corp.com/',
"author": "Elico Corp, Odoo Community Association (OCA)",
'depends': [
'hr_timesheet',
'project_timesheet',
'business_requirement_deliverable_cost',
'business_requirement_deliverable_project',
],
'data': [
'report/br_earned_value_report_view.xml',
],
'license': 'AGPL-3',
'installable': True,
}
5 changes: 5 additions & 0 deletions business_requirement_earned_value/report/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2017 Elico Corp (www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from . import br_earned_value_report
90 changes: 90 additions & 0 deletions business_requirement_earned_value/report/br_earned_value_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
# © 2017 Elico Corp (https://www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import tools
from openerp import fields, models


class BusinessRequirementEarnedValueReport(models.Model):
_name = "business.requirement.earned.value.report"
_description = "Earned Value Report"
_auto = False

name = fields.Char('Name', readonly=True)
description = fields.Char('Description', readonly=True)
partner_id = fields.Many2one('res.partner', 'Customer',
readonly=True)
project_id = fields.Many2one('project.project', 'Master Project',
readonly=True)
res_product = fields.Many2one('product.product', 'Res Product',
readonly=True)
hr_timesheet_product =\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sudhir-serpentcs layout is not ok.
as example do as here:
hr_timesheet_product = fields.Many2one(
'product.product',
'HR Timesheet Product',
...,)

And amend for the others fields as well

fields.Many2one('product.product', 'HR Timesheet Product',
readonly=True)
planned_time_in_rl = fields.Float('Planned time in RL', readonly=True)
product_cost_from_rl = fields.Float('Product Cost from RL', readonly=True)
planned_value = fields.Float('Planned Value', readonly=True)
actual_time_in_timesheet = fields.Float('Actual time in Timesheet',
readonly=True)
product_cost_from_timesheet_product =\
fields.Float('Product Cost from Timesheet product',
readonly=True)
actual_cost = fields.Float('Actual Cost', readonly=True)
variance = fields.Float('Variance', readonly=True)
per_variances = fields.Float('% Variance', readonly=True)
remaining_hours = fields.Float('Remaining time', readonly=True)
total_expected_time = fields.Float('Total expected time', readonly=True)
project_completion = fields.Float('Project Completion', readonly=True)
earned_value = fields.Float('Earned Value', readonly=True)

def init(self, cr):
tools.drop_view_if_exists(cr,
'business_requirement_earned_value_report')
cr.execute("""
CREATE VIEW business_requirement_earned_value_report AS (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a lot of div by zero potential issues in the current view.

SELECT br.id,
br.name as name,
br.description as description,
br.partner_id as partner_id,
br.project_id as project_id,
res.product_id as res_product,
(select id from product_template where id = aal.product_id)
as hr_timesheet_product,
res.qty as planned_time_in_rl,
res.unit_price as product_cost_from_rl,
(res.qty * res.unit_price) as planned_value,
pt.effective_hours as actual_time_in_timesheet,
(select list_price from product_template where id = aal.product_id)
as product_cost_from_timesheet_product,
(pt.effective_hours * (select list_price from product_template
where id = aal.product_id)) as actual_cost,
((pt.effective_hours * (select list_price from product_template
where id = aal.product_id)) - (res.qty * res.unit_price))
as variance,
(((pt.effective_hours * (select list_price from product_template
where id = aal.product_id)) - (res.qty * res.unit_price)) /
res.unit_price) as per_variances,
pt.remaining_hours,
(pt.effective_hours + pt.remaining_hours) as total_expected_time,
CASE WHEN (pt.effective_hours + pt.remaining_hours) > 0 THEN
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sudhir-serpentcs if
pt.effective_hours = 0
pt.remaining_hours = 2

condition (pt.effective_hours + pt.remaining_hours) > 0 is true then a division 0/2 on Postgress will cause error, don't you think?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@victormartinelicocorp

no if 0/2
condition should be (pt.remaining_hours) > 0

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please amend

(pt.effective_hours / (pt.effective_hours + pt.remaining_hours))
ElSE 0.0 END as project_completion,
CASE WHEN (pt.effective_hours + pt.remaining_hours) > 0 THEN
((res.qty * (res.unit_price * res.qty)) * (pt.effective_hours /
(pt.effective_hours + pt.remaining_hours))) ElSE 0.0 END
as earned_value
FROM business_requirement br
FULL OUTER JOIN business_requirement_deliverable dlv
ON br.id = dlv.business_requirement_id
FULL OUTER JOIN business_requirement_resource res
ON res.business_requirement_deliverable_id = dlv.id
JOIN project_task pt
ON br.id = pt.business_requirement_id
JOIN project_task_work ptw
ON pt.id = ptw.task_id
JOIN hr_analytic_timesheet hat
ON ptw.hr_analytic_timesheet_id = hat.id
INNER JOIN account_analytic_line aal
ON hat.line_id = aal.id
Group By dlv.id, br.id, res.id, pt.id, aal.id
)""")
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>

<record id="view_earned_value_graph" model="ir.ui.view">
<field name="name">Earned Value Report</field>
<field name="model">business.requirement.earned.value.report</field>
<field name="arch" type="xml">
<graph string="Earned Value Analysis" type="pivot" stacked="True">
<field name="name" type="row"/>
<field name="planned_time_in_rl" type="measure"/>
<field name="product_cost_from_rl" type="measure"/>
<field name="planned_value" type="measure"/>
<field name="actual_time_in_timesheet" type="measure"/>
<field name="product_cost_from_timesheet_product" type="measure"/>
<field name="actual_cost" type="measure"/>
<field name="variance" type="measure"/>
<field name="per_variances" type="measure"/>
<field name="remaining_hours" type="measure"/>
<field name="total_expected_time" type="measure"/>
<field name="project_completion" type="measure"/>
<field name="earned_value" type="measure"/>
</graph>
</field>
</record>

<record id="action_earned_value_report" model="ir.actions.act_window">
<field name="name">Earned Value Analysis</field>
<field name="res_model">business.requirement.earned.value.report</field>
<field name="view_type">form</field>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_earned_value_graph"/>
</record>

<menuitem action="action_earned_value_report" id="menu_action_deliverable_report"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This report should only visible to the cost group

parent="base.menu_project_report"/>

</data>
</openerp>