Project

General

Profile

Download (10.7 KB) Statistics
| Branch: | Tag: | Revision:

calebasse / scripts / import_ev_reunion.py @ a22b9e74

1
# -*- coding: utf-8 -*-
2
#!/usr/bin/env python
3

    
4
"""
5
"""
6

    
7

    
8
import os
9
import csv
10
import logging
11
from datetime import datetime, timedelta
12

    
13
log_file = "./scripts/import_ev_reunion.log"
14
logging.basicConfig(filename=log_file,level=logging.DEBUG)
15

    
16
import calebasse.settings
17
import django.core.management
18

    
19
django.core.management.setup_environ(calebasse.settings)
20

    
21
from django.db import transaction
22

    
23
from calebasse.agenda.models import Event, EventType
24
from calebasse.personnes.models import Worker
25
from calebasse.ressources.models import Service
26

    
27
from scripts.import_rs import PERIOD_FAURE_NOUS
28

    
29
# Configuration
30
db_path = "./scripts/20121221-192258"
31

    
32
dbs = ["F_ST_ETIENNE_SESSAD_TED", "F_ST_ETIENNE_CMPP", "F_ST_ETIENNE_CAMSP", "F_ST_ETIENNE_SESSAD"]
33
tables = ['rs', 'ev', 'details_rs', 'details_ev']
34

    
35
# Global mappers. This dicts are used to map a Faure id with a calebasse object.
36
tables_data = {}
37

    
38
def _to_datetime(str_date):
39
    if not str_date:
40
        return None
41
    return datetime.strptime(str_date[:19], "%Y-%m-%d %H:%M:%S")
42

    
43
def _to_date(str_date):
44
    dt = _to_datetime(str_date)
45
    return dt and dt.date()
46

    
47
def _to_time(str_date):
48
    dt = _to_datetime(str_date)
49
    return dt and dt.time()
50

    
51
def _to_duration(str_date):
52
    dt = _to_datetime(str_date)
53
    if dt is None:
54
        return timedelta(minutes=15)
55
    return dt - datetime(1900, 01, 01, 0, 0)
56

    
57
def _get_dict(cols, line):
58
    res = {}
59
    for i, data in enumerate(line):
60
        res[cols[i]] = data.decode('utf-8')
61
    return res
62

    
63
import utils
64

    
65
worker_indexes = utils.QuerysetIndex(Worker.objects.all(),
66
        'old_cmpp_id', 'old_camsp_id', 'old_sessad_dys_id', 'old_sessad_ted_id')
67

    
68
def _get_therapists(line, table_name, service):
69
    global worker_indexes
70
    p_ids = []
71
    for id, detail in tables_data['details_%s' % table_name].iteritems():
72
        if detail['%s_id' % table_name] == line['id']:
73
            p_ids.append(detail['thera_id'])
74
    participants = []
75
    for p_id in p_ids:
76
        try:
77
            if service.name == "CMPP":
78
                worker = worker_indexes.by_old_cmpp_id[p_id]
79
            elif service.name == "CAMSP":
80
                worker = worker_indexes.by_old_camsp_id[p_id]
81
            elif service.name == "SESSAD DYS":
82
                worker = worker_indexes.by_old_sessad_dys_id[p_id]
83
            elif service.name == "SESSAD TED":
84
                worker = worker_indexes.by_old_sessad_ted_id[p_id]
85
            participants.append(worker)
86
        except KeyError:
87
            logging.warning("%s %s_id %s thera_id %s" %\
88
                    (service.name, table_name, line['id'], p_id) +\
89
                    " therapeute non trouve")
90

    
91
    return participants
92

    
93
def _is_timetable(line):
94
    return line and line['libelle'].replace(u'é', u'e').upper() in ('ARRIVEE', 'DEPART')
95

    
96
def _get_ev(tables, line):
97
    ev_id = line['rr_ev_id']
98
    if not ev_id or not ev_id.startswith('ev_'):
99
        return None
100
    return tables['ev'].get(ev_id[3:])
