def fill_humor_shifts(humor_hours=2, semester=None): if semester is None: semester = _get_semester() # Humor Shift humor_pool, created = WorkshiftPool.objects.get_or_create( title="Humor Shift", semester=semester, defaults=dict(any_blown=True, hours=humor_hours, weeks_per_period=6), ) if created: humor_pool.managers = Manager.objects.filter(workshift_manager=True) humor_pool.save() make_workshift_pool_hours(semester, pools=[humor_pool]) # Humor Workshifts for type_title, hours, days, start, end in HUMOR_WORKSHIFTS: wtype = WorkshiftType.objects.get(title=type_title) for day in days: RegularWorkshift.objects.get_or_create( workshift_type=wtype, pool=humor_pool, day=day, defaults=dict( start_time=start, end_time=end, hours=hours, ), )
def create_workshift_profile(sender, instance, created, **kwargs): ''' Function to add a workshift profile for every User that is created. Parameters: instance is an of UserProfile that was just saved. ''' if instance.user.username == ANONYMOUS_USERNAME or \ instance.status != UserProfile.RESIDENT: return try: semester = Semester.objects.get(current=True) except (Semester.DoesNotExist, Semester.MultipleObjectsReturned): pass else: from workshift import utils profile, created = WorkshiftProfile.objects.get_or_create( user=instance.user, semester=semester, ) if created: utils.make_workshift_pool_hours( semester=semester, profiles=[profile], )
def save(self, semester): if self.cleaned_data['copy_pool']: pool = super(StartPoolForm, self).save(commit=False) pool.semester = semester pool.save() utils.make_workshift_pool_hours(pool.semester, pools=[pool])
def save(self): if self.cleaned_data["add_profile"]: profile = WorkshiftProfile.objects.create(user=self.user, semester=self.semester) utils.make_workshift_pool_hours(self.semester, profiles=[profile], primary_hours=self.cleaned_data["hours"]) return profile
def save(self): semester = super(SemesterForm, self).save() # Set current to false for previous semesters for semester in Semester.objects.all(): semester.current = False semester.save() semester.workshift_managers = \ [i.incumbent.user for i in Manager.objects.filter(workshift_manager=True)] semester.current = True semester.preferences_open = True semester.save() # Create the primary workshift pool pool = WorkshiftPool.objects.create( semester=semester, is_primary=True, ) pool.managers = Manager.objects.filter(workshift_manager=True) pool.save() # Create this semester's workshift profiles for uprofile in UserProfile.objects.filter(status=UserProfile.RESIDENT): if uprofile.user.username == ANONYMOUS_USERNAME: continue WorkshiftProfile.objects.create( user=uprofile.user, semester=semester, ) utils.make_workshift_pool_hours(semester=semester) utils.make_manager_workshifts(semester=pool.semester) return semester
def save(self, semester): if self.cleaned_data["copy_pool"]: pool = super(StartPoolForm, self).save(commit=False) pool.semester = semester pool.save() utils.make_workshift_pool_hours(pool.semester, pools=[pool])
def initialize_semester(sender, instance, created, **kwargs): if not created: return semester = instance semester.workshift_managers = [i.incumbent.user for i in Manager.objects.filter(workshift_manager=True)] semester.preferences_open = True semester.save(update_fields=["preferences_open"]) # Set current to false for previous semesters for prev_semester in Semester.objects.exclude(pk=semester.pk): prev_semester.current = False prev_semester.save(update_fields=["current"]) # Create the primary workshift pool pool, created = WorkshiftPool.objects.get_or_create(semester=semester, is_primary=True) if created: pool.managers = Manager.objects.filter(workshift_manager=True) # Create this semester's workshift profiles for uprofile in UserProfile.objects.filter(status=UserProfile.RESIDENT).exclude(user__username=ANONYMOUS_USERNAME): WorkshiftProfile.objects.create(user=uprofile.user, semester=semester) utils.make_workshift_pool_hours(semester=semester) utils.make_manager_workshifts(semester=semester)
def create_workshift_pool_hours(sender, instance, **kwargs): pool = instance from workshift import utils utils.make_workshift_pool_hours( semester=pool.semester, pools=[pool], ) utils.make_manager_workshifts(semester=pool.semester, )
def fill_regular_shifts(regular_hours=5, semester=None): if semester is None: semester = _get_semester() _fill_workshift_types() # Regular Weekly Workshift Hours pool, created = WorkshiftPool.objects.get_or_create( semester=semester, is_primary=True, defaults=dict(hours=regular_hours, any_blown=True), ) if created: pool.managers = Manager.objects.filter(workshift_manager=True) pool.save() make_workshift_pool_hours(semester, pools=[pool]) # Regular Workshifts for type_title, hours, days, count, start, end in REGULAR_WORKSHIFTS: wtype = WorkshiftType.objects.get(title=type_title) for day in days: RegularWorkshift.objects.get_or_create( workshift_type=wtype, pool=pool, day=day, start_time=start, end_time=end, defaults=dict( count=count, hours=hours, ), ) for type_title, hours, count in WEEK_LONG: wtype = WorkshiftType.objects.get(title=type_title) RegularWorkshift.objects.get_or_create( workshift_type=wtype, pool=pool, count=count, week_long=True, defaults=dict( start_time=None, end_time=None, hours=hours, ), ) make_instances(semester=semester) make_manager_workshifts(semester)
def save(self): if self.cleaned_data['add_profile']: profile = WorkshiftProfile.objects.create( user=self.user, semester=self.semester, ) utils.make_workshift_pool_hours( self.semester, profiles=[profile], primary_hours=self.cleaned_data["hours"], ) return profile
def test_make_pool_hours_primary(self): PoolHours.objects.all().delete() utils.make_workshift_pool_hours( semester=self.semester, primary_hours=6, ) self.assertEqual( 6, PoolHours.objects.get(pool=self.p1).hours, ) self.assertEqual( self.p2.hours, PoolHours.objects.get(pool=self.p2).hours, )
def fill_hi_shifts(hi_hours=5, semester=None): if semester is None: semester = _get_semester() # HI Hours hi_pool, created = WorkshiftPool.objects.get_or_create( title="Home Improvement", semester=semester, defaults=dict(hours=hi_hours, weeks_per_period=0), ) if created: hi_pool.managers = Manager.objects.filter(title="Maintenance Manager") hi_pool.save() make_workshift_pool_hours(semester, pools=[hi_pool])
def test_make_pool_hours_pools(self): PoolHours.objects.all().delete() utils.make_workshift_pool_hours( semester=self.semester, pools=[self.p1], ) self.assertEqual(1, PoolHours.objects.count()) self.assertEqual(1, self.profile.pool_hours.count()) utils.make_workshift_pool_hours( semester=self.semester, pools=[self.p2], ) self.assertEqual(2, PoolHours.objects.count()) self.assertEqual(2, self.profile.pool_hours.count())
def fill_social_shifts(social_hours=1, semester=None): if semester is None: semester = _get_semester() # Social Hours social_pool, created = WorkshiftPool.objects.get_or_create( title="Social", semester=semester, defaults=dict(hours=social_hours, weeks_per_period=0), ) if created: social_pool.managers = Manager.objects.filter(title="Social Manager") social_pool.save() make_workshift_pool_hours(semester, pools=[social_pool])
def save(self): prev_pool = self.instance new = prev_pool.pk is None pool = super(PoolForm, self).save(commit=False) if self.semester: pool.semester = self.semester pool.save() self.save_m2m() if not new: for pool_hours in PoolHours.objects.filter(pool=pool): if pool_hours.hours == prev_pool.hours: pool_hours.hours = pool.hours pool_hours.save() else: utils.make_workshift_pool_hours(self.semester, pools=[pool]) return pool
def create_workshift_profile(sender, instance, created, **kwargs): """ Function to add a workshift profile for every User that is created. Parameters: instance is an of UserProfile that was just saved. """ if instance.user.username == ANONYMOUS_USERNAME or instance.status != UserProfile.RESIDENT: return try: semester = Semester.objects.get(current=True) except (Semester.DoesNotExist, Semester.MultipleObjectsReturned): pass else: profile, created = WorkshiftProfile.objects.get_or_create(user=instance.user, semester=semester) if created: utils.make_workshift_pool_hours(semester=semester, profiles=[profile])
def save(self): prev_pool = self.instance new = prev_pool.pk is None pool = super(PoolForm, self).save(commit=False) if self.semester: pool.semester = self.semester pool.save() self.save_m2m() if not new: for pool_hours in PoolHours.objects.filter(pool=pool): if pool_hours.hours == prev_pool.hours: pool_hours.hours = pool.hours pool_hours.save() else: utils.make_workshift_pool_hours(self.semester, pools=[pool]) return pool
def test_pre_fill_and_assign(self): """ Tests that shifts can be correctly assigned after farnsworth/pre_fill.py is run. This is a good test of how the assignment code functions "in the wild," rather than with many duplicates of the same shift. """ users = [] for i in range(1, 50): users.append(User.objects.create_user(username="******".format(i))) pre_fill.main(["--managers", "--workshift"]) utils.make_workshift_pool_hours(semester=self.semester) # Assign manager shifts beforehand for user, manager in zip(users, Manager.objects.all()): manager.incumbent = UserProfile.objects.get(user=user) manager.save() unfinished = utils.auto_assign_shifts(self.semester) self.assertEqual([], unfinished)
def setUp(self): self.u = User.objects.create_user(username="******") today = localtime(now()).date() self.semester = Semester.objects.create( year=today.year, start_date=today, end_date=today + timedelta(days=6), ) self.profile = WorkshiftProfile.objects.get( user=self.u, semester=self.semester, ) self.p1 = WorkshiftPool.objects.get( is_primary=True, semester=self.semester, ) self.p2 = WorkshiftPool.objects.create( title="Alternate Workshift", semester=self.semester, ) self.wtype1 = WorkshiftType.objects.create( title="Like Type", ) self.wtype2 = WorkshiftType.objects.create( title="Indifferent Type", ) self.wtype3 = WorkshiftType.objects.create( title="Dislike Type", ) preference1 = WorkshiftRating.objects.create( rating=WorkshiftRating.LIKE, workshift_type=self.wtype1, ) preference2 = WorkshiftRating.objects.create( rating=WorkshiftRating.INDIFFERENT, workshift_type=self.wtype2, ) preference3 = WorkshiftRating.objects.create( rating=WorkshiftRating.DISLIKE, workshift_type=self.wtype3, ) self.profile.ratings = [preference1, preference2, preference3] self.profile.save() utils.make_workshift_pool_hours(semester=self.semester)
def _test_pre_fill_and_assign_humor(self): """ Tests that humor shifts can be correctly assigned after farnsworth/pre_fill.py is run. """ for i in range(1, 50): User.objects.create_user(username="******".format(i)) pre_fill.main(["--managers", "--workshift"]) utils.make_workshift_pool_hours(semester=self.semester) # Assign manager shifts beforehand manager_shifts = RegularWorkshift.objects.filter( pool=self.p1, workshift_type__auto_assign=False, ) profiles = WorkshiftProfile.objects.all() for profile, shift in zip(profiles, manager_shifts): shift.current_assignees.add(profile) shift.save() unfinished = utils.auto_assign_shifts( self.semester, pool=WorkshiftPool.objects.get(title="Humor Shift") ) self.assertEqual([], unfinished)
def _test_auto_assign_one_hundred_and_fifty(self): """ Assign 150 members to 150 shifts, with each shift providing 5 hours of workshift. Ensures that the assignments don't mysteriously break or run for an extremely long time for large houses. """ shifts = [] for i in range(150): shifts.append( RegularWorkshift.objects.create( workshift_type=self.wtype1, pool=self.p1, hours=5, ) ) for i in range(1, 150): User.objects.create_user(username="******".format(i)) utils.make_workshift_pool_hours(semester=self.semester) unfinished = utils.auto_assign_shifts(self.semester) self.assertEqual([], unfinished) for shift in shifts: self.assertEqual(1, shift.current_assignees.count())
def save(self): semester = super(SemesterForm, self).save() # Set current to false for previous semesters for semester in Semester.objects.all(): semester.current = False semester.save() semester.current = True semester.preferences_open = True semester.save() # Create the primary workshift pool pool = WorkshiftPool.objects.create(semester=semester, is_primary=True) pool.managers = Manager.objects.filter(workshift_manager=True) pool.save() # Create this semester's workshift profiles for uprofile in UserProfile.objects.filter(status=UserProfile.RESIDENT): profile = WorkshiftProfile.objects.create(user=uprofile.user, semester=semester) utils.make_workshift_pool_hours(semester) return semester
def save(self): semester = super(SemesterForm, self).save() # Set current to false for previous semesters for semester in Semester.objects.all(): semester.current = False semester.save() semester.workshift_managers = \ [i.incumbent.user for i in Manager.objects.filter(workshift_manager=True)] semester.current = True semester.preferences_open = True semester.save() # Create the primary workshift pool pool = WorkshiftPool.objects.create( semester=semester, is_primary=True, ) pool.managers = Manager.objects.filter(workshift_manager=True) pool.save() # Create this semester's workshift profiles for uprofile in UserProfile.objects.filter( status=UserProfile.RESIDENT): if uprofile.user.username == ANONYMOUS_USERNAME: continue WorkshiftProfile.objects.create( user=uprofile.user, semester=semester, ) utils.make_workshift_pool_hours(semester=semester) utils.make_manager_workshifts(semester=pool.semester) return semester
def main(args): # Add Managers for title, compensation, hours, email, duties in MANAGERS: Manager.objects.create( title=title, compensation=compensation, semester_hours=str(hours), summer_hours=str(hours), duties=duties, email="{0}{1}@bsc.coop".format(settings.HOUSE_ABBREV, email) if email else "", president="president" in title.lower(), workshift_manager="workshift" in title.lower(), ) # Add Requests for name, managers, glyphicon in REQUESTS: r = RequestType.objects.create( name=name, glyphicon=glyphicon, ) r.managers = [Manager.objects.get(title=i) for i in managers] r.save() if "workshift" in settings.INSTALLED_APPS: # Start the Workshift Semester year, season = get_year_season() start_date, end_date = get_semester_start_end(year, season) semester = Semester.objects.create( year=year, season=season, start_date=start_date, end_date=end_date, ) for uprofile in UserProfile.objects.filter(status=UserProfile.RESIDENT): profile = WorkshiftProfile.objects.create( user=uprofile.user, semester=semester, ) # Regular Weekly Workshift Hours pool = WorkshiftPool.objects.create( semester=semester, is_primary=True, hours=5, any_blown=True, ) pool.managers = Manager.objects.filter(workshift_manager=True) pool.save() # HI Hours hi_pool = WorkshiftPool.objects.create( title="Home Improvement", semester=semester, hours=str(4), weeks_per_period=0, ) hi_pool.managers = Manager.objects.filter(title="Maintenance Manager") hi_pool.save() # Social Hours social_pool = WorkshiftPool.objects.create( title="Social", semester=semester, hours=str(1), weeks_per_period=6, ) social_pool.managers = Manager.objects.filter(title="Social Manager") social_pool.save() # Humor Shift humor_pool = WorkshiftPool.objects.create( title="Humor Shift", semester=semester, any_blown=True, hours=str(2), weeks_per_period=6, ) humor_pool.managers = Manager.objects.filter(workshift_manager=True) humor_pool.save() make_workshift_pool_hours(semester) # Workshift Types for title, description, quick_tips, hours, rateable in WORKSHIFT_TYPES: WorkshiftType.objects.create( title=title, description=description, quick_tips=quick_tips, hours=str(hours), rateable=rateable, ) # Regular Workshifts for title, type_title, days, count, start, end in REGULAR_WORKSHIFTS: wtype = WorkshiftType.objects.get(title=type_title) shift = RegularWorkshift.objects.create( workshift_type=wtype, title=title, pool=pool, count=count, start_time=start, end_time=end, hours=wtype.hours, ) shift.days = get_int_days(days) shift.save() for title, type_title, count in WEEK_LONG: wtype = WorkshiftType.objects.get(title=type_title) shift = RegularWorkshift.objects.create( workshift_type=wtype, title=title, pool=pool, count=count, week_long=True, start_time=None, end_time=None, hours=wtype.hours, ) # Humor Workshifts for title, type_title, days, start, end in HUMOR_WORKSHIFTS: wtype = WorkshiftType.objects.get(title=type_title) shift = RegularWorkshift.objects.create( workshift_type=wtype, title=title, pool=humor_pool, start_time=start, end_time=end, hours=wtype.hours, ) shift.days = get_int_days(days) shift.save() make_instances(semester=semester) make_manager_workshifts(semester)
def make_pool_hours(sender, instance, created, **kwargs): pool = instance if created: utils.make_workshift_pool_hours(pool.semester, pools=[pool])
def main(args, verbose=True): # Add Managers managers = 0 for title, compensation, hours, email, duties in MANAGERS: created = Manager.objects.get_or_create( title=title, defaults=dict( compensation=compensation, semester_hours=hours, summer_hours=hours, duties=duties, email="{0}{1}@bsc.coop".format(settings.HOUSE_ABBREV, email) if email else "", president="president" in title.lower(), workshift_manager="workshift" in title.lower(), ), )[1] if created: managers += 1 if verbose: print("Created {0} managers".format(managers)) # Add Requests requests = 0 for name, managers, glyphicon in REQUESTS: r, created = RequestType.objects.get_or_create( name=name, defaults=dict( glyphicon=glyphicon, ), ) if created: r.managers = [Manager.objects.get(title=i) for i in managers] r.save() requests += 1 if verbose: print("Created {0} request types".format(requests)) if "workshift" in settings.INSTALLED_APPS: # Start the Workshift Semester year, season = get_year_season() start_date, end_date = get_semester_start_end(year, season) try: semester = Semester.objects.get(current=True) except Semester.DoesNotExist: semester, created = Semester.objects.get_or_create( year=year, season=season, defaults=dict(start_date=start_date, end_date=end_date), ) else: created = False if created and verbose: print("Started a new workshift semester") # Regular Weekly Workshift Hours pool, created = WorkshiftPool.objects.get_or_create( semester=semester, is_primary=True, defaults=dict(hours=5, any_blown=True), ) if created: pool.managers = Manager.objects.filter(workshift_manager=True) pool.save() # HI Hours hi_pool, created = WorkshiftPool.objects.get_or_create( title="Home Improvement", semester=semester, defaults=dict(hours=4, weeks_per_period=0), ) if created: hi_pool.managers = Manager.objects.filter(title="Maintenance Manager") hi_pool.save() # Social Hours social_pool, created = WorkshiftPool.objects.get_or_create( title="Social", semester=semester, defaults=dict(hours=1, weeks_per_period=0), ) if created: social_pool.managers = Manager.objects.filter(title="Social Manager") social_pool.save() # Humor Shift humor_pool, created = WorkshiftPool.objects.get_or_create( title="Humor Shift", semester=semester, defaults=dict(any_blown=True, hours=2, weeks_per_period=6), ) if created: humor_pool.managers = Manager.objects.filter(workshift_manager=True) humor_pool.save() make_workshift_pool_hours(semester) # Workshift Types for title, description, quick_tips, rateable in WORKSHIFT_TYPES: WorkshiftType.objects.get_or_create( title=title, defaults=dict( description=description, quick_tips=quick_tips, rateable=rateable, ), ) # Regular Workshifts for type_title, hours, days, count, start, end in REGULAR_WORKSHIFTS: wtype = WorkshiftType.objects.get(title=type_title) for day in days: RegularWorkshift.objects.get_or_create( workshift_type=wtype, pool=pool, day=day, start_time=start, end_time=end, defaults=dict( count=count, hours=hours, ), ) for type_title, hours, count in WEEK_LONG: wtype = WorkshiftType.objects.get(title=type_title) RegularWorkshift.objects.get_or_create( workshift_type=wtype, pool=pool, count=count, week_long=True, defaults=dict( start_time=None, end_time=None, hours=hours, ), ) # Humor Workshifts for type_title, hours, days, start, end in HUMOR_WORKSHIFTS: wtype = WorkshiftType.objects.get(title=type_title) for day in days: RegularWorkshift.objects.get_or_create( workshift_type=wtype, pool=humor_pool, day=day, defaults=dict( start_time=start, end_time=end, hours=hours, ), ) make_instances(semester=semester) make_manager_workshifts(semester)
def test_make_pool_hours_all(self): PoolHours.objects.all().delete() utils.make_workshift_pool_hours() self.assertEqual(2, PoolHours.objects.count()) self.assertEqual(2, self.profile.pool_hours.count())
def create_workshift_pool_hours(sender, instance, **kwargs): pool = instance utils.make_workshift_pool_hours(semester=pool.semester, pools=[pool])
def test_collect_blown(self): utils.make_workshift_pool_hours() self.assertEqual( ([], [], []), utils.collect_blown(), ) self.assertEqual( ([], [], []), utils.collect_blown(semester=self.semester), ) moment = localtime(now().replace( hour=20, minute=0, second=0, microsecond=0, )) past = moment - timedelta(days=1) WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="Closed", pool=self.p1, end_time=time(12), ), closed=True, date=past.date(), semester=self.semester, ) to_close = WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="To be closed", pool=self.p1, end_time=time(12), ), date=past.date(), semester=self.semester, ) WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="Not Blown", pool=self.p1, end_time=time(12), ), date=moment.date(), semester=self.semester, ) blown = WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="Blown", pool=self.p1, end_time=time(12), ), date=past.date(), workshifter=self.profile, semester=self.semester, ) WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="Edge Case 1: Not Closed", pool=self.p1, end_time=moment.time(), ), date=moment.date(), semester=self.semester, ) edge_datetime = moment - timedelta( hours=self.p1.verify_cutoff, minutes=1, ) edge_case_2 = WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="Edge Case 2: Closed", pool=self.p1, end_time=edge_datetime.time(), ), date=edge_datetime.date(), ) signed_out_1 = WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="Workshifter signed out early enough", pool=self.p1, end_time=time(12), ), date=past.date(), semester=self.semester, ) signed_out_2 = WorkshiftInstance.objects.create( info=InstanceInfo.objects.create( title="Workshifter signed out too late", pool=self.p1, end_time=time(12), ), liable=self.profile, date=past.date(), semester=self.semester, ) self.assertEqual( ([to_close, edge_case_2, signed_out_1], [], [blown, signed_out_2]), utils.collect_blown(moment=moment), )