@@ -87,19 +87,18 @@ def build_timeslots(meeting,room=None):
8787 # ScheduledSession.objects.create(schedule=schedule,timeslot=t)
8888 #meeting.create_all_timeslots();
8989
90- def build_nonsession (meeting ):
90+ def build_nonsession (meeting , schedule ):
9191 '''
9292 This function takes a meeting object and creates non-session records
9393 for a new meeting, based on the last meeting
9494 '''
9595 last_meeting = get_last_meeting (meeting )
9696 if not last_meeting :
9797 return None
98-
98+
9999 delta = meeting .date - last_meeting .date
100100 system = Person .objects .get (name = '(system)' )
101- schedule = get_schedule (meeting )
102-
101+
103102 for slot in TimeSlot .objects .filter (meeting = last_meeting ,type__in = ('break' ,'reg' ,'other' ,'plenary' )):
104103 new_time = slot .time + delta
105104 session = None
@@ -122,13 +121,36 @@ def build_nonsession(meeting):
122121 if session :
123122 ScheduledSession .objects .create (schedule = schedule ,session = session ,timeslot = ts )
124123
124+ def check_nonsession (meeting ,schedule ):
125+ '''
126+ Ensure non-session timeslots exist and have appropriate ScheduledSession objects
127+ for the specified schedule.
128+ '''
129+ slots = TimeSlot .objects .filter (meeting = meeting ,type__in = ('break' ,'reg' ,'other' ,'plenary' ))
130+ if not slots :
131+ build_nonsession (meeting ,schedule )
132+ return None
133+
134+ scheduledsessions = slots .filter (type = 'plenary' ).first ().scheduledsession_set .all ()
135+ if not scheduledsessions .filter (schedule = schedule ):
136+ source = scheduledsessions .first ().schedule
137+ copy_scheduledsessions (slots ,source ,schedule )
138+
139+ def copy_scheduledsessions (slots ,source ,target ):
140+ '''
141+ Copy scheduledsession objects from source schedule to target schedule. Slots is
142+ a queryset of slots
143+ '''
144+ for ss in ScheduledSession .objects .filter (schedule = source ,timeslot__in = slots ):
145+ ScheduledSession .objects .create (schedule = target ,session = ss .session ,timeslot = ss .timeslot )
146+
125147def get_last_meeting (meeting ):
126148 last_number = int (meeting .number ) - 1
127149 try :
128150 return Meeting .objects .get (number = last_number )
129151 except Meeting .DoesNotExist :
130152 return None
131-
153+
132154def is_combined (session ,meeting ,schedule = None ):
133155 '''
134156 Check to see if this session is using two combined timeslots
@@ -178,7 +200,7 @@ def send_notifications(meeting, groups, person):
178200 # easier to populate template from timeslot perspective. assuming one-to-one timeslot-session
179201 count = 0
180202 session_info = ''
181- data = [ (s ,get_timeslot (s )) for s in sessions ]
203+ data = [ (s ,get_timeslot (s )) for s in sessions if get_timeslot ( s ) ]
182204 for s ,t in data :
183205 count += 1
184206 session_info += session_info_template .format (group .acronym ,
@@ -205,7 +227,7 @@ def send_notifications(meeting, groups, person):
205227 template ,
206228 context ,
207229 cc = cc_list )
208-
230+
209231 # create sent_notification event
210232 GroupEvent .objects .create (group = group ,time = now ,type = 'sent_notification' ,
211233 by = person ,desc = 'sent scheduled notification for %s' % meeting )
@@ -408,10 +430,8 @@ def non_session(request, meeting_id, schedule_name):
408430 '''
409431 meeting = get_object_or_404 (Meeting , number = meeting_id )
410432 schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
411-
412- # if the Break/Registration records don't exist yet (new meeting) create them
413- if not TimeSlot .objects .filter (meeting = meeting ,type__in = ('break' ,'reg' ,'other' )):
414- build_nonsession (meeting )
433+
434+ check_nonsession (meeting ,schedule )
415435
416436 slots = TimeSlot .objects .filter (meeting = meeting ,type__in = ('break' ,'reg' ,'other' ,'plenary' )).order_by ('-type__name' ,'time' )
417437
@@ -435,7 +455,7 @@ def non_session(request, meeting_id, schedule_name):
435455 time = new_time ,
436456 duration = duration ,
437457 show_location = form .cleaned_data ['show_location' ])
438-
458+
439459 # create a dummy Session object to hold materials
440460 # NOTE: we're setting group to none here, but the set_room page will force user
441461 # to pick a legitimate group
@@ -448,14 +468,14 @@ def non_session(request, meeting_id, schedule_name):
448468 requested_by = Person .objects .get (name = '(system)' ),
449469 status_id = 'sched' )
450470 session .save ()
451-
471+
452472 # create association
453473 ScheduledSession .objects .create (timeslot = timeslot ,
454474 session = session ,
455- schedule = meeting . agenda )
475+ schedule = schedule )
456476
457477 messages .success (request , 'Non-Sessions updated successfully' )
458- return redirect ('meetings_non_session' , meeting_id = meeting_id , schedule_name = schedule . name )
478+ return redirect ('meetings_non_session' , meeting_id = meeting_id , schedule_name = schedule_name )
459479 else :
460480 form = NonSessionForm (initial = {'show_location' :True })
461481
@@ -472,19 +492,22 @@ def non_session(request, meeting_id, schedule_name):
472492
473493def non_session_delete (request , meeting_id , schedule_name , slot_id ):
474494 '''
475- This function deletes the non-session TimeSlot. For "other" and "plenary" timeslot types
476- we need to delete the corresponding Session object as well. Check for uploaded material
477- first.
495+ This function deletes the non-session TimeSlot. For "other" and "plenary" timeslot
496+ types we need to delete the corresponding Session object as well. Check for uploaded
497+ material first. ScheduledSession objects get deleted as well .
478498 '''
499+ meeting = get_object_or_404 (Meeting , number = meeting_id )
500+ schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
479501 slot = get_object_or_404 (TimeSlot , id = slot_id )
480502 if slot .type_id in ('other' ,'plenary' ):
481- session = get_session (slot ,schedule = schedule )
482- if session and session .materials .exclude (states__slug = 'deleted' ):
483- messages .error (request , 'Materials have already been uploaded for "%s". You must delete those before deleting the timeslot.' % slot .name )
484- return redirect ('meetings_non_session' , meeting_id = meeting_id , schedule_name = schedule_name )
485-
503+ scheduledsessions = slot .scheduledsession_set .filter (schedule__meeting = meeting )
504+ session_objects = [ x .session for x in scheduledsessions ]
505+ for session in session_objects :
506+ if session .materials .exclude (states__slug = 'deleted' ):
507+ messages .error (request , 'Materials have already been uploaded for "%s". You must delete those before deleting the timeslot.' % slot .name )
508+ return redirect ('meetings_non_session' , meeting_id = meeting_id , schedule_name = schedule_name )
486509 else :
487- slot . sessions . all ( ).delete ()
510+ Session . objects . filter ( pk__in = [ x . pk for x in session_objects ] ).delete ()
488511 slot .delete ()
489512
490513 messages .success (request , 'Non-Session timeslot deleted successfully' )
@@ -496,6 +519,7 @@ def non_session_edit(request, meeting_id, schedule_name, slot_id):
496519 '''
497520 meeting = get_object_or_404 (Meeting , number = meeting_id )
498521 slot = get_object_or_404 (TimeSlot , id = slot_id )
522+ schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
499523 session = get_session (slot ,schedule = schedule )
500524
501525 if request .method == 'POST' :
@@ -533,6 +557,7 @@ def non_session_edit(request, meeting_id, schedule_name, slot_id):
533557 return render_to_response ('meetings/non_session_edit.html' , {
534558 'meeting' : meeting ,
535559 'form' : form ,
560+ 'schedule' : schedule ,
536561 'slot' : slot },
537562 RequestContext (request , {}),
538563 )
@@ -601,7 +626,7 @@ def rooms(request, meeting_id, schedule_name):
601626 '''
602627 meeting = get_object_or_404 (Meeting , number = meeting_id )
603628 schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
604-
629+
605630 # if no rooms exist yet (new meeting) formset extra=10
606631 first_time = not bool (meeting .room_set .all ())
607632 extra = 10 if first_time else 0
@@ -646,7 +671,7 @@ def schedule(request, meeting_id, schedule_name, acronym):
646671 meeting = get_object_or_404 (Meeting , number = meeting_id )
647672 schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
648673 group = get_object_or_404 (Group , acronym = acronym )
649-
674+
650675 sessions = Session .objects .filter (meeting = meeting ,group = group ,status__in = ('schedw' ,'apprw' ,'appr' ,'sched' ,'canceled' ))
651676 legacy_session = get_initial_session (sessions )
652677 session_conflicts = session_conflicts_as_string (group , meeting )
@@ -759,13 +784,13 @@ def select(request, meeting_id, schedule_name):
759784 '''
760785 meeting = get_object_or_404 (Meeting , number = meeting_id )
761786 schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
762-
787+
763788 return render_to_response ('meetings/select.html' , {
764789 'meeting' : meeting ,
765790 'schedule' : schedule },
766791 RequestContext (request , {}),
767792 )
768-
793+
769794def select_group (request , meeting_id , schedule_name ):
770795 '''
771796 In this view the user can select the group to schedule. Only those groups that have
@@ -775,7 +800,7 @@ def select_group(request, meeting_id, schedule_name):
775800 '''
776801 meeting = get_object_or_404 (Meeting , number = meeting_id )
777802 schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
778-
803+
779804 if request .method == 'POST' :
780805 group = request .POST .get ('group' ,None )
781806 if group :
@@ -882,7 +907,7 @@ def times_edit(request, meeting_id, schedule_name, time):
882907 '''
883908 meeting = get_object_or_404 (Meeting , number = meeting_id )
884909 schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
885-
910+
886911 parts = [ int (x ) for x in time .split (':' ) ]
887912 dtime = datetime .datetime (* parts )
888913 timeslots = TimeSlot .objects .filter (meeting = meeting ,time = dtime )
@@ -898,10 +923,10 @@ def times_edit(request, meeting_id, schedule_name, time):
898923 time = form .cleaned_data ['time' ]
899924 duration = form .cleaned_data ['duration' ]
900925 name = form .cleaned_data ['name' ]
901-
926+
902927 t = meeting .date + datetime .timedelta (days = int (day ))
903928 new_time = datetime .datetime (t .year ,t .month ,t .day ,time .hour ,time .minute )
904-
929+
905930 for timeslot in timeslots :
906931 timeslot .time = new_time
907932 timeslot .duration = duration
@@ -937,7 +962,7 @@ def times_delete(request, meeting_id, schedule_name, time):
937962 '''
938963 meeting = get_object_or_404 (Meeting , number = meeting_id )
939964 schedule = get_object_or_404 (Schedule , meeting = meeting , name = schedule_name )
940-
965+
941966 parts = [ int (x ) for x in time .split (':' ) ]
942967 dtime = datetime .datetime (* parts )
943968
@@ -981,7 +1006,7 @@ def view(request, meeting_id):
9811006
9821007 '''
9831008 meeting = get_object_or_404 (Meeting , number = meeting_id )
984-
1009+
9851010 return render_to_response ('meetings/view.html' , {
9861011 'meeting' : meeting },
9871012 RequestContext (request , {}),
0 commit comments