[REM] completion in Gantt chart tasks and projects, not supported by OpenERP and...
[odoo/odoo.git] / addons / project_issue / project_issue.py
index 1524a14..b950bfd 100644 (file)
@@ -28,6 +28,8 @@ import time
 import tools
 from crm import wizard
 
+wizard.mail_compose_message.SUPPORTED_MODELS.append('project.issue')
+
 class project_issue_version(osv.osv):
     _name = "project.issue.version"
     _order = "name desc"
@@ -46,6 +48,13 @@ class project_issue(crm.crm_case, osv.osv):
     _order = "priority, create_date desc"
     _inherit = ['mail.thread']
 
+    def write(self, cr, uid, ids, vals, context=None):
+        #Update last action date everytime the user change the stage, the state or send a new email
+        logged_fields = ['type_id', 'state', 'message_ids']
+        if any([field in vals for field in logged_fields]):
+            vals['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
+        return super(project_issue, self).write(cr, uid, ids, vals, context)
+
     def case_open(self, cr, uid, ids, *args):
         """
         @param self: The object pointer
@@ -56,7 +65,7 @@ class project_issue(crm.crm_case, osv.osv):
         """
 
         res = super(project_issue, self).case_open(cr, uid, ids, *args)
-        self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'), 'assigned_to' : uid})
+        self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'), 'user_id' : uid})
         for (id, name) in self.name_get(cr, uid, ids):
             message = _("Issue '%s' has been opened.") % name
             self.log(cr, uid, id, message)
@@ -90,32 +99,31 @@ class project_issue(crm.crm_case, osv.osv):
 
         res = {}
         for issue in self.browse(cr, uid, ids, context=context):
+            res[issue.id] = {}
             for field in fields:
-                res[issue.id] = {}
                 duration = 0
                 ans = False
                 hours = 0
 
+                date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
                 if field in ['working_hours_open','day_open']:
                     if issue.date_open:
-                        date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
                         date_open = datetime.strptime(issue.date_open, "%Y-%m-%d %H:%M:%S")
                         ans = date_open - date_create
                         date_until = issue.date_open
                         #Calculating no. of working hours to open the issue
                         hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
-                                 datetime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'),
-                                 datetime.strptime(issue.date_open, '%Y-%m-%d %H:%M:%S'))
+                                                           date_create,
+                                                           date_open)
                 elif field in ['working_hours_close','day_close']:
                     if issue.date_closed:
-                        date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
                         date_close = datetime.strptime(issue.date_closed, "%Y-%m-%d %H:%M:%S")
                         date_until = issue.date_closed
                         ans = date_close - date_create
                         #Calculating no. of working hours to close the issue
                         hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
-                                datetime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'),
-                                datetime.strptime(issue.date_closed, '%Y-%m-%d %H:%M:%S'))
+                               date_create,
+                               date_close)
                 elif field in ['days_since_creation']:
                     if issue.create_date:
                         days_since_creation = datetime.today() - datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
@@ -137,7 +145,11 @@ class project_issue(crm.crm_case, osv.osv):
                     duration = float(ans.days)
                     if issue.project_id and issue.project_id.resource_calendar_id:
                         duration = float(ans.days) * 24
