class ScheduleTests( TestCase ): """Tests schedules.models.Schedule""" def setUp( self ): self.pattern = Template.objects.create( name="Some template" ) self.begin, self.finish = datetime.now(), datetime.now() self.sched = Schedule( template=self.pattern, start=self.begin, end=self.finish ) def test_overridden_unicode( self ): """Ensures the schedule unicode is not default""" self.assertNotEqual( str( self.sched ), 'Schedule object' ) def test_template_missing_invalid( self ): """Tests that a Schedule with no template is invalid""" with self.assertRaises( ValueError ): self.sched.template = None def test_start_missing_invalid( self ): """Tests that a Schedule with no start time is invalid""" self.sched.start = None with self.assertRaises( ValidationError ): self.sched.full_clean() def test_end_missing_invalid( self ): """Tests that a Schedule with no end time is invalid""" self.sched.end = None with self.assertRaises( ValidationError ): self.sched.full_clean()
def test_next_occurrence(): """Should have accurately date and time for the next event in the schedule.""" schedule_start = timezone.now() schedule_every = timedelta(hours=1) schedule = Schedule(start=schedule_start, every=schedule_every) expected = schedule_start + schedule_every assert schedule.next_occurrence() == expected
def test_frequency_greater_than_end_date_raises_validation_error(self): s1 = Schedule(content="placeholder", frequency=timedelta(days=5), end_date=default_date_time(), start_date=default_date_time(days=1)) with self.assertRaises(ValidationError): s1.full_clean()
def test_duplicate_schedule_is_invalid(self): start_date = default_date_time() end_date = default_date_time(days=1) s1 = Schedule.objects.create(start_date=start_date, end_date=end_date) with self.assertRaises(ValidationError): s2 = Schedule(start_date=start_date, end_date=end_date) s2.full_clean()
def mutate(self, info, startTime, endTime, location, emp, date): loc = get_object_or_404(Location, id=location) ep = get_object_or_404(Emp, id=emp) if startTime is not 0: schedule = Schedule(start_time=startTime, end_time=endTime, location=loc, emp=ep, date=date) schedule.save() return CreateSchedule(schedule=schedule)
def add_schedule(task, start, finish, name, description, owner, squads): print("Adding schedule: task={}, name={} ".format(task, name)) print(" squads:", ", ".join(('"{}"'.format(r) for r in squads))) schedule = Schedule( task=task, start=start, finish=finish, name=name, description=description, owner=owner, ) schedule.save() schedule.squads.add(*squads) return schedule
def _create_schedules(self): schedule_file = open(SCHEDULE_FILE) event_file = open(EVENT_FILE) current_term = Term.current_term() schedule_categories = {} for row in csv.DictReader(schedule_file): if Schedule.objects.filter(name=row['name'], comments=row['comments']).exists(): continue start_date = datetime.strptime(row['startDate'], "%Y-%m-%d").date() end_date = datetime.strptime(row['endDate'], "%Y-%m-%d").date() start_week = current_term.term_week_of_date(start_date) end_week = current_term.term_week_of_date(end_date) weeks = ','.join([str(w) for w in range(start_week, end_week + 1)]) schedule_categories[row['ID']] = row['category'] s = Schedule(id=row['ID'], name=row['name'], comments=row['comments'], season='All', weeks=weeks, import_to_next_term=True, term=current_term, priority=int(row['priority'])) s.save() for row in csv.DictReader(event_file): if not row['name'] and not row['code']: # don't import exceptions continue if not Schedule.objects.filter(id=row['scheduleID']): continue schedule = Schedule.objects.get(id=row['scheduleID']) event_type = schedule_categories[ row['scheduleID']][0] if schedule_categories[ row['scheduleID']] in ROLL_TYPES else '*' event = Event(weekday=int(row['weekDayID']) - 1, name=row['name'], code=row['code'], start=row['startTime'], end=row['endTime'], type=event_type) event.save() schedule.events.add(event)
def test_stop_date_cannot_be_before_start_date(self): s1 = Schedule() s1.start_date = default_date_time() s1.end_date = s1.start_date - timedelta(days=5) # should raise error with self.assertRaises(ValidationError): s1.full_clean()
def get_context_data(self, **kwargs): ctx = super(TableRollsView, self).get_context_data(**kwargs) selected_date = kwargs['selected_date'] if 'selected_date' in kwargs.keys() else date.today() current_week = CURRENT_TERM.term_week_of_date(selected_date) start_date = CURRENT_TERM.startdate_of_week(current_week) end_date = CURRENT_TERM.enddate_of_week(current_week) event_type = kwargs['event_type'] trainees = kwargs['trainees'] monitor = kwargs['monitor'] event_list, trainee_evt_list = Schedule.get_roll_table_by_type_in_weeks(trainees, monitor, [current_week, ], event_type) rolls = Roll.objects.filter(event__in=event_list, date__gte=start_date, date__lte=end_date).exclude(status='P').select_related('trainee', 'event') roll_dict = OrderedDict() # Populate roll_dict from roll object for look up for building roll table for roll in rolls: r = roll_dict.setdefault(roll.trainee, OrderedDict()) r[(roll.event, roll.date)] = roll # Add roll to each event from roll table for trainee in roll_dict: # Only update if trainee predefined if trainee in trainee_evt_list: evt_list = trainee_evt_list[trainee] if len(evt_list) <= 0: # delete empty column if all blocked out del trainee_evt_list[trainee] else: for i in range(0, len(evt_list)): ev = copy(evt_list[i]) d = ev.start_datetime.date() # Add roll if roll exists for trainee if trainee in roll_dict and (ev, d) in roll_dict[trainee]: ev.roll = roll_dict[trainee][(ev, d)] evt_list[i] = ev ctx['event_type'] = event_type ctx['start_date'] = start_date ctx['term_start_date'] = CURRENT_TERM.start.strftime('%Y%m%d') ctx['current_week'] = current_week ctx['trainees'] = trainees ctx['trainees_event_list'] = trainee_evt_list ctx['event_list'] = event_list ctx['week'] = CURRENT_TERM.term_week_of_date(date.today()) return ctx
def test_add_to_schedule_model(self): r1 = Recipient(email_address="*****@*****.**", name="test1") r2 = Recipient(email_address="*****@*****.**", name="test2") r3 = Recipient.objects.create(email_address="*****@*****.**", name="test3") r1.save() r2.save() s1 = Schedule(subject="test", content="test", frequency=timedelta()) s1.save() s1.recipients.add(r1, r2) s2 = Schedule(subject="test", content="test", frequency=timedelta(hours=1)) s2.save() s2.recipients.add(r1, r2) self.assertEqual([r1, r2], list(s1.recipients.all())) self.assertEqual([r1, r2], list(s2.recipients.all())) self.assertNotEqual([r1, r3], list(s1.recipients.all()))
def test_delete_schedule_cascades_to_map_table(self): s1 = Schedule(content="placeholder 1") s2 = Schedule(content="placeholder 2") r1 = Recipient.objects.create(email_address="*****@*****.**") r2 = Recipient.objects.create(email_address="*****@*****.**") r3 = Recipient.objects.create(email_address="*****@*****.**") s1.save() s2.save() s1.recipients.add(r1, r2) s2.recipients.add(r2, r3) self.assertEqual(r2.schedule_set.count(), 2) s1.delete() self.assertEqual(r2.schedule_set.count(), 1) s2.delete() self.assertEqual(r2.schedule_set.count(), 0) self.assertEqual(Recipient.objects.count(), 3)
def test_save_method_performs_validation(self): s1 = Schedule() s1.start_date = default_date_time(days=2, subtract=True) with self.assertRaises(ValidationError): s1.save()
def test_start_date_cannot_be_before_now(self): s1 = Schedule() s1.start_date = default_date_time(days=5, subtract=True) # should raise error with self.assertRaises(ValidationError): s1.full_clean()
def setUp( self ): self.pattern = Template.objects.create( name="Some template" ) self.begin, self.finish = datetime.now(), datetime.now() self.sched = Schedule( template=self.pattern, start=self.begin, end=self.finish )
def test_default_schedule_is_valid(self): s1 = Schedule() s1.full_clean() s1.save()
def test_default_schedule_values_are_assigned(self): s1 = Schedule() self.assertEqual(s1.content, '') self.assertEqual(s1.frequency, timedelta())
def test_iterator(): """Should use schedule iterator.""" schedule = Schedule() assert isinstance(iter(schedule), ScheduleIterator)
def get_context_data(self, **kwargs): lJRender = JSONRenderer().render ctx = super(RollsView, self).get_context_data(**kwargs) user = self.request.user trainee = trainee_from_user(user) if self.request.method == 'POST': selected_week = self.request.POST.get('week') event_id = self.request.POST.get('events') event = Event.objects.get(id=event_id) selected_date = event.date_for_week(int(selected_week)) event.date = selected_date event.start_datetime = datetime.combine(event.date, event.start) event.end_datetime = datetime.combine(event.date, event.end) else: selected_date = date.today() selected_week = Event.week_from_date(selected_date) # try; events = trainee.immediate_upcoming_event(with_seating_chart=True) # TODO: - if trainee has no current event load other class that is occuring at the same time if len(events) > 0: event = events[0] else: event = None selected_week = int(selected_week) if event: chart = Chart.objects.filter(event=event).first() if chart: seats = Seat.objects.filter( chart=chart).select_related('trainee') partial = Partial.objects.filter( chart=chart).order_by('section_name') # Get roll with with for current event and today's date roll = Roll.objects.filter(event=event, date=selected_date) # TODO - Add group leave slips individualslips = IndividualSlip.objects.filter(rolls__in=roll, status='A') trainees = Trainee.objects.filter(schedules__events=event) schedules = Schedule.get_all_schedules_in_weeks_for_trainees([ selected_week, ], trainees) w_tb = EventUtils.collapse_priority_event_trainee_table([ selected_week, ], schedules, trainees) t_set = EventUtils.get_trainees_attending_event_in_week( w_tb, event, selected_week) for s in seats: if s.trainee in t_set: s.attending = True else: s.attending = False start_datetime = datetime.combine(selected_date, event.start) end_datetime = datetime.combine(selected_date, event.end) group_slip = GroupSlip.objects.filter( end__gte=start_datetime, start__lte=end_datetime, status='A').prefetch_related('trainees') print group_slip, start_datetime, end_datetime trainee_groupslip = set() for gs in group_slip: trainee_groupslip = trainee_groupslip | set( gs.trainees.all()) ctx['event'] = event ctx['event_bb'] = lJRender(EventWithDateSerializer(event).data) ctx['attendance_bb'] = lJRender( RollSerializer(roll, many=True).data) ctx['individualslips_bb'] = lJRender( IndividualSlipSerializer(individualslips, many=True).data) ctx['trainee_groupslip_bb'] = lJRender( TraineeRollSerializer(trainee_groupslip, many=True).data) ctx['trainees_bb'] = lJRender( TraineeRollSerializer(trainees, many=True).data) ctx['chart'] = chart ctx['chart_bb'] = lJRender( ChartSerializer(chart, many=False).data) ctx['seats'] = seats ctx['seats_bb'] = lJRender( SeatSerializer(seats, many=True).data) ctx['partial'] = partial ctx['partial_bb'] = lJRender( PartialSerializer(partial, many=True).data) ctx['weekdays'] = WEEKDAYS ctx['date'] = selected_date ctx['week'] = selected_week ctx['day'] = selected_date.weekday() # ctx['leaveslips'] = chain(list(IndividualSlip.objects.filter(trainee=self.request.user.trainee).filter(events__term=CURRENT_TERM)), list(GroupSlip.objects.filter(trainee=self.request.user.trainee).filter(start__gte=CURRENT_TERM.start).filter(end__lte=CURRENT_TERM.end))) return ctx
subjects = [ Subject(name=row['Name'], hours_per_week=row['Hours At Week'], keycode=row['Keycode']) for index, row in tmp_data.iterrows() ] Subject.objects.bulk_create(subjects) # para importar los datos de los horarios tmp_data = pd.read_csv('Horarios/schedules/sch.csv', header=[0], sep=',') schedules = [ Schedule(monday=row['Monday'], tuesday=row['Tuesday'], wednesday=row['Wednesday'], thursday=row['Thursday'], friday=row['Friday'], saturday=row['Saturday']) for index, row in tmp_data.iterrows() ] Schedule.objects.bulk_create(schedules) # Bloque de Career_Subject tmp_sistemas = pd.read_csv('Horarios/subjects/s_slisc.csv', header=[0], sep=',') tmp_artes = pd.read_csv('Horarios/subjects/s_slad.csv', header=[0], sep=',') carreras = Career.objects.all() materias = Subject.objects.all() # Bloque de Career_Subject
def _create_schedule(self): # Generic Schedule group_s = Schedule(name='Generic Group Events', season='All', term=Term.current_term(), priority=1, trainee_select='GP', import_to_next_term=True) group_s.comments = "Use for group leaveslips" group_s.save() group_s.events = Event.objects.filter(Q(type='H') | Q(type='M')) events = [ "SESS1", "SESS2", "CP Work", "YPCW", "GTF", "Study", "LANG/CHAR" ] for e in events: es = Event.objects.filter(code=e) group_s.events.add(*es) group_s.trainees = Trainee.objects.all() group_s.save() # all trainees main_s = Schedule(name='Main', season='All', term=Term.current_term(), priority=2, import_to_next_term=True) main_s.save() main_s.events = Event.objects.filter( Q(type='H') | Q(type='M') | Q(class_type='MAIN')) main_s.events.add(*Event.objects.filter(code='LANG/CHAR')) main_s.trainees = Trainee.objects.all() main_s.save() # 1st year oneyear_s = Schedule(name='1st Year', season='All', trainee_select='FY', term=Term.current_term(), priority=2, import_to_next_term=True) oneyear_s.save() oneyear_s.events = Event.objects.filter(class_type='1YR') oneyear_s.trainees = Trainee.objects.filter(current_term__lte=2) oneyear_s.save() # 2nd year twoyear_s = Schedule(name='2nd Year', season='All', trainee_select='SY', term=Term.current_term(), priority=2, import_to_next_term=True) twoyear_s.save() twoyear_s.events = Event.objects.filter(class_type='2YR') twoyear_s.trainees = Trainee.objects.filter(current_term__gte=3) twoyear_s.save() for team in Team.objects.all(): schedule = Schedule(name=team.name, season='All', term=Term.current_term(), priority=3, import_to_next_term=True, trainee_select='TE', team_roll=team) schedule.save() schedule.events = Event.objects.filter(monitor='TM') schedule.trainees = Trainee.objects.filter(team=team) schedule.save() campus_generic = Schedule(name='Generic Campus', season='All', term=Term.current_term(), priority=4) campus_generic.save() campus_generic.events = Event.objects.filter(monitor='TM') campus_generic.trainees = Trainee.objects.filter(team__type='CAMPUS') campus_generic.save()
def assign_trainees_to_schedule(schedule): """ This function is used in apimport.utils.import_csv. This function handles new term (no split necessary) and mid term imports (splitting) For new term: - A new term must be created before the term begins. (see. apimport.utils.create_term) - New schedules must be generated or imported from previous terms (see apimport.utils.migrate_schedules) - The new schedules MUST have a queryfilter, even if a schedules should include all trainees. For mid term: - Current schedules do not need to be touched. - The import_csv will change trainee filelds (i.e teams, year, etc.) based on the import file. - The current schedules will assign trainees based on its query filter. - Splitting will based on week this function is called (i.e now) """ if schedule.is_locked: return new_set = schedule._get_qf_trainees() current_set = schedule.trainees.all() # If the schedules are identical, bail early to_add = new_set.exclude(pk__in=current_set) to_delete = current_set.exclude(pk__in=new_set) if not to_add and not to_delete: return # Does the schedule need to be split? term = Term.current_term() if term is None or datetime.now().date() > term.end: return if datetime.now().date() < term.start: week = -1 else: week = term.term_week_of_date(datetime.today().date()) weeks_set = set(eval(schedule.weeks)) if len(set(range(0, week + 1)).intersection(weeks_set)) > 0: # Splitting s1 = Schedule(name=schedule.name, comments=schedule.comments, priority=schedule.priority, season=schedule.season, term=term) s2 = Schedule(name=schedule.name, comments=schedule.comments, priority=schedule.priority, season=schedule.season, term=term) if schedule.parent_schedule: s1.parent_schedule = schedule.parent_schedule s2.parent_schedule = schedule.parent_schedule else: s1.parent_schedule = schedule s2.parent_schedule = schedule sched_weeks = [int(x) for x in schedule.weeks.split(',')] s1_weeks = [] s2_weeks = [] for x in sched_weeks: if x <= week: s1_weeks.append(x) else: s2_weeks.append(x) s1.weeks = ','.join(map(str, s1_weeks)) s2.weeks = ','.join(map(str, s1_weeks)) s1.is_locked = True # only the most recent needs a query_filter. Older ones don't need it. s2.query_filter = schedule.query_filter s1.save() s2.save() s1.trainees = current_set s2.trainees = new_set s1.save() s2.save() schedule.trainees = [] schedule.is_locked = True schedule.save() else: # No split necessary schedule.trainees = new_set schedule.save()