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
|
|