-
Notifications
You must be signed in to change notification settings - Fork 76
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
[12.0][BR001549][MIG] project_completion_report: Migration to 12.0 #235
base: 12.0
Are you sure you want to change the base?
Changes from all commits
13eff34
4f141a5
c4636db
fa94e3f
cf032d9
a5fa7c6
14a4ac9
60ddd5c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
business-requirement https://github.com/OCA/business-requirement.git 12.0 | ||
odoo_enterprise [email protected]:Elico-Corp/odoo_enterprise.git 12.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.png | ||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html | ||
:alt: License: LGPL-3 | ||
|
||
========================= | ||
Project Completion Report | ||
========================= | ||
|
||
This module creates a report that allows you to follow-up the | ||
completion of a project by comparing the estimated time and the | ||
time actually spent in the timesheets. | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you need to: | ||
|
||
#. Go to Reporting > Project > Project Completion Report | ||
|
||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas | ||
:alt: Try me on Runbot | ||
:target: https://runbot.odoo-community.org/runbot/{repo_id}/{branch} | ||
|
||
.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove comments |
||
.. branch is "8.0" for example | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues | ||
<https://github.com/Elico-Corp/odoo-addons/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 | ||
======= | ||
|
||
Images | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this section |
||
------ | ||
|
||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. | ||
|
||
Contributors | ||
------------ | ||
|
||
* Sebastien Maillard <[email protected]> | ||
* Reinhard Sheng <[email protected]> | ||
|
||
Maintainer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is old template |
||
---------- | ||
|
||
.. 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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import report |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# © 2016-2019 Elico Corp (https://www.elico-corp.com) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). | ||
{ | ||
"name": "Project Completion Report", | ||
"summary": "Follow-up project completion (estimated / consumed)", | ||
"version": "12.0.1.0.0", | ||
"category": "Project", | ||
'website': 'https://www.elico-corp.com', | ||
'support': '[email protected]', | ||
"author": "Elico Corp", | ||
"license": "LGPL-3", | ||
"application": False, | ||
"installable": True, | ||
"depends": [ | ||
"hr_timesheet", | ||
"helpdesk_timesheet", | ||
"project_project_category", | ||
"business_requirement_deliverable_project", | ||
], | ||
"data": [ | ||
"report/project_completion_report_view.xml", | ||
"security/ir.model.access.csv", | ||
], | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import project_completion_report |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# © 2016-2019 Elico Corp (https://www.elico-corp.com) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). | ||
|
||
from odoo import models, fields, tools | ||
|
||
|
||
class ProjectCompletionReport(models.Model): | ||
"""Project Completion Report""" | ||
|
||
_name = "project.completion.report" | ||
# Database table should not be created, use init() instead | ||
_auto = False | ||
_description = "Project Completion Report" | ||
# Field used for the Name | ||
_rec_name = 'activity_name' | ||
|
||
id = fields.Integer('ID', readonly=True) | ||
partner_id = fields.Many2one( | ||
'res.partner', 'Customer', readonly=True) | ||
master_project_id = fields.Many2one( | ||
'project.project', 'Master Project', readonly=True, | ||
help="Master Project of the Business Requirement") | ||
br_id = fields.Many2one( | ||
'business.requirement', 'Bus. Req.', | ||
readonly=True, help="Business Requirement") | ||
project_id = fields.Many2one( | ||
'project.project', 'Project', readonly=True) | ||
account_id = fields.Many2one( | ||
'account.analytic.account', 'Analytic Account', readonly=True) | ||
project_state = fields.Char( | ||
'State', readonly=True, help="Project State") | ||
project_categ_id = fields.Many2one( | ||
'project.project.category', | ||
'Project Cat.', readonly=True, help="Project Category") | ||
activity_type = fields.Selection( | ||
[ | ||
('task', 'Task'), | ||
('issue', 'Issue'), | ||
], 'Type', readonly=True, | ||
help="Type is used to separate Tasks and Issues") | ||
activity_id = fields.Char( | ||
'Activity ID', readonly=True, help="Task ID or Issue ID") | ||
activity_name = fields.Char( | ||
'Activity Name', readonly=True, help="Task name or Issue name") | ||
user_id = fields.Many2one( | ||
'res.users', | ||
'Assignee', | ||
readonly=True, | ||
help="Assignee is not necessarily the one who input the Timesheets") | ||
activity_stage_id = fields.Many2one( | ||
'project.task.type', 'Stage', | ||
readonly=True, help="Activity Stage") | ||
# FIXME if BR resource UoM is not hours, `qty` needs to be converted | ||
estimated_hours = fields.Float( | ||
'Est. time', digits=(16, 2), readonly=True, | ||
help="Estimated time (from BR)") | ||
planned_hours = fields.Float( | ||
'Init. time', digits=(16, 2), readonly=True, | ||
help="Initial time (from Task)") | ||
total_tms = fields.Float( | ||
'Time spent', digits=(16, 2), readonly=True, | ||
help="Time spent on timesheet") | ||
remaining_hours = fields.Float( | ||
'Remain. time', digits=(16, 2), readonly=True, | ||
help="Remaining time") | ||
total_hours = fields.Float('Total time', digits=(16, 2), readonly=True) | ||
variance = fields.Float( | ||
'Variance', digits=(16, 2), readonly=True, | ||
help="Variance between Estimated time (from BR) and Total time") | ||
|
||
def init(self, cr): | ||
"""Project Completion Report""" | ||
tools.drop_view_if_exists(cr, 'project_completion_report') | ||
cr.execute(""" | ||
CREATE OR REPLACE VIEW project_completion_report AS ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @seb-elico review requested here |
||
-- Since Odoo requires a unique ID for each line and since some | ||
-- issues and tasks might share the same ID, use the row number | ||
-- to ensure each row has a unique ID | ||
SELECT | ||
row_number() OVER | ||
( | ||
-- Tasks first, then issues | ||
-- Warning: without the sort over the activity type, | ||
-- Odoo is confusing some task IDs as if they were | ||
-- issue IDs | ||
ORDER BY q.activity_type DESC, q.activity_id ASC | ||
) AS id, q.* | ||
FROM | ||
( | ||
( | ||
SELECT | ||
a.partner_id, | ||
b.project_id AS master_project_id, | ||
b.id AS br_id, | ||
p.id AS project_id, | ||
a.id AS account_id, | ||
p.project_categ_id, | ||
p.state AS project_state, | ||
'task' AS activity_type, | ||
t.id AS activity_id, | ||
t.name AS activity_name, | ||
t.user_id, | ||
t.stage_id AS activity_stage_id, | ||
COALESCE(r.qty, 0) AS estimated_hours, | ||
t.planned_hours, | ||
COALESCE(SUM(al.unit_amount), 0) AS total_tms, | ||
t.remaining_hours, | ||
COALESCE(SUM(al.unit_amount), 0) | ||
+ t.remaining_hours AS total_hours, | ||
COALESCE(SUM(al.unit_amount), 0) | ||
+ t.remaining_hours - COALESCE(r.qty, 0) | ||
AS variance | ||
FROM | ||
project_project p | ||
-- Link with the analytic account | ||
INNER JOIN account_analytic_account a | ||
ON a.id = p.analytic_account_id | ||
-- Link with the task | ||
INNER JOIN project_task t ON t.project_id = p.id | ||
-- Link with the timesheet | ||
LEFT OUTER JOIN account_analytic_line al | ||
ON al.task_id = t.id | ||
-- Link with the BR | ||
LEFT OUTER JOIN business_requirement b | ||
ON b.id = p.business_requirement_id | ||
-- Link with the BR resource | ||
LEFT OUTER JOIN business_requirement_resource r | ||
ON r.business_requirement_id = b.id | ||
AND r.id = t.br_resource_id | ||
GROUP BY | ||
t.id, p.id, a.id, b.id, r.id | ||
) | ||
UNION | ||
( | ||
SELECT | ||
a.partner_id, | ||
b.project_id AS master_project_id, | ||
b.id AS br_id, | ||
p.id AS project_id, | ||
a.id AS account_id, | ||
p.project_categ_id, | ||
p.state AS project_state, | ||
'issue' AS activity_type, | ||
h.id AS activity_id, | ||
h.name AS activity_name, | ||
h.user_id, | ||
h.stage_id AS activity_stage_id, | ||
0 AS estimated_hours, | ||
0 AS planned_hours, | ||
COALESCE(SUM(al.unit_amount), 0) AS total_tms, | ||
0 AS remaining_hours, | ||
COALESCE(SUM(al.unit_amount), 0) AS total_hours, | ||
COALESCE(SUM(al.unit_amount), 0) AS variance | ||
FROM | ||
project_project p | ||
-- Link with the analytic account | ||
INNER JOIN account_analytic_account a | ||
ON a.id = p.analytic_account_id | ||
-- Link with the issue | ||
INNER JOIN helpdesk_ticket h | ||
ON h.project_id = p.id | ||
LEFT OUTER JOIN account_analytic_line al | ||
ON al.helpdesk_ticket_id = h.id | ||
-- Link with the BR | ||
LEFT OUTER JOIN business_requirement b | ||
ON b.id = p.business_requirement_id | ||
GROUP BY | ||
h.id, p.id, a.id, b.id | ||
) | ||
) AS q)""") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- # © 2016-2019 Elico Corp (https://www.elico-corp.com) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). --> | ||
<odoo> | ||
|
||
<record id="action_project_completion_tree" model="ir.ui.view"> | ||
<field name="name">Project Completion Tree</field> | ||
<field name="model">project.completion.report</field> | ||
<field name="arch" type="xml"> | ||
<tree string="Project Completion Tree"> | ||
<field name="partner_id" /> | ||
<field name="master_project_id" /> | ||
<field name="br_id" /> | ||
<field name="project_id" /> | ||
<field name="account_id" /> | ||
<field name="project_state" /> | ||
<field name="project_categ_id" /> | ||
<field name="activity_type" /> | ||
<field name="activity_id" string="ID" /> | ||
<field name="activity_name" /> | ||
<field name="user_id" /> | ||
<field name="activity_stage_id" /> | ||
<field name="estimated_hours" /> | ||
<field name="planned_hours" /> | ||
<field name="total_tms" /> | ||
<field name="remaining_hours" /> | ||
<field name="total_hours" /> | ||
<field name="variance" /> | ||
</tree> | ||
</field> | ||
</record> | ||
|
||
<record id="action_project_completion_pivot" model="ir.ui.view"> | ||
<field name="name">Project Completion Pivot Table</field> | ||
<field name="model">project.completion.report</field> | ||
<field name="arch" type="xml"> | ||
<graph type="pivot"> | ||
<field name="estimated_hours" type="measure" /> | ||
<field name="planned_hours" type="measure" /> | ||
<field name="total_tms" type="measure" /> | ||
<field name="remaining_hours" type="measure" /> | ||
<field name="total_hours" type="measure" /> | ||
<field name="variance" type="measure" /> | ||
</graph> | ||
</field> | ||
</record> | ||
|
||
<record id="action_project_completion_report" | ||
model="ir.actions.act_window"> | ||
<field name="name">Project Completion Analysis</field> | ||
<field name="res_model">project.completion.report</field> | ||
<field name="view_type">form</field> | ||
<field name="view_mode">tree,graph</field> | ||
<field name="context">{}</field> | ||
<field name="domain">[]</field> | ||
</record> | ||
|
||
<record model="ir.ui.view" id="project_completion_search"> | ||
<field name="name">Project Completion Search</field> | ||
<field name="model">project.completion.report</field> | ||
<field name="arch" type="xml"> | ||
<search string="Project Completion search"> | ||
<field name="partner_id" /> | ||
<field name="master_project_id" /> | ||
<field name="br_id" /> | ||
<field name="project_id" /> | ||
<field name="account_id" /> | ||
<field name="project_categ_id" /> | ||
<field name="project_state" /> | ||
<field name="activity_id" /> | ||
<field name="user_id" /> | ||
<field name="activity_stage_id" /> | ||
<separator /> | ||
<group expand="0" string="Group By"> | ||
<filter name="customer" string="Customer" domain="[]" | ||
context="{'group_by': 'partner_id'}" /> | ||
<filter name="master_project" string="Master Project" domain="[]" | ||
context="{'group_by': 'master_project_id'}" /> | ||
<filter name="business_requirement" string="Business Requirement" domain="[]" | ||
context="{'group_by': 'br_id'}" /> | ||
<filter name="project" string="Project" domain="[]" | ||
context="{'group_by': 'project_id'}" /> | ||
<filter name="analytic_account" string="Analytic Account" domain="[]" | ||
context="{'group_by': 'account_id'}" /> | ||
<filter name="project_state" string="Project State" domain="[]" | ||
context="{'group_by': 'project_state'}" /> | ||
<filter name="project_category" string="Project Category" domain="[]" | ||
context="{'group_by': 'project_categ_id'}" /> | ||
<filter name="assignee" string="Assignee" domain="[]" | ||
context="{'group_by': 'user_id'}" /> | ||
<filter name="activity_stage" string="Activity Stage" domain="[]" | ||
context="{'group_by': 'activity_stage_id'}" /> | ||
</group> | ||
</search> | ||
</field> | ||
</record> | ||
|
||
<menuitem name="Project Completion Analysis" | ||
id="menu_project_completion_report_tree" | ||
parent="hr.menu_hr_reporting" | ||
action="action_project_completion_report" sequence="1" /> | ||
|
||
</odoo> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink | ||
access_project_completion_report,project.completion.report all,model_project_completion_report,base.group_user,1,1,1,1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adapt