summaryrefslogtreecommitdiff
path: root/addons/project
diff options
context:
space:
mode:
authorsus <sus@openerp.com>2014-07-22 17:54:41 +0530
committerThibault Delavallée <tde@openerp.com>2014-09-18 11:38:10 +0200
commit56dfb4eeb977eb9493b83d0c2f2de22a561bc8c3 (patch)
tree611bd32b82e510f4f5d6bc6a31c6d0a93bee3c81 /addons/project
parente134e409731da0ed68997526dee46fad44d3f7ce (diff)
[IMP] project: onboardin / usability improvements
- project kanban view: dashboard-like view, add sparklines for open tasks and closed issues - project: cleaned demo data, less stages - project: description is now an html field
Diffstat (limited to 'addons/project')
-rw-r--r--addons/project/__openerp__.py3
-rw-r--r--addons/project/project.py48
-rw-r--r--addons/project/project_data.xml33
-rw-r--r--addons/project/project_demo.xml62
-rw-r--r--addons/project/project_view.xml14
-rw-r--r--addons/project/static/src/css/project.css15
6 files changed, 110 insertions, 65 deletions
diff --git a/addons/project/__openerp__.py b/addons/project/__openerp__.py
index e4e62ec8027..0b2308d62ec 100644
--- a/addons/project/__openerp__.py
+++ b/addons/project/__openerp__.py
@@ -44,7 +44,8 @@
'board',
'mail',
'resource',
- 'web_kanban'
+ 'web_kanban',
+ 'web_kanban_sparkline'
],
'description': """
Track multi-level projects, tasks, work done on tasks
diff --git a/addons/project/project.py b/addons/project/project.py
index e278cddd59f..d17980fd33b 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -19,8 +19,11 @@
#
##############################################################################
+import calendar
from datetime import datetime, date
+from dateutil import relativedelta
from lxml import etree
+import json
import time
from openerp import SUPERUSER_ID
@@ -65,6 +68,7 @@ class project(osv.osv):
_inherits = {'account.analytic.account': "analytic_account_id",
"mail.alias": "alias_id"}
_inherit = ['mail.thread', 'ir.needaction_mixin']
+ _period_number = 5
def _auto_init(self, cr, context=None):
""" Installation hook: aliases, project.project """
@@ -224,6 +228,46 @@ class project(osv.osv):
'context': "{'default_res_model': '%s','default_res_id': %d}" % (self._name, res_id)
}
+ def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, context=None):
+ """ Generic method to generate data for bar chart values using SparklineBarWidget.
+ This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field).
+
+ :param obj: the target model (i.e. crm_lead)
+ :param domain: the domain applied to the read_group
+ :param list read_fields: the list of fields to read in the read_group
+ :param str value_field: the field used to compute the value of the bar slice
+ :param str groupby_field: the fields used to group
+
+ :return list section_result: a list of dicts: [
+ { 'value': (int) bar_column_value,
+ 'tootip': (str) bar_column_tooltip,
+ }
+ ]
+ """
+ month_begin = date.today().replace(day=1)
+ section_result = [{
+ 'value': 0,
+ 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B'),
+ } for i in range(self._period_number - 1, -1, -1)]
+ group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context)
+ pattern = tools.DEFAULT_SERVER_DATE_FORMAT if obj.fields_get(cr, uid, groupby_field)[groupby_field]['type'] == 'date' else tools.DEFAULT_SERVER_DATETIME_FORMAT
+ for group in group_obj:
+ group_begin_date = datetime.strptime(group['__domain'][0][2], pattern)
+ month_delta = relativedelta.relativedelta(month_begin, group_begin_date)
+ section_result[self._period_number - (month_delta.months + 1)] = {'value': group.get(value_field, 0), 'tooltip': group.get(groupby_field, 0)}
+ return section_result
+
+ def _get_project_task_data(self, cr, uid, ids, field_name, arg, context=None):
+ obj = self.pool['project.task']
+ month_begin = date.today().replace(day=1)
+ date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+ date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+ res = {}
+ for id in ids:
+ created_domain = [('project_id', '=', id), ('create_date', '>=', date_begin ), ('create_date', '<=', date_end ), ('stage_id.fold', '=', False)]
+ res[id] = json.dumps(self.__get_bar_values(cr, uid, obj, created_domain, [ 'create_date'], 'create_date_count', 'create_date', context=context))
+ return res
+
# Lambda indirection method to avoid passing a copy of the overridable method when declaring the field
_alias_models = lambda self, *args, **kwargs: self._get_alias_models(*args, **kwargs)
_visibility_selection = lambda self, *args, **kwargs: self._get_visibility_selection(*args, **kwargs)
@@ -288,6 +332,8 @@ class project(osv.osv):
('pending','Pending'),
('close','Closed')],
'Status', required=True, copy=False),
+ 'monthly_tasks': fields.function(_get_project_task_data, type='char', readonly=True,
+ string='Project Task By Month'),
'doc_count': fields.function(
_get_attached_docs, string="Number of documents attached", type='integer'
)
@@ -737,7 +783,7 @@ class task(osv.osv):
_columns = {
'active': fields.function(_is_template, store=True, string='Not a Template Task', type='boolean', help="This field is computed automatically and have the same behavior than the boolean 'active' field: if the task is linked to a template or unactivated project, it will be hidden unless specifically asked."),
'name': fields.char('Task Summary', track_visibility='onchange', size=128, required=True, select=True),
- 'description': fields.text('Description'),
+ 'description': fields.html('Description'),
'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority', select=True),
'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of tasks."),
'stage_id': fields.many2one('project.task.type', 'Stage', track_visibility='onchange', select=True,
diff --git a/addons/project/project_data.xml b/addons/project/project_data.xml
index f98ee9aaea6..12a028151bc 100644
--- a/addons/project/project_data.xml
+++ b/addons/project/project_data.xml
@@ -27,44 +27,23 @@
<!-- Task Stages -->
- <record id="project_tt_analysis" model="project.task.type">
+ <record id="project_stage_0" model="project.task.type">
<field name="sequence">1</field>
- <field name="name">Analysis</field>
+ <field name="name">To Do</field>
<field name="case_default" eval="True"/>
</record>
- <record id="project_tt_specification" model="project.task.type">
+ <record id="project_stage_1" model="project.task.type">
<field name="sequence">10</field>
- <field name="name">Specification</field>
+ <field name="name">In Progress</field>
<field name="case_default" eval="True"/>
</record>
- <record id="project_tt_design" model="project.task.type">
- <field name="sequence">11</field>
- <field name="name">Design</field>
- <field name="case_default" eval="True"/>
- </record>
- <record id="project_tt_development" model="project.task.type">
- <field name="sequence">12</field>
- <field name="name">Development</field>
- <field name="case_default" eval="True"/>
- </record>
- <record id="project_tt_testing" model="project.task.type">
- <field name="sequence">13</field>
- <field name="name">Testing</field>
- <field name="case_default" eval="True"/>
- </record>
- <record id="project_tt_merge" model="project.task.type">
- <field name="sequence">14</field>
- <field name="name">Merge</field>
- <field name="case_default" eval="False"/>
- <field name="fold" eval="True"/>
- </record>
- <record id="project_tt_deployment" model="project.task.type">
+ <record id="project_stage_2" model="project.task.type">
<field name="sequence">20</field>
<field name="name">Done</field>
<field name="case_default" eval="True"/>
<field name="fold" eval="True"/>
</record>
- <record id="project_tt_cancel" model="project.task.type">
+ <record id="project_stage_3" model="project.task.type">
<field name="sequence">30</field>
<field name="name">Cancelled</field>
<field name="case_default" eval="True"/>
diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml
index 695aa80af2a..e15586dc420 100644
--- a/addons/project/project_demo.xml
+++ b/addons/project/project_demo.xml
@@ -40,7 +40,7 @@
<!-- We assign after so that default values applies -->
<record id="project_project_1" model="project.project">
- <field name="type_ids" eval="[(4, ref('project_tt_analysis')) ,(4,ref('project_tt_specification')), (4,ref('project_tt_development')), (4,ref('project_tt_testing')), (4,ref('project_tt_deployment'))]"/>
+ <field name="type_ids" eval="[(4, ref('project_stage_0')) ,(4,ref('project_stage_1'))]"/>
</record>
<record id="project_project_2" model="project.project">
@@ -56,7 +56,7 @@
<!-- We assign after so that default values applies -->
<record id="project_project_2" model="project.project">
- <field name="type_ids" eval="[(4, ref('project_tt_specification')),(4,ref('project_tt_development')),(4,ref('project_tt_testing')),(4,ref('project_tt_merge')),(4,ref('project_tt_deployment'))]"/>
+ <field name="type_ids" eval="[(4, ref('project_stage_1'))]"/>
</record>
<record id="project_project_3" model="project.project">
@@ -70,7 +70,7 @@
</record>
<record id="project_project_3" model="project.project">
- <field name="type_ids" eval="[(4, ref('project_tt_specification')),(4,ref('project_tt_development')),(4,ref('project_tt_testing')),(4,ref('project_tt_merge')),(4,ref('project_tt_deployment'))]"/>
+ <field name="type_ids" eval="[(4, ref('project_stage_1')),(4,ref('project_stage_2'))]"/>
</record>
<record id="project_project_4" model="project.project">
@@ -85,7 +85,7 @@
</record>
<record id="project_project_4" model="project.project">
- <field name="type_ids" eval="[(4, ref('project_tt_design')),(4,ref('project_tt_development')),(4,ref('project_tt_testing'))]"/>
+ <field name="type_ids" eval="[(4, ref('project_stage_1')),(4,ref('project_stage_2'))]"/>
</record>
<record id="project_project_5" model="project.project">
@@ -101,7 +101,7 @@
</record>
<record id="project_project_5" model="project.project">
- <field name="type_ids" eval="[(4, ref('project_tt_development'))]"/>
+ <field name="type_ids" eval="[(4, ref('project_stage_2'))]"/>
</record>
@@ -113,7 +113,7 @@
<field name="priority">0</field>
<field name="project_id" ref="project.project_project_1"/>
<field name="name">Prepare Requirements Document</field>
- <field name="stage_id" ref="project_tt_analysis"/>
+ <field name="stage_id" ref="project_stage_0"/>
<field name="color">3</field>
</record>
<record id="project_task_2" model="project.task">
@@ -123,7 +123,7 @@
<field name="priority">0</field>
<field name="project_id" ref="project.project_project_1"/>
<field name="name">Make SRS</field>
- <field name="stage_id" ref="project_tt_specification"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_3" model="project.task">
<field name="planned_hours" eval="10.0"/>
@@ -133,7 +133,7 @@
<field name="project_id" ref="project.project_project_1"/>
<field name="name">Budget Planning</field>
<field name="date_deadline" eval="time.strftime('%Y-%m-24')"/>
- <field name="stage_id" ref="project_tt_testing"/>
+ <field name="stage_id" ref="project_stage_2"/>
<field name="color">4</field>
</record>
<record id="project_task_4" model="project.task">
@@ -146,7 +146,7 @@
<field name="description">Use the account_budget module</field>
<field name="date_deadline" eval="time.strftime('%Y-%m-19')"/>
<field name="color">5</field>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_1"/>
<field name="categ_ids" eval="[(6, 0, [
ref('project_category_02')])]"/>
</record>
@@ -160,7 +160,7 @@
<field name="kanban_state">done</field>
<field name="priority">0</field>
<field name="date_deadline" eval="time.strftime('%Y-%m-%d')"/>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_1"/>
<field name="categ_ids" eval="[(6, 0, [
ref('project_category_02')])]"/>
</record>
@@ -171,7 +171,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_1"/>
<field name="name">Integrate Modules</field>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_7" model="project.task">
<field name="planned_hours" eval="15.0"/>
@@ -180,7 +180,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_1"/>
<field name="name">Internal testing + Software Install</field>
- <field name="stage_id" ref="project_tt_testing"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_8" model="project.task">
<field name="planned_hours" eval="22.0"/>
@@ -190,7 +190,7 @@
<field name="project_id" ref="project.project_project_2"/>
<field name="name">New portal system</field>
<field name="priority">0</field>
- <field name="stage_id" ref="project_tt_specification"/>
+ <field name="stage_id" ref="project_stage_2"/>
<field name="categ_ids" eval="[(6, 0, [
ref('project.project_category_03')])]"/>
</record>
@@ -201,7 +201,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_2"/>
<field name="name">Document history management</field>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_0"/>
</record>
<record id="project_task_10" model="project.task">
<field name="planned_hours" eval="38.0"/>
@@ -211,7 +211,7 @@
<field name="project_id" ref="project.project_project_2"/>
<field name="name">Social network integration</field>
<field name="kanban_state">blocked</field>
- <field name="stage_id" ref="project_tt_testing"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_11" model="project.task">
<field name="planned_hours" eval="16.0"/>
@@ -223,7 +223,7 @@
<field name="categ_ids" eval="[(6, 0, [
ref('project.project_category_02'),
ref('project.project_category_04')])]"/>
- <field name="stage_id" ref="project_tt_merge"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_12" model="project.task">
@@ -233,7 +233,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_2"/>
<field name="name">Improve+clean code and functionality</field>
- <field name="stage_id" ref="project_tt_merge"/>
+ <field name="stage_id" ref="project_stage_0"/>
<field name="color">6</field>
</record>
@@ -244,7 +244,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_3"/>
<field name="name">Design Use Cases</field>
- <field name="stage_id" ref="project_tt_analysis"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_14" model="project.task">
@@ -254,7 +254,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_3"/>
<field name="name">Dataflow Design</field>
- <field name="stage_id" ref="project_tt_analysis"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_15" model="project.task">
<field name="planned_hours" eval="55.0"/>
@@ -263,7 +263,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_3"/>
<field name="name">User Interface design</field>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_2"/>
<field name="date_start">2011-02-06</field>
<field name="categ_ids" eval="[(6, 0, [
ref('project_category_04')])]"/>
@@ -277,7 +277,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_3"/>
<field name="name">Set target for all deparments</field>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_3"/>
</record>
<record id="project_task_17" model="project.task">
@@ -287,7 +287,7 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_3"/>
<field name="name">Integration of core components</field>
- <field name="stage_id" ref="project_tt_testing"/>
+ <field name="stage_id" ref="project_stage_1"/>
</record>
<record id="project_task_18" model="project.task">
@@ -297,13 +297,13 @@
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_3"/>
<field name="name">Deploy and review on live system</field>
- <field name="stage_id" ref="project_tt_deployment"/>
+ <field name="stage_id" ref="project_stage_2"/>
</record>
<record id="project_task_19" model="project.task">
<field name="planned_hours">24.0</field>
<field name="remaining_hours">24.0</field>
- <field name="stage_id" ref="project_tt_design"/>
+ <field name="stage_id" ref="project_stage_3"/>
<field name="user_id" eval="False"/>
<field name="project_id" ref="project.project_project_4"/>
<field name="name">Basic outline</field>
@@ -315,7 +315,7 @@
<field name="planned_hours">42.0</field>
<field name="remaining_hours">42.0</field>
<field name="user_id" eval="False"/>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_0"/>
<field name="project_id" ref="project.project_project_4"/>
<field name="name">Create new components</field>
</record>
@@ -324,7 +324,7 @@
<field name="planned_hours">14.0</field>
<field name="remaining_hours">14.0</field>
<field name="user_id" eval="False"/>
- <field name="stage_id" ref="project_tt_testing"/>
+ <field name="stage_id" ref="project_stage_1"/>
<field name="project_id" ref="project.project_project_4"/>
<field name="name">Useablity review</field>
<field name="categ_ids" eval="[(6, 0, [
@@ -334,7 +334,7 @@
<record id="project_task_22" model="project.task">
<field name="planned_hours">12.0</field>
<field name="remaining_hours">12.0</field>
- <field name="stage_id" ref="project_tt_analysis"/>
+ <field name="stage_id" ref="project_stage_1"/>
<field name="user_id" eval="False"/>
<field name="priority">0</field>
<field name="project_id" ref="project.project_project_5"/>
@@ -345,7 +345,7 @@
<field name="sequence">15</field>
<field name="planned_hours">15.0</field>
<field name="remaining_hours">15.0</field>
- <field name="stage_id" ref="project_tt_specification"/>
+ <field name="stage_id" ref="project_stage_1"/>
<field name="user_id" eval="False"/>
<field name="project_id" ref="project.project_project_5"/>
<field name="name">Data Export flow</field>
@@ -355,7 +355,7 @@
<field name="sequence">17</field>
<field name="planned_hours">8.0</field>
<field name="remaining_hours">8.0</field>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_2"/>
<field name="user_id" eval="False"/>
<field name="priority">2</field>
<field name="project_id" ref="project.project_project_5"/>
@@ -371,7 +371,7 @@
<field name="user_id" eval="False"/>
<field name="project_id" ref="project.project_project_5"/>
<field name="name">Data importation + Doc</field>
- <field name="stage_id" ref="project_tt_development"/>
+ <field name="stage_id" ref="project_stage_0"/>
</record>
<record id="project_task_26" model="project.task">
@@ -381,7 +381,7 @@
<field name="user_id" eval="False"/>
<field name="project_id" ref="project.project_project_5"/>
<field name="name">Unit Testing</field>
- <field name="stage_id" ref="project_tt_testing"/>
+ <field name="stage_id" ref="project_stage_0"/>
</record>
<!-- Schedule tasks to assign users and dates -->
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 650a9b30015..3444f179b90 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -257,7 +257,7 @@
<field name="doc_count"/>
<templates>
<t t-name="kanban-box">
- <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_global_click">
+ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_global_click oe_kanban_project_task_spark">
<div class="oe_dropdown_toggle oe_dropdown_kanban" groups="base.group_user">
<span class="oe_e">í</span>
<ul class="oe_dropdown_menu">
@@ -272,8 +272,11 @@
<small><i class="fa fa-envelope-o"></i> <field name="alias_id"/></small>
</div>
<div class="oe_kanban_project_list">
- <a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: 10px">
- <t t-raw="record.task_ids.raw_value.length"/> Tasks
+ <a t-if="record.use_tasks.raw_value" class="oe_sparkline_bar_link" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: -5px">
+ <t t-raw="record.task_ids.raw_value.length" /> Tasks
+ <field name="monthly_tasks" widget="sparkline_bar" options="{'delayIn': '1000'}">
+ Created Tasks
+ </field>
</a>
<div t-if="record.use_tasks.raw_value and record.task_count.raw_value lt 1" style="margin-top: 6px;margin-left:20px;">
<img src="/project/static/src/img/top_left_arrow.png" style="margin-top: -8px; width: 22px;" />
@@ -414,7 +417,7 @@
</group>
<notebook>
<page string="Description">
- <field name="description" placeholder="Add a Description..."/>
+ <field name="description" type="html"/>
<field name="work_ids" groups="project.group_tasks_work_on_tasks">
<tree string="Task Work" editable="top">
<field name="name"/>
@@ -523,7 +526,7 @@
<div class="oe_kanban_content">
<div><b><field name="name"/></b></div>
<div>
- <field name="project_id"/><br/>
+ <field name="project_id" invisible="context.get('default_project_id', False)"/><br/>
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())" t-set="red">oe_kanban_text_red</t>
<span t-attf-class="#{red || ''}"><i><field name="date_deadline"/></i></span>
</div>
@@ -606,6 +609,7 @@
<field name="arch" type="xml">
<graph string="Project Tasks" type="bar">
<field name="project_id" type="row"/>
+ <field name="stage_id" type="row"/>
</graph>
</field>
</record>
diff --git a/addons/project/static/src/css/project.css b/addons/project/static/src/css/project.css
index 616c8625cd4..3572c45a9fe 100644
--- a/addons/project/static/src/css/project.css
+++ b/addons/project/static/src/css/project.css
@@ -70,3 +70,18 @@
position: relative;
}
+.openerp .oe_kanban_view .oe_kanban_project_task_spark {
+ /* Customize width and height of kanban according bootstrap3 */
+ width: 265px;
+ min-height: 120px;
+ /* End of customize */
+ cursor: default;
+}
+
+.openerp .oe_kanban_view .oe_sparkline_bar {
+ height: 20px;
+ width: 30px;
+ display: inline;
+
+}
+