summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabien Pinckaers <fp@tinyerp.com>2008-09-04 19:16:05 +0200
committerFabien Pinckaers <fp@tinyerp.com>2008-09-04 19:16:05 +0200
commitffa0ca45d6d33de5ec6328ea99aceb98b95fdc01 (patch)
tree136d9fb5f82bf32c2469b080ff990db80994b2a9
parent07b1f0b9daac1d53aa25dcf26e7a3f7cce469520 (diff)
Improved Progress Computation
bzr revid: fp@tinyerp.com-20080904171605-9ytoj3qyp25mkn27
-rw-r--r--addons/project/project.py66
-rw-r--r--addons/project/project_view.xml147
2 files changed, 78 insertions, 135 deletions
diff --git a/addons/project/project.py b/addons/project/project.py
index d4ec285001a..65e827685df 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -92,38 +92,43 @@ class project(osv.osv):
pricelist = self.pool.get('res.partner').browse(cr, uid, part).property_product_pricelist.id
return {'value':{'contact_id': addr['contact'], 'pricelist_id': pricelist}}
- def _progress_rate(self, cursor, user, ids, name, arg, context=None):
- res = {}
- for project in self.browse(cursor, user, ids, context=context):
- tot = 0.0
- if project.state not in ('cancelled'):
- try:
- tot += project.effective_hours * 100.0 / project.planned_hours
- except:
- pass
- res[project.id] = tot
+ def _progress_rate(self, cr, uid, ids, name, arg, context=None):
+ res = {}.fromkeys(ids, 0.0)
+ if not ids:
+ return res
+ cr.execute('''SELECT
+ project_id, sum(progress*planned_hours), sum(planned_hours)
+ FROM
+ project_task
+ WHERE
+ project_id in ('''+','.join(map(str,ids))+''') AND
+ state<>'cancelled'
+ GROUP BY
+ project_id''')
+ for id,prog,tot in cr.fetchall():
+ if tot:
+ res[id] = prog / tot
return res
-
_columns = {
- 'name': fields.char("Project name", size=128, required=True),
+ 'name': fields.char("Project Name", size=128, required=True),
'active': fields.boolean('Active'),
- 'category_id': fields.many2one('account.analytic.account','Analytic Account'),
+ 'category_id': fields.many2one('account.analytic.account','Analytic Account', help="Link this project to an analytic account if you need financial management on projects. It ables to connect projects with budgets, plannings, costs and revenues analysis, timesheet on projects, etc."),
'priority': fields.integer('Sequence'),
- 'manager': fields.many2one('res.users', 'Project manager'),
- 'warn_manager': fields.boolean('Warn manager'),
- 'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project members'),
+ 'manager': fields.many2one('res.users', 'Project Manager'),
+ 'warn_manager': fields.boolean('Warn Manager', help="If you check this field, the project manager will receive a request each time a task is completed by his team."),
+ 'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members'),
'tasks': fields.one2many('project.task', 'project_id', "Project tasks"),
- 'parent_id': fields.many2one('project.project', 'Parent project'),
+ 'parent_id': fields.many2one('project.project', 'Parent Project'),
'child_id': fields.one2many('project.project', 'parent_id', 'Subproject'),
'planned_hours': fields.function(_calc_planned, method=True, string='Planned hours'),
'effective_hours': fields.function(_calc_effective, method=True, string='Hours spent'),
- 'progress_rate': fields.function(_progress_rate, method=True, string='Progress', type='float'),
- 'date_start': fields.date('Project started on'),
- 'date_end': fields.date('Project should end on'),
- 'partner_id': fields.many2one('res.partner', 'Customer'),
+ 'progress_rate': fields.function(_progress_rate, method=True, string='Progress', type='float', help="Percent of tasks closed according to the total of tasks todo."),
+ 'date_start': fields.date('Starting Date'),
+ 'date_end': fields.date('Expected End'),
+ 'partner_id': fields.many2one('res.partner', 'Partner'),
'contact_id': fields.many2one('res.partner.address', 'Contact'),
- 'warn_customer': fields.boolean('Warn customer'),
+ 'warn_customer': fields.boolean('Warn Partner'),
'warn_header': fields.text('Mail header'),
'warn_footer': fields.text('Mail footer'),
'notes': fields.text('Notes'),
@@ -208,18 +213,6 @@ class task(osv.osv):
res[task_id] = sum
return res
- def _progress_rate(self, cursor, user, ids, name, arg, context=None):
- res = {}
- for task in self.browse(cursor, user, ids, context=context):
- if task.state in ('cancelled','done'):
- res[task.id] = 100.0
- else:
- if task.planned_hours:
- res[task.id] = task.effective_hours * 100.0 / task.planned_hours
- else:
- res[task.id] = 0.0
- return res
-
_columns = {
'active': fields.boolean('Active'),
'name': fields.char('Task summary', size=128, required=True),
@@ -239,10 +232,9 @@ class task(osv.osv):
'start_sequence': fields.boolean('Wait for previous sequences'),
'planned_hours': fields.float('Plan. hours'),
'effective_hours': fields.function(_hours_effect, method=True, string='Eff. Hours'),
- 'progress_rate': fields.function(_progress_rate, method=True, string='Progress', type='float'),
'progress': fields.integer('Progress (0-100)'),
'user_id': fields.many2one('res.users', 'Assigned to'),
- 'partner_id': fields.many2one('res.partner', 'Customer'),
+ 'partner_id': fields.many2one('res.partner', 'Partner'),
'work_ids': fields.one2many('project.task.work', 'task_id', 'Work done'),
}
_defaults = {
@@ -312,7 +304,7 @@ class task(osv.osv):
'ref_doc1': 'project.task,%d' % task.id,
'ref_doc2': 'project.project,%d' % project.id,
})
- self.write(cr, uid, [task.id], {'state': 'cancelled'})
+ self.write(cr, uid, [task.id], {'state': 'cancelled', 'progress':100})
return True
def do_open(self, cr, uid, ids, *args):
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 7b9daab3148..4bcc2efe358 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -11,20 +11,23 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Project">
- <notebook>
+ <group colspan="4" col="6">
+ <field name="name" select="1"/>
+ <field name="parent_id"/>
+ <field name="manager" select="1"/>
+ <field name="date_start"/>
+ <field name="date_end"/>
+ <field name="progress_rate" widget="progressbar"/>
+ </group>
+ <notebook colspan="4">
<page string="Administration">
- <field name="name" select="1"/>
+ <field name="priority"/>
<group col="3" colspan="2">
<field name="active" select="2"/>
<button name="toggleActive" string="Toggle activity" type="object"/>
</group>
- <field name="manager" select="1"/>
<field name="warn_manager"/>
<newline/>
- <field name="priority"/>
- <field name="parent_id"/>
- <field name="date_start"/>
- <field name="date_end"/>
<field name="planned_hours" widget="float_time"/>
<field name="effective_hours" widget="float_time"/>
<field name="timesheet_id"/>
@@ -36,11 +39,12 @@
<field colspan="4" name="partner_id" on_change="onchange_partner_id(partner_id)" select="1"/>
<field domain="[('partner_id','=',partner_id)]" name="contact_id" select="2"/>
<field name="category_id" select="2"/>
- <field name="pricelist_id"/>
<field name="warn_customer"/>
- <separator colspan="4" string="Mail texts"/>
- <field name="warn_header"/>
- <field name="warn_footer"/>
+ <newline/>
+ <separator colspan="2" string="Mail Header"/>
+ <separator colspan="2" string="Mail Footer"/>
+ <field name="warn_header" nolabel="1" colspan="2"/>
+ <field name="warn_footer" nolabel="1" colspan="2"/>
<group col="3" colspan="4">
<label string="Task: %%(name)s"/>
<label string="User: %%(user_id)s"/>
@@ -49,76 +53,6 @@
<label string="Date Start: %%(date_start)s"/>
<label string="Date Stop: %%(date_stop)s"/>
</group>
- <separator colspan="4" string="Taxes"/>
- <field colspan="4" name="tax_ids" nolabel="1"/>
- </page>
- <page string="Tasks">
- <field colspan="4" name="tasks" nolabel="1" widget="one2many_list">
- <form string="Task edition">
- <notebook>
- <page string="Task definition">
- <separator colspan="4" string="Task Information"/>
- <field name="name" select="1"/>
- <field name="active" select="1"/>
- <field name="sequence"/>
- <field name="priority" select="1"/>
- <field name="user_id" select="1"/>
- <field name="date_deadline" select="1"/>
- <field name="date_start" select="1"/>
- <field name="date_close" select="1"/>
- <field name="progress"/>
- <newline/>
- <field name="planned_hours" widget="float_time"/>
- <field name="effective_hours" widget="float_time"/>
- <separator colspan="4" string="Description"/>
- <field colspan="4" name="description" nolabel="1"/>
-
- <group col="11" colspan="4">
- <field name="state" select="1"/>
- <button name="do_draft" states="open" string="Set Draft" type="object"/>
- <button name="do_open" states="pending,draft" string="Open task" type="object"/>
- <button name="do_reopen" states="done,cancelled" string="Re-open" type="object"/>
- <button name="do_pending" states="open" string="Set pending" type="object"/>
- <button name="%(wizard_close_task)d" states="pending,open" string="Done" type="action"/>
- <button groups="base.group_extended" name="%(wizard_delegate_task)d" states="pending,open" string="Delegate" type="action"/>
- <button name="do_cancel" states="draft,open,pending" string="Cancel" type="object"/>
- </group>
- </page>
- <page string="Work done">
- <separator colspan="4" string="Work done"/>
- <field colspan="4" name="work_ids" nolabel="1"/>
- </page>
- <page string="Others">
- <separator colspan="4" string="Notes"/>
- <field colspan="4" name="notes" nolabel="1"/>
- <newline/>
- <field name="type"/>
- <field name="start_sequence"/>
- <field colspan="4" name="child_ids" nolabel="1">
- <tree string="Delegated tasks">
- <field name="name"/>
- <field name="user_id"/>
- <field name="date_deadline"/>
- <field name="planned_hours" widget="float_time"/>
- <field name="effective_hours" widget="float_time"/>
- <field name="state"/>
- </tree>
- </field>
- <field colspan="4" name="parent_id"/>
- </page>
- </notebook>
- </form>
- <tree colors="red:date_deadline&lt;current_date and state=='draft';blue:date_deadline==current_date and state=='draft';grey:state=='cancel' or state=='close'" string="All tasks">
- <field name="sequence"/>
- <field name="name"/>
- <field name="user_id"/>
- <field name="date_deadline"/>
- <field name="progress_rate" widget="progressbar"/>
- <field name="planned_hours" widget="float_time"/>
- <field name="effective_hours" widget="float_time"/>
- <field name="state"/>
- </tree>
- </field>
</page>
<page string="Notes">
<field colspan="4" name="notes" nolabel="1"/>
@@ -154,6 +88,16 @@
</record>
<menuitem action="open_view_all_project" id="menu_all_project" parent="project.menu_main"/>
+ <record id="open_view_project" model="ir.actions.act_window">
+ <field name="name">New Project</field>
+ <field name="res_model">project.project</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form,tree,calendar</field>
+ <field name="view_id" eval="False"/>
+ </record>
+ <menuitem action="open_view_project" id="menu_open_view_project" parent="menu_all_project"/>
+
+
<record id="open_view_all_project_unclosed" model="ir.actions.act_window">
<field name="name">Unclosed projects</field>
<field name="res_model">project.project</field>
@@ -184,15 +128,6 @@
<menuitem id="next_id_54" name="Projects" parent="project.menu_definitions"/><menuitem action="open_view_project_open" id="menu_open_view_project_open" parent="next_id_54"/>
- <record id="open_view_project" model="ir.actions.act_window">
- <field name="name">Projects</field>
- <field name="res_model">project.project</field>
- <field name="view_type">form</field>
- <field name="domain">[]</field>
- <field name="view_id" ref="view_project"/>
- </record>
- <menuitem action="open_view_project" id="menu_open_view_project" parent="project.menu_definitions"/>
-
<record id="view_task_work_form" model="ir.ui.view">
<field name="name">project.task.work.form</field>
<field name="model">project.task.work</field>
@@ -274,14 +209,14 @@
<field eval="2" name="priority"/>
<field name="arch" type="xml">
<form string="Task edition">
- <notebook>
+ <field name="name" select="1"/>
+ <field name="project_id" required="1" select="1"/>
+ <field name="user_id" select="1"/>
+ <field name="planned_hours" widget="float_time"/>
+ <notebook colspan="4">
<page string="Information">
- <field name="name" select="1"/>
- <field name="project_id" required="1" select="1"/>
- <field name="user_id" select="1"/>
- <field name="priority"/>
<field name="date_deadline" select="2"/>
- <field name="planned_hours" widget="float_time"/>
+ <field name="priority"/>
<separator colspan="4" string="Description"/>
<field colspan="4" name="description" nolabel="1" select="2"/>
<field name="effective_hours" widget="float_time"/>
@@ -341,9 +276,9 @@
<field name="project_id"/>
<field name="user_id"/>
<field name="date_deadline"/>
- <field name="progress_rate" widget="progressbar"/>
<field name="planned_hours" sum="Planned hours" widget="float_time"/>
<field name="effective_hours" sum="Effective hours" widget="float_time"/>
+ <field name="progress" widget="progressbar"/>
<field name="priority"/>
<field name="state"/>
</tree>
@@ -491,7 +426,23 @@
<act_window domain="[('manager', '=', active_id)]" id="act_res_users_2_project_project" name="User's projects" res_model="project.project" src_model="res.users" view_mode="tree,form" view_type="form"/>
- <act_window domain="[('project_id', '=', active_id),('state', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', 'done')]" id="act_project_project_2_project_task_opened" name="Opened tasks" res_model="project.task" src_model="project.project" view_mode="tree,form" view_type="form"/>
+ <act_window
+ domain="[('project_id', '=', active_id)]"
+ id="act_project_project_2_project_task_all"
+ name="All Tasks"
+ res_model="project.task"
+ src_model="project.project"
+ view_mode="tree,form,calendar"
+ view_type="form"/>
+
+ <act_window
+ domain="[('project_id', '=', active_id),('state', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', 'done')]"
+ id="act_project_project_2_project_task_opened"
+ name="Open Tasks"
+ res_model="project.task"
+ src_model="project.project"
+ view_mode="tree,form,calendar"
+ view_type="form"/>
<act_window domain="[('user_id', '=', active_id),('state', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', 'done')]" id="act_res_users_2_project_task_opened" name="Assigned tasks" res_model="project.task" src_model="res.users" view_mode="tree,form" view_type="form"/>