diff --git a/addons/project/project.py b/addons/project/project.py
index 76e62df6a80..996e79a1f8b 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -441,6 +441,7 @@ class task(osv.osv):
'work_ids': fields.one2many('project.task.work', 'task_id', 'Work done'),
'manager_id': fields.related('project_id', 'analytic_account_id', 'user_id', type='many2one', relation='res.users', string='Project Manager'),
'company_id': fields.many2one('res.company', 'Company'),
+ 'id': fields.integer('ID'),
}
_defaults = {
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 69833383efe..6efc64dd494 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -303,6 +303,7 @@
+
diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py
index 82d5a1d70a1..2788b59ed7d 100644
--- a/addons/project_issue/project_issue.py
+++ b/addons/project_issue/project_issue.py
@@ -185,7 +185,7 @@ class project_issue(crm.crm_case, osv.osv):
method=True, multi='day_open', type="float", store=True),
'day_close': fields.function(_compute_day, string='Days to Close', \
method=True, multi='day_close', type="float", store=True),
- 'assigned_to': fields.many2one('res.users', 'Assigned to', help='This is the current user to whom the related task have been assigned'),
+ 'assigned_to': fields.related('task_id', 'user_id', string = 'Assigned to', type="many2one", relation="res.users", store=True, help='This is the current user to whom the related task have been assigned'),
'working_hours_open': fields.function(_compute_day, string='Working Hours to Open the Issue', \
method=True, multi='working_days_open', type="float", store=True),
'working_hours_close': fields.function(_compute_day, string='Working Hours to Close the Issue', \
@@ -318,6 +318,7 @@ class project_issue(crm.crm_case, osv.osv):
else:
raise osv.except_osv(_('Warning !'), _('You cannot escalate this issue.\nThe relevant Project has not configured the Escalation Project!'))
self.write(cr, uid, [case.id], data)
+ self._history(cr, uid, cases, _('Escalate'))
return True
def message_new(self, cr, uid, msg, context):
@@ -369,6 +370,31 @@ class project_issue(crm.crm_case, osv.osv):
return res
+ def get_stage_dict(self, cr, uid, ids, context=None):
+ """This function gives dictionary for stage according to stage levels
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of case IDs
+ @param context: A standard dictionary for contextual values"""
+ if not context:
+ context = {}
+ stage_obj = self.pool.get('crm.case.stage')
+ domain = [('object_id.model', '=', self._name)]
+ if 'force_domain' in context and context['force_domain']:
+ domain += context['force_domain']
+ sid = stage_obj.search(cr, uid, domain, context=context)
+ s = {}
+ previous = {}
+ section = self._name
+
+ for stage in stage_obj.browse(cr, uid, sid, context=context):
+ s.setdefault(section, {})
+ s[section][previous.get(section, False)] = stage.id
+ previous[section] = stage.id
+ return s
+
+
def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context=None):
if context is None:
context = {}
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml
index 9062b47a25e..b3b981d9847 100644
--- a/addons/project_issue/project_issue_view.xml
+++ b/addons/project_issue/project_issue_view.xml
@@ -73,7 +73,6 @@
-
@@ -89,6 +88,7 @@
+
@@ -202,6 +202,7 @@
+
@@ -225,9 +226,9 @@
-
+
diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py
index d1df71630f8..2caf36766b0 100644
--- a/addons/project_long_term/project_long_term.py
+++ b/addons/project_long_term/project_long_term.py
@@ -109,8 +109,8 @@ class project_phase(osv.osv):
'name': fields.char("Name", size=64, required=True),
'date_start': fields.date('Start Date', help="Starting Date of the phase", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'date_end': fields.date('End Date', help="Ending Date of the phase", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'constraint_date_start': fields.date('Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'constraint_date_end': fields.date('End Date', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'constraint_date_start': fields.date('Minimum Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'constraint_date_end': fields.date('Deadline', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'project_id': fields.many2one('project.project', 'Project', required=True),
'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases', states={'cancelled':[('readonly',True)]}),
'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases', states={'cancelled':[('readonly',True)]}),
@@ -394,8 +394,10 @@ class project_resource_allocation(osv.osv):
_columns = {
'resource_id': fields.many2one('resource.resource', 'Resource', required=True),
'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True),
- 'phase_id_date_start': fields.related('phase_id', 'date_start', type='date', string='Starting Date of the phase'),
- 'phase_id_date_end': fields.related('phase_id', 'date_end', type='date', string='Ending Date of the phase'),
+ 'project_id': fields.related('phase_id', 'project_id', type='many2one', relation="project.project", string='Project', store=True),
+ 'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'),
+ 'date_start': fields.date('Start Date', help="Starting Date"),
+ 'date_end': fields.date('End Date', help="Ending Date"),
'useability': fields.float('Usability', help="Usability of this resource for this project phase in percentage (=50%)"),
}
_defaults = {
diff --git a/addons/project_long_term/project_long_term_view.xml b/addons/project_long_term/project_long_term_view.xml
index 5a70e5acb5e..3412ba7ca08 100644
--- a/addons/project_long_term/project_long_term_view.xml
+++ b/addons/project_long_term/project_long_term_view.xml
@@ -13,14 +13,27 @@
project.resource.allocation
gantt
-
-
-
+
+
+
+
+ project.resource.allocation.calendar
+ project.resource.allocation
+ calendar
+
+
+
+
+
+
+
+
+
project.resource.allocation.form
@@ -28,9 +41,14 @@
form
@@ -44,6 +62,7 @@
+
@@ -58,11 +77,13 @@
+
+
@@ -73,7 +94,7 @@
Resource Allocations
project.resource.allocation
form
- tree,form,gantt
+ gantt,tree,form,calendar
{}
@@ -110,10 +131,14 @@
+
+
@@ -265,7 +290,7 @@
Project Phases
project.phase
form
- tree,form,gantt,calendar
+ gantt,tree,form,calendar
{'search_default_responsible_id':uid}
You can subdivide your larger projects into several phases. For each phase, you can define your resources allocation (humans or engine), describe de differend task and link your phase with previous and next one, add constraints date and scheduling. A gantt view of your project phase is also available from this menu. Gantt view is a graphically draw of the project plan; it includes any task dependencies by visually adjusting task durations and priorities, and by linking tasks to each other.
diff --git a/addons/project_messages/project_messages.py b/addons/project_messages/project_messages.py
index 88142f78984..93f83d62f4a 100644
--- a/addons/project_messages/project_messages.py
+++ b/addons/project_messages/project_messages.py
@@ -30,6 +30,7 @@ class messages(osv.osv):
logger = netsvc.Logger()
_columns = {
+ 'create_date': fields.datetime('Creation Date', readonly=True),
'from_id': fields.many2one('res.users', 'From', required=True, ondelete="CASCADE"),
'to_id': fields.many2one('res.users', 'To', ondelete="CASCADE", help="Keep this empty to broadcast the message."),
'project_id': fields.many2one('project.project', 'Project',
diff --git a/addons/project_messages/project_messages_view.xml b/addons/project_messages/project_messages_view.xml
index 3c574ed3d8d..e8a013cf2ae 100644
--- a/addons/project_messages/project_messages_view.xml
+++ b/addons/project_messages/project_messages_view.xml
@@ -44,7 +44,6 @@
-
@@ -56,6 +55,7 @@
tree
+
@@ -70,11 +70,12 @@
+
+
-
diff --git a/addons/project_scrum/project_scrum.py b/addons/project_scrum/project_scrum.py
index 5a758090309..f472369211b 100644
--- a/addons/project_scrum/project_scrum.py
+++ b/addons/project_scrum/project_scrum.py
@@ -18,13 +18,13 @@
# along with this program. If not, see .
#
##############################################################################
-from mx import DateTime
from osv import fields, osv
from tools.translate import _
import re
import time
import tools
-
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
class project_scrum_project(osv.osv):
_inherit = 'project.project'
@@ -147,7 +147,7 @@ class project_scrum_sprint(osv.osv):
proj = self.pool.get('project.project').browse(cr, uid, [project_id])[0]
v['product_owner_id']= proj.product_owner_id and proj.product_owner_id.id or False
v['scrum_master_id']= proj.user_id and proj.user_id.id or False
- v['date_stop'] = (DateTime.now() + DateTime.RelativeDateTime(days=int(proj.sprint_size or 14))).strftime('%Y-%m-%d')
+ v['date_stop'] = (datetime.now() + relativedelta(days=int(proj.sprint_size or 14))).strftime('%Y-%m-%d')
return {'value':v}
project_scrum_sprint()
@@ -264,7 +264,7 @@ class project_scrum_product_backlog(osv.osv):
'tasks_id': fields.one2many('project.task', 'product_backlog_id', 'Tasks Details'),
'state': fields.selection([('draft','Draft'),('open','Open'),('pending','Pending'),('done','Done'),('cancel','Cancelled')], 'State', required=True),
'progress': fields.function(_compute, multi="progress", group_operator="avg", type='float', method=True, string='Progress', help="Computed as: Time Spent / Total Time."),
- 'effective_hours': fields.function(_compute, multi="effective_hours", method=True, string='Spent Hours', help="Computed using the sum of the time spent on every related tasks"),
+ 'effective_hours': fields.function(_compute, multi="effective_hours", method=True, string='Spent Hours', help="Computed using the sum of the time spent on every related tasks", store=True),
'expected_hours': fields.float('Planned Hours', help='Estimated total time to do the Backlog'),
'create_date': fields.datetime("Creation Date", readonly=True),
'task_hours': fields.function(_compute, multi="task_hours", method=True, string='Task Hours', help='Estimated time of the total hours of the tasks')
diff --git a/addons/project_scrum/project_scrum_view.xml b/addons/project_scrum/project_scrum_view.xml
index 9c0cc2af4c1..843b35646e4 100644
--- a/addons/project_scrum/project_scrum_view.xml
+++ b/addons/project_scrum/project_scrum_view.xml
@@ -41,7 +41,7 @@
-
+
@@ -198,7 +198,7 @@
project.scrum.sprint
calendar
-
+
@@ -364,7 +364,7 @@
calendar
-
+
diff --git a/addons/project_scrum/wizard/project_scrum_backlog_create_task.py b/addons/project_scrum/wizard/project_scrum_backlog_create_task.py
index 2b8a641622d..1e0e9df66d5 100644
--- a/addons/project_scrum/wizard/project_scrum_backlog_create_task.py
+++ b/addons/project_scrum/wizard/project_scrum_backlog_create_task.py
@@ -31,6 +31,7 @@ class backlog_create_task(osv.osv_memory):
mod_obj = self.pool.get('ir.model.data')
task = self.pool.get('project.task')
backlog_id = self.pool.get('project.scrum.product.backlog')
+ document_pool = self.pool.get('ir.attachment')
ids_task = []
if context is None:
@@ -39,9 +40,9 @@ class backlog_create_task(osv.osv_memory):
backlogs = backlog_id.browse(cr, uid, context['active_ids'], context=context)
result = mod_obj._get_id(cr, uid, 'project', 'view_task_search_form')
id = mod_obj.read(cr, uid, result, ['res_id'])
-
+
for backlog in backlogs:
- ids_task.append(task.create(cr, uid, {
+ task_id = task.create(cr, uid, {
'product_backlog_id': backlog.id,
'name': backlog.name,
'description': backlog.note,
@@ -50,8 +51,11 @@ class backlog_create_task(osv.osv_memory):
'planned_hours': backlog.expected_hours,
'remaining_hours':backlog.expected_hours,
'sequence':backlog.sequence,
- }))
-
+ })
+ document_ids = document_pool.search(cr, uid, [('res_id', '=', backlog.id), ('res_model', '=', backlog_id._name)])
+ for document_id in document_ids:
+ document_pool.copy(cr, uid, document_id, default={'res_id':task_id, 'res_model':task._name})
+ ids_task.append(task_id)
return {
'domain': "[('product_backlog_id','in',["+','.join(map(str, context['active_ids']))+"])]",
'name': 'Tasks',