#
##############################################################################
-import time
-from lxml import etree
from datetime import datetime, date
+from lxml import etree
+import time
-import tools
-from base_status.base_stage import base_stage
-from osv import fields, osv
-from openerp.addons.resource.faces import task as Task
-from tools.translate import _
from openerp import SUPERUSER_ID
+from openerp import tools
+from openerp.osv import fields, osv
+from openerp.tools.translate import _
+
+from openerp.addons.base_status.base_stage import base_stage
+from openerp.addons.resource.faces import task as Task
_TASK_STATE = [('draft', 'New'),('open', 'In Progress'),('pending', 'Pending'), ('done', 'Done'), ('cancelled', 'Cancelled')]
'name': fields.char('Stage Name', required=True, size=64, translate=True),
'description': fields.text('Description'),
'sequence': fields.integer('Sequence'),
- 'case_default': fields.boolean('Common to All Projects',
+ 'case_default': fields.boolean('Default for New Projects',
help="If you check this field, this stage will be proposed by default on each new project. It will not assign this stage to existing projects."),
'project_ids': fields.many2many('project.project', 'project_task_type_rel', 'type_id', 'project_id', 'Projects'),
'state': fields.selection(_TASK_STATE, 'Related Status', required=True,
help="The status of your document is automatically changed regarding the selected stage. " \
"For example, if a stage is related to the status 'Close', when your document reaches this stage, it is automatically closed."),
- 'fold': fields.boolean('Hide in views if empty',
+ 'fold': fields.boolean('Folded by Default',
help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
}
+ def _get_default_project_id(self, cr, uid, ctx={}):
+ proj = ctx.get('default_project_id', False)
+ if type(proj) is int:
+ return [proj]
+ return proj
_defaults = {
'sequence': 1,
'state': 'open',
'fold': False,
- 'case_default': True,
+ 'case_default': False,
+ 'project_ids': _get_default_project_id
}
_order = 'sequence'
res[id]['progress_rate'] = 0.0
return res
- def unlink(self, cr, uid, ids, *args, **kwargs):
+ def unlink(self, cr, uid, ids, context=None):
alias_ids = []
mail_alias = self.pool.get('mail.alias')
- for proj in self.browse(cr, uid, ids):
+ for proj in self.browse(cr, uid, ids, context=context):
if proj.tasks:
raise osv.except_osv(_('Invalid Action!'),
_('You cannot delete a project containing tasks. You can either delete all the project\'s tasks and then delete the project or simply deactivate the project.'))
elif proj.alias_id:
alias_ids.append(proj.alias_id.id)
- res = super(project, self).unlink(cr, uid, ids, *args, **kwargs)
- mail_alias.unlink(cr, uid, alias_ids, *args, **kwargs)
+ res = super(project, self).unlink(cr, uid, ids, context=context)
+ mail_alias.unlink(cr, uid, alias_ids, context=context)
return res
def _get_attached_docs(self, cr, uid, ids, field_name, arg, context):
attachment = self.pool.get('ir.attachment')
task = self.pool.get('project.task')
for id in ids:
- project_attachments = attachment.search(cr, uid, [('res_model', '=', 'project.project'), ('res_id', 'in', [id])], context=context, count=True)
- task_ids = task.search(cr, uid, [('project_id', 'in', [id])], context=context)
+ project_attachments = attachment.search(cr, uid, [('res_model', '=', 'project.project'), ('res_id', '=', id)], context=context, count=True)
+ task_ids = task.search(cr, uid, [('project_id', '=', id)], context=context)
task_attachments = attachment.search(cr, uid, [('res_model', '=', 'project.task'), ('res_id', 'in', task_ids)], context=context, count=True)
- res[id] = project_attachments or 0 + task_attachments or 0
+ res[id] = (project_attachments or 0) + (task_attachments or 0)
return res
def _task_count(self, cr, uid, ids, field_name, arg, context=None):
def _get_alias_models(self, cr, uid, context=None):
"""Overriden in project_issue to offer more options"""
return [('project.task', "Tasks")]
-
+
def attachment_tree_view(self, cr, uid, ids, context):
task_ids = self.pool.get('project.task').search(cr, uid, [('project_id', 'in', ids)])
domain = [
- ('|',
- '&', 'res_model', '=', 'project.project'), ('res_id', 'in', ids),
+ '|',
+ '&', ('res_model', '=', 'project.project'), ('res_id', 'in', ids),
'&', ('res_model', '=', 'project.task'), ('res_id', 'in', task_ids)
]
res_id = ids and ids[0] or False
ids = self.pool.get('project.task.type').search(cr, uid, [('case_default','=',1)], context=context)
return ids
- _order = "sequence"
+ _order = "sequence, id"
_defaults = {
'active': True,
'type': 'contract',
task_obj = self.pool.get('project.task')
task_ids = task_obj.search(cr, uid, [('project_id', 'in', ids), ('state', 'not in', ('cancelled', 'done'))])
task_obj.case_close(cr, uid, task_ids, context=context)
- self.write(cr, uid, ids, {'state':'close'}, context=context)
- self.set_close_send_note(cr, uid, ids, context=context)
- return True
+ return self.write(cr, uid, ids, {'state':'close'}, context=context)
def set_cancel(self, cr, uid, ids, context=None):
task_obj = self.pool.get('project.task')
task_ids = task_obj.search(cr, uid, [('project_id', 'in', ids), ('state', '!=', 'done')])
task_obj.case_cancel(cr, uid, task_ids, context=context)
- self.write(cr, uid, ids, {'state':'cancelled'}, context=context)
- self.set_cancel_send_note(cr, uid, ids, context=context)
- return True
+ return self.write(cr, uid, ids, {'state':'cancelled'}, context=context)
def set_pending(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, {'state':'pending'}, context=context)
- self.set_pending_send_note(cr, uid, ids, context=context)
- return True
+ return self.write(cr, uid, ids, {'state':'pending'}, context=context)
def set_open(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, {'state':'open'}, context=context)
- self.set_open_send_note(cr, uid, ids, context=context)
- return True
+ return self.write(cr, uid, ids, {'state':'open'}, context=context)
def reset_project(self, cr, uid, ids, context=None):
- res = self.setActive(cr, uid, ids, value=True, context=context)
- self.set_open_send_note(cr, uid, ids, context=context)
- return res
+ return self.setActive(cr, uid, ids, value=True, context=context)
def map_tasks(self, cr, uid, old_project_id, new_project_id, context=None):
""" copy and map tasks from old to new project """
context['active_test'] = False
default['state'] = 'open'
+ default['line_ids'] = []
default['tasks'] = []
default.pop('alias_name', None)
default.pop('alias_id', None)
resource = %s
""" % (
project.id,
- project.date_start, working_days,
+ project.date_start or time.strftime('%Y-%m-%d'), working_days,
'|'.join(['User_'+str(x) for x in puids])
)
vacation = calendar_id and tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context)) or False
# Prevent double project creation when 'use_tasks' is checked!
context = dict(context, project_creation_in_progress=True)
mail_alias = self.pool.get('mail.alias')
- if not vals.get('alias_id'):
+ if not vals.get('alias_id') and vals.get('name', False):
vals.pop('alias_name', None) # prevent errors during copy()
alias_id = mail_alias.create_unique_alias(cr, uid,
# Using '+' allows using subaddressing for those who don't
model_name=vals.get('alias_model', 'project.task'),
context=context)
vals['alias_id'] = alias_id
- vals['type'] = 'contract'
+ if vals.get('type', False) not in ('template','contract'):
+ vals['type'] = 'contract'
project_id = super(project, self).create(cr, uid, vals, context)
mail_alias.write(cr, uid, [vals['alias_id']], {'alias_defaults': {'project_id': project_id} }, context)
- self.create_send_note(cr, uid, [project_id], context=context)
return project_id
- def create_send_note(self, cr, uid, ids, context=None):
- return self.message_post(cr, uid, ids, body=_("Project has been <b>created</b>."), context=context)
-
- def set_open_send_note(self, cr, uid, ids, context=None):
- return self.message_post(cr, uid, ids, body=_("Project has been <b>opened</b>."), context=context)
-
- def set_pending_send_note(self, cr, uid, ids, context=None):
- return self.message_post(cr, uid, ids, body=_("Project is now <b>pending</b>."), context=context)
-
- def set_cancel_send_note(self, cr, uid, ids, context=None):
- return self.message_post(cr, uid, ids, body=_("Project has been <b>canceled</b>."), context=context)
-
- def set_close_send_note(self, cr, uid, ids, context=None):
- return self.message_post(cr, uid, ids, body=_("Project has been <b>closed</b>."), context=context)
-
def write(self, cr, uid, ids, vals, context=None):
# if alias_model has been changed, update alias_model_id accordingly
if vals.get('alias_model'):
_date_name = "date_start"
_inherit = ['mail.thread', 'ir.needaction_mixin']
+ _track = {
+ 'state': {
+ 'project.mt_task_new': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'new',
+ 'project.mt_task_started': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'open',
+ 'project.mt_task_closed': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
+ },
+ 'stage_id': {
+ 'project.mt_task_stage': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['new', 'done', 'open'],
+ },
+ 'kanban_state': { # kanban state: tracked, but only block subtype
+ 'project.mt_task_blocked': lambda self, cr, uid, obj, ctx=None: obj['kanban_state'] == 'blocked',
+ },
+ }
+
def _get_default_project_id(self, cr, uid, context=None):
""" Gives default section by checking if present in the context """
return (self._resolve_project_id_from_context(cr, uid, context=context) or False)
stage_obj = self.pool.get('project.task.type')
order = stage_obj._order
access_rights_uid = access_rights_uid or uid
- # lame way to allow reverting search, should just work in the trivial case
if read_group_order == 'stage_id desc':
order = '%s desc' % order
- # retrieve section_id from the context and write the domain
- # - ('id', 'in', 'ids'): add columns that should be present
- # - OR ('case_default', '=', True), ('fold', '=', False): add default columns that are not folded
- # - OR ('project_ids', 'in', project_id), ('fold', '=', False) if project_id: add project columns that are not folded
search_domain = []
project_id = self._resolve_project_id_from_context(cr, uid, context=context)
if project_id:
search_domain += ['|', ('project_ids', '=', project_id)]
- search_domain += ['|', ('id', 'in', ids), ('case_default', '=', True)]
+ search_domain += [('id', 'in', ids)]
stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context)
result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
# restore order of the search
'user_id': _read_group_user_id,
}
- def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
- obj_project = self.pool.get('project.project')
- for domain in args:
- if domain[0] == 'project_id' and (not isinstance(domain[2], str)):
- id = isinstance(domain[2], list) and domain[2][0] or domain[2]
- if id and isinstance(id, (long, int)):
- if obj_project.read(cr, user, id, ['state'])['state'] == 'template':
- args.append(('active', '=', False))
- return super(task, self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
-
def _str_get(self, task, level=0, border='***', context=None):
return border+' '+(task.user_id and task.user_id.name.upper() or '')+(level and (': L'+str(level)) or '')+(' - %.1fh / %.1fh'%(task.effective_hours or 0.0,task.planned_hours))+' '+border+'\n'+ \
border[0]+' '+(task.name or '')+'\n'+ \
'description': fields.text('Description'),
'priority': fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Important'), ('0','Very important')], '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',
- domain="['&', ('fold', '=', False), '|', ('project_ids', '=', project_id), ('case_default', '=', True)]"),
+ 'stage_id': fields.many2one('project.task.type', 'Stage', track_visibility='onchange',
+ domain="['&', ('fold', '=', False), ('project_ids', '=', project_id)]"),
'state': fields.related('stage_id', 'state', type="selection", store=True,
selection=_TASK_STATE, string="Status", readonly=True,
help='The status is set to \'Draft\', when a case is created.\
set to \'Pending\'.'),
'categ_ids': fields.many2many('project.category', string='Tags'),
'kanban_state': fields.selection([('normal', 'Normal'),('blocked', 'Blocked'),('done', 'Ready for next stage')], 'Kanban State',
+ track_visibility='onchange',
help="A task's kanban state indicates special situations affecting it:\n"
" * Normal is the default situation\n"
" * Blocked indicates something is preventing the progress of this task\n"
'date_start': fields.datetime('Starting Date',select=True),
'date_end': fields.datetime('Ending Date',select=True),
'date_deadline': fields.date('Deadline',select=True),
- 'project_id': fields.many2one('project.project', 'Project', ondelete='set null', select="1"),
+ 'project_id': fields.many2one('project.project', 'Project', ondelete='set null', select="1", track_visibility='onchange'),
'parent_ids': fields.many2many('project.task', 'project_task_parent_rel', 'task_id', 'parent_id', 'Parent Tasks'),
'child_ids': fields.many2many('project.task', 'project_task_parent_rel', 'parent_id', 'task_id', 'Delegated Tasks'),
'notes': fields.text('Notes'),
'project.task': (lambda self, cr, uid, ids, c={}: ids, ['work_ids', 'remaining_hours', 'planned_hours'], 10),
'project.task.work': (_get_task, ['hours'], 10),
}),
- 'user_id': fields.many2one('res.users', 'Assigned to'),
+ 'user_id': fields.many2one('res.users', 'Assigned to', track_visibility='onchange'),
'delegated_user_id': fields.related('child_ids', 'user_id', type='many2one', relation='res.users', string='Delegated To'),
'partner_id': fields.many2one('res.partner', 'Customer'),
'work_ids': fields.one2many('project.task.work', 'task_id', 'Work done'),
}
_order = "priority, sequence, date_start, name, id"
- def set_priority(self, cr, uid, ids, priority, *args):
- """Set task priority
- """
- return self.write(cr, uid, ids, {'priority' : priority})
-
- def set_very_high_priority(self, cr, uid, ids, *args):
- """Set task priority to very high
- """
- return self.set_priority(cr, uid, ids, '0')
-
def set_high_priority(self, cr, uid, ids, *args):
"""Set task priority to high
"""
- return self.set_priority(cr, uid, ids, '1')
+ return self.write(cr, uid, ids, {'priority' : '0'})
def set_normal_priority(self, cr, uid, ids, *args):
"""Set task priority to normal
"""
- return self.set_priority(cr, uid, ids, '2')
+ return self.write(cr, uid, ids, {'priority' : '2'})
def _check_recursion(self, cr, uid, ids, context=None):
for id in ids:
for task in cases:
if task.project_id:
section_ids.append(task.project_id.id)
- # OR all section_ids and OR with case_default
search_domain = []
if section_ids:
- search_domain += [('|')] * len(section_ids)
+ search_domain = [('|')] * (len(section_ids)-1)
for section_id in section_ids:
search_domain.append(('project_ids', '=', section_id))
- search_domain.append(('case_default', '=', True))
- # AND with the domain in parameter
search_domain += list(domain)
# perform search, return the first found
stage_ids = self.pool.get('project.task.type').search(cr, uid, search_domain, order=order, context=context)
if not task.date_end:
vals['date_end'] = fields.datetime.now()
self.case_set(cr, uid, [task.id], 'done', vals, context=context)
- self.case_close_send_note(cr, uid, [task.id], context=context)
return True
def do_reopen(self, cr, uid, ids, context=None):
for task in self.browse(cr, uid, ids, context=context):
project = task.project_id
self.case_set(cr, uid, [task.id], 'open', {}, context=context)
- self.case_open_send_note(cr, uid, [task.id], context)
return True
def do_cancel(self, cr, uid, ids, context=None):
self._check_child_task(cr, uid, ids, context=context)
for task in tasks:
self.case_set(cr, uid, [task.id], 'cancelled', {'remaining_hours': 0.0}, context=context)
- self.case_cancel_send_note(cr, uid, [task.id], context=context)
return True
def do_open(self, cr, uid, ids, context=None):
def case_open(self, cr, uid, ids, context=None):
if not isinstance(ids,list): ids = [ids]
- self.case_set(cr, uid, ids, 'open', {'date_start': fields.datetime.now()}, context=context)
- self.case_open_send_note(cr, uid, ids, context)
- return True
+ return self.case_set(cr, uid, ids, 'open', {'date_start': fields.datetime.now()}, context=context)
def do_draft(self, cr, uid, ids, context=None):
""" Compatibility when changing to case_draft. """
return self.case_draft(cr, uid, ids, context=context)
def case_draft(self, cr, uid, ids, context=None):
- self.case_set(cr, uid, ids, 'draft', {}, context=context)
- self.case_draft_send_note(cr, uid, ids, context=context)
- return True
+ return self.case_set(cr, uid, ids, 'draft', {}, context=context)
def do_pending(self, cr, uid, ids, context=None):
""" Compatibility when changing to case_pending. """
return self.case_pending(cr, uid, ids, context=context)
def case_pending(self, cr, uid, ids, context=None):
- self.case_set(cr, uid, ids, 'pending', {}, context=context)
- return self.case_pending_send_note(cr, uid, ids, context=context)
+ return self.case_set(cr, uid, ids, 'pending', {}, context=context)
def _delegate_task_attachments(self, cr, uid, task_id, delegated_task_id, context=None):
attachment = self.pool.get('ir.attachment')
self.do_pending(cr, uid, [task.id], context=context)
elif delegate_data['state'] == 'done':
self.do_close(cr, uid, [task.id], context=context)
- self.do_delegation_send_note(cr, uid, [task.id], context)
delegated_tasks[task.id] = delegated_task_id
return delegated_tasks
return self.set_remaining_time(cr, uid, ids, 10.0, context)
def set_kanban_state_blocked(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, {'kanban_state': 'blocked'}, context=context)
- return False
+ return self.write(cr, uid, ids, {'kanban_state': 'blocked'}, context=context)
def set_kanban_state_normal(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, {'kanban_state': 'normal'}, context=context)
- return False
+ return self.write(cr, uid, ids, {'kanban_state': 'normal'}, context=context)
def set_kanban_state_done(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'done'}, context=context)
return True
def create(self, cr, uid, vals, context=None):
+ if context is None:
+ context = {}
+ if not vals.get('stage_id'):
+ ctx = context.copy()
+ if vals.get('project_id'):
+ ctx['default_project_id'] = vals['project_id']
+ vals['stage_id'] = self._get_default_stage_id(cr, uid, context=ctx)
task_id = super(task, self).create(cr, uid, vals, context=context)
- task_record = self.browse(cr, uid, task_id, context=context)
- project_obj = self.pool.get("project.project")
- subtype_obj = self.pool.get('mail.message.subtype')
- subtype_ids = []
- if task_record.project_id:
- project_subtype = task_record.project_id.message_subtype_data
- for key in project_subtype:
- subtype_ids = subtype_obj.search(cr, uid, [('res_model', '=', self._name), ('name', 'ilike', key)], context=context)
- if subtype_ids:
- subtype_obj.write(cr,uid, subtype_ids, {'default': project_subtype[key]['default']},context=context)
- project_follower_ids = [follower.id for follower in task_record.project_id.message_follower_ids]
- self.message_subscribe(cr, uid, [task_id], project_follower_ids, subtype_ids = subtype_ids,
- context=context)
self._store_history(cr, uid, [task_id], context=context)
- self.create_send_note(cr, uid, [task_id], context=context)
return task_id
# Overridden to reset the kanban_state to normal whenever
def write(self, cr, uid, ids, vals, context=None):
if isinstance(ids, (int, long)):
ids = [ids]
- project_obj = self.pool.get("project.project")
- subtype_obj = self.pool.get('mail.message.subtype')
if vals.get('project_id'):
- project_id = project_obj.browse(cr, uid, vals.get('project_id'), context=context)
- vals['message_follower_ids'] = [(4, follower.id) for follower in project_id.message_follower_ids]
- for key in project_id.message_subtype_data:
- subtype_ids = subtype_obj.search(cr, uid, [('res_model', '=', self._name), ('name', '=', key)], context=context)
- if subtype_ids:
- subtype_obj.write(cr,uid, subtype_ids, {'default': project_id.message_subtype_data[key]['default']},context=context)
+ project_id = self.pool.get('project.project').browse(cr, uid, vals.get('project_id'), context=context)
+ if project_id:
+ vals.setdefault('message_follower_ids', [])
+ vals['message_follower_ids'] += [(6, 0,[follower.id]) for follower in project_id.message_follower_ids]
if vals and not 'kanban_state' in vals and 'stage_id' in vals:
new_stage = vals.get('stage_id')
vals_reset_kstate = dict(vals, kanban_state='normal')
#if new_stage not in stages:
#raise osv.except_osv(_('Warning!'), _('Stage is not defined in the project.'))
write_vals = vals_reset_kstate if t.stage_id != new_stage else vals
- super(task,self).write(cr, uid, [t.id], write_vals, context=context)
- self.stage_set_send_note(cr, uid, [t.id], new_stage, context=context)
+ super(task, self).write(cr, uid, [t.id], write_vals, context=context)
result = True
else:
- result = super(task,self).write(cr, uid, ids, vals, context=context)
+ result = super(task, self).write(cr, uid, ids, vals, context=context)
if ('stage_id' in vals) or ('remaining_hours' in vals) or ('user_id' in vals) or ('state' in vals) or ('kanban_state' in vals):
self._store_history(cr, uid, ids, context=context)
return result
# Mail gateway
# ---------------------------------------------------
+ def message_get_reply_to(self, cr, uid, ids, context=None):
+ """ Override to get the reply_to of the parent project. """
+ return [task.project_id.message_get_reply_to()[0] if task.project_id else False
+ for task in self.browse(cr, uid, ids, context=context)]
+
def message_new(self, cr, uid, msg, custom_values=None, context=None):
""" Override to updates the document according to the email. """
if custom_values is None: custom_values = {}
- custom_values.update({
+ defaults = {
'name': msg.get('subject'),
'planned_hours': 0.0,
- })
- return super(task,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
+ }
+ defaults.update(custom_values)
+ return super(task,self).message_new(cr, uid, msg, custom_values=defaults, context=context)
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
""" Override to update the task according to the email. """
}
for line in msg['body'].split('\n'):
line = line.strip()
- res = tools.misc.command_re.match(line)
+ res = tools.command_re.match(line)
if res:
match = res.group(1).lower()
field = maps.get(match)
act = 'do_%s' % res.group(2).lower()
if act:
getattr(self,act)(cr, uid, ids, context=context)
- return super(task,self).message_update(cr, uid, msg, update_vals=update_vals, context=context)
-
- # ---------------------------------------------------
- # OpenChatter methods and notifications
- # ---------------------------------------------------
-
- def case_get_note_msg_prefix(self, cr, uid, id, context=None):
- """ Override of default prefix for notifications. """
- return 'Task'
-
- def get_needaction_user_ids(self, cr, uid, ids, context=None):
- """ Returns the user_ids that have to perform an action.
- Add to the previous results given by super the document responsible
- when in draft mode.
- :return: dict { record_id: [user_ids], }
- """
- result = super(task, self).get_needaction_user_ids(cr, uid, ids, context=context)
- for obj in self.browse(cr, uid, ids, context=context):
- if obj.state == 'draft' and obj.user_id:
- result[obj.id].append(obj.user_id.id)
- return result
-
- def message_get_monitored_follower_fields(self, cr, uid, ids, context=None):
- """ Add 'user_id' and 'manager_id' to the monitored fields """
- res = super(task, self).message_get_monitored_follower_fields(cr, uid, ids, context=context)
- return res + ['user_id', 'manager_id']
-
- def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
- """ Override of the (void) default notification method. """
- stage_name = self.pool.get('project.task.type').name_get(cr, uid, [stage_id], context=context)[0][1]
- return self.message_post(cr, uid, ids, body=_("Stage changed to <b>%s</b>.") % (stage_name),
- context=context)
-
- def create_send_note(self, cr, uid, ids, context=None):
- return self.message_post(cr, uid, ids, body=_("Task has been <b>created</b>."), context=context)
-
- def case_draft_send_note(self, cr, uid, ids, context=None):
- return self.message_post(cr, uid, ids, body=_('Task has been set as <b>draft</b>.'), context=context)
-
- def do_delegation_send_note(self, cr, uid, ids, context=None):
- for task in self.browse(cr, uid, ids, context=context):
- msg = _('Task has been <b>delegated</b> to <em>%s</em>.') % (task.user_id.name)
- self.message_post(cr, uid, [task.id], body=msg, context=context)
- return True
+ return super(task,self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
+ def project_task_reevaluate(self, cr, uid, ids, context=None):
+ if self.pool.get('res.users').has_group(cr, uid, 'project.group_time_work_estimation_tasks'):
+ return {
+ 'view_type': 'form',
+ "view_mode": 'form',
+ 'res_model': 'project.task.reevaluate',
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+ return self.do_reopen(cr, uid, ids, context=context)
class project_work(osv.osv):
_name = "project.task.work"
_inherit = 'account.analytic.account'
_description = 'Analytic Account'
_columns = {
- 'use_tasks': fields.boolean('Tasks',help="If check,this contract will be available in the project menu and you will be able to manage tasks or track issues"),
+ 'use_tasks': fields.boolean('Tasks',help="If checked, this contract will be available in the project menu and you will be able to manage tasks or track issues"),
'company_uom_id': fields.related('company_id', 'project_time_mode_id', type='many2one', relation='product.uom'),
}
project_values = {
'name': vals.get('name'),
'analytic_account_id': analytic_account_id,
+ 'type': vals.get('type','contract'),
}
return project_pool.create(cr, uid, project_values, context=context)
return False
for account in self.browse(cr, uid, ids, context=context):
if not name:
vals['name'] = account.name
+ if not vals.get('type'):
+ vals['type'] = account.type
self.project_create(cr, uid, account.id, vals, context=context)
return super(account_analytic_account, self).write(cr, uid, ids, vals, context=context)