1111from tuber .api .util import *
1212from .room_matcher import rematch_hotel_block , clear_hotel_block
1313from .uber import export_requests
14+ from .util import paginate
1415import time
1516
1617@app .route ("/api/event/<int:event>/hotel/<int:hotel_block>/room/<int:room_id>/remove_roommates" , methods = ["POST" ])
@@ -128,22 +129,19 @@ def room_details(event):
128129 HotelRoomRequest , HotelRoomRequest .badge == RoomNightAssignment .badge
129130 ).filter (HotelRoom .id .in_ (rooms )).distinct ().options (
130131 selectinload (HotelRoomRequest .roommate_requests ).load_only (
131- Badge .id , Badge .public_name )
132- ).options (
132+ Badge .id , Badge .public_name ),
133133 selectinload (
134- HotelRoomRequest .roommate_anti_requests ).load_only (Badge .id , Badge .public_name )
135- ).options (
134+ HotelRoomRequest .roommate_anti_requests ).load_only (Badge .id , Badge .public_name ),
136135 selectinload (HotelRoomRequest .room_night_requests ).load_only (
137- RoomNightRequest .room_night , RoomNightRequest .requested )
138- ).options (
139- selectinload (HotelRoomRequest .room_night_approvals ).load_only (
140- RoomNightApproval .room_night , RoomNightApproval .approved
141- )
142- ).options (
136+ RoomNightRequest .room_night , RoomNightRequest .requested ),
137+ selectinload (HotelRoom .roommates ).load_only (
138+ Badge .id , Badge .public_name
139+ ).selectinload (Badge .manually_approved_nights ),
143140 selectinload (HotelRoom .roommates ).load_only (
144- Badge .id , Badge .public_name )
141+ Badge .id , Badge .public_name
142+ ).selectinload (Badge .shift_overlap_nights ),
145143 ).all ()
146-
144+
147145 for hotel_room , request in hotel_rooms :
148146 if not hotel_room .id in gender_prefs :
149147 gender_prefs [hotel_room .id ] = set ()
@@ -165,11 +163,10 @@ def room_details(event):
165163 nights = set ()
166164 for night_request in request .room_night_requests :
167165 if night_request .requested :
168- #if room_nights[night_request.room_night].restricted:
169- # for approval in request.room_night_approvals:
170- # if approval.room_night == night_request.room_night and approval.approved:
171- # nights.add(night_request.room_night)
172- #else:
166+ approved_nights = set ()
167+ for roommate in hotel_room .roommates :
168+ approved_nights .update ([x .id for x in roommate .approved_hotel_nights ])
169+ if night_request .room_night in approved_nights :
173170 nights .add (night_request .room_night )
174171 assigned_nights = [x .room_night for x in rnas_by_badge [request .badge ]]
175172 missing_nights = nights .difference (set (assigned_nights ))
@@ -219,21 +216,18 @@ def matching_roommates(event):
219216
220217 badges = db .query (Badge ).join (HotelRoomRequest , HotelRoomRequest .badge == Badge .id ).filter (
221218 or_ (HotelRoomRequest .declined == False , HotelRoomRequest .declined == None )
222- ).filter (Badge .event == event , Badge .search_name .contains (g .data .get ('search' , "" ).lower ())).order_by (Badge .public_name ).limit (20 ).all ()
219+ ).filter (Badge .event == event , Badge .search_name .contains (g .data .get ('search' , "" ).lower ())
220+ ).options (selectinload (Badge .shift_overlap_nights ), selectinload (Badge .manually_approved_nights )
221+ ).order_by (Badge .public_name ).limit (20 ).all ()
223222
224223 results = []
225224 for badge in badges :
226225 missing = []
226+ approved_nights = badge .approved_hotel_nights
227227 for night in badge .room_night_requests :
228228 assign = False
229- if night .requested :
230- #if room_nights[night.room_night].restricted:
231- # for approval in badge.room_night_approvals:
232- # if approval.room_night == night.room_night and approval.approved:
233- # assign = True
234- # break
235- #else:
236- assign = True
229+ if night .requested and night .room_night in [x .id for x in approved_nights ]:
230+ assign = True
237231 for assignment in badge .room_night_assignments :
238232 if assignment .room_night == night .room_night :
239233 assign = False
@@ -265,11 +259,46 @@ def room_search(event):
265259 return jsonify (hotel_rooms = HotelRoom .serialize (rooms , serialize_relationships = True ), count = count ), 200
266260
267261
262+ @app .route ("/api/event/<int:event>/hotel/list_requests" , methods = ["GET" ])
263+ def list_requests (event ):
264+ if not check_permission ("hotel_block.*.read" ):
265+ return "" , 403
266+
267+ query = db .query (HotelRoomRequest )
268+ if "hotel_block" in g .data :
269+ query = query .filter (HotelRoomRequest .hotel_block == int (g .data ['hotel_block' ]))
270+ query = query .options (
271+ selectinload (HotelRoomRequest .badge_obj , Badge .manually_approved_nights ),
272+ selectinload (HotelRoomRequest .badge_obj , Badge .shift_overlap_nights )
273+ )
274+
275+ query = paginate (query , HotelRoomRequest , event )
276+
277+ if request .args .get ("count" , False , type = lambda x : x .lower () == "true" ):
278+ return json .dumps (query .count ()), 200
279+ requests = query .all ()
280+
281+ room_nights = db .query (HotelRoomNight ).filter (HotelRoomNight .event == event ).all ()
282+
283+ return [
284+ {
285+ "first_name" : x .badge_obj .first_name ,
286+ "last_name" : x .badge_obj .last_name ,
287+ "notes" : x .notes ,
288+ "id" : x .id ,
289+ "approved_nights" : {y .id : y in x .badge_obj .approved_hotel_nights for y in room_nights },
290+ "requested_nights" : {z .id : z .id in [y .room_night for y in x .room_night_requests if y .requested ] for z in room_nights }
291+ } for x in requests
292+ ]
293+
294+
268295@app .route ("/api/event/<int:event>/hotel/<int:hotel_block>/request_search" , methods = ["GET" ])
269296def request_search (event , hotel_block ):
270297 if not check_permission ("hotel_block.*.read" ):
271298 return "" , 403
272299
300+ room_nights = db .query (HotelRoomNight ).filter (HotelRoomNight .event == event ).all ()
301+
273302 assigned_nights = db .query (RoomNightRequest .id ).filter (RoomNightRequest .requested ).join (
274303 RoomNightAssignment , and_ (RoomNightAssignment .badge == RoomNightRequest .badge ,
275304 RoomNightAssignment .room_night == RoomNightRequest .room_night )
@@ -280,7 +309,10 @@ def request_search(event, hotel_block):
280309 HotelRoomRequest .hotel_block == hotel_block ,
281310 or_ (HotelRoomRequest .declined == False , HotelRoomRequest .declined == None ),
282311 HotelRoomRequest .room_night_requests .any (and_ (RoomNightRequest .requested , not_ (RoomNightRequest .id .in_ (assigned_nights ))))
283- ).join (Badge , Badge .id == HotelRoomRequest .badge )
312+ ).join (Badge , Badge .id == HotelRoomRequest .badge ).options (
313+ selectinload (HotelRoomRequest .badge_obj , Badge .shift_overlap_nights ),
314+ selectinload (HotelRoomRequest .badge_obj , Badge .manually_approved_nights )
315+ )
284316 if g .data ['search_term' ]:
285317 reqs = reqs .filter (
286318 or_ (Badge .search_name .contains (g .data ['search_term' ].lower ()), func .lower (
@@ -295,7 +327,18 @@ def request_search(event, hotel_block):
295327 if g .data ['order' ] == "desc" :
296328 sort = sort .desc ()
297329 reqs = reqs .order_by (sort ).offset (int (g .data ['offset' ])).limit (int (g .data ['limit' ])).all ()
298- return jsonify (requests = HotelRoomRequest .serialize (reqs , serialize_relationships = True , deep = True ), count = count ), 200
330+
331+ results = [{
332+ "id" : req .id ,
333+ "approved_nights" : {x .id : x in req .badge_obj .approved_hotel_nights for x in room_nights },
334+ "requested_nights" : {x .id : x .id in [y .room_night for y in req .room_night_requests if y .requested ] for x in room_nights },
335+ "notes" : req .notes ,
336+ "first_name" : req .first_name ,
337+ "last_name" : req .last_name ,
338+ "public_name" : req .badge_obj .public_name ,
339+ "badge" : req .badge ,
340+ } for req in reqs ]
341+ return jsonify (requests = results , count = count ), 200
299342
300343
301344@app .route ("/api/event/<int:event>/hotel/submitted_requests" , methods = ["GET" ])
@@ -382,7 +425,7 @@ def block_assignments(event):
382425@app .route ("/api/event/<int:event>/hotel/requests/<int:department>" , methods = ["GET" ])
383426def hotel_requests (event , department ):
384427 requests = db .query (Badge , HotelRoomRequest ).join (BadgeToDepartment , BadgeToDepartment .badge == Badge .id ).filter (
385- BadgeToDepartment .department == department ).join (HotelRoomRequest , HotelRoomRequest .badge == BadgeToDepartment .badge ).all ()
428+ BadgeToDepartment .department == department ).join (HotelRoomRequest , HotelRoomRequest .badge == BadgeToDepartment .badge ).options ( selectinload ( Badge . manually_approved_nights ), selectinload ( Badge . shift_overlap_nights )). all ()
386429 res = []
387430 for req in requests :
388431 badge , roomrequest = req
@@ -399,6 +442,8 @@ def hotel_requests(event, department):
399442 "id" : btr .id ,
400443 "requested" : btr .requested ,
401444 "room_night" : btr .room_night ,
445+ "approved_by_anyone" : btr .room_night in [x .id for x in badge .manually_approved_nights ],
446+ "approved_by_shifts" : btr .room_night in [x .id for x in badge .shift_overlap_nights ],
402447 "approved" : rna .approved if rna else None
403448 } for btr , rna in room_nights }
404449 })
@@ -410,20 +455,20 @@ def hotel_requests(event, department):
410455def hotel_approve (event , department ):
411456 if check_permission ("hotel_request.*.approve" , event = event , department = department ):
412457 room_night_request = db .query (RoomNightRequest ).filter (
413- RoomNightRequest .room_night == request .json ['room_night' ], RoomNightRequest .badge == request .json ['badge' ]).one_or_none ()
458+ RoomNightRequest .room_night == int ( request .json ['room_night' ]) , RoomNightRequest .badge == int ( request .json ['badge' ]) ).one_or_none ()
414459 if not room_night_request :
415460 return "Could not find corresponding request." , 404
416461 approval = db .query (RoomNightApproval ).filter (RoomNightApproval .badge ==
417- request .json ['badge' ], RoomNightApproval .room_night == request .json ['room_night' ], RoomNightApproval .department == department ).one_or_none ()
462+ int ( request .json ['badge' ]) , RoomNightApproval .room_night == int ( request .json ['room_night' ]) , RoomNightApproval .department == department ).one_or_none ()
418463 if request .json ['approved' ] is None :
419464 if approval :
420465 db .delete (approval )
421466 else :
422467 if not approval :
423468 approval = RoomNightApproval (
424- event = event , badge = request .json ['badge' ], department = department )
469+ event = event , badge = int ( request .json ['badge' ]) , department = department )
425470 approval .approved = request .json ['approved' ]
426- approval .room_night = request .json ['room_night' ]
471+ approval .room_night = int ( request .json ['room_night' ])
427472 db .add (approval )
428473 hotel_room_request = db .query (HotelRoomRequest ).filter (
429474 HotelRoomRequest .badge == room_night_request .badge ).one ()
0 commit comments