101

    
102
ServicesThrough = Event.services.through
103
ParticipantsThrough = Event.participants.through
104

    
105
event_type_4 = EventType.objects.get(id=4)
106

    
107
def create_event(line, service, tables_data, rs_by_id, events_by_id, events,
108
        participants_by_id, exceptions_set):
109
    if line['id'] not in rs_by_id:
110
        # Manage exception
111
        exception_date = None
112
        exception_to = None
113
        exception_error = False
114
        if line['rr_ev_id']:
115
            assert line['rr_ev_id'].startswith('ev_')
116
            ev_id = int(line['rr_ev_id'][3:])
117
            exception_date = _to_date(line['date_rdv'])
118
            exception_to = events_by_id.get(str(ev_id))
119
            if exception_to:
120
                p = (exception_date, exception_to)
121
                if p in exceptions_set:
122
                    logging.info("rs_id %s is duplicated" % line["id"])
123
                    return
124
                exceptions_set.add(p)
125
            else:
126
                exception_error = True
127
        start_datetime = datetime.strptime(
128
                line['date_rdv'][:-13] + ' ' + line['heure'][11:-4],
129
                "%Y-%m-%d %H:%M:%S")
130
        end_datetime = start_datetime + timedelta(
131
                hours=int(line['duree'][11:-10]),
132
                minutes=int(line['duree'][14:-7]),
133
                )
134
        participants = _get_therapists(line, 'rs', service)
135
        if not participants:
136
            logging.error("%s rs_id %s exception aucun participant importable" % (service.name,
137
                line["id"]))
138
            return
139
        if not exception_error:
140
            event = Event(
141
                    title=line['libelle'][:60],
142
                    description=line['texte'],
143
                    event_type=event_type_4,
144
                    start_datetime=start_datetime,
145
                    end_datetime=end_datetime,
146
                    old_rs_id=line['id'],
147
                    exception_to = Event(id=exception_to),
148
                    exception_date = exception_date
149
                    )
150
            participants_by_id[line['id']] = participants
151
            events.append(event)
152
        else:
153
            logging.error("%s rs_id %s exception pas d'ev trouve %s" % (service.name,
154
                line["id"], line))
155

    
156
def create_recurrent_event(line, service, tables_data, events, participants_by_id):
157
    if not Event.objects.filter(old_ev_id=line['id'], services__in=[service]):
158
        start_date = _to_date(line['date_debut'])
159
        end_date = _to_date(line['date_fin'])
160
        if end_date and start_date > end_date:
161
            logging.warning('%s ev_id %s date_fin < date_debut' % \
162
                    (service.name, line['id']))
163
        time = _to_time(line['heure'])
164
        duration = _to_duration(line['duree'])
165
        start_datetime = datetime.combine(start_date, time)
166
        end_datetime = start_datetime + duration
167

    
168
        # connect rythme
169
        rythme = int(line['rythme'])
170
        if PERIOD_FAURE_NOUS.get(rythme):
171
            recurrence_periodicity = PERIOD_FAURE_NOUS[rythme]
172
        else:
173
            recurrence_periodicity = None
174
            logging.warning('%s ev_id %s rythme not found %s' % \
175
                    (service.name, line['id'], line['rythme']))
176

    
177
        participants = _get_therapists(line, 'ev', service)
178
        if not participants:
179
            logging.error("%s ev_id %s exception aucun participant importable" % (service.name,
180
                line["id"]))
181
            return
182
        try:
183
            event = Event(
184
                start_datetime=start_datetime,
185
                end_datetime=end_datetime,
186
                event_type=event_type_4,
187
                title=line['libelle'],
188
                old_ev_id=line['id'],
189
                description=line['note'],
190
                recurrence_periodicity=recurrence_periodicity,
191
                recurrence_end_date=end_date)
192
            participants_by_id[line['id']] = participants
193
            events.append(event)
194
        except django.core.exceptions.ValidationError, e:
195
            logging.error(service.name + ' ev recurrence non valide %s %s' % (line, e))