-                        new_dates = cal_obj.interval_min_get(cr, uid, issue.project_id.resource_calendar_id.id, datetime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'), duration, resource=resource_id)
+
+                        new_dates = cal_obj.interval_min_get(cr, uid,
+                                                             issue.project_id.resource_calendar_id.id,
+                                                             date_create,
+                                                             duration, resource=resource_id)
                         no_days = []
                         date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
                         for in_time, out_time in new_dates:
@@ -146,10 +158,12 @@ class project_issue(crm.crm_case, osv.osv):
                             if out_time > date_until:
                                 break
                         duration = len(no_days)
+
                 if field in ['working_hours_open','working_hours_close']:
                     res[issue.id][field] = hours
                 else:
                     res[issue.id][field] = abs(float(duration))
+
         return res
 
     def _get_issue_task(self, cr, uid, ids, context=None):
@@ -178,7 +192,7 @@ class project_issue(crm.crm_case, osv.osv):
         return res
 
     _columns = {
-        'id': fields.integer('ID'),
+        'id': fields.integer('ID', readonly=True),
         'name': fields.char('Issue', size=128, required=True),
         'active': fields.boolean('Active', required=False),
         'create_date': fields.datetime('Creation Date', readonly=True,select=True),
@@ -189,13 +203,12 @@ class project_issue(crm.crm_case, osv.osv):
         'section_id': fields.many2one('crm.case.section', 'Sales Team', \
                         select=True, help='Sales team to which Case belongs to.\
                              Define Responsible user and Email account for mail gateway.'),
-        'user_id': fields.related('project_id', 'user_id', type='many2one', relation='res.users', store=True, select=1, string='Responsible'),
         'partner_id': fields.many2one('res.partner', 'Partner', select=1),
         'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
                                  domain="[('partner_id','=',partner_id)]"),
         'company_id': fields.many2one('res.company', 'Company'),
         'description': fields.text('Description'),
-        'state': fields.selection([('draft', 'New'), ('open', 'To Do'), ('cancel', 'Cancelled'), ('done', 'Closed'),('pending', 'Pending'), ], 'State', size=16, readonly=True,
+        'state': fields.selection([('draft', 'New'), ('open', 'In Progress'), ('cancel', 'Cancelled'), ('done', 'Done'),('pending', 'Pending'), ], 'State', size=16, readonly=True,
                                   help='The state is set to \'Draft\', when a case is created.\
                                   \nIf the case is in progress the state is set to \'Open\'.\
                                   \nWhen the case is over, the state is set to \'Done\'.\
@@ -206,15 +219,11 @@ class project_issue(crm.crm_case, osv.osv):
         # Project Issue fields
         'date_closed': fields.datetime('Closed', readonly=True,select=True),
         'date': fields.datetime('Date'),
-        'canal_id': fields.many2one('res.partner.canal', 'Channel', help="The channels represent the different communication modes available with the customer." \
-                                                                        " With each commercial opportunity, you can indicate the canall which is this opportunity source."),
+        'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel."),
         'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('object_id.model', '=', 'crm.project.bug')]"),
-        'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
+        'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority', select=True),
         'version_id': fields.many2one('project.issue.version', 'Version'),
-        'partner_name': fields.char("Partner Name", size=64),
-        'partner_mobile': fields.char('Mobile', size=32),
-        'partner_phone': fields.char('Phone', size=32),
-        'type_id': fields.many2one ('project.task.type', 'Resolution', domain="[('project_ids', '=', project_id)]"),
+        'type_id': fields.many2one ('project.task.type', 'Stages', domain="[('project_ids', '=', project_id)]"),
         'project_id':fields.many2one('project.project', 'Project'),
         'duration': fields.float('Duration'),
         'task_id': fields.many2one('project.task', 'Task', domain="[('project_id','=',project_id)]"),
@@ -222,13 +231,15 @@ class project_issue(crm.crm_case, osv.osv):
                                 multi='compute_day', type="float", store=True),
         'day_close': fields.function(_compute_day, string='Days to Close', \
                                 multi='compute_day', type="float", store=True),
-        'assigned_to': fields.many2one('res.users', 'Assigned to', required=False, select=1),
+        'user_id': fields.many2one('res.users', 'Assigned to', required=False, select=1),
         'working_hours_open': fields.function(_compute_day, string='Working Hours to Open the Issue', \
                                 multi='compute_day', type="float", store=True),
         'working_hours_close': fields.function(_compute_day, string='Working Hours to Close the Issue', \
                                 multi='compute_day', type="float", store=True),
         'inactivity_days': fields.function(_compute_day, string='Days since last action', \
                                 multi='compute_day', type="integer", help="Difference in days between last action and current date"),
+        'color': fields.integer('Color Index'),
+        'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
         'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
         'date_action_last': fields.datetime('Last Action', readonly=1),
         'date_action_next': fields.datetime('Next Action', readonly=1),
@@ -247,19 +258,11 @@ class project_issue(crm.crm_case, osv.osv):
         return False
 
     def on_change_project(self, cr, uid, ids, project_id, context=None):
-        result = {}
-
-        if project_id:
-            project = self.pool.get('project.project').browse(cr, uid, project_id, context=context)
-            if project.user_id:
-                result['value'] = {'user_id' : project.user_id.id}
-
-        return result
+        return {}
 
 
     _defaults = {
         'active': 1,
-        #'user_id': crm.crm_case._get_default_user,
         'partner_id': crm.crm_case._get_default_partner,
         'partner_address_id': crm.crm_case._get_default_partner_address,
         'email_from': crm.crm_case._get_default_email,
@@ -269,8 +272,22 @@ class project_issue(crm.crm_case, osv.osv):
         'priority': crm.AVAILABLE_PRIORITIES[2][0],
         'project_id':_get_project,
         'categ_id' : lambda *a: False,
-        #'assigned_to' : lambda obj, cr, uid, context: uid,
-    }
+         }
+
+    def set_priority(self, cr, uid, ids, priority):
+        """Set lead priority
+        """
+        return self.write(cr, uid, ids, {'priority' : priority})
+
+    def set_high_priority(self, cr, uid, ids, *args):
+        """Set lead priority to high
+        """
+        return self.set_priority(cr, uid, ids, '1')
+
+    def set_normal_priority(self, cr, uid, ids, *args):
+        """Set lead priority to normal
+        """
+        return self.set_priority(cr, uid, ids, '3')
 
     def convert_issue_task(self, cr, uid, ids, context=None):
         case_obj = self.pool.get('project.issue')
