wip
This commit is contained in:
parent
7d12a1a153
commit
fad4290cc3
@ -4,11 +4,22 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Toby\Architecture\Providers;
|
namespace Toby\Architecture\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
|
use Illuminate\Notifications\ChannelManager;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Toby\Domain\Slack\Channels\SlackApiChannel;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
Notification::resolved(function (ChannelManager $service) {
|
||||||
|
$service->extend("slack", fn(Application $app) => $app->make(SlackApiChannel::class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
Carbon::macro("toDisplayString", fn() => $this->translatedFormat("d.m.Y"));
|
Carbon::macro("toDisplayString", fn() => $this->translatedFormat("d.m.Y"));
|
||||||
|
@ -53,7 +53,6 @@ class CreateAction
|
|||||||
$vacationRequest->save();
|
$vacationRequest->save();
|
||||||
|
|
||||||
$days = $this->vacationDaysCalculator->calculateDays(
|
$days = $this->vacationDaysCalculator->calculateDays(
|
||||||
$vacationRequest->yearPeriod,
|
|
||||||
$vacationRequest->from,
|
$vacationRequest->from,
|
||||||
$vacationRequest->to,
|
$vacationRequest->to,
|
||||||
);
|
);
|
||||||
|
@ -20,7 +20,17 @@ class VacationRequestCreatedNotification extends Notification
|
|||||||
|
|
||||||
public function via(): array
|
public function via(): array
|
||||||
{
|
{
|
||||||
return ["mail"];
|
return ["mail", "slack"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toSlack(): string
|
||||||
|
{
|
||||||
|
$url = route("vacation.requests.show", ["vacationRequest" => $this->vacationRequest->id]);
|
||||||
|
|
||||||
|
return implode("\n", [
|
||||||
|
$this->buildDescription(),
|
||||||
|
"<${url}|Zobacz szczegóły>",
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,18 +90,16 @@ class VacationRequestCreatedNotification extends Notification
|
|||||||
protected function buildDescription(): string
|
protected function buildDescription(): string
|
||||||
{
|
{
|
||||||
$name = $this->vacationRequest->name;
|
$name = $this->vacationRequest->name;
|
||||||
$appName = config("app.name");
|
|
||||||
|
|
||||||
if ($this->vacationRequest->creator()->is($this->vacationRequest->user)) {
|
if ($this->vacationRequest->creator()->is($this->vacationRequest->user)) {
|
||||||
return __("The vacation request :title has been created correctly in the :appName.", [
|
return __("The vacation request :title for user :user has been created successfully.", [
|
||||||
|
"user" => $this->vacationRequest->user->profile->full_name,
|
||||||
"title" => $name,
|
"title" => $name,
|
||||||
"appName" => $appName,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return __("The vacation request :title has been created correctly by user :creator on your behalf in the :appName.", [
|
return __("The vacation request :title has been created successfully by user :creator on your behalf.", [
|
||||||
"title" => $this->vacationRequest->name,
|
"title" => $this->vacationRequest->name,
|
||||||
"appName" => $appName,
|
|
||||||
"creator" => $this->vacationRequest->creator->profile->full_name,
|
"creator" => $this->vacationRequest->creator->profile->full_name,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,17 @@ class VacationRequestStatusChangedNotification extends Notification
|
|||||||
|
|
||||||
public function via(): array
|
public function via(): array
|
||||||
{
|
{
|
||||||
return ["mail"];
|
return ["mail", "slack"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toSlack(): string
|
||||||
|
{
|
||||||
|
$url = route("vacation.requests.show", ["vacationRequest" => $this->vacationRequest->id]);
|
||||||
|
|
||||||
|
return implode("\n", [
|
||||||
|
$this->buildDescription(),
|
||||||
|
"<${url}|Zobacz szczegóły>",
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,27 +53,17 @@ class VacationRequestStatusChangedNotification extends Notification
|
|||||||
protected function buildMailMessage(string $url): MailMessage
|
protected function buildMailMessage(string $url): MailMessage
|
||||||
{
|
{
|
||||||
$user = $this->user->profile->first_name;
|
$user = $this->user->profile->first_name;
|
||||||
$title = $this->vacationRequest->name;
|
|
||||||
$type = $this->vacationRequest->type->label();
|
$type = $this->vacationRequest->type->label();
|
||||||
$status = $this->vacationRequest->state->label();
|
|
||||||
$from = $this->vacationRequest->from->toDisplayString();
|
$from = $this->vacationRequest->from->toDisplayString();
|
||||||
$to = $this->vacationRequest->to->toDisplayString();
|
$to = $this->vacationRequest->to->toDisplayString();
|
||||||
$days = $this->vacationRequest->vacations()->count();
|
$days = $this->vacationRequest->vacations()->count();
|
||||||
$requester = $this->vacationRequest->user->profile->full_name;
|
|
||||||
|
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->greeting(__("Hi :user!", [
|
->greeting(__("Hi :user!", [
|
||||||
"user" => $user,
|
"user" => $user,
|
||||||
]))
|
]))
|
||||||
->subject(__("Vacation request :title has been :status", [
|
->subject($this->buildSubject())
|
||||||
"title" => $title,
|
->line($this->buildDescription())
|
||||||
"status" => $status,
|
|
||||||
]))
|
|
||||||
->line(__("The vacation request :title from user :requester has been :status.", [
|
|
||||||
"title" => $title,
|
|
||||||
"requester" => $requester,
|
|
||||||
"status" => $status,
|
|
||||||
]))
|
|
||||||
->line(__("Vacation type: :type", [
|
->line(__("Vacation type: :type", [
|
||||||
"type" => $type,
|
"type" => $type,
|
||||||
]))
|
]))
|
||||||
@ -74,4 +74,21 @@ class VacationRequestStatusChangedNotification extends Notification
|
|||||||
]))
|
]))
|
||||||
->action(__("Click here for details"), $url);
|
->action(__("Click here for details"), $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function buildSubject(): string
|
||||||
|
{
|
||||||
|
return __("Vacation request :title has been :status", [
|
||||||
|
"title" => $this->vacationRequest->name,
|
||||||
|
"status" => $this->vacationRequest->state->label(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildDescription(): string
|
||||||
|
{
|
||||||
|
return __("The vacation request :title from user :requester has been :status.", [
|
||||||
|
"title" => $this->vacationRequest->name,
|
||||||
|
"requester" => $this->vacationRequest->user->profile->full_name,
|
||||||
|
"status" => $this->vacationRequest->state->label(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,17 @@ class VacationRequestWaitsForApprovalNotification extends Notification
|
|||||||
|
|
||||||
public function via(): array
|
public function via(): array
|
||||||
{
|
{
|
||||||
return ["mail"];
|
return ["mail", "slack"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toSlack(): string
|
||||||
|
{
|
||||||
|
$url = route("vacation.requests.show", ["vacationRequest" => $this->vacationRequest->id]);
|
||||||
|
|
||||||
|
return implode("\n", [
|
||||||
|
$this->buildDescription(),
|
||||||
|
"<${url}|Zobacz szczegóły>",
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
25
app/Domain/Slack/Channels/SlackApiChannel.php
Normal file
25
app/Domain/Slack/Channels/SlackApiChannel.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Toby\Domain\Slack\Channels;
|
||||||
|
|
||||||
|
use Illuminate\Http\Client\Response;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
|
||||||
|
class SlackApiChannel
|
||||||
|
{
|
||||||
|
public function send($notifiable, Notification $notification): Response
|
||||||
|
{
|
||||||
|
$baseUrl = config("services.slack.url");
|
||||||
|
$url = "{$baseUrl}/chat.postMessage";
|
||||||
|
$channel = $notifiable->routeNotificationFor('slack', $notification);
|
||||||
|
|
||||||
|
return Http::withToken(config("services.slack.client_token"))
|
||||||
|
->post($url, [
|
||||||
|
"channel" => $channel,
|
||||||
|
"text" => $notification->toSlack(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
51
app/Domain/Slack/Handlers/CatchAll.php
Normal file
51
app/Domain/Slack/Handlers/CatchAll.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
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\Request;
|
||||||
|
use Spatie\SlashCommand\Response;
|
||||||
|
|
||||||
|
class CatchAll extends BaseCatchAllHandler
|
||||||
|
{
|
||||||
|
public function handle(Request $request): Response
|
||||||
|
{
|
||||||
|
$response = $this->respondToSlack("Nie rozpoznaję tej komendy: `/{$request->command} {$request->text}`");
|
||||||
|
|
||||||
|
[$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 $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);
|
||||||
|
}
|
||||||
|
}
|
74
app/Domain/Slack/Handlers/DailySummary.php
Normal file
74
app/Domain/Slack/Handlers/DailySummary.php
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
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\Eloquent\Models\User;
|
||||||
|
use Toby\Eloquent\Models\Vacation;
|
||||||
|
|
||||||
|
class DailySummary extends SignatureHandler
|
||||||
|
{
|
||||||
|
protected $signature = "toby dzisiaj";
|
||||||
|
|
||||||
|
protected $description = "Podsumowanie";
|
||||||
|
|
||||||
|
public function handle(Request $request): Response
|
||||||
|
{
|
||||||
|
$configRetriever = app(VacationTypeConfigRetriever::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()
|
||||||
|
->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()
|
||||||
|
->map(fn(Vacation $vacation) => $vacation->user->profile->full_name);
|
||||||
|
|
||||||
|
$birthdays = User::query()
|
||||||
|
->whereRelation("profile", "birthday", $now)
|
||||||
|
->get()
|
||||||
|
->map(fn(User $user) => $user->profile->full_name);
|
||||||
|
|
||||||
|
$absencesAttachment = Attachment::create()
|
||||||
|
->setTitle("Nieobecności :palm_tree:")
|
||||||
|
->setColor('#eab308')
|
||||||
|
->setText($absences->isNotEmpty() ? $absences->implode("\n") : "Wszyscy dzisiaj pracują :muscle:");
|
||||||
|
|
||||||
|
$remoteAttachment = Attachment::create()
|
||||||
|
->setTitle("Praca zdalna :house_with_garden:")
|
||||||
|
->setColor('#d946ef')
|
||||||
|
->setText($remoteDays->isNotEmpty() ? $remoteDays->implode("\n") : "Wszyscy dzisiaj są w biurze :boom:");
|
||||||
|
|
||||||
|
$birthdayAttachment = Attachment::create()
|
||||||
|
->setTitle("Urodziny :birthday:")
|
||||||
|
->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();
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Toby\Domain\Slack;
|
namespace Toby\Domain\Slack\Handlers;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Spatie\SlashCommand\Request;
|
use Spatie\SlashCommand\Request;
|
||||||
@ -13,13 +13,13 @@ use Toby\Eloquent\Models\User;
|
|||||||
|
|
||||||
class GiveKeysTo extends SignatureHandler
|
class GiveKeysTo extends SignatureHandler
|
||||||
{
|
{
|
||||||
protected $signature = "toby klucze:dla {to}";
|
protected $signature = "toby klucze:dla {użytkownik}";
|
||||||
|
|
||||||
protected $description = "Daj klucze użytkownikowi {to}";
|
protected $description = "Daj klucze wskazanemu użytkownikowi";
|
||||||
|
|
||||||
public function handle(Request $request): Response
|
public function handle(Request $request): Response
|
||||||
{
|
{
|
||||||
$to = $this->getArgument('to');
|
$to = $this->getArgument('użytkownik');
|
||||||
|
|
||||||
$id = Str::between($to, "@", "|");
|
$id = Str::between($to, "@", "|");
|
||||||
|
|
45
app/Domain/Slack/Handlers/Help.php
Normal file
45
app/Domain/Slack/Handlers/Help.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
class Help extends BaseHelpHandler
|
||||||
|
{
|
||||||
|
protected $signature = "toby pomoc";
|
||||||
|
protected $description = "Wyświetl wszystkie dostępne komendy tobiego";
|
||||||
|
|
||||||
|
public function handle(Request $request): Response
|
||||||
|
{
|
||||||
|
$handlers = $this->findAvailableHandlers();
|
||||||
|
|
||||||
|
return $this->displayListOfAllCommands($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')
|
||||||
|
->withAttachment(
|
||||||
|
Attachment::create()
|
||||||
|
->setColor('good')
|
||||||
|
->setFields($attachmentFields)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Toby\Domain\Slack;
|
namespace Toby\Domain\Slack\Handlers;
|
||||||
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Spatie\SlashCommand\Request;
|
use Spatie\SlashCommand\Request;
|
||||||
@ -15,12 +15,12 @@ use Toby\Eloquent\Models\YearPeriod;
|
|||||||
|
|
||||||
class HomeOffice extends SignatureHandler
|
class HomeOffice extends SignatureHandler
|
||||||
{
|
{
|
||||||
protected $signature = "toby zdalnie {date=dzisiaj}";
|
protected $signature = "toby zdalnie {kiedy?}";
|
||||||
protected $description = "Praca zdalna {kiedy}";
|
protected $description = "Pracuj zdalnie wybranego dnia (domyślnie dzisiaj)";
|
||||||
|
|
||||||
public function handle(Request $request): Response
|
public function handle(Request $request): Response
|
||||||
{
|
{
|
||||||
$date = $this->getDateFromArgument($this->getArgument('date'));
|
$date = $this->getDateFromArgument($this->getArgument('kiedy') ?? "dzisiaj");
|
||||||
$user = $this->findUserBySlackId($request->userId);
|
$user = $this->findUserBySlackId($request->userId);
|
||||||
|
|
||||||
$yearPeriod = YearPeriod::findByYear($date->year);
|
$yearPeriod = YearPeriod::findByYear($date->year);
|
||||||
@ -34,7 +34,8 @@ class HomeOffice extends SignatureHandler
|
|||||||
"flow_skipped" => false,
|
"flow_skipped" => false,
|
||||||
], $user);
|
], $user);
|
||||||
|
|
||||||
return $this->respondToSlack("Praca zdalna dnia {$date->toDisplayString()} została utworzona pomyślnie");
|
return $this->respondToSlack("Praca zdalna dnia {$date->toDisplayString()} została utworzona pomyślnie.")
|
||||||
|
->displayResponseToEveryoneOnChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getDateFromArgument(string $argument): Carbon
|
protected function getDateFromArgument(string $argument): Carbon
|
33
app/Domain/Slack/Handlers/KeyList.php
Normal file
33
app/Domain/Slack/Handlers/KeyList.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Toby\Domain\Slack\Handlers;
|
||||||
|
|
||||||
|
use Spatie\SlashCommand\Attachment;
|
||||||
|
use Spatie\SlashCommand\Request;
|
||||||
|
use Spatie\SlashCommand\Response;
|
||||||
|
use Spatie\SlashCommand\Handlers\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
|
||||||
|
{
|
||||||
|
$keys = Key::query()
|
||||||
|
->orderBy("id")
|
||||||
|
->get()
|
||||||
|
->map(fn(Key $key) => "Klucz nr {$key->id} - <@{$key->user->profile->slack_id}>");
|
||||||
|
|
||||||
|
return $this->respondToSlack("Lista kluczy")
|
||||||
|
->withAttachment(
|
||||||
|
Attachment::create()
|
||||||
|
->setColor('#3C5F97')
|
||||||
|
->setText($keys->implode("\n"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
24
app/Domain/Slack/Handlers/SaySomething.php
Normal file
24
app/Domain/Slack/Handlers/SaySomething.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?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();
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Toby\Domain\Slack;
|
namespace Toby\Domain\Slack\Handlers;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Spatie\SlashCommand\Request;
|
use Spatie\SlashCommand\Request;
|
||||||
@ -13,13 +13,13 @@ use Toby\Eloquent\Models\User;
|
|||||||
|
|
||||||
class TakeKeysFrom extends SignatureHandler
|
class TakeKeysFrom extends SignatureHandler
|
||||||
{
|
{
|
||||||
protected $signature = "toby klucze:od {from}";
|
protected $signature = "toby klucze:od {użytkownik}";
|
||||||
|
|
||||||
protected $description = "Zabierz klucze użytkownikowi {from}";
|
protected $description = "Zabierz klucze wskazanemu użytkownikowi";
|
||||||
|
|
||||||
public function handle(Request $request): Response
|
public function handle(Request $request): Response
|
||||||
{
|
{
|
||||||
$from = $this->getArgument('from');
|
$from = $this->getArgument("użytkownik");
|
||||||
|
|
||||||
$id = Str::between($from, "@", "|");
|
$id = Str::between($from, "@", "|");
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Toby\Domain\Slack;
|
|
||||||
|
|
||||||
use Spatie\SlashCommand\Request;
|
|
||||||
use Spatie\SlashCommand\Response;
|
|
||||||
use Spatie\SlashCommand\Handlers\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
|
|
||||||
{
|
|
||||||
$temp = [];
|
|
||||||
|
|
||||||
foreach (Key::orderBy("id")->get() as $key) {
|
|
||||||
$temp[] = "Klucz nr {$key->id} - <@{$key->user->profile->slack_id}>";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return $this->respondToSlack(implode("\n", $temp))
|
|
||||||
->displayResponseToEveryoneOnChannel();
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,9 +11,10 @@ use Toby\Eloquent\Models\YearPeriod;
|
|||||||
|
|
||||||
class VacationDaysCalculator
|
class VacationDaysCalculator
|
||||||
{
|
{
|
||||||
public function calculateDays(YearPeriod $yearPeriod, CarbonInterface $from, CarbonInterface $to): Collection
|
public function calculateDays(CarbonInterface $from, CarbonInterface $to): Collection
|
||||||
{
|
{
|
||||||
$period = CarbonPeriod::create($from, $to);
|
$period = CarbonPeriod::create($from, $to);
|
||||||
|
$yearPeriod = YearPeriod::findByYear($from->year);
|
||||||
$holidays = $yearPeriod->holidays()->pluck("date");
|
$holidays = $yearPeriod->holidays()->pluck("date");
|
||||||
|
|
||||||
$validDays = new Collection();
|
$validDays = new Collection();
|
||||||
|
@ -29,7 +29,7 @@ class DoesNotExceedLimitRule implements VacationRequestRule
|
|||||||
|
|
||||||
$limit = $this->getUserVacationLimit($vacationRequest->user, $vacationRequest->yearPeriod);
|
$limit = $this->getUserVacationLimit($vacationRequest->user, $vacationRequest->yearPeriod);
|
||||||
$vacationDays = $this->getVacationDaysWithLimit($vacationRequest->user, $vacationRequest->yearPeriod);
|
$vacationDays = $this->getVacationDaysWithLimit($vacationRequest->user, $vacationRequest->yearPeriod);
|
||||||
$estimatedDays = $this->vacationDaysCalculator->calculateDays($vacationRequest->yearPeriod, $vacationRequest->from, $vacationRequest->to)->count();
|
$estimatedDays = $this->vacationDaysCalculator->calculateDays($vacationRequest->from, $vacationRequest->to)->count();
|
||||||
|
|
||||||
return $limit >= ($vacationDays + $estimatedDays);
|
return $limit >= ($vacationDays + $estimatedDays);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class MinimumOneVacationDayRule implements VacationRequestRule
|
|||||||
public function check(VacationRequest $vacationRequest): bool
|
public function check(VacationRequest $vacationRequest): bool
|
||||||
{
|
{
|
||||||
return $this->vacationDaysCalculator
|
return $this->vacationDaysCalculator
|
||||||
->calculateDays($vacationRequest->yearPeriod, $vacationRequest->from, $vacationRequest->to)
|
->calculateDays($vacationRequest->from, $vacationRequest->to)
|
||||||
->isNotEmpty();
|
->isNotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ use Toby\Eloquent\Helpers\ColorGenerator;
|
|||||||
* @property string $position
|
* @property string $position
|
||||||
* @property EmploymentForm $employment_form
|
* @property EmploymentForm $employment_form
|
||||||
* @property Carbon $employment_date
|
* @property Carbon $employment_date
|
||||||
|
* @property Carbon $birthday
|
||||||
*/
|
*/
|
||||||
class Profile extends Model
|
class Profile extends Model
|
||||||
{
|
{
|
||||||
@ -32,6 +33,7 @@ class Profile extends Model
|
|||||||
protected $casts = [
|
protected $casts = [
|
||||||
"employment_form" => EmploymentForm::class,
|
"employment_form" => EmploymentForm::class,
|
||||||
"employment_date" => "date",
|
"employment_date" => "date",
|
||||||
|
"birthday" => "date",
|
||||||
];
|
];
|
||||||
|
|
||||||
public function user(): BelongsTo
|
public function user(): BelongsTo
|
||||||
|
@ -125,6 +125,11 @@ class User extends Authenticatable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function routeNotificationForSlack()
|
||||||
|
{
|
||||||
|
return $this->profile->slack_id;
|
||||||
|
}
|
||||||
|
|
||||||
protected static function newFactory(): UserFactory
|
protected static function newFactory(): UserFactory
|
||||||
{
|
{
|
||||||
return UserFactory::new();
|
return UserFactory::new();
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Toby\Infrastructure\Console\Commands;
|
||||||
|
|
||||||
|
use Carbon\CarbonInterface;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Spatie\SlashCommand\Attachment;
|
||||||
|
use Toby\Domain\Enums\VacationType;
|
||||||
|
use Toby\Domain\VacationTypeConfigRetriever;
|
||||||
|
use Toby\Eloquent\Models\Holiday;
|
||||||
|
use Toby\Eloquent\Models\User;
|
||||||
|
use Toby\Eloquent\Models\Vacation;
|
||||||
|
|
||||||
|
class SendDailySummaryToSlack extends Command
|
||||||
|
{
|
||||||
|
protected $signature = "toby:slack:daily-summary {--f|force}";
|
||||||
|
protected $description = "Sent daily summary to slack";
|
||||||
|
|
||||||
|
public function handle(VacationTypeConfigRetriever $configRetriever): void
|
||||||
|
{
|
||||||
|
$now = Carbon::today();
|
||||||
|
|
||||||
|
if (!$this->option("force") && !$this->shouldHandle($now)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Collection $absences */
|
||||||
|
$absences = Vacation::query()
|
||||||
|
->with(["user", "vacationRequest"])
|
||||||
|
->whereDate("date", $now)
|
||||||
|
->approved()
|
||||||
|
->whereTypes(VacationType::all()->filter(fn(VacationType $type) => $configRetriever->isVacation($type)))
|
||||||
|
->get()
|
||||||
|
->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()
|
||||||
|
->map(fn(Vacation $vacation) => $vacation->user->profile->full_name);
|
||||||
|
|
||||||
|
$birthdays = User::query()
|
||||||
|
->whereRelation("profile", "birthday", $now)
|
||||||
|
->get()
|
||||||
|
->map(fn(User $user) => $user->profile->full_name);
|
||||||
|
|
||||||
|
$absencesAttachment = Attachment::create()
|
||||||
|
->setTitle("Nieobecności :palm_tree:")
|
||||||
|
->setColor('#eab308')
|
||||||
|
->setText($absences->isNotEmpty() ? $absences->implode("\n") : "Wszyscy dzisiaj pracują :muscle:");
|
||||||
|
|
||||||
|
$remoteAttachment = Attachment::create()
|
||||||
|
->setTitle("Praca zdalna :house_with_garden:")
|
||||||
|
->setColor('#d946ef')
|
||||||
|
->setText($remoteDays->isNotEmpty() ? $remoteDays->implode("\n") : "Wszyscy dzisiaj są w biurze :boom:");
|
||||||
|
|
||||||
|
$birthdayAttachment = Attachment::create()
|
||||||
|
->setTitle("Urodziny :birthday:")
|
||||||
|
->setColor('#3C5F97')
|
||||||
|
->setText($birthdays->isNotEmpty() ? $birthdays->implode("\n") : "Dzisiaj nikt nie ma urodzin :cry:");
|
||||||
|
|
||||||
|
$baseUrl = config("services.slack.url");
|
||||||
|
$url = "{$baseUrl}/chat.postMessage";
|
||||||
|
|
||||||
|
Http::withToken(config("services.slack.client_token"))
|
||||||
|
->post($url, [
|
||||||
|
"channel" => config("services.slack.default_channel"),
|
||||||
|
"text" => "Podsumowanie dla dnia {$now->toDisplayString()}",
|
||||||
|
'attachments' => collect([$absencesAttachment, $remoteAttachment, $birthdayAttachment])->map(
|
||||||
|
fn(Attachment $attachment) => $attachment->toArray()
|
||||||
|
)->toArray(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function shouldHandle(CarbonInterface $day): bool
|
||||||
|
{
|
||||||
|
$holidays = Holiday::query()->whereDate("date", $day)->pluck("date");
|
||||||
|
|
||||||
|
if ($day->isWeekend()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($holidays->contains($day)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ class CalculateVacationDaysController extends Controller
|
|||||||
{
|
{
|
||||||
public function __invoke(CalculateVacationDaysRequest $request, VacationDaysCalculator $calculator): JsonResponse
|
public function __invoke(CalculateVacationDaysRequest $request, VacationDaysCalculator $calculator): JsonResponse
|
||||||
{
|
{
|
||||||
$days = $calculator->calculateDays($request->yearPeriod(), $request->from(), $request->to());
|
$days = $calculator->calculateDays($request->from(), $request->to());
|
||||||
|
|
||||||
return new JsonResponse($days->map(fn(Carbon $day) => $day->toDateString())->all());
|
return new JsonResponse($days->map(fn(Carbon $day) => $day->toDateString())->all());
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ class UserRequest extends FormRequest
|
|||||||
"position" => ["required"],
|
"position" => ["required"],
|
||||||
"employmentForm" => ["required", new Enum(EmploymentForm::class)],
|
"employmentForm" => ["required", new Enum(EmploymentForm::class)],
|
||||||
"employmentDate" => ["required", "date_format:Y-m-d"],
|
"employmentDate" => ["required", "date_format:Y-m-d"],
|
||||||
|
"birthday" => ["nullable", "date_format:Y-m-d"],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +42,7 @@ class UserRequest extends FormRequest
|
|||||||
"position" => $this->get("position"),
|
"position" => $this->get("position"),
|
||||||
"employment_form" => $this->get("employmentForm"),
|
"employment_form" => $this->get("employmentForm"),
|
||||||
"employment_date" => $this->get("employmentDate"),
|
"employment_date" => $this->get("employmentDate"),
|
||||||
|
"birthday" => $this->get("birthday"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ class UserFormDataResource extends JsonResource
|
|||||||
"position" => $this->profile->position,
|
"position" => $this->profile->position,
|
||||||
"employmentForm" => $this->profile->employment_form,
|
"employmentForm" => $this->profile->employment_form,
|
||||||
"employmentDate" => $this->profile->employment_date->toDateString(),
|
"employmentDate" => $this->profile->employment_date->toDateString(),
|
||||||
|
"birthday" => $this->profile->birthday->toDateString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ return [
|
|||||||
Illuminate\Validation\ValidationServiceProvider::class,
|
Illuminate\Validation\ValidationServiceProvider::class,
|
||||||
Illuminate\View\ViewServiceProvider::class,
|
Illuminate\View\ViewServiceProvider::class,
|
||||||
Barryvdh\DomPDF\ServiceProvider::class,
|
Barryvdh\DomPDF\ServiceProvider::class,
|
||||||
Spatie\SlashCommand\SlashCommandServiceProvider::class,
|
|
||||||
Toby\Architecture\Providers\AppServiceProvider::class,
|
Toby\Architecture\Providers\AppServiceProvider::class,
|
||||||
Toby\Architecture\Providers\AuthServiceProvider::class,
|
Toby\Architecture\Providers\AuthServiceProvider::class,
|
||||||
Toby\Architecture\Providers\EventServiceProvider::class,
|
Toby\Architecture\Providers\EventServiceProvider::class,
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Toby\Domain\Slack\GiveKeysTo;
|
declare(strict_types=1);
|
||||||
use Toby\Domain\Slack\HomeOffice;
|
|
||||||
use Toby\Domain\Slack\KeyList;
|
use Toby\Domain\Slack\Handlers\CatchAll;
|
||||||
use Toby\Domain\Slack\TakeKeysFrom;
|
use Toby\Domain\Slack\Handlers\DailySummary;
|
||||||
|
use Toby\Domain\Slack\Handlers\GiveKeysTo;
|
||||||
|
use Toby\Domain\Slack\Handlers\Help;
|
||||||
|
use Toby\Domain\Slack\Handlers\HomeOffice;
|
||||||
|
use Toby\Domain\Slack\Handlers\KeyList;
|
||||||
|
use Toby\Domain\Slack\Handlers\SaySomething;
|
||||||
|
use Toby\Domain\Slack\Handlers\TakeKeysFrom;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'url' => 'api/slack',
|
'url' => 'api/slack',
|
||||||
@ -14,7 +20,9 @@ return [
|
|||||||
GiveKeysTo::class,
|
GiveKeysTo::class,
|
||||||
KeyList::class,
|
KeyList::class,
|
||||||
HomeOffice::class,
|
HomeOffice::class,
|
||||||
Spatie\SlashCommand\Handlers\Help::class,
|
DailySummary::class,
|
||||||
Spatie\SlashCommand\Handlers\CatchAll::class,
|
SaySomething::class,
|
||||||
|
Help::class,
|
||||||
|
CatchAll::class
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -8,4 +8,9 @@ return [
|
|||||||
"client_secret" => env("GOOGLE_CLIENT_SECRET"),
|
"client_secret" => env("GOOGLE_CLIENT_SECRET"),
|
||||||
"redirect" => env("GOOGLE_REDIRECT"),
|
"redirect" => env("GOOGLE_REDIRECT"),
|
||||||
],
|
],
|
||||||
|
"slack" => [
|
||||||
|
"url" => "https://slack.com/api",
|
||||||
|
"client_token" => env("SLACK_CLIENT_TOKEN"),
|
||||||
|
"default_channel" => env("SLACK_DEFAULT_CHANNEL"),
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
@ -23,6 +23,7 @@ class ProfileFactory extends Factory
|
|||||||
"employment_form" => $this->faker->randomElement(EmploymentForm::cases()),
|
"employment_form" => $this->faker->randomElement(EmploymentForm::cases()),
|
||||||
"position" => $this->faker->jobTitle(),
|
"position" => $this->faker->jobTitle(),
|
||||||
"employment_date" => Carbon::createFromInterface($this->faker->dateTimeBetween("2020-10-27"))->toDateString(),
|
"employment_date" => Carbon::createFromInterface($this->faker->dateTimeBetween("2020-10-27"))->toDateString(),
|
||||||
|
"birthday" => Carbon::createFromInterface($this->faker->dateTimeBetween("1970-01-01", "1998-01-01"))->toDateString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,15 @@ return new class() extends Migration {
|
|||||||
{
|
{
|
||||||
Schema::table("profiles", function (Blueprint $table): void {
|
Schema::table("profiles", function (Blueprint $table): void {
|
||||||
$table->string("slack_id")->nullable();
|
$table->string("slack_id")->nullable();
|
||||||
|
$table->date("birthday")->nullable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::table("profiles", function (Blueprint $table): void {
|
Schema::table("profiles", function (Blueprint $table): void {
|
||||||
$table->string("slack_id");
|
$table->dropColumn("slack_id");
|
||||||
|
$table->dropColumn("birthday");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -234,6 +234,29 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="items-center py-4 sm:grid sm:grid-cols-3">
|
||||||
|
<label
|
||||||
|
for="birthday"
|
||||||
|
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||||
|
>
|
||||||
|
Data urodzenia
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
|
<FlatPickr
|
||||||
|
id="birthday"
|
||||||
|
v-model="form.birthday"
|
||||||
|
placeholder="Wybierz datę"
|
||||||
|
class="block w-full max-w-lg rounded-md shadow-sm sm:text-sm"
|
||||||
|
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.birthday, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.birthday }"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
v-if="form.errors.birthday"
|
||||||
|
class="mt-2 text-sm text-red-600"
|
||||||
|
>
|
||||||
|
{{ form.errors.birthday }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="flex justify-end py-3">
|
<div class="flex justify-end py-3">
|
||||||
<div class="space-x-3">
|
<div class="space-x-3">
|
||||||
<InertiaLink
|
<InertiaLink
|
||||||
@ -274,6 +297,7 @@ const form = useForm({
|
|||||||
role: props.roles[0],
|
role: props.roles[0],
|
||||||
position: null,
|
position: null,
|
||||||
employmentDate: null,
|
employmentDate: null,
|
||||||
|
birthday: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
function createUser() {
|
function createUser() {
|
||||||
|
@ -241,6 +241,29 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="items-center py-4 sm:grid sm:grid-cols-3">
|
||||||
|
<label
|
||||||
|
for="birthday"
|
||||||
|
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||||
|
>
|
||||||
|
Data urodzenia
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
|
<FlatPickr
|
||||||
|
id="birthday"
|
||||||
|
v-model="form.birthday"
|
||||||
|
placeholder="Wybierz datę"
|
||||||
|
class="block w-full max-w-lg rounded-md shadow-sm sm:text-sm"
|
||||||
|
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.birthday, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.birthday }"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
v-if="form.errors.birthday"
|
||||||
|
class="mt-2 text-sm text-red-600"
|
||||||
|
>
|
||||||
|
{{ form.errors.birthday }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="flex justify-end py-3">
|
<div class="flex justify-end py-3">
|
||||||
<div class="space-x-3">
|
<div class="space-x-3">
|
||||||
<InertiaLink
|
<InertiaLink
|
||||||
@ -282,6 +305,7 @@ const form = useForm({
|
|||||||
position: props.user.position,
|
position: props.user.position,
|
||||||
employmentForm: props.employmentForms.find(form => form.value === props.user.employmentForm),
|
employmentForm: props.employmentForms.find(form => form.value === props.user.employmentForm),
|
||||||
employmentDate: props.user.employmentDate,
|
employmentDate: props.user.employmentDate,
|
||||||
|
birthday: props.user.birthday,
|
||||||
})
|
})
|
||||||
|
|
||||||
function editUser() {
|
function editUser() {
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
"All rights reserved.": "Wszelkie prawa zastrzeżone",
|
"All rights reserved.": "Wszelkie prawa zastrzeżone",
|
||||||
"Show vacation request": "Pokaż wniosek",
|
"Show vacation request": "Pokaż wniosek",
|
||||||
"Vacation request :title has been created" : "Wniosek :title został utworzony",
|
"Vacation request :title has been created" : "Wniosek :title został utworzony",
|
||||||
"The vacation request :title has been created correctly in the :appName.": "W systemie :appName został poprawnie utworzony wniosek urlopowy :title.",
|
"The vacation request :title from user :requester has been created sucessfully.": "Wniosek :title użytkownika :requester został utworzony pomyślnie.",
|
||||||
"Vacation type: :type": "Rodzaj wniosku: :type",
|
"Vacation type: :type": "Rodzaj wniosku: :type",
|
||||||
"From :from to :to (number of days: :days)": "Od :from do :to (liczba dni: :days)",
|
"From :from to :to (number of days: :days)": "Od :from do :to (liczba dni: :days)",
|
||||||
"Click here for details": "Kliknij, aby zobaczyć szczegóły",
|
"Click here for details": "Kliknij, aby zobaczyć szczegóły",
|
||||||
@ -67,7 +67,7 @@
|
|||||||
"Vacation request :title has been :status": "Wniosek :title został :status",
|
"Vacation request :title has been :status": "Wniosek :title został :status",
|
||||||
"The vacation request :title from user :requester has been :status.": "Wniosek urlopowy :title użytkownika :requester został :status.",
|
"The vacation request :title from user :requester has been :status.": "Wniosek urlopowy :title użytkownika :requester został :status.",
|
||||||
"Vacation request :title has been created on your behalf": "Wniosek urlopowy :title został utworzony w Twoim imieniu",
|
"Vacation request :title has been created on your behalf": "Wniosek urlopowy :title został utworzony w Twoim imieniu",
|
||||||
"The vacation request :title has been created correctly by user :creator on your behalf in the :appName.": "W systemie :appName został poprawnie utworzony wniosek urlopowy :title w Twoim imieniu przez użytkownika :creator.",
|
"The vacation request :title has been created successfully by user :creator on your behalf.": "Wniosek urlopowy :title został pomyślnie utworzony w Twoim imieniu przez użytkownika :creator.",
|
||||||
"Key no :number has been created.": "Klucz nr :number został utworzony.",
|
"Key no :number has been created.": "Klucz nr :number został utworzony.",
|
||||||
"Key no :number has been deleted.": "Klucz nr :number został usunięty.",
|
"Key no :number has been deleted.": "Klucz nr :number został usunięty.",
|
||||||
"Key no :number has been taken from :user.": "Klucz nr :number został zabrany użytkownikowi :user.",
|
"Key no :number has been taken from :user.": "Klucz nr :number został zabrany użytkownikowi :user.",
|
||||||
|
82
tests/Unit/SendDailySummaryToSlackTest.php
Normal file
82
tests/Unit/SendDailySummaryToSlackTest.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Unit;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Tests\Traits\InteractsWithYearPeriods;
|
||||||
|
use Toby\Eloquent\Models\Holiday;
|
||||||
|
use Toby\Infrastructure\Console\Commands\SendDailySummaryToSlack;
|
||||||
|
|
||||||
|
class SendDailySummaryToSlackTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
use InteractsWithYearPeriods;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
Http::fake();
|
||||||
|
$this->createCurrentYearPeriod();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCommandSendsMessageToSlackIfWeekday(): void
|
||||||
|
{
|
||||||
|
$weekDay = Carbon::create(2022, 4, 22);
|
||||||
|
$this->assertTrue($weekDay->isWeekday());
|
||||||
|
|
||||||
|
$this->travelTo($weekDay);
|
||||||
|
|
||||||
|
$this->artisan(SendDailySummaryToSlack::class)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
Http::assertSentCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCommandDoesntSendIfIsWeekend(): void
|
||||||
|
{
|
||||||
|
$weekend = Carbon::create(2022, 4, 23);
|
||||||
|
$this->assertTrue($weekend->isWeekend());
|
||||||
|
|
||||||
|
$this->travelTo($weekend);
|
||||||
|
|
||||||
|
$this->artisan(SendDailySummaryToSlack::class)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
Http::assertNothingSent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCommandDoesntSendIfIsHoliday(): void
|
||||||
|
{
|
||||||
|
$holiday = Holiday::factory(["date" => Carbon::create(2022, 4, 22)])->create();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas("holidays", [
|
||||||
|
"date" => $holiday->date->toDateString(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->travelTo(Carbon::create(2022, 4, 22));
|
||||||
|
|
||||||
|
$this->artisan(SendDailySummaryToSlack::class)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
Http::assertNothingSent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCommandForceSendsMessageEvenIsWeekendOrHoliday(): void
|
||||||
|
{
|
||||||
|
$weekend = Carbon::create(2022, 4, 23);
|
||||||
|
$this->assertTrue($weekend->isWeekend());
|
||||||
|
|
||||||
|
$this->travelTo($weekend);
|
||||||
|
|
||||||
|
$this->artisan(SendDailySummaryToSlack::class, ["--force" => true])
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
Http::assertSentCount(1);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user