Merge lp:~akretion-team/project-service/add-project-action-item into lp:~project-core-editors/project-service/trunk

Proposed by Alexis de Lattre
Status: Needs review
Proposed branch: lp:~akretion-team/project-service/add-project-action-item
Merge into: lp:~project-core-editors/project-service/trunk
Diff against target: 1296 lines (+1230/-0)
11 files modified
project_action_item/__init__.py (+24/-0)
project_action_item/__openerp__.py (+54/-0)
project_action_item/i18n/fr.po (+277/-0)
project_action_item/i18n/project_action_item.pot (+277/-0)
project_action_item/project.py (+179/-0)
project_action_item/project_demo.xml (+64/-0)
project_action_item/project_view.xml (+151/-0)
project_action_item/security/ir.model.access.csv (+2/-0)
project_action_item/wizard/__init__.py (+23/-0)
project_action_item/wizard/update_action_generate_timesheet.py (+137/-0)
project_action_item/wizard/update_action_generate_timesheet_view.xml (+42/-0)
To merge this branch: bzr merge lp:~akretion-team/project-service/add-project-action-item
Reviewer Review Type Date Requested Status
Lorenzo Battistini (community) Abstain
Raphaël Valyi - http://www.akretion.com Approve
Daniel Reis Needs Fixing
Review via email: mp+216224@code.launchpad.net

Description of the change

This merge proposal adds the module "project_action_item".

Extract from the module description :

This module adds action items on project tasks. When a user has completed the action item of a task, he can click on a button "Done with Timesheet" that starts a wizard ; this wizard will mark the action item as done and will create a timesheet line.

The idea behind this module is the following : on a task, we have the timesheet lines that give you the history of the actions made for that task... but we don't have anything to store the actions that must be carried out for that action (apart from the text field "description"). So, with this module : on a task, the timesheet lines (object hr.analytic.timesheet) still store the "past" actions carried out ; the action items (new object project.action.item) in "todo" state store the future actions that must be carried out. And we have a wizard to set an action item from todo to done and generate the corresponding timesheet line.

To post a comment you must log in.
Revision history for this message
Daniel Reis (dreis-pt) wrote :

Very nice feature Alexis.

I tried it out, and I have some comments:

* I would be nice to inform where the lp branch "hr_timesheet_task" can be found, at least until openerpapps.info rules the world.
* The "Done with timesheet" is not a real button. It took me some time to realize it's test was clickable.
* IMO "Done with timesheet" is a confusing label. I would prefer "Log on Timesheet" or the even simpler "Done".
* Actions should heave a sequence field, and be manually reordered in the Task Actions tab.
* If you have the "Manage time estimation on tasks" feature activated, the Task's estimated time should be computed as the total Actions estimated time (in the demo data, the Tasks estimated time is 22h and the Action estimated time is 70h).
* When an Action is Done, you can't see the actual time spent.
* At the time you are creating the Action list, you should be able to set if you expect it to be billable (or expected Invoicing Ratio).
* You can't log time on an Action without completing it. The demo action "Develop final version" is 42h long, will surely span more than a week, and you will surely won't be able to wait until it's completed to log the time spent.
I suggest the wizard to let you log time on timesheet for an action, but keep it as not done / in progress.

Just some food for thought; it may be a bad idea, but:
What if instead of "Actions" we had "Child Tasks"? If that implementation strategy doesn't bring a lot of difficulties, It would open up a lot of interesting use cases ...

review: Needs Fixing
Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote :

Hello Daniel,

I just want t mention that yesterday I talked with Alexis and I spontaneously made exactly the same remark as you with the concept of children tasks instead of that new actions object.

There are several modules trying to fix the need for a standard Workbench Breakdown Structure (WBS from PMI) in OpenERP.

Ferdinand Gassauer at C2C2 maintained a parent-child task hierarchy module for years (not remembering the link though) and there is also this project_scope_wbs PMI WBS module from Efficient now that would eventually be interesting to bring into OCA:
http://bazaar.launchpad.net/~eficent/eficent-openerp-project-management/7.0/files

On our side at Akretion we will also soon push an other module called project_feature that also aim at managing different granularity scales for projects, this time bridging operational tasks with the customer metric expressed with a new object called project.feature.

So there is definitely effort in that direction and we should avoid "leaky abstraction". That is as you said, if with minimum effort would could make it work with a hierarchy instead of introducing that action object, that would be cool.

If that is not possible, we should try to make it at least compatible with the modules trying to bring WBS hierarchy.

All in all, this module seems great, but we should double check if we can make the most of it before blessing it to OCA.

Regards

Revision history for this message
JB (eficent.com) (jb.eficent) wrote :
Download full text (3.5 KiB)

Hello Alexis, Daniel and Raphaël,

The module developed by Alexis is a valid option me. Let me expose the two alternatives that I can see as being valid.

First of all, some key definitions of project management terminology as defined by PMI:
- Control Account
A control account is a management control point where scope, budget, actual cost, and schedule are integrated and compared to the earned value for performance measurement (3).

- Planning Package
A planning package is a work breakdown structure component below the control account with known work content but without detailed schedule activities (3).

- Work Package
Same as a planning package, but with detailed activites defined within.
Work package is a more deliverable oriented definition of the work to be completed (identifies work to be done to complete the project scope, but does not provide the low level detail).

- Activty
Activities represent the effort needed to complete a work package. Each work package is decomposed into the activities required to produce the work package deliverables (4). Activities more specifically identify the individual low level actions needed to complete the work package.

- Milestone
Milestones are similar to regular schedule activities, with the same structure and
attributes, but they have zero duration because milestones represent a moment in time (5).

Now let's see how OpenERP seems to be mapping these concepts.
- Control Account --> project.project
- Planning Package --> project.task
- Work Package --> project.task
- Activity --> ?
- Milestone -> ?

From a PMI terminology perspective, OpenERP's project.task is now being used more as a work-package than as an activity (1),(2):
- project.task is now being used to assign work to be done without detailed breakdown (work packages) from other modules such project.issue or sales order lines that are related to internally procured service items.
- project.task is built with the capability to define multiple stages required to complete the work (analysis, design, ..). That is unnecessary in activities, but useful in work packages.

Now let's see how can we completely map in OpenERP the PMI concepts. I can see two options here:
Option 1 -> Use project.project to implement work packages and project.task to implement activities.
Option 2 -> Use project.task to implement work packages and project.action.item to implement activities.

Option 1 adheres to my current project management modules (https://launchpad.net/eficent-openerp-project-management), but has the following limitations:
1) Project Issue module should create project.project records as workd packages instead of project.task
2) Sale module should create project.project records as work packages instead of project.task.

Option 2 would require a significant redesign of my modules.

Mapping of concepts in Option 1:
Control Account --> project.project
Planning Package --> project.project
Work Package --> project.project
Activity --> project.task
Milestone -> project.task

Mapping of concepts in Option 2:
Control Account --> project.project
Planning Package --> project.task
Work Package --> project.task
Activity --> project.action.item
Milestone -> ...

Read more...

35. By Alexis de Lattre

Implement some suggestions of Daniel Reis :
- explain where to find the module hr_timesheet_task in module description
- add state "In Progress" and adapt the wizard and buttons
- add field "to_invoice" on action item, that will be copied to the timesheet
- change "Done with timesheet" to "Done" in the tree view.

36. By Alexis de Lattre

Continue to implement the remarks of Daniel :
- add computed field timesheet_hours on project.action.item
- replace the native field 'planned_hours' on task by a computed field (sum of action items)
Update some strings and field names (Quantity -> Hours)
Flake8 validation

Revision history for this message
Alexis de Lattre (alexis-via) wrote :

@Daniel Reis

I have implemented all your remarks :

* I would be nice to inform where the lp branch "hr_timesheet_task" can be found, at least until openerpapps.info rules the world.

=> Done

* The "Done with timesheet" is not a real button. It took me some time to realize it's test was clickable.

=> What do you suggest for that ?

* IMO "Done with timesheet" is a confusing label. I would prefer "Log on Timesheet" or the even simpler "Done".

=> We now have 2 buttons : "Done" and "Progress"

* Actions should heave a sequence field, and be manually reordered in the Task Actions tab.

=> They have that since my first commit :) Re-ordering action items works fine.

