~jgrandguillaume-c2c/openobject-addons/multi-company-cost-price

« back to all changes in this revision

Viewing changes to project_long_term/wizard/schedule_tasks.py

  • Committer: Joël Grand-Guillaume
  • Date: 2010-04-08 09:00:10 UTC
  • mfrom: (2533.3.664)
  • Revision ID: joel.grandguillaume@camptocamp.com-20100408090010-c0pqjan341s18bxs
[MRG] Merge from last trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
 
6
#
 
7
#    This program is free software: you can redistribute it and/or modify
 
8
#    it under the terms of the GNU Affero General Public License as
 
9
#    published by the Free Software Foundation, either version 3 of the
 
10
#    License, or (at your option) any later version.
 
11
#
 
12
#    This program is distributed in the hope that it will be useful,
 
13
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
#    GNU Affero General Public License for more details.
 
16
#
 
17
#    You should have received a copy of the GNU Affero General Public License
 
18
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
#
 
20
##############################################################################
 
21
import datetime
 
22
from resource.faces import *
 
23
from new import classobj
 
24
import operator
 
25
 
 
26
import working_calendar as wkcal
 
27
 
 
28
import wizard
 
29
import pooler
 
30
from tools.translate import _
 
31
 
 
32
success_msg = """<?xml version="1.0" ?>
 
33
<form string="Compute Scheduling of Tasks">
 
34
    <label string="Task Scheduling completed successfully."/>
 
35
</form>"""
 
36
 
 
37
class wizard_schedule_task(wizard.interface):
 
38
 
 
39
    def _create_resources(self, cr, uid, phase, context={}):
 
40
        """
 
41
        Return a list of  Resource Class objects for the resources allocated to the phase.
 
42
        """
 
43
        resource_objs = []
 
44
        for resource in phase.resource_ids:
 
45
            res = resource.resource_id
 
46
            leaves = []
 
47
            resource_eff = res.time_efficiency
 
48
            resource_cal = res.calendar_id.id
 
49
            if resource_cal:
 
50
                cal_id  = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
 
51
                leaves = wkcal.compute_leaves(cr, uid, cal_id, res.id, resource_cal, context=context)
 
52
            resource_objs.append(classobj(res.user_id.name.encode('utf8'), (Resource,),
 
53
                                         {'__doc__': res.user_id.name,
 
54
                                          '__name__': res.user_id.name,
 
55
                                          'vacation': tuple(leaves),
 
56
                                          'efficiency': resource_eff
 
57
                                          }))
 
58
        return resource_objs
 
59
 
 
60
    def _compute_date(self, cr, uid, data, context={}):
 
61
        """
 
62
        Schedule the tasks according to resource available and priority.
 
63
        """
 
64
        pool = pooler.get_pool(cr.dbname)
 
65
        phase_obj = pool.get('project.phase')
 
66
        task_obj = pool.get('project.task')
 
67
        user_obj = pool.get('res.users')
 
68
        phase = phase_obj.browse(cr, uid, data['id'], context=context)
 
69
        task_ids = map(lambda x : x.id, (filter(lambda x : x.state in ['open', 'draft', 'pending'] , phase.task_ids)))
 
70
        if task_ids:
 
71
            task_ids.sort()
 
72
            tasks = task_obj.browse(cr, uid, task_ids, context=context)
 
73
            start_date = str(phase.date_start)[:-9]
 
74
            if not phase.date_start:
 
75
                if not phase.project_id.date_start:
 
76
                    start_date = datetime.datetime.now().strftime("%Y-%m-%d")
 
77
                else:
 
78
                    start_date = phase.project_id.date_start
 
79
            date_start = datetime.datetime.strftime(datetime.datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M")
 
80
            calendar_id = phase.project_id.resource_calendar_id.id
 
81
            resources = self._create_resources(cr, uid, phase)
 
82
            priority_dict = {'0': 1000, '1': 800, '2': 500, '3': 300, '4': 100}
 
83
            # Create dynamic no of tasks with the resource specified
 
84
            def create_tasks(j, eff, priorty=500, obj=False):
 
85
                def task():
 
86
                    """
 
87
                    task is a dynamic method!
 
88
                    """
 
89
                    effort = eff
 
90
                    if obj:
 
91
                        resource = obj
 
92
                    priority = priorty
 
93
                task.__doc__ = "TaskNO%d" %j
 
94
                task.__name__ = "task%d" %j
 
95
                return task
 
96
 
 
97
            # Create a 'Faces' project with all the tasks and resources
 
98
            def Project():
 
99
                title = "Project"
 
100
                start = date_start
 
101
                try:
 
102
                    resource = reduce(operator.or_, resources)
 
103
                except:
 
104
                    raise wizard.except_wizard(_('Error'), _('Phase must have resources assigned !'))
 
105
                minimum_time_unit = 1
 
106
                if calendar_id:            # If project has working calendar
 
107
                    working_days = wkcal.compute_working_calendar(cr, uid, calendar_id)
 
108
                    vacation = tuple(wkcal.compute_leaves(cr, uid, calendar_id))
 
109
                # Dynamic creation of tasks
 
110
                i = 0
 
111
                for each_task in tasks:
 
112
                    hours = str(each_task.planned_hours / each_task.occupation_rate)+ 'H'
 
113
                    if each_task.priority in priority_dict.keys():
 
114
                        priorty = priority_dict[each_task.priority]
 
115
                    if each_task.user_id:
 
116
                       for resource in resources:
 
117
                            if resource.__name__ == each_task.user_id.name:
 
118
                               task = create_tasks(i, hours, priorty, resource)
 
119
                    else:
 
120
                        task = create_tasks(i, hours, priorty)
 
121
                    i += 1
 
122
 
 
123
            project = BalancedProject(Project)
 
124
            loop_no = 0
 
125
            # Write back the computed dates
 
126
            for t in project:
 
127
                s_date = t.start.to_datetime()
 
128
                e_date = t.end.to_datetime()
 
129
                if loop_no > 0:
 
130
                    ctx = context.copy()
 
131
                    ctx.update({'scheduler': True})
 
132
                    user_id = user_obj.search(cr, uid, [('name', '=', t.booked_resource[0].__name__)])
 
133
                    task_obj.write(cr, uid, [tasks[loop_no-1].id], {'date_start': s_date.strftime('%Y-%m-%d %H:%M:%S'),
 
134
                                                                    'date_deadline': e_date.strftime('%Y-%m-%d %H:%M:%S'),
 
135
                                                                    'user_id': user_id[0]},
 
136
                                                                    context=ctx)
 
137
                loop_no +=1
 
138
        return {}
 
139
    states = {
 
140
        'init': {
 
141
            'actions': [_compute_date],
 
142
            'result': {'type':'form','arch':success_msg,'fields':{}, 'state':[('end', 'Ok')]},
 
143
        }
 
144
    }
 
145
wizard_schedule_task('phase.schedule.tasks')
 
146
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: