This commit is contained in:
Adrian Hopek
2022-04-25 13:23:49 +02:00
parent 851a52fe32
commit 25816cc47a
28 changed files with 531 additions and 239 deletions

View File

@@ -4,48 +4,32 @@ declare(strict_types=1);
namespace Toby\Domain\Slack\Handlers;
use Illuminate\Support\Collection;
use Spatie\SlashCommand\Attachment;
use Spatie\SlashCommand\AttachmentField;
use Spatie\SlashCommand\Handlers\CatchAll as BaseCatchAllHandler;
use Spatie\SlashCommand\Handlers\SignatureHandler;
use Spatie\SlashCommand\Handlers\BaseHandler;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Domain\Slack\Traits\ListsHandlers;
class CatchAll extends BaseCatchAllHandler
class CatchAll extends BaseHandler
{
use ListsHandlers;
public function canHandle(Request $request): bool
{
return true;
}
public function handle(Request $request): Response
{
$response = $this->respondToSlack("Nie rozpoznaję tej komendy: `/{$request->command} {$request->text}`");
$handlers = $this->findAvailableHandlers();
$attachmentFields = $this->mapHandlersToAttachments($handlers);
[$command] = explode(' ', $this->request->text ?? "");
$alternativeHandlers = $this->findAlternativeHandlers($command);
if ($alternativeHandlers->count()) {
$response->withAttachment($this->getCommandListAttachment($alternativeHandlers));
}
if ($this->containsHelpHandler($alternativeHandlers)) {
$response->withAttachment(Attachment::create()
->setText("Aby wyświetlić wszystkie komendy, napisz: `/toby pomoc`")
return $this->respondToSlack(":x: Nie rozpoznaję tej komendy. Lista wszystkich komend:")
->withAttachment(
Attachment::create()
->setColor("danger")
->useMarkdown()
->setFields($attachmentFields),
);
}
return $response;
}
protected function getCommandListAttachment(Collection $handlers): Attachment
{
$attachmentFields = $handlers
->map(function (SignatureHandler $handler) {
return AttachmentField::create($handler->getFullCommand(), $handler->getDescription());
})
->all();
return Attachment::create()
->setColor('warning')
->setTitle('Czy miałeś na myśli:')
->setFields($attachmentFields);
}
}

View File

@@ -5,70 +5,52 @@ declare(strict_types=1);
namespace Toby\Domain\Slack\Handlers;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Spatie\SlashCommand\Attachment;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\SignatureHandler;
use Toby\Domain\Enums\VacationType;
use Toby\Domain\VacationTypeConfigRetriever;
use Toby\Domain\DailySummaryRetriever;
use Toby\Domain\Slack\SignatureHandler;
use Toby\Eloquent\Models\User;
use Toby\Eloquent\Models\Vacation;
class DailySummary extends SignatureHandler
{
protected $signature = "toby dzisiaj";
protected $description = "Podsumowanie";
protected $description = "Codzienne podsumowanie";
public function handle(Request $request): Response
{
$configRetriever = app(VacationTypeConfigRetriever::class);
$dailySummaryRetriever = app()->make(DailySummaryRetriever::class);
$now = Carbon::today();
/** @var Collection $absences */
$absences = Vacation::query()
->with(["user", "vacationRequest"])
->whereDate("date", $now)
->approved()
->whereTypes(VacationType::all()->filter(fn(VacationType $type) => $configRetriever->isVacation($type)))
->get()
$absences = $dailySummaryRetriever->getAbsences($now)
->map(fn(Vacation $vacation) => $vacation->user->profile->full_name);
/** @var Collection $remoteDays */
$remoteDays = Vacation::query()
->with(["user", "vacationRequest"])
->whereDate("date", $now)
->approved()
->whereTypes(VacationType::all()->filter(fn(VacationType $type) => !$configRetriever->isVacation($type)))
->get()
$remoteDays = $dailySummaryRetriever->getRemoteDays($now)
->map(fn(Vacation $vacation) => $vacation->user->profile->full_name);
$birthdays = User::query()
->whereRelation("profile", "birthday", $now)
->get()
$birthdays = $dailySummaryRetriever->getBirthdays($now)
->map(fn(User $user) => $user->profile->full_name);
$absencesAttachment = Attachment::create()
->setTitle("Nieobecności :palm_tree:")
->setColor('#eab308')
->setColor("#eab308")
->setText($absences->isNotEmpty() ? $absences->implode("\n") : "Wszyscy dzisiaj pracują :muscle:");
$remoteAttachment = Attachment::create()
->setTitle("Praca zdalna :house_with_garden:")
->setColor('#d946ef')
->setColor("#d946ef")
->setText($remoteDays->isNotEmpty() ? $remoteDays->implode("\n") : "Wszyscy dzisiaj są w biurze :boom:");
$birthdayAttachment = Attachment::create()
->setTitle("Urodziny :birthday:")
->setColor('#3C5F97')
->setColor("#3C5F97")
->setText($birthdays->isNotEmpty() ? $birthdays->implode("\n") : "Dzisiaj nikt nie ma urodzin :cry:");
return $this->respondToSlack("Podsumowanie dla dnia {$now->toDisplayString()}")
->withAttachment($absencesAttachment)
->withAttachment($remoteAttachment)
->withAttachment($birthdayAttachment)
->displayResponseToEveryoneOnChannel();
->withAttachment($birthdayAttachment);
}
}

View File

@@ -4,46 +4,69 @@ declare(strict_types=1);
namespace Toby\Domain\Slack\Handlers;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\SignatureHandler;
use Toby\Domain\Notifications\KeyHasBeenGivenNotification;
use Toby\Domain\Slack\SignatureHandler;
use Toby\Domain\Slack\SlackUserExistsRule;
use Toby\Domain\Slack\Traits\FindsUserBySlackId;
use Toby\Domain\Slack\UserNotFoundException;
use Toby\Eloquent\Models\Key;
use Toby\Eloquent\Models\User;
class GiveKeysTo extends SignatureHandler
{
protected $signature = "toby klucze:dla {użytkownik}";
use FindsUserBySlackId;
protected $description = "Daj klucze wskazanemu użytkownikowi";
protected $signature = "toby klucze:dla {user}";
protected $description = "Przekaż klucze wskazanemu użytkownikowi";
/**
* @throws UserNotFoundException
* @throws ValidationException
*/
public function handle(Request $request): Response
{
$to = $this->getArgument('użytkownik');
["user" => $from] = $this->validate();
$id = Str::between($to, "@", "|");
$authUser = $this->findUserBySlackId($request->userId);
$user = $this->findUserBySlackId($id);
$authUser = $this->findUserBySlackIdOrFail($request->userId);
$user = $this->findUserBySlackId($from);
/** @var Key $key */
$key = $authUser->keys()->first();
if (!$key) {
throw ValidationException::withMessages(["key" => "Nie masz żadnego klucza do przekazania"]);
}
if ($user->is($authUser)) {
throw ValidationException::withMessages([
"key" => "Nie możesz przekazać sobie kluczy :dzban:",
]);
}
$key->user()->associate($user);
$key->save();
return $this->respondToSlack("<@{$authUser->profile->slack_id}> daje klucz nr {$key->id} użytkownikowi <@{$user->profile->slack_id}>")
->displayResponseToEveryoneOnChannel();
$key->notify(new KeyHasBeenGivenNotification($authUser, $user));
return $this->respondToSlack(
":white_check_mark: Klucz nr {$key->id} został przekazany użytkownikowi <@{$user->profile->slack_id}>",
);
}
protected function findUserBySlackId(string $slackId): User
protected function getRules(): array
{
/** @var User $user */
$user = User::query()
->whereRelation("profile", "slack_id", $slackId)
->first();
return [
"user" => ["required", new SlackUserExistsRule()],
];
}
return $user;
protected function getMessages(): array
{
return [
"user.required" => "Musisz podać użytkownika, któremu chcesz przekazać klucze",
];
}
}

View File

@@ -4,42 +4,31 @@ declare(strict_types=1);
namespace Toby\Domain\Slack\Handlers;
use Illuminate\Support\Collection;
use Spatie\SlashCommand\Attachment;
use Spatie\SlashCommand\AttachmentField;
use Spatie\SlashCommand\Handlers\Help as BaseHelpHandler;
use Spatie\SlashCommand\Handlers\SignatureHandler;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Domain\Slack\SignatureHandler;
use Toby\Domain\Slack\Traits\ListsHandlers;
class Help extends BaseHelpHandler
class Help extends SignatureHandler
{
use ListsHandlers;
protected $signature = "toby pomoc";
protected $description = "Wyświetl wszystkie dostępne komendy tobiego";
protected $description = "Wyświetl wszystkie dostępne komendy";
public function handle(Request $request): Response
{
$handlers = $this->findAvailableHandlers();
return $this->displayListOfAllCommands($handlers);
}
$attachmentFields = $this->mapHandlersToAttachments($handlers);
protected function displayListOfAllCommands(Collection $handlers): Response
{
$attachmentFields = $handlers
->sort(function (SignatureHandler $handlerA, SignatureHandler $handlerB) {
return strcmp($handlerA->getFullCommand(), $handlerB->getFullCommand());
})
->map(function (SignatureHandler $handler) {
return AttachmentField::create("/{$handler->getSignature()}", $handler->getDescription());
})
->all();
return $this->respondToSlack('Dostępne komendy')
return $this->respondToSlack("Dostępne komendy:")
->withAttachment(
Attachment::create()
->setColor('good')
->setFields($attachmentFields)
->setColor("good")
->useMarkdown()
->setFields($attachmentFields),
);
}
}

View File

@@ -7,22 +7,31 @@ namespace Toby\Domain\Slack\Handlers;
use Illuminate\Support\Carbon;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\SignatureHandler;
use Toby\Domain\Actions\VacationRequest\CreateAction;
use Toby\Domain\Enums\VacationType;
use Toby\Domain\Slack\SignatureHandler;
use Toby\Domain\Slack\Traits\FindsUserBySlackId;
use Toby\Eloquent\Models\User;
use Toby\Eloquent\Models\YearPeriod;
class HomeOffice extends SignatureHandler
{
protected $signature = "toby zdalnie {kiedy?}";
protected $description = "Pracuj zdalnie wybranego dnia (domyślnie dzisiaj)";
use FindsUserBySlackId;
protected $signature = "toby zdalnie";
protected $description = "Pracuj dzisiaj zdalnie";
public function handle(Request $request): Response
{
$date = $this->getDateFromArgument($this->getArgument('kiedy') ?? "dzisiaj");
$user = $this->findUserBySlackId($request->userId);
$this->createRemoteday($user, Carbon::today());
return $this->respondToSlack(":white_check_mark: Pracujesz dzisiaj zdalnie");
}
protected function createRemoteday(User $user, Carbon $date): void
{
$yearPeriod = YearPeriod::findByYear($date->year);
app(CreateAction::class)->execute([
@@ -33,27 +42,5 @@ class HomeOffice extends SignatureHandler
"year_period_id" => $yearPeriod->id,
"flow_skipped" => false,
], $user);
return $this->respondToSlack("Praca zdalna dnia {$date->toDisplayString()} została utworzona pomyślnie.")
->displayResponseToEveryoneOnChannel();
}
protected function getDateFromArgument(string $argument): Carbon
{
return match ($argument) {
"dzisiaj" => Carbon::today(),
"jutro" => Carbon::tomorrow(),
default => Carbon::create($argument),
};
}
protected function findUserBySlackId(string $slackId): User
{
/** @var User $user */
$user = User::query()
->whereRelation("profile", "slack_id", $slackId)
->first();
return $user;
}
}

View File

@@ -7,13 +7,12 @@ namespace Toby\Domain\Slack\Handlers;
use Spatie\SlashCommand\Attachment;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\SignatureHandler;
use Toby\Domain\Slack\SignatureHandler;
use Toby\Eloquent\Models\Key;
class KeyList extends SignatureHandler
{
protected $signature = "toby klucze";
protected $description = "Lista wszystkich kluczy";
public function handle(Request $request): Response
@@ -23,11 +22,11 @@ class KeyList extends SignatureHandler
->get()
->map(fn(Key $key) => "Klucz nr {$key->id} - <@{$key->user->profile->slack_id}>");
return $this->respondToSlack("Lista kluczy")
return $this->respondToSlack("Lista kluczy :key:")
->withAttachment(
Attachment::create()
->setColor('#3C5F97')
->setText($keys->implode("\n"))
->setColor("#3C5F97")
->setText($keys->isNotEmpty() ? $keys->implode("\n") : "Nie ma żadnych kluczy w tobym"),
);
}
}

View File

@@ -1,24 +0,0 @@
<?php
declare(strict_types=1);
namespace Toby\Domain\Slack\Handlers;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\SignatureHandler;
class SaySomething extends SignatureHandler
{
protected $signature = "toby powiedz {zdanie}";
protected $description = "Powiedz zdanie";
public function handle(Request $request): Response
{
$sentence = $this->getArgument("zdanie");
return $this->respondToSlack($sentence)
->displayResponseToEveryoneOnChannel();
}
}

View File

@@ -4,46 +4,68 @@ declare(strict_types=1);
namespace Toby\Domain\Slack\Handlers;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Spatie\SlashCommand\Handlers\SignatureHandler;
use Toby\Domain\Notifications\KeyHasBeenTakenNotification;
use Toby\Domain\Slack\SignatureHandler;
use Toby\Domain\Slack\SlackUserExistsRule;
use Toby\Domain\Slack\Traits\FindsUserBySlackId;
use Toby\Domain\Slack\UserNotFoundException;
use Toby\Eloquent\Models\Key;
use Toby\Eloquent\Models\User;
class TakeKeysFrom extends SignatureHandler
{
protected $signature = "toby klucze:od {użytkownik}";
use FindsUserBySlackId;
protected $signature = "toby klucze:od {user}";
protected $description = "Zabierz klucze wskazanemu użytkownikowi";
/**
* @throws UserNotFoundException|ValidationException
*/
public function handle(Request $request): Response
{
$from = $this->getArgument("użytkownik");
["user" => $from] = $this->validate();
$id = Str::between($from, "@", "|");
$authUser = $this->findUserBySlackId($request->userId);
$user = $this->findUserBySlackId($id);
$authUser = $this->findUserBySlackIdOrFail($request->userId);
$user = $this->findUserBySlackId($from);
/** @var Key $key */
$key = $user->keys()->first();
if (!$key) {
throw ValidationException::withMessages([
"key" => "Użytkownik <@{$user->profile->slack_id}> nie ma żadnych kluczy",
]);
}
if ($key->user()->is($authUser)) {
throw ValidationException::withMessages([
"key" => "Nie możesz zabrać sobie kluczy :dzban:",
]);
}
$key->user()->associate($authUser);
$key->save();
return $this->respondToSlack("<@{$authUser->profile->slack_id}> zabiera klucz nr {$key->id} użytkownikowi <@{$user->profile->slack_id}>")
->displayResponseToEveryoneOnChannel();
$key->notify(new KeyHasBeenTakenNotification($authUser, $user));
return $this->respondToSlack(":white_check_mark: Klucz nr {$key->id} został zabrany użytkownikowi <@{$user->profile->slack_id}>");
}
protected function findUserBySlackId(string $slackId): User
protected function getRules(): array
{
/** @var User $user */
$user = User::query()
->whereRelation("profile", "slack_id", $slackId)
->first();
return [
"user" => ["required", new SlackUserExistsRule()],
];
}
return $user;
protected function getMessages(): array
{
return [
"user.required" => "Musisz podać użytkownika, któremu chcesz zabrać klucze",
];
}
}