* If you have the "Manage time estimation on tasks" feature activated, the Task's estimated time should be computed as the total Actions estimated time (in the demo data, the Tasks estimated time is 22h and the Action estimated time is 70h).

=> Done?

* When an Action is Done, you can't see the actual time spent.

=> I added a field "timesheet_hours" on action items

* At the time you are creating the Action list, you should be able to set if you expect it to be billable (or expected Invoicing Ratio).

=> Done.

* You can't log time on an Action without completing it. The demo action "Develop final version" is 42h long, will surely span more than a week, and you will surely won't be able to wait until it's completed to log the time spent.
I suggest the wizard to let you log time on timesheet for an action, but keep it as not done / in progress.

=> Very good idea. Action items now have 3 states instead of 2 : todo, in progress and done.

37. By Alexis de Lattre

Add icon on button in tree view
Add related field projet_id
Now that we have both "todo" and "progress", the state field should always be visible.

Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote :

Considering the suggestion from Jordi that WBS is better implemented using a project hierarchy than a task hierarchy (it's true that OpenERP has some support for a hierarchy of projects), then I approve Alexis' merge.

review: Approve
38. By Alexis de Lattre

[Usability] Put action items above timesheets, in the same tab

Revision history for this message
Daniel Reis (dreis-pt) wrote :

Great work Alexis. I hope you don't think it's too nitpicking, but I still have some (mostly UI) comments.

Regarding the "Manage time estimation on tasks" feature, you did a good job, but were tricked but thr ORM limitations: the "Initially planned hours" at the top of the Task form is now correct, but the "Remaining" and "Total Time" at the bottom still calculate as before. (Maybe you need to keep task estimated time a plain float updated when you write on an Action's.)

My UI suggestions are:

1) I find confusing to have both Actions and Work Ids on the same page. Maybe move Actions to a new form Page?
2) Add a read only "Actual Hours" after "Estimated Hours" and remove the "State" field. This gives better information with the same number of columns.
3) Replace the two icon button with a single "Log Time" classic button (I think the icon buttons are no longer used in v7), and instead have two action buttons on the wizard to log time on an Action ("Log and Continue", "Log and Complete"). This also makes the "Action Item Complete" checkbox unnecessary.
4) Remove the menu "Action Items": it's the same as the "My Action Items" menu, except that it has a removable default filter.

39. By Alexis de Lattre

[Usability] implement some of the remarks of Daniel Reis :
- one menu entry instead of 2
- display "Worked Hours" in Tree view and re-order cols

Revision history for this message
Alexis de Lattre (alexis-via) wrote :

@Daniel : about your UI suggestions :

1) I have precisely changed the task view so that the Actions and Works Ids are in the same tab, so that a user can see what he has done and what he has left to do in the same screen. I find it very usefull.

2) I added the field "Worked Hours" in the tree view ; I kept the "State" field because I find it usefull and there is enough room to keep it

3) The icon buttons are still used in v7 in the tree views (and only in tree views). For example, on the form view of a delivery order, there are 3 icon buttons : Scrap Products, Put in current pack, Put in new pack. So it's coherent with the rest of OpenERP.

4) I agree with you ; I kept only one menu entry "Action Items", with the filter.

40. By Alexis de Lattre

[Usability] Larger display for the action description.

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Thanks Alexis,
some style notes

project_action_item/__openerp__.py:52:9: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:65:17: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:66:13: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:71:13: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:76:9: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:93:9: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:100:13: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:106:13: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:113:13: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:141:9: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:176:17: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/project.py:179:9: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/wizard/update_action_generate_timesheet.py:39:9: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/wizard/update_action_generate_timesheet.py:66:13: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/wizard/update_action_generate_timesheet.py:89:13: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/wizard/update_action_generate_timesheet.py:98:17: E123 closing bracket does not match indentation of opening bracket's line
project_action_item/wizard/update_action_generate_timesheet.py:136:17: E123 closing bracket does not match indentation of opening bracket's line

project_action_item/__openerp__.py:34:80: E501 line too long (250 > 79 characters)
project_action_item/__openerp__.py:36:80: E501 line too long (115 > 79 characters)
project_action_item/__openerp__.py:38:80: E501 line too long (120 > 79 characters)
project_action_item/__openerp__.py:51:80: E501 line too long (82 > 79 characters)

review: Needs Fixing
Revision history for this message
Alexis de Lattre (alexis-via) wrote :

@Lorenzo :

You have a non-default configuration for flake8 ; as you can see below, flake8 gives me 0 error on the python files (except in __openerp__.py).

% flake8 project_action_item
project_action_item/__init__.py:23:1: F401 'project' imported but unused
project_action_item/__init__.py:24:1: F401 'wizard' imported but unused
project_action_item/__openerp__.py:34:80: E501 line too long (250 > 79 characters)
project_action_item/__openerp__.py:36:80: E501 line too long (115 > 79 characters)
project_action_item/__openerp__.py:38:80: E501 line too long (120 > 79 characters)
project_action_item/__openerp__.py:51:80: E501 line too long (82 > 79 characters)
project_action_item/wizard/__init__.py:23:1: F401 'update_action_generate_timesheet' imported but unused

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Uh, I'm using this
http://bazaar.launchpad.net/~openerp-community-reviewer/lp-community-utils/openerp-reviewers-nag/view/32/checkout-flake8.sh#L40
+
https://github.com/nbessi/openerp-conventions

The command
'flake8 project_action_item --ignore E501'
is the responsible for adding those output lines.
But I don't understand why

review: Abstain
Revision history for this message
Alexis de Lattre (alexis-via) wrote :

@Daniel

I have implemented and/or answered your UI remarks at the end of April. Could you update your review status (currently Needs Fixing) ?

Revision history for this message
Daniel Reis (dreis-pt) wrote :

This project is now hosted on https://github.com/OCA/project-service. Please move your proposal there.
This guide may help you https://github.com/OCA/maintainers-tools/wiki/How-to-move-a-Merge-Proposal-to-GitHub

Revision history for this message
Alexis de Lattre (alexis-via) wrote :

@Daniel :

I won't move this MP in the short term, because I am not familiar with git. By the way, if you had updated your "Needs fixing" review status after I implemented your remarks back in April, this MP would probably have been merged before the move to github !!! So it would have avoided all this additional work to move the MP to github !!!

Revision history for this message
Daniel Reis (dreis-pt) wrote :

Alexis: I understand it was an avoidable inconvenience.
Since I caused it I'll take the burden for to move.
I'll update the status here.

Revision history for this message
Alexis de Lattre (alexis-via) wrote :

@Daniel

Thanks a lot for your proposal... it is very much appreciated !

Revision history for this message
Daniel Reis (dreis-pt) wrote :

Unmerged revisions

40. By Alexis de Lattre

[Usability] Larger display for the action description.

39. By Alexis de Lattre

[Usability] implement some of the remarks of Daniel Reis :
- one menu entry instead of 2
- display "Worked Hours" in Tree view and re-order cols

38. By Alexis de Lattre

[Usability] Put action items above timesheets, in the same tab

37. By Alexis de Lattre

Add icon on button in tree view
Add related field projet_id
Now that we have both "todo" and "progress", the state field should always be visible.

36. By Alexis de Lattre

Continue to implement the remarks of Daniel :
- add computed field timesheet_hours on project.action.item
- replace the native field 'planned_hours' on task by a computed field (sum of action items)
Update some strings and field names (Quantity -> Hours)
Flake8 validation

35. By Alexis de Lattre

Implement some suggestions of Daniel Reis :
- explain where to find the module hr_timesheet_task in module description
- add state "In Progress" and adapt the wizard and buttons
- add field "to_invoice" on action item, that will be copied to the timesheet
- change "Done with timesheet" to "Done" in the tree view.

34. By Alexis de Lattre

