Skip to content

Commit

Permalink
working, but without interviewers
Browse files Browse the repository at this point in the history
  • Loading branch information
Snorre98 committed Sep 23, 2024
1 parent a7b4398 commit c0f0bb6
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
2 changes: 1 addition & 1 deletion backend/samfundet/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,6 @@
path('recruitment-interview-availability/', views.RecruitmentInterviewAvailabilityView.as_view(), name='recruitment_interview_availability'),
path('recruitment/<int:id>/availability/', views.RecruitmentAvailabilityView.as_view(), name='recruitment_availability'),
path('feedback/', views.UserFeedbackView.as_view(), name='feedback'),
# path('generate-interview-blocks/<int:pk>', views.GenerateInterviewTimeblocksView.as_view(), name='generate_interview_blocks'),
path('generate-interview-blocks/<int:pk>', views.GenerateInterviewTimeblocksView.as_view(), name='generate_interview_blocks'),
path('purchase-feedback/', views.PurchaseFeedbackView.as_view(), name='purchase_feedback'),
]
42 changes: 31 additions & 11 deletions backend/samfundet/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,7 @@ def get_perm(*, perm: str, model: type[Model]) -> Permission:

def generate_interview_timeblocks(recruitment_id):
recruitment = Recruitment.objects.get(id=recruitment_id)

# Delete existing time blocks for this recruitment
InterviewTimeblock.objects.filter(recruitment_position__recruitment=recruitment).delete()

positions = RecruitmentPosition.objects.filter(recruitment=recruitment)
block_count = 0

Expand All @@ -116,38 +113,61 @@ def generate_interview_timeblocks(recruitment_id):
end_date = recruitment.actual_application_deadline.date()
start_time = time(8, 0) # 8:00 AM
end_time = time(20, 0) # 8:00 PM
interval_minutes = 30

current_date = start_date
while current_date <= end_date:
current_datetime = timezone.make_aware(datetime.combine(current_date, start_time))
end_datetime = timezone.make_aware(datetime.combine(current_date, end_time))

while current_datetime < end_datetime:
next_datetime = current_datetime + timedelta(minutes=interval_minutes)
next_datetime, available_interviewers = find_next_change(position, recruitment, current_datetime, end_datetime)

available_interviewers = position.interviewers.exclude(
occupied_timeslots__recruitment=recruitment, occupied_timeslots__start_dt__lt=next_datetime, occupied_timeslots__end_dt__gt=current_datetime
)
if next_datetime == current_datetime:
# No change in availability, move to next 30-minute slot
next_datetime = current_datetime + timedelta(minutes=30)

rating = calculate_rating(recruitment, position, current_datetime, next_datetime, available_interviewers.count())
rating = calculate_rating(recruitment, position, current_datetime, next_datetime, len(available_interviewers))

InterviewTimeblock.objects.create(
recruitment_position=position, date=current_date, start_dt=current_datetime, end_dt=next_datetime, rating=rating
)
block_count += 1

current_datetime = next_datetime

current_date += timedelta(days=1)

return block_count


def find_next_change(position, recruitment, start_dt, end_dt):
current_dt = start_dt
step = timedelta(minutes=30)
current_interviewers = set(
position.interviewers.exclude(
occupied_timeslots__recruitment=recruitment, occupied_timeslots__start_dt__lte=current_dt, occupied_timeslots__end_dt__gt=current_dt
)
)

while current_dt < end_dt:
next_dt = current_dt + step
next_interviewers = set(
position.interviewers.exclude(
occupied_timeslots__recruitment=recruitment, occupied_timeslots__start_dt__lt=next_dt, occupied_timeslots__end_dt__gt=current_dt
)
)

if next_interviewers != current_interviewers:
return current_dt, current_interviewers

current_dt = next_dt
current_interviewers = next_interviewers

return end_dt, current_interviewers


def calculate_rating(recruitment, position, start_dt, end_dt, available_interviewers_count):
block_length = (end_dt - start_dt).total_seconds() / 3600 # in hours
occupied_slots = OccupiedTimeslot.objects.filter(recruitment=recruitment, start_dt__lt=end_dt, end_dt__gt=start_dt).count()

# You can adjust these weights based on your preferences
rating = (available_interviewers_count * 2) + (block_length * 0.5) - (occupied_slots * 1)
return max(0, rating) # Ensure the rating is not negative

0 comments on commit c0f0bb6

Please sign in to comment.