From ffb4bdc86222ab733031636d95687b91aefef801 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Tue, 4 Apr 2017 18:33:04 +0530 Subject: [PATCH 01/13] [WIP] Added Earned Value Management Report --- .../models/business.py | 2 +- business_requirement_earned_value/__init__.py | 4 + .../__openerp__.py | 23 +++++ .../report/__init__.py | 5 ++ .../report/br_earned_value_report.py | 88 +++++++++++++++++++ .../report/br_earned_value_report_view.xml | 39 ++++++++ 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 business_requirement_earned_value/__init__.py create mode 100644 business_requirement_earned_value/__openerp__.py create mode 100644 business_requirement_earned_value/report/__init__.py create mode 100644 business_requirement_earned_value/report/br_earned_value_report.py create mode 100644 business_requirement_earned_value/report/br_earned_value_report_view.xml diff --git a/business_requirement_deliverable_cost/models/business.py b/business_requirement_deliverable_cost/models/business.py index 9a564deae..134de7273 100644 --- a/business_requirement_deliverable_cost/models/business.py +++ b/business_requirement_deliverable_cost/models/business.py @@ -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')) + 'price_total')) @api.multi @api.depends('deliverable_lines') diff --git a/business_requirement_earned_value/__init__.py b/business_requirement_earned_value/__init__.py new file mode 100644 index 000000000..3f3dce610 --- /dev/null +++ b/business_requirement_earned_value/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# © 2016 Elico Corp (https://www.elico-corp.com). +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import report diff --git a/business_requirement_earned_value/__openerp__.py b/business_requirement_earned_value/__openerp__.py new file mode 100644 index 000000000..46901ebf3 --- /dev/null +++ b/business_requirement_earned_value/__openerp__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# © 2016 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 \ + 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, +} diff --git a/business_requirement_earned_value/report/__init__.py b/business_requirement_earned_value/report/__init__.py new file mode 100644 index 000000000..07a443bfe --- /dev/null +++ b/business_requirement_earned_value/report/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 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 diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py new file mode 100644 index 000000000..f62865138 --- /dev/null +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# © 2016 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 =\ + 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 ( + 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, + (pt.effective_hours / (pt.effective_hours + pt.remaining_hours)) + as project_completion, + ((res.qty * (res.unit_price * res.qty)) * (pt.effective_hours / ( + pt.effective_hours + pt.remaining_hours))) 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 + )""") diff --git a/business_requirement_earned_value/report/br_earned_value_report_view.xml b/business_requirement_earned_value/report/br_earned_value_report_view.xml new file mode 100644 index 000000000..3d156c36c --- /dev/null +++ b/business_requirement_earned_value/report/br_earned_value_report_view.xml @@ -0,0 +1,39 @@ + + + + + + Earned Value Report + business.requirement.earned.value.report + + + + + + + + + + + + + + + + + + + + + Earned Value Analysis + business.requirement.earned.value.report + form + graph + + + + + + + From fec5d5cbb301e3fac9b812c4f4f85e189e7340d0 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Wed, 5 Apr 2017 18:42:57 +0530 Subject: [PATCH 02/13] [IMP] Improved code --- business_requirement_earned_value/__init__.py | 2 +- .../__openerp__.py | 2 +- .../report/__init__.py | 2 +- .../report/br_earned_value_report.py | 22 ++++++++++--------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/business_requirement_earned_value/__init__.py b/business_requirement_earned_value/__init__.py index 3f3dce610..efd2b5131 100644 --- a/business_requirement_earned_value/__init__.py +++ b/business_requirement_earned_value/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- -# © 2016 Elico Corp (https://www.elico-corp.com). +# © 2017 Elico Corp (https://www.elico-corp.com). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import report diff --git a/business_requirement_earned_value/__openerp__.py b/business_requirement_earned_value/__openerp__.py index 46901ebf3..4bb6801dc 100644 --- a/business_requirement_earned_value/__openerp__.py +++ b/business_requirement_earned_value/__openerp__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Elico Corp (https://www.elico-corp.com). +# © 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', diff --git a/business_requirement_earned_value/report/__init__.py b/business_requirement_earned_value/report/__init__.py index 07a443bfe..74ad1a1d3 100644 --- a/business_requirement_earned_value/report/__init__.py +++ b/business_requirement_earned_value/report/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Elico Corp (www.elico-corp.com). +# © 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 diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py index f62865138..c99d7cc96 100644 --- a/business_requirement_earned_value/report/br_earned_value_report.py +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Elico Corp (https://www.elico-corp.com). +# © 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 @@ -54,23 +54,25 @@ def init(self, cr): 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, + (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, + 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, + (pt.effective_hours + pt.remaining_hours) as total_expected_time, + CASE WHEN (pt.effective_hours + pt.remaining_hours) > 0 THEN (pt.effective_hours / (pt.effective_hours + pt.remaining_hours)) - as project_completion, - ((res.qty * (res.unit_price * res.qty)) * (pt.effective_hours / ( - pt.effective_hours + pt.remaining_hours))) as earned_value + 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 From df59e89439351c91377be89fa1cd71185a3c9396 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Thu, 6 Apr 2017 11:05:34 +0530 Subject: [PATCH 03/13] [ADD]business_requirement_earned_value:- Added security group and access rights --- business_requirement_earned_value/__openerp__.py | 1 + .../report/br_earned_value_report_view.xml | 2 +- business_requirement_earned_value/security/ir.model.access.csv | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 business_requirement_earned_value/security/ir.model.access.csv diff --git a/business_requirement_earned_value/__openerp__.py b/business_requirement_earned_value/__openerp__.py index 4bb6801dc..e9fc2b33c 100644 --- a/business_requirement_earned_value/__openerp__.py +++ b/business_requirement_earned_value/__openerp__.py @@ -16,6 +16,7 @@ 'business_requirement_deliverable_project', ], 'data': [ + 'security/ir.model.access.csv', 'report/br_earned_value_report_view.xml', ], 'license': 'AGPL-3', diff --git a/business_requirement_earned_value/report/br_earned_value_report_view.xml b/business_requirement_earned_value/report/br_earned_value_report_view.xml index 3d156c36c..5d3cc1b76 100644 --- a/business_requirement_earned_value/report/br_earned_value_report_view.xml +++ b/business_requirement_earned_value/report/br_earned_value_report_view.xml @@ -33,7 +33,7 @@ + parent="base.menu_project_report" groups="business_requirement_deliverable_cost.group_business_requirement_cost_control"/> diff --git a/business_requirement_earned_value/security/ir.model.access.csv b/business_requirement_earned_value/security/ir.model.access.csv new file mode 100644 index 000000000..7b4cf2ecf --- /dev/null +++ b/business_requirement_earned_value/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_business_requirement_earned_value_report,business.requirement.earned.value.report,model_business_requirement_earned_value_report,business_requirement.group_business_requirement_user,1,0,0,0 From 51bce200570209b1b5942fea129807e75d312ca5 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Thu, 6 Apr 2017 17:52:01 +0530 Subject: [PATCH 04/13] [IMP] Added security group & Improved code. --- .../report/br_earned_value_report.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py index c99d7cc96..e48fbdeab 100644 --- a/business_requirement_earned_value/report/br_earned_value_report.py +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -18,9 +18,9 @@ class BusinessRequirementEarnedValueReport(models.Model): readonly=True) res_product = fields.Many2one('product.product', 'Res Product', readonly=True) - hr_timesheet_product =\ - fields.Many2one('product.product', 'HR Timesheet Product', - readonly=True) + hr_timesheet_product = 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) @@ -66,10 +66,10 @@ def init(self, cr): 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 + CASE WHEN (pt.remaining_hours) > 0 THEN (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 + CASE WHEN (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 d80c7396719427f39fe4b87d9cb3b547cee6570b Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Fri, 7 Apr 2017 12:38:32 +0530 Subject: [PATCH 05/13] [ADD/IMP] added readme and improved code. --- business_requirement_earned_value/README.rst | 248 ++++++++++++++++++ .../__openerp__.py | 7 +- .../report/br_earned_value_report_view.xml | 6 +- 3 files changed, 255 insertions(+), 6 deletions(-) create mode 100644 business_requirement_earned_value/README.rst diff --git a/business_requirement_earned_value/README.rst b/business_requirement_earned_value/README.rst new file mode 100644 index 000000000..a5d3a2d56 --- /dev/null +++ b/business_requirement_earned_value/README.rst @@ -0,0 +1,248 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + + +=============================== +Earned Value Management Report +=============================== + +Introduction +============ + +What is a Business Requirement? +------------------------------- + +A **Business requirement** (BR) is the expression of a business need by a customer +or internal project user. + +A BR contains multiple different parts to explain the stakeholder need and how to +meet his/her requirements: + +* **Customer Story**: this is the requirement as expressed by the customer +* **Scenario**: How/where the current solution can provide a suitable scenario to + answer the customer story +* **Gap**: For the uncovered part of the scenario, elaborate the gap/need for specific + developments/setup +* **Test case**: A set of conditions under which a tester will determine whether the application, software system or + one of its features is working as it was originally established for it to do. +* **Deliverables** to be provided to the customer/user +* **Resources** necessary to achieve the deliverables +* **Additional** information (approval, cost control etc.) + +This set of modules was originally designed for the service/IT industry but the +requirement management design has been kept as generic as possible so that it can +apply to many other cases/industries (customer or internal projects): + +* Construction +* Trading (New product development) +* Business Consultancy +* Web or IT development +* R&D projects +* etc. + +More information about business requirements management: + +* `Wikipedia `_ +* `Six Sigma `_ + +Business Requirement set of modules +----------------------------------- + +This module is part of a set (`Business Requirements repo `_). + +The base Business Requirements module creates the basic objects and +can be used as a standalone module. + +.. figure:: ../business_requirement/static/img/bus_req_tree.png + :width: 600 px + :alt: Business Requirement List view + +Multiple modules integrate the BR with other business areas, such as Sales, +Procurement, Project or Analytic Accounting. For example: + +* Sales Quotation can have an estimation supported by a BR analysis +* Project Tasks can be related to the BRs they implement or support +* Procurement and purchase can be generated out of the BR + +.. figure:: ../business_requirement/static/img/bus_req_module_diag.png + :width: 600 px + :alt: Business Requirement modules diagram + +The following workflow explains the business workflow between the BR modules and other applications in Odoo: + +.. figure:: ../business_requirement/static/img/bus_req_workflow.png + :width: 600 px + :alt: Business Requirement integration in Odoo + + +How to use this module? +----------------------- + +This module only contains the standard base models for business requirement: + +* BR model definition +* Standard setup and views +* Standard Workflow + +.. figure:: ../business_requirement/static/img/bus_req.png + :width: 600 px + :alt: Business Requirement Form + + +Configuration +============= + +Users +----- + +* **Business Requirement User**: can create and confirm a BR +* **Business Requirement Manager**: can create, confirm and approve a BR + +Alias and emails +---------------- +You can setup an alias in Settings/Technical/Email/Alias in order to create +business requirements directly from email received at a specific address. + +.. figure:: ../business_requirement/static/img/bus_req_alias.png + :width: 600 px + :alt: Email Alias setup + +You can start conversation with the followers in the chatter area of the +BR like in tasks, issue or CRM leads. + +Sequences +--------- + +Default numbering format: BR123456. + +You can modify the default numbering sequence in Settings/Technical/Sequences&Identifier/Sequences. + +Search for Business Requirement sequence and alter it if necessary. + +Tags +---- + +You can create and assign tags for your business requirements in Business Requirements/Configuration/Bus. Req. Category + +.. figure:: ../business_requirement/static/img/bus_req_tags.png + :width: 600 px + :alt: Define Tags + + +Master project +-------------- + +You can define a master project linked to the business requirement. + +Followers from the project will automatically be added to the business requirements. + + +Usage +===== +Simple BR +--------- + +1. Define the header information + + * Master Project (Partner is the one related to the master project) + * Priority (low, Medium, High) + * Change request: Is it a change request? (currently only informational with n model or action) + * Tags: any relevant tag for the business. + * Owner and approver by default + + .. figure:: ../business_requirement/static/img/bus_req_tags2.png + :width: 600 px + :alt: Input header information + +2. Input the customer story, scenario gap and test case(simple html editor with image and text) + + .. figure:: ../business_requirement/static/img/bus_req_cust_story.png + :width: 600 px + :alt: Input customer story, scenario, gap and test case + +3. Confirm the Business requirement (for BR User and Manager) + At that stage the Customer story/Scenario/Gap/Test case is not modifiable anymore + + .. figure:: ../business_requirement/static/img/bus_req_confirmed.png + :width: 600 px + :alt: Confirm your business requirement + +4. Approve the Business requirement (for BR Manager) + + .. figure:: ../business_requirement/static/img/bus_req_approved.png + :width: 600 px + :alt: Confirm your business requirement + +5. Once your requirement is finished and delivered you can set it as Done + + .. figure:: ../business_requirement/static/img/bus_req_done.png + :width: 600 px + :alt: Confirm your business requirement + +6. Alternatively, you can cancel the BR (in case it is not relevant or mistake) or drop it (when customer makes the decision to discontinue it) + + .. figure:: ../business_requirement/static/img/bus_req_cancel.png + :width: 600 px + :alt: Cancel your business requirement + + + .. figure:: ../business_requirement/static/img/bus_req_drop.png + :width: 600 px + :alt: Drop your business requirement + + +Sub-business requirements +------------------------- +User can create sub business requirements for a given BR for complex cases. + +This is a simple parent/child relation (see roadmap). + +.. figure:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/222/8.0 + +Known issues / Roadmap +====================== + +* Multi-company management +* Full change request management +* Analytic account management +* Complex relationship management +* Integration with earned-value module. +* Improve the followers details (eg: depending on the stages) + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. + + +Credits +======= + +Contributors +------------ + +* Eric Caudal +* Alex Duan +* Xie XiaoPeng +* Victor M. Martin +* Evan Li + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/business_requirement_earned_value/__openerp__.py b/business_requirement_earned_value/__openerp__.py index e9fc2b33c..841549b58 100644 --- a/business_requirement_earned_value/__openerp__.py +++ b/business_requirement_earned_value/__openerp__.py @@ -2,13 +2,12 @@ # © 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', + 'name': 'Earned Value Management', 'category': 'Business Requirements Management', - 'summary': 'Manage the Business Requirement Deliverables and \ - Resources for your customers', + 'summary': 'Manage the Earned Value for your customers', 'version': '8.0.1.0.0', 'website': 'https://www.elico-corp.com/', - "author": "Elico Corp, Odoo Community Association (OCA)", + 'author': 'Elico Corp, Odoo Community Association (OCA)', 'depends': [ 'hr_timesheet', 'project_timesheet', diff --git a/business_requirement_earned_value/report/br_earned_value_report_view.xml b/business_requirement_earned_value/report/br_earned_value_report_view.xml index 5d3cc1b76..f749f87bd 100644 --- a/business_requirement_earned_value/report/br_earned_value_report_view.xml +++ b/business_requirement_earned_value/report/br_earned_value_report_view.xml @@ -32,8 +32,10 @@ - + From 1f4d0f16f231dd138a07299f0265545293357d3c Mon Sep 17 00:00:00 2001 From: "Eric @ Elico Corp" Date: Sun, 9 Apr 2017 12:40:17 +0800 Subject: [PATCH 06/13] Update README (without pictures) --- business_requirement_earned_value/README.rst | 215 +++---------------- 1 file changed, 29 insertions(+), 186 deletions(-) diff --git a/business_requirement_earned_value/README.rst b/business_requirement_earned_value/README.rst index a5d3a2d56..d7f20b863 100644 --- a/business_requirement_earned_value/README.rst +++ b/business_requirement_earned_value/README.rst @@ -10,207 +10,54 @@ Earned Value Management Report Introduction ============ -What is a Business Requirement? -------------------------------- +This module is part of a set of modules (`Business Requirements `_). -A **Business requirement** (BR) is the expression of a business need by a customer -or internal project user. -A BR contains multiple different parts to explain the stakeholder need and how to -meet his/her requirements: - -* **Customer Story**: this is the requirement as expressed by the customer -* **Scenario**: How/where the current solution can provide a suitable scenario to - answer the customer story -* **Gap**: For the uncovered part of the scenario, elaborate the gap/need for specific - developments/setup -* **Test case**: A set of conditions under which a tester will determine whether the application, software system or - one of its features is working as it was originally established for it to do. -* **Deliverables** to be provided to the customer/user -* **Resources** necessary to achieve the deliverables -* **Additional** information (approval, cost control etc.) - -This set of modules was originally designed for the service/IT industry but the -requirement management design has been kept as generic as possible so that it can -apply to many other cases/industries (customer or internal projects): - -* Construction -* Trading (New product development) -* Business Consultancy -* Web or IT development -* R&D projects -* etc. - -More information about business requirements management: - -* `Wikipedia `_ -* `Six Sigma `_ - -Business Requirement set of modules ------------------------------------ - -This module is part of a set (`Business Requirements repo `_). - -The base Business Requirements module creates the basic objects and -can be used as a standalone module. - -.. figure:: ../business_requirement/static/img/bus_req_tree.png - :width: 600 px - :alt: Business Requirement List view - -Multiple modules integrate the BR with other business areas, such as Sales, -Procurement, Project or Analytic Accounting. For example: - -* Sales Quotation can have an estimation supported by a BR analysis -* Project Tasks can be related to the BRs they implement or support -* Procurement and purchase can be generated out of the BR - -.. figure:: ../business_requirement/static/img/bus_req_module_diag.png - :width: 600 px - :alt: Business Requirement modules diagram - -The following workflow explains the business workflow between the BR modules and other applications in Odoo: - -.. figure:: ../business_requirement/static/img/bus_req_workflow.png - :width: 600 px - :alt: Business Requirement integration in Odoo - - -How to use this module? ------------------------ - -This module only contains the standard base models for business requirement: - -* BR model definition -* Standard setup and views -* Standard Workflow - -.. figure:: ../business_requirement/static/img/bus_req.png - :width: 600 px - :alt: Business Requirement Form +This module introduces **Earned Value Management report** based on the information from the Business Requirements Resources and Deliverable lines. You can check the following resources for more information about EVM: +* `[RFC] Earned Value Management Report `_ +* `Earned Value Management introduction `_ +* `Wikipedia Entry `_ Configuration ============= -Users ------ - -* **Business Requirement User**: can create and confirm a BR -* **Business Requirement Manager**: can create, confirm and approve a BR - -Alias and emails ----------------- -You can setup an alias in Settings/Technical/Email/Alias in order to create -business requirements directly from email received at a specific address. - -.. figure:: ../business_requirement/static/img/bus_req_alias.png - :width: 600 px - :alt: Email Alias setup - -You can start conversation with the followers in the chatter area of the -BR like in tasks, issue or CRM leads. - -Sequences ---------- - -Default numbering format: BR123456. - -You can modify the default numbering sequence in Settings/Technical/Sequences&Identifier/Sequences. +To fully be able to use the report, the following information must be properly maintained: -Search for Business Requirement sequence and alter it if necessary. +* Cost price in the products associated to resources +* Resources lines should contain valid cost and total cost. +* Employees should contain a valid resource product (comparable to the one in the Resource lines) +* The time spent on Timesheets should be properly recorded -Tags ----- - -You can create and assign tags for your business requirements in Business Requirements/Configuration/Bus. Req. Category +Usage +===== -.. figure:: ../business_requirement/static/img/bus_req_tags.png +#. In the Business requirement, you add Deliverable Lines as necessary,with the + corresponding Resources lines. +#. When the BR is validated the project should be created so that the users can + manage their tasks. +#. When the users spend time on a given task they should input their timesheets + accordingly in the task. + +.. note:: + When creating new tasks, the related BR should be set up properly in the task in + order to be properly accounted + +.. figure:: static/img/bus_req_category.png :width: 600 px - :alt: Define Tags - - -Master project --------------- + :alt: Inputing the deliverables and resources lines -You can define a master project linked to the business requirement. -Followers from the project will automatically be added to the business requirements. - - -Usage -===== -Simple BR ---------- - -1. Define the header information - - * Master Project (Partner is the one related to the master project) - * Priority (low, Medium, High) - * Change request: Is it a change request? (currently only informational with n model or action) - * Tags: any relevant tag for the business. - * Owner and approver by default - - .. figure:: ../business_requirement/static/img/bus_req_tags2.png - :width: 600 px - :alt: Input header information - -2. Input the customer story, scenario gap and test case(simple html editor with image and text) - - .. figure:: ../business_requirement/static/img/bus_req_cust_story.png - :width: 600 px - :alt: Input customer story, scenario, gap and test case - -3. Confirm the Business requirement (for BR User and Manager) - At that stage the Customer story/Scenario/Gap/Test case is not modifiable anymore - - .. figure:: ../business_requirement/static/img/bus_req_confirmed.png - :width: 600 px - :alt: Confirm your business requirement - -4. Approve the Business requirement (for BR Manager) - - .. figure:: ../business_requirement/static/img/bus_req_approved.png - :width: 600 px - :alt: Confirm your business requirement - -5. Once your requirement is finished and delivered you can set it as Done - - .. figure:: ../business_requirement/static/img/bus_req_done.png - :width: 600 px - :alt: Confirm your business requirement - -6. Alternatively, you can cancel the BR (in case it is not relevant or mistake) or drop it (when customer makes the decision to discontinue it) - - .. figure:: ../business_requirement/static/img/bus_req_cancel.png - :width: 600 px - :alt: Cancel your business requirement - - - .. figure:: ../business_requirement/static/img/bus_req_drop.png - :width: 600 px - :alt: Drop your business requirement - - -Sub-business requirements -------------------------- -User can create sub business requirements for a given BR for complex cases. - -This is a simple parent/child relation (see roadmap). - -.. figure:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot :target: https://runbot.odoo-community.org/runbot/222/8.0 Known issues / Roadmap ====================== -* Multi-company management -* Full change request management -* Analytic account management -* Complex relationship management -* Integration with earned-value module. -* Improve the followers details (eg: depending on the stages) +* Needs timesheets on the tasks related to BR. In the future we might think of a way + to input TS on project directly + Bug Tracker =========== @@ -227,10 +74,6 @@ Contributors ------------ * Eric Caudal -* Alex Duan -* Xie XiaoPeng -* Victor M. Martin -* Evan Li Maintainer ---------- From 18e76b34299ea268fe7860ca9d98e8ce17a08bef Mon Sep 17 00:00:00 2001 From: "Eric @ Elico Corp" Date: Sun, 9 Apr 2017 12:41:04 +0800 Subject: [PATCH 07/13] Update README.rst --- business_requirement_earned_value/README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/business_requirement_earned_value/README.rst b/business_requirement_earned_value/README.rst index d7f20b863..bb8841068 100644 --- a/business_requirement_earned_value/README.rst +++ b/business_requirement_earned_value/README.rst @@ -13,7 +13,9 @@ Introduction This module is part of a set of modules (`Business Requirements `_). -This module introduces **Earned Value Management report** based on the information from the Business Requirements Resources and Deliverable lines. You can check the following resources for more information about EVM: +This module introduces **Earned Value Management report** based on the information +from the Business Requirements Resources and Deliverable lines. You can check the +following resources for more information about EVM: * `[RFC] Earned Value Management Report `_ * `Earned Value Management introduction `_ From b89879c859820032af4a5682da27ef7743160212 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Tue, 11 Apr 2017 19:59:14 +0530 Subject: [PATCH 08/13] [IMP]Improved code as per FS requirement --- .../report/br_earned_value_report.py | 88 +++++++++---------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py index e48fbdeab..a76a216f4 100644 --- a/business_requirement_earned_value/report/br_earned_value_report.py +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -42,49 +42,47 @@ def init(self, cr): 'business_requirement_earned_value_report') cr.execute(""" CREATE VIEW business_requirement_earned_value_report AS ( - 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.remaining_hours) > 0 THEN - (pt.effective_hours / (pt.effective_hours + pt.remaining_hours)) - ElSE 0.0 END as project_completion, - CASE WHEN (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 + SELECT + br.id, + br.name as name, + br.description as description, + br.partner_id as partner_id, + br.project_id as project_id, + ptm.id as hr_timesheet_product, + sum(res.qty) as planned_time_in_rl, + sum(res.unit_price) as product_cost_from_rl, + (sum(res.qty) * sum(res.unit_price)) as planned_value, + (pt.effective_hours) as actual_time_in_timesheet, + (ptm.list_price) as product_cost_from_timesheet_product, + (pt.effective_hours * ptm.list_price) + as actual_cost, + abs((pt.effective_hours * ptm.list_price + ) - (sum(res.qty) * sum(res.unit_price))) + as variance, + (abs((pt.effective_hours * ptm.list_price + ) - (sum(res.qty) * sum(res.unit_price))) / + sum(res.unit_price)) as per_variances, + pt.remaining_hours as remaining_hours, + (pt.effective_hours + pt.remaining_hours) + as total_expected_time, + CASE WHEN (pt.remaining_hours) > 0 THEN + (pt.effective_hours / (pt.effective_hours + pt.remaining_hours + )) + ElSE 0.0 END as project_completion, + CASE WHEN (pt.remaining_hours) > 0 THEN + (((sum(res.qty) * (sum(res.unit_price) * sum(res.qty)) + ) * (pt.effective_hours / + pt.effective_hours + pt.remaining_hours))) ElSE 0.0 END + as earned_value + From + business_requirement br + LEFT JOIN business_requirement_deliverable dlv + ON dlv.business_requirement_id = br.id + LEFT JOIN business_requirement_resource res + ON res.business_requirement_deliverable_id = dlv.id + LEFT JOIN project_task pt + ON pt.business_requirement_id = br.id + JOIN product_template as ptm ON ptm.id = res.product_id + group by + br.id,pt.id,ptm.id )""") From 0a32794a2db5c439026911a8d3d37ecc0ccb1795 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Tue, 11 Apr 2017 20:14:21 +0530 Subject: [PATCH 09/13] [IMP] Fixed Travis --- .../report/br_earned_value_report.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py index a76a216f4..2aa347df5 100644 --- a/business_requirement_earned_value/report/br_earned_value_report.py +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -42,7 +42,7 @@ def init(self, cr): 'business_requirement_earned_value_report') cr.execute(""" CREATE VIEW business_requirement_earned_value_report AS ( - SELECT + SELECT br.id, br.name as name, br.description as description, @@ -74,15 +74,15 @@ def init(self, cr): ) * (pt.effective_hours / pt.effective_hours + pt.remaining_hours))) ElSE 0.0 END as earned_value - From + From business_requirement br LEFT JOIN business_requirement_deliverable dlv ON dlv.business_requirement_id = br.id LEFT JOIN business_requirement_resource res ON res.business_requirement_deliverable_id = dlv.id - LEFT JOIN project_task pt - ON pt.business_requirement_id = br.id + LEFT JOIN project_task pt + ON pt.business_requirement_id = br.id JOIN product_template as ptm ON ptm.id = res.product_id - group by + group by br.id,pt.id,ptm.id )""") From 3b0fdda7ffb2c9838e22bfa24e54b11dca957066 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Thu, 13 Apr 2017 12:21:30 +0530 Subject: [PATCH 10/13] [IMP]Improved Earned Value Report Query code. --- .../report/br_earned_value_report.py | 97 +++++++++++++------ 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py index 2aa347df5..d49ce91c2 100644 --- a/business_requirement_earned_value/report/br_earned_value_report.py +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -45,44 +45,77 @@ def init(self, cr): SELECT br.id, br.name as name, - br.description as description, - br.partner_id as partner_id, - br.project_id as project_id, - ptm.id as hr_timesheet_product, - sum(res.qty) as planned_time_in_rl, - sum(res.unit_price) as product_cost_from_rl, - (sum(res.qty) * sum(res.unit_price)) as planned_value, - (pt.effective_hours) as actual_time_in_timesheet, - (ptm.list_price) as product_cost_from_timesheet_product, - (pt.effective_hours * ptm.list_price) - as actual_cost, - abs((pt.effective_hours * ptm.list_price - ) - (sum(res.qty) * sum(res.unit_price))) - as variance, - (abs((pt.effective_hours * ptm.list_price - ) - (sum(res.qty) * sum(res.unit_price))) / - sum(res.unit_price)) as per_variances, - pt.remaining_hours as remaining_hours, - (pt.effective_hours + pt.remaining_hours) - as total_expected_time, - CASE WHEN (pt.remaining_hours) > 0 THEN - (pt.effective_hours / (pt.effective_hours + pt.remaining_hours + br.description AS description, + br.partner_id AS partner_id, + br.project_id AS project_id, + ptm.id AS hr_timesheet_product, + SUM(res.qty) AS planned_time_in_rl, + SUM(res.unit_price) AS product_cost_from_rl, + (SUM(res.qty) * SUM(res.unit_price)) AS planned_value, + (SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id) + AS actual_time_in_timesheet, + (ptm.list_price) AS product_cost_from_timesheet_product, + ((SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id) * ptm.list_price) + AS actual_cost, + abs(((SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id) * ptm.list_price + ) - (SUM(res.qty) * SUM(res.unit_price))) + AS variance, + (abs(((SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id) * ptm.list_price + ) - (SUM(res.qty) * SUM(res.unit_price))) / + SUM(res.unit_price)) AS per_variances, + (SELECT SUM(pt.remaining_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id) AS remaining_hours, + ((SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id + ) + (SELECT SUM(pt.remaining_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id)) + AS total_expected_time, + CASE WHEN ((SELECT SUM(pt.remaining_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id)) > 0 THEN + ((SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id + ) / ((SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id + ) + (SELECT SUM(pt.remaining_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id) )) ElSE 0.0 END as project_completion, - CASE WHEN (pt.remaining_hours) > 0 THEN - (((sum(res.qty) * (sum(res.unit_price) * sum(res.qty)) - ) * (pt.effective_hours / - pt.effective_hours + pt.remaining_hours))) ElSE 0.0 END - as earned_value - From + CASE WHEN ((SELECT SUM(pt.remaining_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id)) > 0 THEN + (((SUM(res.qty) * (SUM(res.unit_price) * SUM(res.qty)) + ) * ((SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id) / + (SELECT SUM(pt.effective_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id + ) + (SELECT SUM(pt.remaining_hours) + FROM project_task pt, business_requirement br + WHERE pt.business_requirement_id = br.id)))) ElSE 0.0 END + AS earned_value + FROM business_requirement br LEFT JOIN business_requirement_deliverable dlv ON dlv.business_requirement_id = br.id LEFT JOIN business_requirement_resource res ON res.business_requirement_deliverable_id = dlv.id - LEFT JOIN project_task pt - ON pt.business_requirement_id = br.id JOIN product_template as ptm ON ptm.id = res.product_id - group by - br.id,pt.id,ptm.id + GROUP BY + br.id,ptm.id )""") From ef9bcc0217e16f6413b4d937187ee04329e82c8f Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Fri, 14 Apr 2017 14:15:45 +0530 Subject: [PATCH 11/13] [IMP]Improved Earned Value Report Query code. --- .../report/br_earned_value_report.py | 270 +++++++++++++----- 1 file changed, 196 insertions(+), 74 deletions(-) diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py index d49ce91c2..1cc10fdc5 100644 --- a/business_requirement_earned_value/report/br_earned_value_report.py +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -11,7 +11,6 @@ class BusinessRequirementEarnedValueReport(models.Model): _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', @@ -21,101 +20,224 @@ class BusinessRequirementEarnedValueReport(models.Model): hr_timesheet_product = 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_time_in_rl = fields.Float('Planned Time', readonly=True) + product_cost_from_rl = fields.Float('Unit Cost', readonly=True) planned_value = fields.Float('Planned Value', readonly=True) - actual_time_in_timesheet = fields.Float('Actual time in Timesheet', + actual_time_in_timesheet = fields.Float('Actual Time', readonly=True) product_cost_from_timesheet_product =\ - fields.Float('Product Cost from Timesheet product', + fields.Float('Act. Unit Cost', 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) + 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 ( + def _select(self): + select_str = """ SELECT br.id, - br.name as name, - br.description AS description, + CONCAT(br.name,'[',br.description,']') as name, br.partner_id AS partner_id, br.project_id AS project_id, ptm.id AS hr_timesheet_product, SUM(res.qty) AS planned_time_in_rl, SUM(res.unit_price) AS product_cost_from_rl, (SUM(res.qty) * SUM(res.unit_price)) AS planned_value, - (SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id) - AS actual_time_in_timesheet, + (SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) + AS actual_time_in_timesheet, (ptm.list_price) AS product_cost_from_timesheet_product, - ((SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id) * ptm.list_price) + ((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) * ptm.list_price) AS actual_cost, - abs(((SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id) * ptm.list_price - ) - (SUM(res.qty) * SUM(res.unit_price))) - AS variance, - (abs(((SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id) * ptm.list_price - ) - (SUM(res.qty) * SUM(res.unit_price))) / - SUM(res.unit_price)) AS per_variances, - (SELECT SUM(pt.remaining_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id) AS remaining_hours, - ((SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id - ) + (SELECT SUM(pt.remaining_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id)) - AS total_expected_time, - CASE WHEN ((SELECT SUM(pt.remaining_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id)) > 0 THEN - ((SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id - ) / ((SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id - ) + (SELECT SUM(pt.remaining_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id) - )) - ElSE 0.0 END as project_completion, - CASE WHEN ((SELECT SUM(pt.remaining_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id)) > 0 THEN - (((SUM(res.qty) * (SUM(res.unit_price) * SUM(res.qty)) - ) * ((SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id) / - (SELECT SUM(pt.effective_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id - ) + (SELECT SUM(pt.remaining_hours) - FROM project_task pt, business_requirement br - WHERE pt.business_requirement_id = br.id)))) ElSE 0.0 END - AS earned_value - FROM - business_requirement br + CASE + WHEN (SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) > 0 + THEN + (((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id + ) * ptm.list_price) - (SUM(res.qty + ) * SUM(res.unit_price))) + ElSE 0.0 END AS variance, + CASE + WHEN + (SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) > 0 + THEN + (abs(((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id + ) * ptm.list_price) - (SUM(res.qty + ) * SUM(res.unit_price))) / + SUM(res.unit_price)) + ElSE 0.0 END AS per_variances, + CASE + WHEN + (SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) > 0 + THEN + (SELECT + SUM(pt.remaining_hours) + FROM + project_task pt + WHERE pt.business_requirement_id = br.id) + ElSE 0.0 END AS remaining_hours, + CASE + WHEN + (SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) > 0 + THEN + ((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id + ) + (SELECT + SUM(pt.remaining_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id)) + ElSE 0.0 END AS total_expected_time, + CASE + WHEN ((SELECT + SUM(pt.remaining_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id)) > 0 + THEN + CASE + WHEN + (SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) > 0 + THEN + ((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id + ) / ((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id + ) + (SELECT + SUM(pt.remaining_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) + ) * 100) ELSE 0.0 END + ElSE 0.0 END AS project_completion, + CASE + WHEN + (SELECT + SUM(pt.remaining_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) > 0 + THEN + CASE + WHEN + (SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id) > 0 + THEN + ((SUM(res.qty) * SUM(res.unit_price) + ) * ((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id + ) / ((SELECT + SUM(pt.effective_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id + ) + (SELECT + SUM(pt.remaining_hours) + FROM + project_task pt + WHERE + pt.business_requirement_id = br.id)))) + ElSE 0.0 END + ElSE 0.0 END AS earned_value + """ + return select_str + + def _from(self): + from_str = """ + business_requirement br LEFT JOIN business_requirement_deliverable dlv - ON dlv.business_requirement_id = br.id + ON dlv.business_requirement_id = br.id LEFT JOIN business_requirement_resource res - ON res.business_requirement_deliverable_id = dlv.id - JOIN product_template as ptm ON ptm.id = res.product_id + ON res.business_requirement_deliverable_id = dlv.id + JOIN product_template as ptm + ON ptm.id = res.product_id + """ + return from_str + + def _group_by(self): + group_by_str = """ GROUP BY br.id,ptm.id - )""") + """ + return group_by_str + + def init(self, cr): + tools.drop_view_if_exists(cr, self._table) + cr.execute("""CREATE or REPLACE VIEW %s as ( + %s + FROM ( %s ) + %s + )""" % (self._table, self._select(), self._from(), + self._group_by())) From 2c8b74612c2f4ed0581af3ba7ae7cc2011420ee3 Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Fri, 14 Apr 2017 16:33:40 +0530 Subject: [PATCH 12/13] [IMP]Improved Earned Value Report Lable Name. --- .../report/br_earned_value_report.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/business_requirement_earned_value/report/br_earned_value_report.py b/business_requirement_earned_value/report/br_earned_value_report.py index 1cc10fdc5..20aae01b2 100644 --- a/business_requirement_earned_value/report/br_earned_value_report.py +++ b/business_requirement_earned_value/report/br_earned_value_report.py @@ -32,8 +32,8 @@ class BusinessRequirementEarnedValueReport(models.Model): 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) + total_expected_time = fields.Float('Total Exp. time', readonly=True) + project_completion = fields.Float('% Completion', readonly=True) earned_value = fields.Float('Earned Value', readonly=True) def _select(self): From 37eb011639eb1214fdfbfaa0a84b1247459263ac Mon Sep 17 00:00:00 2001 From: Sudhir Arya Date: Mon, 17 Apr 2017 14:24:23 +0530 Subject: [PATCH 13/13] [IMP]Improved Indentation. --- business_requirement_deliverable_cost/models/business.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/business_requirement_deliverable_cost/models/business.py b/business_requirement_deliverable_cost/models/business.py index 134de7273..9a564deae 100644 --- a/business_requirement_deliverable_cost/models/business.py +++ b/business_requirement_deliverable_cost/models/business.py @@ -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')) + 'price_total')) @api.multi @api.depends('deliverable_lines')