1- from flask import Blueprint , flash , render_template , redirect , url_for , request , session
1+ from flask import Blueprint , flash , render_template , redirect , url_for , request , session , send_file
22from flask_app import admin_required , db , set_route , socketio
33from flask_app .admin .editions .form import Edition_form
44from flask_login import login_required , current_user
5- from flask_app .models import Event , Parcours , Edition , Inscription
5+ from flask_app .models import Event , Parcours , Edition , Inscription , User
66from datetime import datetime
77from flask_socketio import join_room , leave_room
8+ from xlsxwriter import Workbook
9+ from io import BytesIO
10+ from flask_babel import _
11+ from flask_app .custom_validators import DataRequired , Length , EqualTo , DonTExist , DbLength
12+ from .form import NewCoureurForm , ValidateNewCoureurForm
13+ from sqlalchemy import func , and_ , or_ , not_
814
915dossard = Blueprint ('dossard' , __name__ , template_folder = 'templates' )
1016
@@ -24,8 +30,88 @@ def generate_dossard(event_name, edition_name):
2430 edition : Edition = event .editions .filter_by (name = edition_name ).first_or_404 ()
2531 user = current_user
2632
33+ form = NewCoureurForm ()
34+ choices = edition .parcours
35+ form .parcours .choices = [str ((p .name , p .description )) for p in choices ]
2736
28- return render_template ('generate_dossard.html' , user_data = user , event_data = event , edition_data = edition , now = datetime .now (), inscriptions = edition .inscriptions , event_modif = True , edition_sidebar = True )
37+ if form .validate_on_submit ():
38+ users = User .query .filter (and_ (or_ (func .lower (User .username )== func .lower (form .username .data ),
39+ and_ (func .lower (User .name )== func .lower (form .name .data ), func .lower (User .lastname )== func .lower (form .lastname .data ))),
40+ User .datenaiss == form .datenaiss .data )).all ()
41+ if len (users ) > 0 :
42+ validate_form = ValidateNewCoureurForm ()
43+ else :
44+ validate_form = None
45+
46+ supp_validators = {
47+ 'name' :[DataRequired (), DbLength (User , 'name' )],
48+ 'lastname' :[DataRequired (), DbLength (User , 'lastname' )],
49+ 'username' :[DataRequired (), DbLength (User , 'username' )],
50+ 'email' :[DataRequired (), DbLength (User , 'email' )]
51+ }
52+ ic ('first validation' , form .validate (extra_validators = supp_validators ), form .parcours .data )
53+ if form .validate (extra_validators = supp_validators ):
54+ # create a new user with the form data and add it to all the parcours
55+ username = f'{ form .name .data } .{ form .lastname .data } '
56+ nb = User .query .filter (User .username .contains (username )).count ()
57+ username += str (nb ) if nb > 0 else ''
58+ hash_pwd = 'dev' #! ''.join(secrets.choice(alphabet) for _ in range(10))
59+
60+ choices = event .parcours .filter (Parcours .name .in_ ([eval (data )[0 ] for data in form .parcours .data ])).all ()
61+ user = User (name = form .name .data ,
62+ lastname = form .lastname .data ,
63+ username = username ,
64+ email = form .email .data if form .email .data else None ,
65+ phone = form .phone .data if form .phone .data else None ,
66+ datenaiss = form .datenaiss .data ,
67+ password = hash_pwd )
68+ db .session .add (user )
69+ db .session .commit ()
70+ db .session .refresh (user )
71+ inscriptions = []
72+ for parcours in choices :
73+ inscriptions .append (Inscription (user_id = user .id ,
74+ event_id = event .id ,
75+ edition_id = edition .id ,
76+ parcours_id = parcours .id ))
77+ db .session .add_all (inscriptions )
78+ db .session .commit ()
79+
80+ else :
81+ users = []
82+ validate_form = None
83+
84+ return render_template ('generate_dossard.html' , user_data = user , event_data = event , edition_data = edition , now = datetime .now (), inscriptions = edition .inscriptions , event_modif = True , edition_sidebar = True , form = form , validate_form = validate_form , validate_users = users )
85+
86+ @set_route (dossard , '/event/<event_name>/editions/<edition_name>/dossard/newuser' , methods = ['POST' ])
87+ @login_required
88+ @admin_required
89+ def validate_new_user (event_name , edition_name ):
90+ event = Event .query .filter_by (name = event_name ).first_or_404 ()
91+ edition : Edition = event .editions .filter_by (name = edition_name ).first_or_404 ()
92+ form = ValidateNewCoureurForm ()
93+ form .parcours .choices = [str ((p .name , p .description )) for p in edition .parcours ]
94+ ic (form .parcours .data )
95+ if form .validate_on_submit ():
96+ user = User .query .get_or_404 (form .user_id .data )
97+
98+ choices = event .parcours .filter (Parcours .name .in_ ([eval (data )[0 ] for data in form .parcours .data ]),
99+ not_ (Parcours .inscriptions .any (Inscription .user_id == user .id ))).all ()
100+
101+ inscriptions = []
102+ for parcours in choices :
103+ inscriptions .append (Inscription (user_id = user .id ,
104+ event_id = event .id ,
105+ edition_id = edition .id ,
106+ parcours_id = parcours .id ))
107+ db .session .add_all (inscriptions )
108+ db .session .commit ()
109+
110+ flash (_ ('flash.success.newuser:username:name:lastname' ).format (username = user .username , name = user .name , lastname = user .lastname ), 'success' )
111+
112+ return redirect (url_for ('admin.editions.dossard.generate_dossard' , event_name = event_name , edition_name = edition_name ))
113+ else :
114+ return {'ok' :False }
29115
30116@socketio .on ('connect' , namespace = '/dossard' )
31117def dossard_connect (auth ):
@@ -87,3 +173,52 @@ def generate_all_dossard(event_name, edition_name):
87173 db .session .commit ()
88174
89175 return redirect (url_for ("admin.editions.dossard.generate_dossard" , event_name = event .name , edition_name = edition .name ))
176+
177+
178+ # methode for download dossard as excel
179+ @set_route (dossard , '/event/<event_name>/editions/<edition_name>/dossard/download' , methods = ['POST' , 'GET' ])
180+ @login_required
181+ @admin_required
182+ def export_dossard (event_name , edition_name ):
183+ event : Event = Event .query .filter_by (name = event_name ).first_or_404 ()
184+ edition : Edition = event .editions .filter_by (name = edition_name ).first_or_404 ()
185+ user = current_user
186+
187+ buffer = BytesIO ()
188+
189+ workbook = Workbook (buffer )
190+ worksheet = workbook .add_worksheet ()
191+
192+ headers = [_ ('admin.editions.dossard.dossard' ),
193+ _ ('admin.editions.dossard.name' ),
194+ _ ('admin.editions.dossard.lastname' ),
195+ _ ('admin.editions.dossard.email' ),
196+ _ ('admin.editions.dossard.phone' ),
197+ _ ('admin.editions.dossard.datenaiss' ),
198+ _ ('admin.editions.dossard.username' ),
199+ _ ('admin.editions.dossard.parcours' ),
200+ _ ('admin.editions.dossard.edition_date' ),
201+ _ ('admin.editions.dossard.edition_name' ),
202+ _ ('admin.editions.dossard.event_name' )]
203+
204+ row :int
205+ for row , inscription in enumerate (edition .inscriptions .all (), 1 ):
206+ # dossard, name, lastname, email, phone, datenaiss, username, parcours, edition_date, edition_name, event_name
207+ worksheet .write (row , 0 , inscription .dossard )
208+ worksheet .write (row , 1 , inscription .inscrit .name )
209+ worksheet .write (row , 2 , inscription .inscrit .lastname )
210+ worksheet .write (row , 3 , inscription .inscrit .email )
211+ worksheet .write (row , 4 , inscription .inscrit .phone )
212+ worksheet .write (row , 5 , inscription .inscrit .datenaiss )
213+ worksheet .write (row , 6 , inscription .inscrit .username )
214+ worksheet .write (row , 7 , inscription .parcours .name )
215+ worksheet .write (row , 8 , inscription .edition .edition_date )
216+ worksheet .write (row , 9 , inscription .edition .name )
217+ worksheet .write (row , 10 , inscription .event .name )
218+
219+ worksheet .add_table (0 ,0 ,max (edition .inscriptions .count (), 1 ),len (headers )- 1 , {'columns' : [{'header' : h } for h in headers ], 'autofilter' : False })
220+ worksheet .autofit ()
221+ workbook .close ()
222+
223+ buffer .seek (0 )
224+ return send_file (buffer , download_name = 'dossard.xlsx' , as_attachment = True )
0 commit comments