Add a view to import HyperPlanning csv files
This commit is contained in:
parent
7b62c9cba1
commit
1a84c26f94
8 changed files with 144 additions and 16 deletions
|
|
@ -30,4 +30,7 @@ class PeriodForm(forms.Form):
|
|||
|
||||
def __init__(self, data, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class UploadHPFileForm(forms.Form):
|
||||
upload = forms.FileField(label='Fichier HyperPlanning')
|
||||
|
|
|
|||
31
stages/test_files/HYPERPLANNING.csv
Normal file
31
stages/test_files/HYPERPLANNING.csv
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
NOMPERSO_ENS;UID_ENS;LIBELLE_MAT;NOMPERSO_DIP;TOTAL
|
||||
Bernasconi Laurie;;#ASE Colloque;#Mandat_ASE;24.00
|
||||
Bernasconi Laurie;;#ASE MP Expérientiel;#Mandat_ASE;40.00
|
||||
Bernasconi Laurie;;#ASE TA;#Mandat_ASE;18.00
|
||||
Bernasconi Laurie;;#IFFP;;
|
||||
Bernasconi Laurie;;#IFFP;;
|
||||
Bernasconi Laurie;;#IFFP;#Mandat_ASE;172.00
|
||||
Bernasconi Laurie;;Animer I (B);1ASEFEa, 1ASEFEd, 1ASEFEe;8.00
|
||||
Bernasconi Laurie;;Animer I (B);1ASEFEa, 1ASEFEd, 1ASEFEe;8.00
|
||||
Bernasconi Laurie;;Animer I (B);1ASEFEb, 1ASEFEc, 1ASEFEd, 1ASEFEf;8.00
|
||||
Bernasconi Laurie;;Animer I (B);1ASEFEb, 1ASEFEc, 1ASEFEd, 1ASEFEf;8.00
|
||||
Bernasconi Laurie;;Animer II (Bgén);2MPTS ASE1;8.00
|
||||
Bernasconi Laurie;;Animer II (Bgén);2MPTS ASE1;8.00
|
||||
Bernasconi Laurie;;Animer II (Bgén);2MPTS ASE1;8.00
|
||||
Bernasconi Laurie;;Animer II (Bgén);2MPTS ASE1;8.00
|
||||
Bernasconi Laurie;;Animer II (Bgén);2MPTS ASE1;8.00
|
||||
Bernasconi Laurie;;Colloque ASE;;
|
||||
Bernasconi Laurie;;Conseil de classe;;
|
||||
Bernasconi Laurie;;Conseil de classe;;
|
||||
Bernasconi Laurie;;Formation AMOK EPC;;
|
||||
Bernasconi Laurie;;Relations prof. (I);1ASEFEf, 3MPS ASE1;2.00
|
||||
Bernasconi Laurie;;Relations prof. (I);1MPTS ASE3, 3MPS ASE3;2.00
|
||||
Bernasconi Laurie;;Relations prof. (I);3MPS ASE1;8.00
|
||||
Bernasconi Laurie;;Relations prof. (I);3MPS ASE1;8.00
|
||||
Bernasconi Laurie;;Relations prof. (I);3MPS ASE3;8.00
|
||||
Bernasconi Laurie;;Remise des titres;;
|
||||
Bernasconi Laurie;;Sém. enfance 2;[2ASEFE c-d E S2];8.00
|
||||
Bernasconi Laurie;;Sém. enfance 2;[2ASEFE c-d E S2];8.00
|
||||
Bernasconi Laurie;;Sém. enfance 2;[2ASEFE c-d E S2];8.00
|
||||
Bernasconi Laurie;;Sém. enfance 2;[2ASEFE c-d E S2];8.00
|
||||
Bernasconi Laurie;;Travail personnel;[2ASEFE c-d E S2];8.00
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.utils.html import escape
|
|||
|
||||
from .models import (
|
||||
Level, Domain, Section, Klass, Period, Student, Corporation, Availability,
|
||||
CorpContact, Referent, Training
|
||||
CorpContact, Referent, Teacher, Training,
|
||||
)
|
||||
from .utils import school_year
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ class ImportTests(TestCase):
|
|||
path = os.path.join(os.path.dirname(__file__), 'test_files', 'EXPORT_GAN.xls')
|
||||
self.client.login(username='me', password='mepassword')
|
||||
with open(path, 'rb') as fh:
|
||||
response = self.client.post(reverse('tabimport'), {'upload': fh}, follow=True)
|
||||
response = self.client.post(reverse('import-students'), {'upload': fh}, follow=True)
|
||||
self.assertContains(response, escape("La classe '1ASEFEa' n'existe pas encore"))
|
||||
|
||||
lev1 = Level.objects.create(name='1')
|
||||
|
|
@ -172,5 +172,16 @@ class ImportTests(TestCase):
|
|||
level=lev1,
|
||||
)
|
||||
with open(path, 'rb') as fh:
|
||||
response = self.client.post(reverse('tabimport'), {'upload': fh}, follow=True)
|
||||
response = self.client.post(reverse('import-students'), {'upload': fh}, follow=True)
|
||||
self.assertContains(response, "Created objects: 2")
|
||||
|
||||
def test_import_hp(self):
|
||||
teacher = Teacher.objects.create(
|
||||
first_name='Laurie', last_name='Bernasconi', birth_date='1974-08-08'
|
||||
)
|
||||
path = os.path.join(os.path.dirname(__file__), 'test_files', 'HYPERPLANNING.csv')
|
||||
self.client.login(username='me', password='mepassword')
|
||||
with open(path, 'rb') as fh:
|
||||
response = self.client.post(reverse('import-hp'), {'upload': fh}, follow=True)
|
||||
self.assertContains(response, "Created objects: 13, modified objects: 10")
|
||||
self.assertEqual(teacher.course_set.count(), 13)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ import json
|
|||
from collections import OrderedDict
|
||||
from datetime import date, datetime, timedelta
|
||||
|
||||
from tabimport import FileFactory
|
||||
from tabimport import CSVImportedFile, FileFactory
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.files import File
|
||||
from django.db.models import Case, Count, When
|
||||
from django.http import HttpResponse, HttpResponseNotAllowed, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
|
@ -13,9 +14,11 @@ from django.urls import reverse
|
|||
from django.utils.translation import ugettext as _
|
||||
from django.views.generic import DetailView, FormView, TemplateView, ListView
|
||||
|
||||
from .forms import PeriodForm, StudentImportForm
|
||||
from .models import (Klass, Section, Student, Corporation, CorpContact, Period,
|
||||
Training, Referent, Availability)
|
||||
from .forms import PeriodForm, StudentImportForm, UploadHPFileForm
|
||||
from .models import (
|
||||
Klass, Section, Student, Teacher, Corporation, CorpContact, Course, Period,
|
||||
Training, Referent, Availability,
|
||||
)
|
||||
|
||||
|
||||
def school_year_start():
|
||||
|
|
@ -282,13 +285,18 @@ def del_training(request):
|
|||
return HttpResponse(json.dumps({'ref_id': ref_id}), content_type="application/json")
|
||||
|
||||
|
||||
class StudentImportView(FormView):
|
||||
template_name = 'student_import.html'
|
||||
form_class = StudentImportForm
|
||||
class ImportViewBase(FormView):
|
||||
template_name = 'file_import.html'
|
||||
|
||||
def form_valid(self, form):
|
||||
upfile = form.cleaned_data['upload']
|
||||
try:
|
||||
imp_file = FileFactory(form.cleaned_data['upload'])
|
||||
if 'csv' in upfile.content_type:
|
||||
# Reopen the file in text mode
|
||||
upfile = open(upfile.temporary_file_path(), mode='r', encoding='utf-8-sig')
|
||||
imp_file = CSVImportedFile(File(upfile))
|
||||
else:
|
||||
imp_file = FileFactory(upfile)
|
||||
created, modified = self.import_data(imp_file)
|
||||
except Exception as e:
|
||||
if settings.DEBUG:
|
||||
|
|
@ -299,6 +307,11 @@ class StudentImportView(FormView):
|
|||
'cr': created, 'mod': modified})
|
||||
return HttpResponseRedirect(reverse('admin:index'))
|
||||
|
||||
|
||||
class StudentImportView(ImportViewBase):
|
||||
title = "Importation étudiants"
|
||||
form_class = StudentImportForm
|
||||
|
||||
def import_data(self, up_file):
|
||||
""" Import Student data from uploaded file. """
|
||||
student_mapping = settings.STUDENT_IMPORT_MAPPING
|
||||
|
|
@ -334,6 +347,74 @@ class StudentImportView(FormView):
|
|||
return obj_created, obj_modified
|
||||
|
||||
|
||||
class HPImportView(ImportViewBase):
|
||||
"""
|
||||
Importation du fichier HyperPlanning pour l'établissement des feuilles
|
||||
de charges.
|
||||
"""
|
||||
form_class = UploadHPFileForm
|
||||
mapping = {
|
||||
'NOMPERSO_ENS': 'teacher',
|
||||
'LIBELLE_MAT': 'subject',
|
||||
'NOMPERSO_DIP': 'klass',
|
||||
'TOTAL': 'period',
|
||||
}
|
||||
# Mapping between klass field and imputation
|
||||
account_categories = {
|
||||
'ASAFE': 'ASA',
|
||||
'ASEFE': 'ASE',
|
||||
'ASSCFE': 'ASSC',
|
||||
'MP': 'LEP',
|
||||
'EDEpe': 'EDEpe',
|
||||
'EDEps': 'EDEps',
|
||||
'EDE': 'EDE',
|
||||
'EDS': 'EDS',
|
||||
'CAS-FPP': 'CAS-FPP',
|
||||
'Mandat_ASSC': 'ASSC',
|
||||
'Mandat_ASE': 'ASE',
|
||||
'Mandat_EDE': 'EDE',
|
||||
'Mandat_EDS': 'EDA',
|
||||
}
|
||||
|
||||
def import_data(self, up_file):
|
||||
obj_created = obj_modified = 0
|
||||
|
||||
#Pour accélérer la recherche
|
||||
profs = {}
|
||||
for t in Teacher.objects.all():
|
||||
profs[t.__str__()] = t
|
||||
Course.objects.all().delete()
|
||||
|
||||
for line in up_file:
|
||||
if (line['LIBELLE_MAT'] == '' or line['NOMPERSO_DIP'] == '' or
|
||||
line['TOTAL'] == ''):
|
||||
continue
|
||||
defaults = {
|
||||
'teacher': profs[line['NOMPERSO_ENS']],
|
||||
'subject': line['LIBELLE_MAT'],
|
||||
'klass': line['NOMPERSO_DIP'],
|
||||
}
|
||||
|
||||
obj, created = Course.objects.get_or_create(
|
||||
teacher = defaults['teacher'],
|
||||
subject = defaults['subject'],
|
||||
klass = defaults['klass'])
|
||||
|
||||
period = int(float(line['TOTAL']))
|
||||
if created:
|
||||
obj.period = period
|
||||
obj_created += 1
|
||||
for k, v in self.account_categories.items():
|
||||
if k in obj.klass:
|
||||
obj.imputation = v
|
||||
break
|
||||
else:
|
||||
obj.period += period
|
||||
obj_modified += 1
|
||||
obj.save()
|
||||
return obj_created, obj_modified
|
||||
|
||||
|
||||
EXPORT_FIELDS = [
|
||||
('Prénom', 'student__first_name'), ('Nom', 'student__last_name'),
|
||||
('ID externe', 'student__ext_id'),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue