Skip to content

Commit

Permalink
Rototron: Reconfigure how unavailable and manual overrides react
Browse files Browse the repository at this point in the history
Previously, if you marked yourself unavailable on a day, but
someone else marked you manually configured for that day, you'd
be assigned that day. That doesn't seem quite right.

Now, instead, explicit unavailable wins
  • Loading branch information
wolfsage committed Aug 25, 2020
1 parent 9eb98a0 commit 3c1b9a8
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 12 deletions.
23 changes: 23 additions & 0 deletions lib/Synergy/Reactor/Rototron.pm
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,29 @@ sub handle_manual_assignment ($self, $event) {
$assign_to = $target->username;
}

my (@okay, @errors);

for my $date (@dates) {
my $debug = [];
if ($self->availability_checker->user_is_available_on($assign_to, $date, $debug)) {
push @okay, $date;
} else {
push @errors, @$debug;
}
}

@dates = @okay;

unless (@dates) {
$event->reply("$username was not available for any of those dates:\n" . join("\n", @errors));

return;
}

if (@errors) {
$event->reply("$username was not available for these dates:\n" . join("\n", @errors));
}

$self->availability_checker->update_manual_assignments({
$rotor_name => { map {; $_->ymd => $assign_to } @dates },
});
Expand Down
60 changes: 48 additions & 12 deletions lib/Synergy/Rototron.pm
Original file line number Diff line number Diff line change
Expand Up @@ -457,14 +457,24 @@ package Synergy::Rototron::Rotor {

if (my $username = $self->manual_assignment_for($rotor, $day)) {
my ($user) = grep {; $_->{username} eq $username } $self->_full_staff->@*;
return $user if $user;

$Logger->log([
"no user named %s, but that name is assigned for %s on %s",
$username,
$rotor->name,
$day->ymd,
]);

if ($user && $self->user_is_blocked_on($user->{username}, $day)) {
$Logger->log([
"user %s manually assigned but they are marked unavailable for %s on %s, skipping",
$user->{username},
$rotor->name,
$day->ymd,
]);
} elsif ($user) {
return $user;
} else {
$Logger->log([
"no user named %s, but that name is assigned for %s on %s",
$username,
$rotor->name,
$day->ymd,
]);
}
}

my $weekn = _week_of_date($day);
Expand Down Expand Up @@ -665,24 +675,50 @@ package Synergy::Rototron::AvailabilityChecker {
return;
}

sub user_is_available_on ($self, $username, $dt) {
sub user_is_available_on ($self, $username, $dt, $debug = []) {
my $ymd = $dt->ymd;

unless ($self->user_typically_works_on($username, $dt)) {
push @$debug, "$username does not work on " . $dt->ymd;
return 0;
}

if ($self->user_has_leave_on($username, $dt)) {
push @$debug, "$username has leave scheduled on " . $dt->ymd;
return 0;
}

if ($self->user_is_blocked_on($username, $dt)) {
push @$debug, "$username is marked unavailable on " . $dt->ymd;
return 0;
}

return 1;
}

sub user_typically_works_on ($self, $username, $dt) {
if (my $user = $self->user_directory->user_named($username)) {
return 0 unless $user->hours_for_dow($dt->day_of_week);
return 1 if $user->hours_for_dow($dt->day_of_week);
}

return 0;
}

sub user_has_leave_on ($self, $username, $dt) {
my $leave = $self->_leave_days;
return 0 if $leave->{$username}{$dt->ymd};

return 1 if $leave->{$username}{$dt->ymd};
}

sub user_is_blocked_on ($self, $username, $dt) {
my ($count) = $self->_dbh->selectrow_array(
q{SELECT COUNT(*) FROM blocked_days WHERE username = ? AND date = ?},
undef,
$username,
$dt->ymd,
);

return $count == 0;
return $count ? 1 : 0;
}

sub set_user_unavailable_on ($self, $username, $dt, $reason = undef) {
Expand Down

0 comments on commit 3c1b9a8

Please sign in to comment.