@@ -295,10 +312,11 @@ class project_issue(crm.crm_case, osv.osv):
                 'name': bug.name,
                 'partner_id': bug.partner_id.id,
                 'description':bug.description,
-                'date': bug.date,
+                'date_deadline': bug.date,
                 'project_id': bug.project_id.id,
-                'priority': bug.priority,
-                'user_id': bug.assigned_to.id,
+                # priority must be in ['0','1','2','3','4'], while bug.priority is in ['1','2','3','4','5']
+                'priority': str(int(bug.priority) - 1),
+                'user_id': bug.user_id.id,
                 'planned_hours': 0.0,
             })
 
@@ -360,13 +378,12 @@ class project_issue(crm.crm_case, osv.osv):
                     self.write(cr, uid, task.id, {'type_id': index and types[index-1] or False})
         return True
 
-
     def onchange_task_id(self, cr, uid, ids, task_id, context=None):
         result = {}
         if not task_id:
             return {'value':{}}
         task = self.pool.get('project.task').browse(cr, uid, task_id, context=context)
-        return {'value':{'assigned_to': task.user_id.id,}}
+        return {'value':{'user_id': task.user_id.id,}}
 
     def case_escalate(self, cr, uid, ids, *args):
         """Escalates case to top level
@@ -378,7 +395,7 @@ class project_issue(crm.crm_case, osv.osv):
         """
         cases = self.browse(cr, uid, ids)
         for case in cases:
-            data = {}
+            data = {'state' : 'draft'}
             if case.project_id.project_escalation_id:
                 data['project_id'] = case.project_id.project_escalation_id.id
                 if case.project_id.project_escalation_id.user_id:
@@ -408,7 +425,7 @@ class project_issue(crm.crm_case, osv.osv):
         }
         if priority:
             vals['priority'] = priority
-        vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
+        vals.update(self.message_partner_by_email(cr, uid, msg_from))
         context.update({'state_to' : 'draft'})
 
         if custom_values and isinstance(custom_values, dict):
@@ -454,7 +471,7 @@ class project_issue(crm.crm_case, osv.osv):
 
         vals.update(vls)
         res = self.write(cr, uid, ids, vals)
-        self.message_append_dict(cr, uid, [res_id], msg, context=context)
+        self.message_append_dict(cr, uid, ids, msg, context=context)
         return res
 
     def copy(self, cr, uid, id, default=None, context=None):
@@ -471,7 +488,6 @@ project_issue()
 class project(osv.osv):
     _inherit = "project.project"
     _columns = {
-        'resource_calendar_id' : fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
         'project_escalation_id' : fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
         'reply_to' : fields.char('Reply-To Email Address', size=256)
     }