# Type: Input and output # Category: Extra # Description: Notifies users when work hours are enough # Author: Andriy Lesyuk new Orangutan::Context( request => sub { my ($context, $user) = @_; if ($user->GetOption('WorkOverNotify')) { my $message = Orangutan::Context::Random( 'Hey! Your working day is over now... Please go away!', "That's enough work hours! You may go home now!..", 'You can leave now! You worked enough time!..' ); $context->SetField('notified', 1); return $message; } return undef; }, response => '^(?:Let me know|((?:stop(?: to)?|do(?:n\'t| not)) )?(?:notify|tell)(?:ing)?(?: me)?) '. '(?:when|if) (?:(?:my )?(?:work(?:ing)? )?hours are enough|I (?:can|may) (?:leave|go(?: home)?))!*\.*$', handler => sub { my ($context, $user, $item, $negation) = @_; my $hours = $user->GetWorkTimeHours; if (!$hours) { $user->SendMessage([ 'You need to tell me first how many hours you should work per day...', 'I would do this if I knew how many hours you should work per day...', 'I have no idea how much time you need to work!..' ]); return; } my $active = $user->GetOption('WorkOverNotify'); if ($active) { if ($negation) { $user->ClearOption('WorkOverNotify'); $main::config->Context('Ok')->Tell($user); } else { $user->SendMessage([ 'You already asked...', 'You already told...', 'Ok, ok...' ]); } } else { if ($negation) { $user->SendMessage([ 'You already told...', "I'm not going to...", "I don't..." ]); } else { $user->SetOption('WorkOverNotify', 'true'); $main::config->Context('Ok')->Tell($user); } } }, ontask => sub { my ($context, $user, $type, $status, $task) = @_; my $hours = $user->GetWorkTimeHours; my $workover = $user->GetResponse($context->GetID); if ($hours && defined($workover) && $user->GetOption('WorkOverNotify')) { my $date = new Orangutan::Date; my $seconds = $workover->GetField('seconds'); if (!defined($seconds) || ($status eq 'change') || ($status eq 'remove')) { $seconds = $user->GetWorkHours($date->WorkDayStart, $date->WorkDayEnd) || 0; $workover->SetField('seconds', $seconds); } elsif (($status eq 'break') || ($status eq 'add')) { if ($task->GetStart && $task->GetEnd) { my $daystart = $date->WorkDayStart->Date; my $dayend = $date->WorkDayEnd->Date; my $start = $task->GetStart->Date; my $end = $task->GetEnd->Date; if (($end > $daystart) && ($start < $dayend)) { if ($start < $daystart) { $start = $daystart; } if ($end > $dayend) { $end = $dayend; } $seconds += $end - $start; $workover->SetField('seconds', $seconds); } } else { if ($task->GetDate->DayStart->Date == $date->DayStart->Date) { $seconds += $task->GetDuration; $workover->SetField('seconds', $seconds); } } } if (($status eq 'start') || ($status eq 'break') || ($status eq 'add') || ($status eq 'change') || ($status eq 'remove')) { my $currtask = $user->GetTask; if ($currtask) { my $delay = ($hours * 3600) - ($seconds + $currtask->GetStart->Elapsed); if (($delay > 60) && (($date->Date + $delay) < $date->WorkDayEnd->Date)) { my $schedule = $main::users->GetSchedule($context, 'notify'); if (defined($schedule)) { if ($schedule->[2] > ($date->Date + $delay)) { $main::users->CancelSchedule($context, 'notify'); $main::users->Schedule($date->Date + $delay, $context, 'notify', $user); } } else { $main::users->Schedule($date->Date + $delay, $context, 'notify', $user); } } elsif (!$workover->GetField('notified')) { if ($user->GetRequest($workover->GetID)) { $user->RemoveRequest($workover); } $user->SendMessage([ 'You worked enough hours... No need to work more.', 'You are not required to work more...', 'It is enough work hours for today...' ]); $workover->SetField('notified', 1); } } } elsif (($status eq 'cancel') || ($status eq 'end')) { if ($status eq 'end') { my $daystart = $date->WorkDayStart->Date; my $dayend = $date->WorkDayEnd->Date; my $start = $task->GetStart->Date; my $end = $task->GetEnd->Date; if (($end > $daystart) && ($start < $dayend)) { if ($start < $daystart) { $start = $daystart; } if ($end > $dayend) { $end = $dayend; } $seconds += $end - $start; $workover->SetField('seconds', $seconds); } } my $schedule = $main::users->GetSchedule($workover, 'notify'); if (defined($schedule) && defined($schedule[3]) && (ref $schedule[3] eq 'Orangutan::User') && ($schedule[3]->GetUserID == $user->GetUserID)) { $main::users->CancelSchedule($context, 'notify'); $context->CallSchedule($main::users, 'notify', $user); } } } }, schedule => sub { my ($context, $scheduler, $arg) = @_; my $date = new Orangutan::Date; if ($arg eq 'notify') { my $nexttime; foreach my $username ($main::users->GetUsers) { my $user = $main::users->GetUser($username); my $hours = $user->GetWorkTimeHours; my $workover = $user->GetResponse($context->GetID); if ($hours && defined($workover) && $user->GetOption('WorkOverNotify')) { my $task = $user->GetTask; if ($task) { my $seconds = $workover->GetField('seconds'); if (defined($seconds)) { my $delay = ($hours * 3600) - ($seconds + $task->GetStart->Elapsed); if ($delay < 60) { if (!$workover->GetField('notified') && !$user->GetRequest($workover->GetID)) { $user->AddRequest($workover, 100); } } elsif (!defined($nexttime) || ($nexttime > ($date->Date + $delay))) { $nexttime = $date->Date + $delay; } } } } } if (defined($nexttime) && ($nexttime < $date->WorkDayEnd->Date)) { $main::users->Schedule($nexttime, $context, 'notify'); } } else { foreach my $username ($main::users->GetUsers) { my $user = $main::users->GetUser($username); my $workover = $user->GetResponse($context->GetID); if (defined($workover)) { my $seconds = $workover->GetField('seconds'); if (defined($seconds) && ($seconds > 0)) { $workover->SetField('seconds', 0); } if ($workover->GetField('notified')) { $workover->UnsetField('notified'); } } } $scheduler->Schedule($date->WorkDayEnd->Date, $context, 'clean'); } }, help => { title => 'How can I disable/enable notifying when work hours are enough?', question => '^(?:How )?(?:(?:can|do) I |to )(?:disable(?:/enable)?|turn (?:on|off)|enable) '. 'notifying(?: me)? when (?:(?:my )?work(?:ing)? (?:hours are enough|day is over)|'. 'I (?:can|may) (?:leave|go home)|I (?:have )?worked enough hours)\?*!*\.*$', answer => "Orangutan can notify you when you have worked enough hours. ". "By default Orangutan does not do this.\n". "Sample queries to enable notifications:\n". " o Notify me if my work hours are enough\n". " o Let me know when I can go home\n". " o Tell me when I can leave\n". "If you changed your mind you can disable notifications:\n". " o Stop notifying me when my work hours are enough\n". " o Don't tell me when I can leave!\n". "Currently Orangutan forgets whether he should notify you after restart...", weight => 590 }, weight => [ undef, 0, undef ] ); # kate: syntax perl