Add module project_action_item.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'project_action_item'
2=== added file 'project_action_item/__init__.py'
3--- project_action_item/__init__.py 1970-01-01 00:00:00 +0000
4+++ project_action_item/__init__.py 2014-05-05 12:05:37 +0000
5@@ -0,0 +1,24 @@
6+# -*- encoding: utf-8 -*-
7+##############################################################################
8+#
9+# Project Action Item module for OpenERP
10+# Copyright (C) 2014 Akretion (http://www.akretion.com)
11+# @author Alexis de Lattre <alexis.delattre@akretion.com>
12+#
13+# This program is free software: you can redistribute it and/or modify
14+# it under the terms of the GNU Affero General Public License as
15+# published by the Free Software Foundation, either version 3 of the
16+# License, or (at your option) any later version.
17+#
18+# This program is distributed in the hope that it will be useful,
19+# but WITHOUT ANY WARRANTY; without even the implied warranty of
20+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+# GNU Affero General Public License for more details.
22+#
23+# You should have received a copy of the GNU Affero General Public License
24+# along with this program. If not, see <http://www.gnu.org/licenses/>.
25+#
26+##############################################################################
27+
28+from . import project
29+from . import wizard
30
31=== added file 'project_action_item/__openerp__.py'
32--- project_action_item/__openerp__.py 1970-01-01 00:00:00 +0000
33+++ project_action_item/__openerp__.py 2014-05-05 12:05:37 +0000
34@@ -0,0 +1,54 @@
35+# -*- encoding: utf-8 -*-
36+##############################################################################
37+#
38+# Project Action Item module for OpenERP
39+# Copyright (C) 2014 Akretion (http://www.akretion.com)
40+# @author Alexis de Lattre <alexis.delattre@akretion.com>
41+#
42+# This program is free software: you can redistribute it and/or modify
43+# it under the terms of the GNU Affero General Public License as
44+# published by the Free Software Foundation, either version 3 of the
45+# License, or (at your option) any later version.
46+#
47+# This program is distributed in the hope that it will be useful,
48+# but WITHOUT ANY WARRANTY; without even the implied warranty of
49+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+# GNU Affero General Public License for more details.
51+#
52+# You should have received a copy of the GNU Affero General Public License
53+# along with this program. If not, see <http://www.gnu.org/licenses/>.
54+#
55+##############################################################################
56+
57+
58+{
59+ 'name': 'Project Action Item',
60+ 'version': '0.1',
61+ 'category': 'Project Management',
62+ 'license': 'AGPL-3',
63+ 'summary': 'Adds action items on tasks',
64+ 'description': """
65+Project Action Item
66+===================
67+
68+This module adds action items on project tasks. When a user has completed the action item of a task, he can click on a button *Done with Timesheet* that starts a wizard ; this wizard will mark the action item as done and will create a timesheet line.
69+
70+This module depends on the module *hr_timesheet_task* which is available on http://code.launchpad.net/hr-timesheet.
71+
72+Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
73+ """,
74+ 'author': 'Akretion',
75+ 'website': 'http://www.akretion.com',
76+ 'depends': ['project', 'hr_timesheet_task'],
77+ 'data': [
78+ 'wizard/update_action_generate_timesheet_view.xml',
79+ 'project_view.xml',
80+ 'security/ir.model.access.csv',
81+ ],
82+ 'demo': ['project_demo.xml'],
83+ 'images': [
84+ 'static/src/img/screenshots/task_with_action_items.jpg',
85+ 'static/src/img/screenshots/create_timesheet_from_action_item_wizard.jpg',
86+ ],
87+ 'installable': True,
88+}
89
90=== added directory 'project_action_item/i18n'
91=== added file 'project_action_item/i18n/fr.po'
92--- project_action_item/i18n/fr.po 1970-01-01 00:00:00 +0000
93+++ project_action_item/i18n/fr.po 2014-05-05 12:05:37 +0000
94@@ -0,0 +1,277 @@
95+# Translation of OpenERP Server.
96+# This file contains the translation of the following modules:
97+# * project_action_item
98+#
99+msgid ""
100+msgstr ""
101+"Project-Id-Version: OpenERP Server 7.0\n"
102+"Report-Msgid-Bugs-To: \n"
103+"POT-Creation-Date: 2014-04-24 21:17+0000\n"
104+"PO-Revision-Date: 2014-04-24 21:17+0000\n"
105+"Last-Translator: <>\n"
106+"Language-Team: \n"
107+"MIME-Version: 1.0\n"
108+"Content-Type: text/plain; charset=UTF-8\n"
109+"Content-Transfer-Encoding: \n"
110+"Plural-Forms: \n"
111+
112+#. module: project_action_item
113+#: field:hr.analytic.timesheet,action_item_id:0
114+#: view:project.action.item:0
115+msgid "Action Item"
116+msgstr "Point d'action"
117+
118+#. module: project_action_item
119+#: field:project.action.item.timesheet,completed:0
120+msgid "Action Item Completed"
121+msgstr "Point d'action fini"
122+
123+#. module: project_action_item
124+#: model:ir.actions.act_window,name:project_action_item.project_action_item_action
125+#: model:ir.ui.menu,name:project_action_item.project_action_item_menu
126+#: view:project.action.item:0
127+#: view:project.task:0
128+#: field:project.task,action_item_ids:0
129+msgid "Action Items"
130+msgstr "Points d'action"
131+
132+#. module: project_action_item
133+#: field:project.task,done_action_item_ids:0
134+msgid "Action Items Done"
135+msgstr "Points d'action faits"
136+
137+#. module: project_action_item
138+#: field:project.task,to_work_action_item_ids:0
139+msgid "Action Items To Do"
140+msgstr "Points d'action à faire"
141+
142+#. module: project_action_item
143+#: view:project.task:0
144+msgid "Action Items To Work On"
145+msgstr "Points d'action à travailler"
146+
147+#. module: project_action_item
148+#: field:project.action.item,user_id:0
149+msgid "Assigned To"
150+msgstr "Assigné à"
151+
152+#. module: project_action_item
153+#: view:project.action.item:0
154+msgid "Back to To Do"
155+msgstr "Revenir à À faire"
156+
157+#. module: project_action_item
158+#: view:project.action.item.timesheet:0
159+msgid "Cancel"
160+msgstr "Annuler"
161+
162+#. module: project_action_item
163+#: field:project.action.item,create_uid:0
164+msgid "Created By"
165+msgstr "Créé par"
166+
167+#. module: project_action_item
168+#: field:project.action.item,create_date:0
169+msgid "Creation Date"
170+msgstr "Date de création"
171+
172+#. module: project_action_item
173+#: field:project.action.item.timesheet,date:0
174+msgid "Date"
175+msgstr "Date"
176+
177+#. module: project_action_item
178+#: field:project.action.item,date_done:0
179+msgid "Date Done"
180+msgstr "Fait le"
181+
182+#. module: project_action_item
183+#: field:project.action.item,date_deadline:0
184+msgid "Deadline"
185+msgstr "Date limite"
186+
187+#. module: project_action_item
188+#: field:project.action.item,name:0
189+#: view:project.task:0
190+msgid "Description"
191+msgstr "Description"
192+
193+#. module: project_action_item
194+#: view:project.action.item:0
195+#: selection:project.action.item,state:0
196+msgid "Done"
197+msgstr "Fait"
198+
199+#. module: project_action_item
200+#: code:addons/project_action_item/wizard/update_action_generate_timesheet.py:51
201+#, python-format
202+msgid "Error:"
203+msgstr "Erreur :"
204+
205+#. module: project_action_item
206+#: field:project.action.item,estimated_hours:0
207+msgid "Estimated Hours"
208+msgstr "Heures estimées"
209+
210+#. module: project_action_item
211+#: field:project.action.item,to_invoice:0
212+msgid "Expected Invoicing Ratio"
213+msgstr "Expected Invoicing Ratio"
214+
215+#. module: project_action_item
216+#: view:project.action.item:0
217+msgid "Group By..."
218+msgstr "Groupé par..."
219+
220+#. module: project_action_item
221+#: selection:project.action.item,state:0
222+msgid "In Progress"
223+msgstr "En cours"
224+
225+#. module: project_action_item
226+#: view:project.action.item:0
227+msgid "Mark as Done"
228+msgstr "Marquer comme fait"
229+
230+#. module: project_action_item
231+#: view:project.action.item:0
232+msgid "Mark as Done with Timesheet"
233+msgstr "Marquer comme fait avec feuille de temps"
234+
235+#. module: project_action_item
236+#: view:project.action.item:0
237+msgid "Mark as In Progress"
238+msgstr "Marquer comme en cours"
239+
240+#. module: project_action_item
241+#: view:project.action.item:0
242+msgid "Mark as Progress with Timesheet"
243+msgstr "Marquer comme en cours avec feuille de temps"
244+
245+#. module: project_action_item
246+#: model:ir.actions.act_window,name:project_action_item.my_project_action_item_action
247+#: model:ir.ui.menu,name:project_action_item.my_project_action_item_menu
248+#: view:project.action.item:0
249+msgid "My Action Items"
250+msgstr "Mes points d'action"
251+
252+#. module: project_action_item
253+#: view:project.action.item:0
254+msgid "My Action Items To Work On"
255+msgstr "Mes points d'action à travailler"
256+
257+#. module: project_action_item
258+#: view:project.action.item:0
259+msgid "Progress"
260+msgstr "Avancer"
261+
262+#. module: project_action_item
263+#: model:ir.model,name:project_action_item.model_project_action_item
264+msgid "Project Action Items"
265+msgstr "Points d'action projet"
266+
267+#. module: project_action_item
268+#: field:project.action.item,task_id:0
269+msgid "Related Task"
270+msgstr "Tâche associée"
271+
272+#. module: project_action_item
273+#: field:project.action.item,timesheet_ids:0
274+msgid "Related Timesheets"
275+msgstr "Feuilles de temps associées"
276+
277+#. module: project_action_item
278+#: view:project.action.item:0
279+msgid "Search Action Items"
280+msgstr "Recherche de points d'action"
281+
282+#. module: project_action_item
283+#: field:project.action.item,sequence:0
284+msgid "Sequence"
285+msgstr "Séquence"
286+
287+#. module: project_action_item
288+#: field:project.action.item,state:0
289+msgid "State"
290+msgstr "État"
291+
292+#. module: project_action_item
293+#: code:addons/project_action_item/wizard/update_action_generate_timesheet.py:127
294+#: model:ir.model,name:project_action_item.model_project_task
295+#: view:project.action.item:0
296+#, python-format
297+msgid "Task"
298+msgstr "Tâche"
299+
300+#. module: project_action_item
301+#: code:addons/project_action_item/wizard/update_action_generate_timesheet.py:52
302+#, python-format
303+msgid "This action item is not linked to a task, so we cannot generate a timesheet from it."
304+msgstr "Ce point d'action n'est pas lié à une tâche, donc on ne peut pas générer de feuille de temps à partir de celui-ci."
305+
306+#. module: project_action_item
307+#: help:project.action.item,timesheet_hours:0
308+msgid "This is the sum of the related timesheets."
309+msgstr "Ce champ est la somme des feuilles de temps associées."
310+
311+#. module: project_action_item
312+#: field:project.action.item.timesheet,to_invoice:0
313+msgid "Timesheet Invoicing Ratio"
314+msgstr "Timesheet Invoicing Ratio"
315+
316+#. module: project_action_item
317+#: model:ir.model,name:project_action_item.model_hr_analytic_timesheet
318+msgid "Timesheet Line"
319+msgstr "Ligne de feuille de temps"
320+
321+#. module: project_action_item
322+#: view:project.action.item:0
323+msgid "Timesheets"
324+msgstr "Feuilles de temps"
325+
326+#. module: project_action_item
327+#: selection:project.action.item,state:0
328+msgid "To Do"
329+msgstr "À faire"
330+
331+#. module: project_action_item
332+#: view:project.action.item:0
333+msgid "To Work On"
334+msgstr "À travailler"
335+
336+#. module: project_action_item
337+#: view:project.action.item:0
338+msgid "Total Estimated Hours"
339+msgstr "Nb d'heures total estimée"
340+
341+#. module: project_action_item
342+#: code:addons/project_action_item/project.py:121
343+#: model:ir.actions.act_window,name:project_action_item.project_action_item_timesheet_action
344+#: model:ir.model,name:project_action_item.model_project_action_item_timesheet
345+#: view:project.action.item.timesheet:0
346+#, python-format
347+msgid "Update Action Item and Create Timesheet Line"
348+msgstr "Mettre à jour le point d'action et créer la ligne de feuille de temps"
349+
350+#. module: project_action_item
351+#: view:project.action.item.timesheet:0
352+msgid "Update Action and Create Timesheet"
353+msgstr "Mettre à jour le point d'action et créer la feuille de temps"
354+
355+#. module: project_action_item
356+#: view:project.action.item:0
357+#: field:project.action.item.timesheet,user_id:0
358+msgid "User"
359+msgstr "Utilisateur"
360+
361+#. module: project_action_item
362+#: field:project.action.item.timesheet,name:0
363+msgid "Work Description"
364+msgstr "Description du travail réalisé"
365+
366+#. module: project_action_item
367+#: field:project.action.item,timesheet_hours:0
368+#: field:project.action.item.timesheet,hours:0
369+msgid "Worked Hours"
370+msgstr "Heures travaillées"
371+
372
373=== added file 'project_action_item/i18n/project_action_item.pot'
374--- project_action_item/i18n/project_action_item.pot 1970-01-01 00:00:00 +0000
375+++ project_action_item/i18n/project_action_item.pot 2014-05-05 12:05:37 +0000
376@@ -0,0 +1,277 @@
377+# Translation of OpenERP Server.
378+# This file contains the translation of the following modules:
379+# * project_action_item
380+#
381+msgid ""
382+msgstr ""
383+"Project-Id-Version: OpenERP Server 7.0\n"
384+"Report-Msgid-Bugs-To: \n"
385+"POT-Creation-Date: 2014-04-24 21:17+0000\n"
386+"PO-Revision-Date: 2014-04-24 21:17+0000\n"
387+"Last-Translator: <>\n"
388+"Language-Team: \n"
389+"MIME-Version: 1.0\n"
390+"Content-Type: text/plain; charset=UTF-8\n"
391+"Content-Transfer-Encoding: \n"
392+"Plural-Forms: \n"
393+
394+#. module: project_action_item
395+#: field:hr.analytic.timesheet,action_item_id:0
396+#: view:project.action.item:0
397+msgid "Action Item"
398+msgstr ""
399+
400+#. module: project_action_item
401+#: field:project.action.item.timesheet,completed:0
402+msgid "Action Item Completed"
403+msgstr ""
404+
405+#. module: project_action_item
406+#: model:ir.actions.act_window,name:project_action_item.project_action_item_action
407+#: model:ir.ui.menu,name:project_action_item.project_action_item_menu
408+#: view:project.action.item:0
409+#: view:project.task:0
410+#: field:project.task,action_item_ids:0
411+msgid "Action Items"
412+msgstr ""
413+
414+#. module: project_action_item
415+#: field:project.task,done_action_item_ids:0
416+msgid "Action Items Done"
417+msgstr ""
418+
419+#. module: project_action_item
420+#: field:project.task,to_work_action_item_ids:0
421+msgid "Action Items To Do"
422+msgstr ""
423+
424+#. module: project_action_item
425+#: view:project.task:0
426+msgid "Action Items To Work On"
427+msgstr ""
428+
429+#. module: project_action_item
430+#: field:project.action.item,user_id:0
431+msgid "Assigned To"
432+msgstr ""
433+
434+#. module: project_action_item
435+#: view:project.action.item:0
436+msgid "Back to To Do"
437+msgstr ""
438+
439+#. module: project_action_item
440+#: view:project.action.item.timesheet:0
441+msgid "Cancel"
442+msgstr ""
443+
444+#. module: project_action_item
445+#: field:project.action.item,create_uid:0
446+msgid "Created By"
447+msgstr ""
448+
449+#. module: project_action_item
450+#: field:project.action.item,create_date:0
451+msgid "Creation Date"
452+msgstr ""
453+
454+#. module: project_action_item
455+#: field:project.action.item.timesheet,date:0
456+msgid "Date"
457+msgstr ""
458+
459+#. module: project_action_item
460+#: field:project.action.item,date_done:0
461+msgid "Date Done"
462+msgstr ""
463+
464+#. module: project_action_item
465+#: field:project.action.item,date_deadline:0
466+msgid "Deadline"
467+msgstr ""
468+
469+#. module: project_action_item
470+#: field:project.action.item,name:0
471+#: view:project.task:0
472+msgid "Description"
473+msgstr ""
474+
475+#. module: project_action_item
476+#: view:project.action.item:0
477+#: selection:project.action.item,state:0
478+msgid "Done"
479+msgstr ""
480+
481+#. module: project_action_item
482+#: code:addons/project_action_item/wizard/update_action_generate_timesheet.py:51
483+#, python-format
484+msgid "Error:"
485+msgstr ""
486+
487+#. module: project_action_item
488+#: field:project.action.item,estimated_hours:0
489+msgid "Estimated Hours"
490+msgstr ""
491+
492+#. module: project_action_item
493+#: field:project.action.item,to_invoice:0
494+msgid "Expected Invoicing Ratio"
495+msgstr ""
496+
497+#. module: project_action_item
498+#: view:project.action.item:0
499+msgid "Group By..."
500+msgstr ""
501+
502+#. module: project_action_item
503+#: selection:project.action.item,state:0
504+msgid "In Progress"
505+msgstr ""
506+
507+#. module: project_action_item
508+#: view:project.action.item:0
509+msgid "Mark as Done"
510+msgstr ""
511+
512+#. module: project_action_item
513+#: view:project.action.item:0
514+msgid "Mark as Done with Timesheet"
515+msgstr ""
516+
517+#. module: project_action_item
518+#: view:project.action.item:0
519+msgid "Mark as In Progress"
520+msgstr ""
521+
522+#. module: project_action_item
523+#: view:project.action.item:0
524+msgid "Mark as Progress with Timesheet"
525+msgstr ""
526+
527+#. module: project_action_item
528+#: model:ir.actions.act_window,name:project_action_item.my_project_action_item_action
529+#: model:ir.ui.menu,name:project_action_item.my_project_action_item_menu
530+#: view:project.action.item:0
531+msgid "My Action Items"
532+msgstr ""
533+
534+#. module: project_action_item
535+#: view:project.action.item:0
536+msgid "My Action Items To Work On"
537+msgstr ""
538+
539+#. module: project_action_item
540+#: view:project.action.item:0
541+msgid "Progress"
542+msgstr ""
543+
544+#. module: project_action_item
545+#: model:ir.model,name:project_action_item.model_project_action_item
546+msgid "Project Action Items"
547+msgstr ""
548+
549+#. module: project_action_item
550+#: field:project.action.item,task_id:0
551+msgid "Related Task"
552+msgstr ""
553+
554+#. module: project_action_item
555+#: field:project.action.item,timesheet_ids:0
556+msgid "Related Timesheets"
557+msgstr ""
558+
559+#. module: project_action_item
560+#: view:project.action.item:0
561+msgid "Search Action Items"
562+msgstr ""
563+
564+#. module: project_action_item
565+#: field:project.action.item,sequence:0
566+msgid "Sequence"
567+msgstr ""
568+
569+#. module: project_action_item
570+#: field:project.action.item,state:0
571+msgid "State"
572+msgstr ""
573+
574+#. module: project_action_item
575+#: code:addons/project_action_item/wizard/update_action_generate_timesheet.py:127
576+#: model:ir.model,name:project_action_item.model_project_task
577+#: view:project.action.item:0
578+#, python-format
579+msgid "Task"
580+msgstr ""
581+
582+#. module: project_action_item
583+#: code:addons/project_action_item/wizard/update_action_generate_timesheet.py:52
584+#, python-format
585+msgid "This action item is not linked to a task, so we cannot generate a timesheet from it."
586+msgstr ""
587+
588+#. module: project_action_item
589+#: help:project.action.item,timesheet_hours:0
590+msgid "This is the sum of the related timesheets."
591+msgstr ""
592+
593+#. module: project_action_item
594+#: field:project.action.item.timesheet,to_invoice:0
595+msgid "Timesheet Invoicing Ratio"
596+msgstr ""
597+
598+#. module: project_action_item
599+#: model:ir.model,name:project_action_item.model_hr_analytic_timesheet
600+msgid "Timesheet Line"
601+msgstr ""
602+
603+#. module: project_action_item
604+#: view:project.action.item:0
605+msgid "Timesheets"
606+msgstr ""
607+
608+#. module: project_action_item
609+#: selection:project.action.item,state:0
610+msgid "To Do"
611+msgstr ""
612+
613+#. module: project_action_item
614+#: view:project.action.item:0
615+msgid "To Work On"
616+msgstr ""
617+
618+#. module: project_action_item
619+#: view:project.action.item:0
620+msgid "Total Estimated Hours"
621+msgstr ""
622+
623+#. module: project_action_item
624+#: code:addons/project_action_item/project.py:121
625+#: model:ir.actions.act_window,name:project_action_item.project_action_item_timesheet_action
626+#: model:ir.model,name:project_action_item.model_project_action_item_timesheet
627+#: view:project.action.item.timesheet:0
628+#, python-format
629+msgid "Update Action Item and Create Timesheet Line"
630+msgstr ""
631+
632+#. module: project_action_item
633+#: view:project.action.item.timesheet:0
634+msgid "Update Action and Create Timesheet"
635+msgstr ""
636+
637+#. module: project_action_item
638+#: view:project.action.item:0
639+#: field:project.action.item.timesheet,user_id:0
640+msgid "User"
641+msgstr ""
642+
643+#. module: project_action_item
644+#: field:project.action.item.timesheet,name:0
645+msgid "Work Description"
646+msgstr ""
647+
648+#. module: project_action_item
649+#: field:project.action.item,timesheet_hours:0
650+#: field:project.action.item.timesheet,hours:0
651+msgid "Worked Hours"
652+msgstr ""
653+
654
655=== added file 'project_action_item/project.py'
656--- project_action_item/project.py 1970-01-01 00:00:00 +0000
657+++ project_action_item/project.py 2014-05-05 12:05:37 +0000
658@@ -0,0 +1,179 @@
659+# -*- encoding: utf-8 -*-
660+##############################################################################
661+#
662+# Project Action Item module for OpenERP
663+# Copyright (C) 2014 Akretion (http://www.akretion.com)
664+# @author Alexis de Lattre <alexis.delattre@akretion.com>
665+#
666+# This program is free software: you can redistribute it and/or modify
667+# it under the terms of the GNU Affero General Public License as
668+# published by the Free Software Foundation, either version 3 of the
669+# License, or (at your option) any later version.
670+#
671+# This program is distributed in the hope that it will be useful,
672+# but WITHOUT ANY WARRANTY; without even the implied warranty of
673+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
674+# GNU Affero General Public License for more details.
675+#
676+# You should have received a copy of the GNU Affero General Public License
677+# along with this program. If not, see <http://www.gnu.org/licenses/>.
678+#
679+##############################################################################
680+
681+from openerp.osv import orm, fields
682+from openerp.tools.translate import _
683+
684+
685+class project_action_item(orm.Model):
686+ _name = "project.action.item"
687+ _description = "Project Action Items"
688+
689+ def _compute_timesheet_hours(
690+ self, cr, uid, ids, name, arg, context=None):
691+ res = {}
692+ for action in self.browse(cr, uid, ids, context=context):
693+ res[action.id] = 0
694+ for timesheet in action.timesheet_ids:
695+ res[action.id] += timesheet.unit_amount
696+ return res
697+
698+ def _get_action_from_timesheet(self, cr, uid, ids, context=None):
699+ return self.pool['project.action.item'].search(
700+ cr, uid, [('timesheet_ids', 'in', ids)], context=context)
701+
702+ _columns = {
703+ 'task_id': fields.many2one('project.task', 'Related Task'),
704+ 'project_id': fields.related(
705+ 'task_id', 'project_id', type='many2one',
706+ relation="project.project", readonly=True, string="Project"),
707+ 'name': fields.char('Description', size=256, required=True),
708+ 'date_deadline': fields.date('Deadline'),
709+ 'date_done': fields.date('Date Done'),
710+ 'user_id': fields.many2one('res.users', 'Assigned To'),
711+ 'estimated_hours': fields.float('Estimated Hours'),
712+ 'to_invoice': fields.many2one(
713+ 'hr_timesheet_invoice.factor', 'Expected Invoicing Ratio'),
714+ 'timesheet_ids': fields.one2many(
715+ 'hr.analytic.timesheet', 'action_item_id', 'Related Timesheets'),
716+ 'timesheet_hours': fields.function(
717+ _compute_timesheet_hours, type='float',
718+ string="Worked Hours", readonly=True, store={
719+ 'hr.analytic.timesheet': (
720+ _get_action_from_timesheet,
721+ ['unit_amount', 'action_item_id'],
722+ 10),
723+ }, help="This is the sum of the related timesheets."
724+ ),
725+ 'state': fields.selection([
726+ ('todo', 'To Do'),
727+ ('progress', 'In Progress'),
728+ ('done', 'Done'),
729+ ], 'State', readonly=True),
730+ 'create_uid': fields.many2one(
731+ 'res.users', 'Created By', readonly=True),
732+ 'create_date': fields.datetime('Creation Date', readonly=True),
733+ 'sequence': fields.integer('Sequence'),
734+ }
735+
736+ def _get_default_invoice_ratio(self, cr, uid, context=None):
737+ if context is None:
738+ context = {}
739+ active_id = context.get('active_id')
740+ active_model = context.get('active_model')
741+ if active_model == 'project.task' and active_id:
742+ task = self.pool['project.task'].browse(
743+ cr, uid, active_id, context=context)
744+ return task.project_id and task.project_id.to_invoice.id or False
745+ else:
746+ return False
747+
748+ _defaults = {
749+ 'state': 'todo',
750+ 'to_invoice': _get_default_invoice_ratio,
751+ }
752+
753+ def set_to_done(self, cr, uid, ids, context=None):
754+ today = fields.date.context_today(self, cr, uid, context=context)
755+ self.write(cr, uid, ids, {
756+ 'state': 'done',
757+ 'date_done': today,
758+ }, context=context)
759+ return
760+
761+ def set_to_progress(self, cr, uid, ids, context=None):
762+ self.write(cr, uid, ids, {
763+ 'state': 'progress',
764+ }, context=context)
765+ return
766+
767+ def back_to_todo(self, cr, uid, ids, context=None):
768+ self.write(cr, uid, ids, {
769+ 'state': 'todo',
770+ 'date_done': False,
771+ }, context=context)
772+ return
773+
774+ def action_item_done_with_timesheet_wizard(
775+ self, cr, uid, ids, context=None):
776+ # I cannot pass the context is the button of a tree view,
777+ # that's why I wrote a special function for that...
778+ if context is None:
779+ context = {}
780+ context['action_item_completed'] = True
781+ return {
782+ 'name': _('Update Action Item and Create Timesheet Line'),
783+ 'type': 'ir.actions.act_window',
784+ 'res_model': 'project.action.item.timesheet',
785+ 'view_type': 'form',
786+ 'view_mode': 'form',
787+ 'nodestroy': True,
788+ 'target': 'new',
789+ 'context': context,
790+ }
791+
792+
793+class hr_analytic_timesheet(orm.Model):
794+ _inherit = "hr.analytic.timesheet"
795+
796+ _columns = {
797+ 'action_item_id': fields.many2one(
798+ 'project.action.item', 'Action Item'),
799+ }
800+
801+
802+class project_task(orm.Model):
803+ _inherit = "project.task"
804+
805+ def _compute_planned_hours(
806+ self, cr, uid, ids, name, arg, context=None):
807+ res = {}
808+ for task in self.browse(cr, uid, ids, context=context):
809+ res[task.id] = 0
810+ for action in task.action_item_ids:
811+ res[task.id] += action.estimated_hours
812+ return res
813+
814+ def _get_task_from_action(self, cr, uid, ids, context=None):
815+ return self.pool['project.task'].search(
816+ cr, uid, [('action_item_ids', 'in', ids)], context=context)
817+
818+ _columns = {
819+ 'to_work_action_item_ids': fields.one2many(
820+ 'project.action.item', 'task_id', 'Action Items To Do',
821+ domain=[('state', 'in', ('todo', 'progress'))]),
822+ 'done_action_item_ids': fields.one2many(
823+ 'project.action.item', 'task_id', 'Action Items Done',
824+ domain=[('state', '=', 'done')]),
825+ 'action_item_ids': fields.one2many(
826+ 'project.action.item', 'task_id', 'Action Items'),
827+ 'planned_hours': fields.function(
828+ _compute_planned_hours, type="float",
829+ string="Initially Planned Hours", store={
830+ 'project.action.item': (
831+ _get_task_from_action,
832+ ['estimated_hours', 'task_id'],
833+ 10),
834+ },
835+ help="Estimated time to do the task. It is the sum of the "
836+ "estimated time of all the action items of this task."),
837+ }
838
839=== added file 'project_action_item/project_demo.xml'
840--- project_action_item/project_demo.xml 1970-01-01 00:00:00 +0000
841+++ project_action_item/project_demo.xml 2014-05-05 12:05:37 +0000
842@@ -0,0 +1,64 @@
843+<?xml version="1.0" encoding="utf-8"?>
844+<openerp>
845+<data noupdate="1">
846+
847+<record id="action_item_1" model="project.action.item">
848+ <field name="name">Write specs</field>
849+ <field name="task_id" ref="project.project_task_8"/>
850+ <field name="user_id" ref="base.user_demo"/>
851+ <field name="estimated_hours">4.5</field>
852+ <field name="sequence">1</field>
853+</record>
854+
855+<record id="action_item_2" model="project.action.item">
856+ <field name="name">Develop a proto</field>
857+ <field name="task_id" ref="project.project_task_8"/>
858+ <field name="user_id" ref="base.user_demo"/>
859+ <field name="estimated_hours">16</field>
860+ <field name="sequence">2</field>
861+</record>
862+
863+<record id="action_item_3" model="project.action.item">
864+ <field name="name">Show proto to management</field>
865+ <field name="task_id" ref="project.project_task_8"/>
866+ <field name="user_id" ref="base.user_demo"/>
867+ <field name="estimated_hours">1</field>
868+ <field name="sequence">3</field>
869+</record>
870+
871+<record id="action_item_4" model="project.action.item">
872+ <field name="name">Update specs after management meeting</field>
873+ <field name="task_id" ref="project.project_task_8"/>
874+ <field name="user_id" ref="base.user_demo"/>
875+ <field name="estimated_hours">1</field>
876+ <field name="sequence">4</field>
877+</record>
878+
879+<record id="action_item_5" model="project.action.item">
880+ <field name="name">Develop final version</field>
881+ <field name="task_id" ref="project.project_task_8"/>
882+ <field name="user_id" ref="base.user_demo"/>
883+ <field name="estimated_hours">42</field>
884+ <field name="sequence">5</field>
885+</record>
886+
887+<record id="action_item_6" model="project.action.item">
888+ <field name="name">Show final version to usability team</field>
889+ <field name="task_id" ref="project.project_task_8"/>
890+ <field name="user_id" ref="base.user_demo"/>
891+ <field name="estimated_hours">3</field>
892+ <field name="sequence">6</field>
893+</record>
894+
895+<record id="action_item_7" model="project.action.item">
896+ <field name="name">Merge proposal and review</field>
897+ <field name="task_id" ref="project.project_task_8"/>
898+ <field name="user_id" ref="base.user_demo"/>
899+ <field name="estimated_hours">3.5</field>
900+ <field name="sequence">7</field>
901+</record>
902+
903+
904+
905+</data>
906+</openerp>
907
908=== added file 'project_action_item/project_view.xml'
909--- project_action_item/project_view.xml 1970-01-01 00:00:00 +0000
910+++ project_action_item/project_view.xml 2014-05-05 12:05:37 +0000
911@@ -0,0 +1,151 @@
912+<?xml version="1.0" encoding="utf-8"?>
913+<!--
914+ Copyright (C) 2014 Akretion (http://www.akretion.com/)
915+ @author: Alexis de Lattre <alexis.delattre@akretion.com>
916+ The licence is in the file __openerp__.py
917+-->
918+
919+<openerp>
920+<data>
921+
922+<record id="project_action_item_form" model="ir.ui.view">
923+ <field name="name">project_action_item.form</field>
924+ <field name="model">project.action.item</field>
925+ <field name="arch" type="xml">
926+ <form string="Action Item" version="7.0">
927+ <header>
928+ <button name="%(project_action_item_timesheet_action)d"
929+ type="action" string="Mark as Done with Timesheet"
930+ class="oe_highlight" states="todo,progress"
931+ context="{'action_item_completed': True}"/>
932+ <button name="%(project_action_item_timesheet_action)d"
933+ type="action" string="Mark as Progress with Timesheet"
934+ class="oe_highlight" states="todo,progress"
935+ context="{'action_item_completed': False}" />
936+ <button name="set_to_progress" type="object"
937+ string="Mark as In Progress" states="todo"/>
938+ <button name="set_to_done" type="object"
939+ string="Mark as Done" states="todo,progress"/>
940+ <button name="back_to_todo" type="object"
941+ string="Back to To Do" states="done,progress"/>
942+ <field name="state" widget="statusbar"/>
943+ </header>
944+ <group name="main">
945+ <field name="project_id"
946+ invisible="not context.get('project_action_item_main_view')"/>
947+ <field name="task_id"
948+ invisible="not context.get('project_action_item_main_view')"/>
949+ <field name="name" widget="text"/>
950+ <field name="date_deadline"/>
951+ <field name="date_done" states="done"/>
952+ <field name="estimated_hours" widget="float_time"/>
953+ <field name="timesheet_hours" widget="float_time"/>
954+ <field name="user_id"/>
955+ <field name="to_invoice"/>
956+ <field name="create_date"/>
957+ <field name="create_uid"/>
958+ <field name="sequence" invisible="1"/>
959+ </group>
960+ <group main="timesheet" string="Timesheets">
961+ <field name="timesheet_ids" nolabel="1"/>
962+ </group>
963+ </form>
964+ </field>
965+</record>
966+
967+<record id="project_action_item_tree" model="ir.ui.view">
968+ <field name="name">project_action_item.tree</field>
969+ <field name="model">project.action.item</field>
970+ <field name="arch" type="xml">
971+ <tree string="Action Items" editable="bottom" colors="blue:state=='todo';grey:state=='progress'">
972+ <field name="name"/>
973+ <field name="project_id"
974+ invisible="not context.get('project_action_item_main_view')"/>
975+ <field name="task_id"
976+ invisible="not context.get('project_action_item_main_view')"/>
977+ <field name="date_deadline"/>
978+ <field name="user_id"/>
979+ <field name="estimated_hours"
980+ widget="float_time" sum="Total Estimated Hours"/>
981+ <field name="timesheet_hours"
982+ widget="float_time" sum="Total Estimated Hours"/>
983+ <field name="to_invoice"/>
984+ <button name="%(project_action_item_timesheet_action)d"
985+ type="action" string="Progress" states="todo,progress"
986+ icon="gtk-go-forward"
987+ context="{'action_item_completed': False}"/>
988+ <button name="action_item_done_with_timesheet_wizard"
989+ type="object" icon="terp-gtk-jump-to-ltr" string="Done"
990+ states="todo,progress"/>
991+ <field name="state"/>
992+ <field name="sequence" invisible="1"/>
993+ </tree>
994+ </field>
995+</record>
996+
997+<record id="project_action_item_search" model="ir.ui.view">
998+ <field name="name">project_action_item.search</field>
999+ <field name="model">project.action.item</field>
1000+ <field name="arch" type="xml">
1001+ <search string="Search Action Items">
1002+ <field name="name" />
1003+ <filter name="my_action_items_to_work"
1004+ string="My Action Items To Work On"
1005+ domain="[('user_id', '=', uid), ('state', 'in', ('todo', 'progress'))]"/>
1006+ <filter name="my_action_items" string="My Action Items"
1007+ domain="[('user_id', '=', uid)]"/>
1008+ <filter name="to_work" string="To Work On"
1009+ domain="[('state', 'in', ('todo', 'progress'))]" />
1010+ <filter name="done" string="Done"
1011+ domain="[('state', '=', 'done')]" />
1012+ <group string="Group By..." name="groupby">
1013+ <filter name="user_id_groupby" string="User"
1014+ context="{'group_by': 'user_id'}"/>
1015+ <filter name="task_groupby" string="Task"
1016+ context="{'group_by': 'task_id'}"/>
1017+ </group>
1018+ </search>
1019+ </field>
1020+</record>
1021+
1022+<record id="project_action_item_action" model="ir.actions.act_window">
1023+ <field name="name">Action Items</field>
1024+ <field name="res_model">project.action.item</field>
1025+ <field name="view_type">form</field>
1026+ <field name="view_mode">tree,form</field>
1027+ <field name="context">{'project_action_item_main_view': True, 'search_default_my_action_items_to_work': 1}</field>
1028+</record>
1029+
1030+
1031+<menuitem id="project_action_item_menu" action="project_action_item_action"
1032+ parent="project.menu_project_management" sequence="11"/>
1033+
1034+<!-- add todo action items on tasks -->
1035+<record id="view_task_form2" model="ir.ui.view">
1036+ <field name="name">add.action.items.on.tasks.form</field>
1037+ <field name="model">project.task</field>
1038+ <field name="inherit_id" ref="project.view_task_form2"/>
1039+ <field name="arch" type="xml">
1040+ <field name="work_ids" position="before">
1041+ <group name="to_work_action_items" string="Action Items To Work On">
1042+ <field name="to_work_action_item_ids" nolabel="1"/>
1043+ </group>
1044+ <separator string="Timesheets" />
1045+ </field>
1046+ </field>
1047+</record>
1048+
1049+<!-- add link to action item on timesheet -->
1050+<record id="hr_timesheet_line_form" model="ir.ui.view">
1051+ <field name="name">add.action.items.on.timesheet.form</field>
1052+ <field name="model">hr.analytic.timesheet</field>
1053+ <field name="inherit_id" ref="hr_timesheet_task.hr_timesheet_line_form"/>
1054+ <field name="arch" type="xml">
1055+ <field name="task_id" position="after">
1056+ <field name="action_item_id"/>
1057+ </field>
1058+ </field>
1059+</record>
1060+
1061+</data>
1062+</openerp>
1063
1064=== added directory 'project_action_item/security'
1065=== added file 'project_action_item/security/ir.model.access.csv'
1066--- project_action_item/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
1067+++ project_action_item/security/ir.model.access.csv 2014-05-05 12:05:37 +0000
1068@@ -0,0 +1,2 @@
1069+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
1070+access_project_action_item_user,Full access on action items to Project Users,model_project_action_item,project.group_project_user,1,1,1,1
1071
1072=== added directory 'project_action_item/static'
1073=== added directory 'project_action_item/static/src'
1074=== added directory 'project_action_item/static/src/img'
1075=== added directory 'project_action_item/static/src/img/screenshots'
1076=== added file 'project_action_item/static/src/img/screenshots/create_timesheet_from_action_item_wizard.jpg'
1077Binary files project_action_item/static/src/img/screenshots/create_timesheet_from_action_item_wizard.jpg 1970-01-01 00:00:00 +0000 and project_action_item/static/src/img/screenshots/create_timesheet_from_action_item_wizard.jpg 2014-05-05 12:05:37 +0000 differ
1078=== added file 'project_action_item/static/src/img/screenshots/task_with_action_items.jpg'
1079Binary files project_action_item/static/src/img/screenshots/task_with_action_items.jpg 1970-01-01 00:00:00 +0000 and project_action_item/static/src/img/screenshots/task_with_action_items.jpg 2014-05-05 12:05:37 +0000 differ
1080=== added directory 'project_action_item/wizard'
1081=== added file 'project_action_item/wizard/__init__.py'
1082--- project_action_item/wizard/__init__.py 1970-01-01 00:00:00 +0000
1083+++ project_action_item/wizard/__init__.py 2014-05-05 12:05:37 +0000
1084@@ -0,0 +1,23 @@
1085+# -*- encoding: utf-8 -*-
1086+##############################################################################
1087+#
1088+# Project Action Item module for OpenERP
1089+# Copyright (C) 2014 Akretion (http://www.akretion.com)
1090+# @author Alexis de Lattre <alexis.delattre@akretion.com>
1091+#
1092+# This program is free software: you can redistribute it and/or modify
1093+# it under the terms of the GNU Affero General Public License as
1094+# published by the Free Software Foundation, either version 3 of the
1095+# License, or (at your option) any later version.
1096+#
1097+# This program is distributed in the hope that it will be useful,
1098+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1099+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1100+# GNU Affero General Public License for more details.
1101+#
1102+# You should have received a copy of the GNU Affero General Public License
1103+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1104+#
1105+##############################################################################
1106+
1107+from . import update_action_generate_timesheet
1108
1109=== added file 'project_action_item/wizard/update_action_generate_timesheet.py'
1110--- project_action_item/wizard/update_action_generate_timesheet.py 1970-01-01 00:00:00 +0000
1111+++ project_action_item/wizard/update_action_generate_timesheet.py 2014-05-05 12:05:37 +0000
1112@@ -0,0 +1,137 @@
1113+# -*- encoding: utf-8 -*-
1114+##############################################################################
1115+#
1116+# Project Action Item module for OpenERP
1117+# Copyright (C) 2014 Akretion (http://www.akretion.com)
1118+# @author Alexis de Lattre <alexis.delattre@akretion.com>
1119+#
1120+# This program is free software: you can redistribute it and/or modify
1121+# it under the terms of the GNU Affero General Public License as
1122+# published by the Free Software Foundation, either version 3 of the
1123+# License, or (at your option) any later version.
1124+#
1125+# This program is distributed in the hope that it will be useful,
1126+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1127+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1128+# GNU Affero General Public License for more details.
1129+#
1130+# You should have received a copy of the GNU Affero General Public License
1131+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1132+#
1133+##############################################################################
1134+
1135+from openerp.osv import orm, fields
1136+from openerp.tools.translate import _
1137+
1138+
1139+class project_action_item_timesheet(orm.TransientModel):
1140+ _name = 'project.action.item.timesheet'
1141+ _description = 'Update Action Item and Create Timesheet Line'
1142+
1143+ _columns = {
1144+ 'date': fields.date('Date', required=True),
1145+ 'user_id': fields.many2one('res.users', 'User', required=True),
1146+ 'hours': fields.float('Worked Hours'),
1147+ 'name': fields.char('Work Description', size=256, required=True),
1148+ 'to_invoice': fields.many2one(
1149+ 'hr_timesheet_invoice.factor', 'Timesheet Invoicing Ratio'),
1150+ 'completed': fields.boolean('Action Item Completed'),
1151+ }
1152+
1153+ def default_get(self, cr, uid, fields_list, context=None):
1154+ if context is None:
1155+ context = {}
1156+ active_id = context.get('active_id')
1157+ res = {}
1158+ if active_id:
1159+ item = self.pool['project.action.item'].browse(
1160+ cr, uid, active_id, context=context)
1161+ if not item.task_id:
1162+ raise orm.except_orm(
1163+ _('Error:'),
1164+ _("This action item is not linked to a task, "
1165+ "so we cannot generate a timesheet from it."))
1166+ remaining = item.estimated_hours - item.timesheet_hours
1167+ if remaining < 0:
1168+ remaining = 0
1169+ res = {
1170+ 'name': item.name,
1171+ 'quantity': remaining,
1172+ 'to_invoice': item.to_invoice.id or False,
1173+ }
1174+ res.update({
1175+ 'user_id': uid,
1176+ 'date': fields.date.context_today(self, cr, uid, context=context),
1177+ 'completed': context.get('action_item_completed'),
1178+ })
1179+ return res
1180+
1181+ def _prepare_timesheet(self, cr, uid, action_item, wizard, context=None):
1182+ task_id = action_item.task_id.id
1183+ to_invoice = wizard.to_invoice.id or False
1184+ res_user = self.pool['hr.analytic.timesheet'].on_change_user_id(
1185+ cr, uid, False, context['user_id'])
1186+ journal_id = res_user['value']['journal_id']
1187+ product_id = res_user['value']['product_id']
1188+ res_unit = self.pool['hr.analytic.timesheet'].on_change_unit_amount(
1189+ cr, uid, False, product_id, wizard.hours, False, unit=False,
1190+ journal_id=journal_id, task_id=task_id, to_invoice=to_invoice,
1191+ context=context)
1192+ res_unit['value'].update({
1193+ 'name': wizard.name,
1194+ 'date': wizard.date,
1195+ 'user_id': wizard.user_id.id,
1196+ 'unit_amount': wizard.hours,
1197+ 'journal_id': journal_id,
1198+ 'task_id': task_id,
1199+ 'to_invoice': to_invoice,
1200+ 'action_item_id': action_item.id,
1201+ })
1202+ return res_unit['value']
1203+
1204+ def _prepare_action_item_update(
1205+ self, cr, uid, action_item, wizard, context=None):
1206+ if wizard.completed:
1207+ res = {
1208+ 'state': 'done',
1209+ 'date_done': wizard.date,
1210+ }
1211+ else:
1212+ res = {'state': 'progress'}
1213+ return res
1214+
1215+ def update_action_create_timesheet(self, cr, uid, ids, context=None):
1216+ assert len(ids) == 1, "Only one ID"
1217+ wizard = self.browse(cr, uid, ids[0], context=context)
1218+ if context is None:
1219+ context = {}
1220+ action_item_id = context['active_id']
1221+ ts_ctx = context.copy()
1222+ ts_ctx['user_id'] = wizard.user_id.id
1223+ action_item_obj = self.pool['project.action.item']
1224+ action_item = action_item_obj.browse(
1225+ cr, uid, action_item_id, context=context)
1226+ ts_vals = self._prepare_timesheet(
1227+ cr, uid, action_item, wizard, context=ts_ctx)
1228+ self.pool['hr.analytic.timesheet'].create(
1229+ cr, uid, ts_vals, context=ts_ctx)
1230+ action_vals = self._prepare_action_item_update(
1231+ cr, uid, action_item, wizard, context=context)
1232+ self.pool['project.action.item'].write(
1233+ cr, uid, action_item_id, action_vals, context=context)
1234+ if context.get('project_action_item_main_view'):
1235+ res = True
1236+ else:
1237+ # refresh the view of the task after completion of the wizard
1238+ res = {
1239+ 'name': _('Task'),
1240+ 'type': 'ir.actions.act_window',
1241+ 'res_model': 'project.task',
1242+ 'view_type': 'form',
1243+ 'view_mode': 'form,tree,kanban,calendar,gantt,graph',
1244+ 'nodestroy': False,
1245+ 'target': 'current',
1246+ 'res_id': action_item.task_id.id,
1247+ 'context': context,
1248+ }
1249+ return res
1250
1251=== added file 'project_action_item/wizard/update_action_generate_timesheet_view.xml'
1252--- project_action_item/wizard/update_action_generate_timesheet_view.xml 1970-01-01 00:00:00 +0000
1253+++ project_action_item/wizard/update_action_generate_timesheet_view.xml 2014-05-05 12:05:37 +0000
1254@@ -0,0 +1,42 @@
1255+<?xml version="1.0" encoding="utf-8"?>
1256+<!--
1257+ Copyright (C) 2014 Akretion (http://www.akretion.com/)
1258+ @author: Alexis de Lattre <alexis.delattre@akretion.com>
1259+ The licence is in the file __openerp__.py
1260+-->
1261+
1262+<openerp>
1263+<data>
1264+
1265+<record id="project_action_item_timesheet_form" model="ir.ui.view">
1266+ <field name="name">project_action_item_timesheet.form</field>
1267+ <field name="model">project.action.item.timesheet</field>
1268+ <field name="arch" type="xml">
1269+ <form string="Update Action Item and Create Timesheet Line" version="7.0">
1270+ <group name="main">
1271+ <field name="name" widget="text"/>
1272+ <field name="date"/>
1273+ <field name="hours" widget="float_time"/>
1274+ <field name="user_id"/>
1275+ <field name="to_invoice"/>
1276+ <field name="completed"/>
1277+ </group>
1278+ <footer>
1279+ <button name="update_action_create_timesheet" type="object"
1280+ string="Update Action and Create Timesheet" class="oe_highlight"/>
1281+ <button special="cancel" string="Cancel" class="oe_link"/>
1282+ </footer>
1283+ </form>
1284+ </field>
1285+</record>
1286+
1287+<record id="project_action_item_timesheet_action" model="ir.actions.act_window">
1288+ <field name="name">Update Action Item and Create Timesheet Line</field>
1289+ <field name="res_model">project.action.item.timesheet</field>
1290+ <field name="view_type">form</field>
1291+ <field name="view_mode">form</field>
1292+ <field name="target">new</field>
1293+</record>
1294+
1295+</data>
1296+</openerp>

Subscribers

People subscribed via source and target branches