196

    
197
@transaction.commit_on_success
198
def main():
199
    for db in dbs:
200
        if "F_ST_ETIENNE_CMPP" == db:
201
            service = Service.objects.get(name="CMPP")
202
        elif "F_ST_ETIENNE_CAMSP" == db:
203
            service = Service.objects.get(name="CAMSP")
204
        elif "F_ST_ETIENNE_SESSAD_TED" == db:
205
            service = Service.objects.get(name="SESSAD TED")
206
        elif "F_ST_ETIENNE_SESSAD" == db:
207
            service = Service.objects.get(name="SESSAD DYS")
208

    
209
        for table in tables:
210
            tables_data[table] = None
211
            csvfile = open(os.path.join(db_path, db, '%s.csv' % table), 'rb')
212
            csvlines = csv.reader(csvfile, delimiter=';', quotechar='|')
213
            cols = csvlines.next()
214
            tables_data[table] = {}
215
            for line in csvlines:
216
                data = _get_dict(cols, line)
217
                tables_data[table][data['id']] = data
218
            csvfile.close()
219

    
220
        total = 0
221
        events = []
222
        participants = dict()
223
        for id, line in tables_data['ev'].iteritems():
224
            if not _is_timetable(line):
225
                total += 1
226
                create_recurrent_event(line, service, tables_data, events,
227
                        participants)
228

    
229
        # create events
230
        logging.info('%s creating %s events on %s',
231
                service.name, len(events), total)
232
        Event.objects.bulk_create(events)
233
        participants_through = []
234
        # get their ids
235
        events_by_id = dict(Event.objects \
236
                .exclude(event_type_id=1) \
237
                .filter(services__isnull=True, old_ev_id__isnull=False) \
238
                .values_list('old_ev_id', 'id'))
239
        for line_id, participants in participants.iteritems():
240
            for participant in participants:
241
                pt = ParticipantsThrough(event_id=events_by_id[line_id],
242
                        people_id=participant.people_ptr_id)
243
                participants_through.append(pt)
244
        ParticipantsThrough.objects.bulk_create(participants_through)
245
        ServicesThrough.objects.bulk_create([
246
            ServicesThrough(service_id=service.id, event_id=event_id) for event_id in events_by_id.values()])
247
        participants = {}
248

    
249
        total = 0
250
        events = []
251
        participants = dict()
252
        exceptions_set = set()
253
        # get their ids
254
        rs_by_id = dict(Event.objects \
255
                .exclude(event_type_id=1) \
256
                .filter(services=service, old_rs_id__isnull=False) \
257
                .values_list('old_rs_id', 'id'))
258
        for id, line in tables_data['rs'].iteritems():
259
            if (not line['enfant_id'] or not int(line['enfant_id'])) \
260
                    and not _is_timetable(line) \
261
                    and (not _is_timetable(_get_ev(tables_data, line))):
262
                total += 1
263
                create_event(line, service, tables_data, rs_by_id, events_by_id,
264
                        events, participants, exceptions_set)
265
        # create events
266
        logging.info('%s creating %s events on %s',
267
                service.name, len(events), total)
268
        Event.objects.bulk_create(events)
269
        participants_through = []
270
        # get their ids
271
        events_by_id = dict(Event.objects \
272
                .exclude(event_type_id=1) \
273
                .filter(services__isnull=True, old_rs_id__isnull=False) \
274
                .values_list('old_rs_id', 'id'))
275
        for line_id, participants in participants.iteritems():
276
            for participant in participants:
277
                pt = ParticipantsThrough(event_id=events_by_id[line_id],
278
                        people_id=participant.people_ptr_id)
279
                participants_through.append(pt)
280
        ParticipantsThrough.objects.bulk_create(participants_through)
281
        ServicesThrough.objects.bulk_create([
282
            ServicesThrough(service_id=service.id, event_id=event_id) for event_id in events_by_id.values()])
283
        participants = {}
284

    
285

    
286
if __name__ == "__main__":
287
    main()
288

    
(13-13/28)