#116 - cr fix
This commit is contained in:
		| @@ -9,19 +9,19 @@ use Illuminate\Notifications\ChannelManager; | |||||||
| use Illuminate\Support\Carbon; | use Illuminate\Support\Carbon; | ||||||
| use Illuminate\Support\Facades\Notification; | use Illuminate\Support\Facades\Notification; | ||||||
| use Illuminate\Support\ServiceProvider; | use Illuminate\Support\ServiceProvider; | ||||||
| use Toby\Domain\Slack\Channels\SlackApiChannel; | use Toby\Infrastructure\Slack\Channels\SlackApiChannel; | ||||||
|  |  | ||||||
| class AppServiceProvider extends ServiceProvider | class AppServiceProvider extends ServiceProvider | ||||||
| { | { | ||||||
|     public function register(): void |     public function register(): void | ||||||
|     { |     { | ||||||
|         Notification::resolved(function (ChannelManager $service): void { |         Notification::resolved(function (ChannelManager $service): void { | ||||||
|             $service->extend("slack", fn(Application $app) => $app->make(SlackApiChannel::class)); |             $service->extend("slack", fn(Application $app): SlackApiChannel => $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(): string => $this->translatedFormat("d.m.Y")); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -30,10 +30,10 @@ class AuthServiceProvider extends ServiceProvider | |||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         Gate::define("manageUsers", fn(User $user) => $user->role === Role::AdministrativeApprover); |         Gate::define("manageUsers", fn(User $user): bool => $user->role === Role::AdministrativeApprover); | ||||||
|         Gate::define("manageHolidays", fn(User $user) => $user->role === Role::AdministrativeApprover); |         Gate::define("manageHolidays", fn(User $user): bool => $user->role === Role::AdministrativeApprover); | ||||||
|         Gate::define("manageVacationLimits", fn(User $user) => $user->role === Role::AdministrativeApprover); |         Gate::define("manageVacationLimits", fn(User $user): bool => $user->role === Role::AdministrativeApprover); | ||||||
|         Gate::define("generateTimesheet", fn(User $user) => $user->role === Role::AdministrativeApprover); |         Gate::define("generateTimesheet", fn(User $user): bool => $user->role === Role::AdministrativeApprover); | ||||||
|         Gate::define("listMonthlyUsage", fn(User $user) => $user->role === Role::AdministrativeApprover); |         Gate::define("listMonthlyUsage", fn(User $user): bool => $user->role === Role::AdministrativeApprover); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,6 +28,6 @@ class RouteServiceProvider extends ServiceProvider | |||||||
|  |  | ||||||
|     protected function configureRateLimiting(): void |     protected function configureRateLimiting(): void | ||||||
|     { |     { | ||||||
|         RateLimiter::for("api", fn(Request $request) => Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip())); |         RateLimiter::for("api", fn(Request $request): Limit => Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip())); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -57,6 +57,6 @@ class CalendarGenerator | |||||||
|             ->approved() |             ->approved() | ||||||
|             ->with("vacationRequest") |             ->with("vacationRequest") | ||||||
|             ->get() |             ->get() | ||||||
|             ->groupBy(fn(Vacation $vacation) => $vacation->date->toDateString()); |             ->groupBy(fn(Vacation $vacation): string => $vacation->date->toDateString()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,7 +22,9 @@ class DailySummaryRetriever | |||||||
|             ->with(["user", "vacationRequest"]) |             ->with(["user", "vacationRequest"]) | ||||||
|             ->whereDate("date", $date) |             ->whereDate("date", $date) | ||||||
|             ->approved() |             ->approved() | ||||||
|             ->whereTypes(VacationType::all()->filter(fn(VacationType $type): bool => $this->configRetriever->isVacation($type))) |             ->whereTypes( | ||||||
|  |                 VacationType::all()->filter(fn(VacationType $type): bool => $this->configRetriever->isVacation($type)), | ||||||
|  |             ) | ||||||
|             ->get(); |             ->get(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -32,7 +34,9 @@ class DailySummaryRetriever | |||||||
|             ->with(["user", "vacationRequest"]) |             ->with(["user", "vacationRequest"]) | ||||||
|             ->whereDate("date", $date) |             ->whereDate("date", $date) | ||||||
|             ->approved() |             ->approved() | ||||||
|             ->whereTypes(VacationType::all()->filter(fn(VacationType $type): bool => !$this->configRetriever->isVacation($type))) |             ->whereTypes( | ||||||
|  |                 VacationType::all()->filter(fn(VacationType $type): bool => !$this->configRetriever->isVacation($type)), | ||||||
|  |             ) | ||||||
|             ->get(); |             ->get(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ enum EmploymentForm: string | |||||||
|         $cases = collect(EmploymentForm::cases()); |         $cases = collect(EmploymentForm::cases()); | ||||||
|  |  | ||||||
|         return $cases->map( |         return $cases->map( | ||||||
|             fn(EmploymentForm $enum) => [ |             fn(EmploymentForm $enum): array => [ | ||||||
|                 "label" => $enum->label(), |                 "label" => $enum->label(), | ||||||
|                 "value" => $enum->value, |                 "value" => $enum->value, | ||||||
|             ], |             ], | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ enum Role: string | |||||||
|         $cases = collect(Role::cases()); |         $cases = collect(Role::cases()); | ||||||
|  |  | ||||||
|         return $cases->map( |         return $cases->map( | ||||||
|             fn(Role $enum) => [ |             fn(Role $enum): array => [ | ||||||
|                 "label" => $enum->label(), |                 "label" => $enum->label(), | ||||||
|                 "value" => $enum->value, |                 "value" => $enum->value, | ||||||
|             ], |             ], | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ enum VacationType: string | |||||||
|         $cases = VacationType::all(); |         $cases = VacationType::all(); | ||||||
|  |  | ||||||
|         return $cases->map( |         return $cases->map( | ||||||
|             fn(VacationType $enum) => [ |             fn(VacationType $enum): array => [ | ||||||
|                 "label" => $enum->label(), |                 "label" => $enum->label(), | ||||||
|                 "value" => $enum->value, |                 "value" => $enum->value, | ||||||
|             ], |             ], | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								app/Domain/Notifications/Channels.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/Domain/Notifications/Channels.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Notifications; | ||||||
|  |  | ||||||
|  | class Channels | ||||||
|  | { | ||||||
|  |     public const MAIL = "mail"; | ||||||
|  |     public const SLACK = "slack"; | ||||||
|  | } | ||||||
| @@ -19,10 +19,10 @@ class KeyHasBeenGivenNotification extends Notification | |||||||
|  |  | ||||||
|     public function via(): array |     public function via(): array | ||||||
|     { |     { | ||||||
|         return ["slack"]; |         return [Channels::SLACK]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function toSlack($notifiable): string |     public function toSlack(Notifiable $notifiable): string | ||||||
|     { |     { | ||||||
|         return __(":sender gives key no :key to :recipient", [ |         return __(":sender gives key no :key to :recipient", [ | ||||||
|             "sender" => $this->getName($this->sender), |             "sender" => $this->getName($this->sender), | ||||||
|   | |||||||
| @@ -19,10 +19,10 @@ class KeyHasBeenTakenNotification extends Notification | |||||||
|  |  | ||||||
|     public function via(): array |     public function via(): array | ||||||
|     { |     { | ||||||
|         return ["slack"]; |         return [Channels::SLACK]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function toSlack($notifiable): string |     public function toSlack(Notifiable $notifiable): string | ||||||
|     { |     { | ||||||
|         return __(":recipient takes key no :key from :sender", [ |         return __(":recipient takes key no :key from :sender", [ | ||||||
|             "recipient" => $this->getName($this->recipient), |             "recipient" => $this->getName($this->recipient), | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								app/Domain/Notifications/Notifiable.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/Domain/Notifications/Notifiable.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Notifications; | ||||||
|  |  | ||||||
|  | interface Notifiable | ||||||
|  | { | ||||||
|  |     public function notify($instance); | ||||||
|  | } | ||||||
| @@ -20,7 +20,7 @@ class VacationRequestCreatedNotification extends Notification | |||||||
|  |  | ||||||
|     public function via(): array |     public function via(): array | ||||||
|     { |     { | ||||||
|         return ["mail", "slack"]; |         return [Channels::MAIL, Channels::SLACK]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function toSlack(): string |     public function toSlack(): string | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ class VacationRequestStatusChangedNotification extends Notification | |||||||
|  |  | ||||||
|     public function via(): array |     public function via(): array | ||||||
|     { |     { | ||||||
|         return ["mail", "slack"]; |         return [Channels::MAIL, Channels::SLACK]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function toSlack(): string |     public function toSlack(): string | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ class VacationRequestWaitsForApprovalNotification extends Notification | |||||||
|  |  | ||||||
|     public function via(): array |     public function via(): array | ||||||
|     { |     { | ||||||
|         return ["mail", "slack"]; |         return [Channels::MAIL, Channels::SLACK]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function toSlack(): string |     public function toSlack(): string | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ class PolishHolidaysRetriever | |||||||
|  |  | ||||||
|     protected function prepareHolidays(array $holidays): Collection |     protected function prepareHolidays(array $holidays): Collection | ||||||
|     { |     { | ||||||
|         return collect($holidays)->map(fn(Holiday $holiday) => [ |         return collect($holidays)->map(fn(Holiday $holiday): array => [ | ||||||
|             "name" => $holiday->getName([static::LANG_KEY]), |             "name" => $holiday->getName([static::LANG_KEY]), | ||||||
|             "date" => Carbon::createFromTimestamp($holiday->getTimestamp()), |             "date" => Carbon::createFromTimestamp($holiday->getTimestamp()), | ||||||
|         ])->values(); |         ])->values(); | ||||||
|   | |||||||
| @@ -1,25 +0,0 @@ | |||||||
| <?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($notifiable), |  | ||||||
|             ]); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,55 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Slack\Handlers; |  | ||||||
|  |  | ||||||
| use Illuminate\Support\Carbon; |  | ||||||
| use Spatie\SlashCommand\Attachment; |  | ||||||
| use Spatie\SlashCommand\Request; |  | ||||||
| use Spatie\SlashCommand\Response; |  | ||||||
| use Toby\Domain\DailySummaryRetriever; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
| use Toby\Eloquent\Models\Vacation; |  | ||||||
|  |  | ||||||
| class DailySummary extends SignatureHandler |  | ||||||
| { |  | ||||||
|     protected $signature = "toby dzisiaj"; |  | ||||||
|     protected $description = "Codzienne podsumowanie"; |  | ||||||
|  |  | ||||||
|     public function handle(Request $request): Response |  | ||||||
|     { |  | ||||||
|         $dailySummaryRetriever = app()->make(DailySummaryRetriever::class); |  | ||||||
|  |  | ||||||
|         $now = Carbon::today(); |  | ||||||
|  |  | ||||||
|         $absences = $dailySummaryRetriever->getAbsences($now) |  | ||||||
|             ->map(fn(Vacation $vacation): string => $vacation->user->profile->full_name); |  | ||||||
|  |  | ||||||
|         $remoteDays = $dailySummaryRetriever->getRemoteDays($now) |  | ||||||
|             ->map(fn(Vacation $vacation): string => $vacation->user->profile->full_name); |  | ||||||
|  |  | ||||||
|         $birthdays = $dailySummaryRetriever->getBirthdays($now) |  | ||||||
|             ->map(fn(User $user): string => $user->profile->full_name); |  | ||||||
|  |  | ||||||
|         $absencesAttachment = Attachment::create() |  | ||||||
|             ->setTitle("Nieobecności :sunny:") |  | ||||||
|             ->setColor("#eab308") |  | ||||||
|             ->setText($absences->isNotEmpty() ? $absences->implode("\n") : "Wszyscy dzisiaj pracują :muscle:"); |  | ||||||
|  |  | ||||||
|         $remoteAttachment = Attachment::create() |  | ||||||
|             ->setTitle("Praca zdalna :house_with_garden:") |  | ||||||
|             ->setColor("#527aba") |  | ||||||
|             ->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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -18,7 +18,7 @@ class TimesheetExport implements WithMultipleSheets | |||||||
|     public function sheets(): array |     public function sheets(): array | ||||||
|     { |     { | ||||||
|         return $this->users |         return $this->users | ||||||
|             ->map(fn(User $user) => new TimesheetPerUserSheet($user, $this->month, $this->types)) |             ->map(fn(User $user): TimesheetPerUserSheet => new TimesheetPerUserSheet($user, $this->month, $this->types)) | ||||||
|             ->toArray(); |             ->toArray(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -193,8 +193,8 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With | |||||||
|             ->get() |             ->get() | ||||||
|             ->groupBy( |             ->groupBy( | ||||||
|                 [ |                 [ | ||||||
|                     fn(Vacation $vacation) => $vacation->date->toDateString(), |                     fn(Vacation $vacation): string => $vacation->date->toDateString(), | ||||||
|                     fn(Vacation $vacation) => $vacation->vacationRequest->type->value, |                     fn(Vacation $vacation): string => $vacation->vacationRequest->type->value, | ||||||
|                 ], |                 ], | ||||||
|             ); |             ); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -42,8 +42,8 @@ class UserVacationStatsRetriever | |||||||
|                     ->states(VacationRequestStatesRetriever::successStates()), |                     ->states(VacationRequestStatesRetriever::successStates()), | ||||||
|             ) |             ) | ||||||
|             ->get() |             ->get() | ||||||
|             ->groupBy(fn(Vacation $vacation) => strtolower($vacation->date->englishMonth)) |             ->groupBy(fn(Vacation $vacation): string => strtolower($vacation->date->englishMonth)) | ||||||
|             ->map(fn(Collection $items) => $items->count()); |             ->map(fn(Collection $items): int => $items->count()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function getPendingVacationDays(User $user, YearPeriod $yearPeriod): int |     public function getPendingVacationDays(User $user, YearPeriod $yearPeriod): int | ||||||
| @@ -107,13 +107,13 @@ class UserVacationStatsRetriever | |||||||
|     { |     { | ||||||
|         $types = VacationType::all(); |         $types = VacationType::all(); | ||||||
|  |  | ||||||
|         return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type)); |         return $types->filter(fn(VacationType $type): bool => $this->configRetriever->hasLimit($type)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected function getNotLimitableVacationTypes(): Collection |     protected function getNotLimitableVacationTypes(): Collection | ||||||
|     { |     { | ||||||
|         $types = VacationType::all(); |         $types = VacationType::all(); | ||||||
|  |  | ||||||
|         return $types->filter(fn(VacationType $type) => !$this->configRetriever->hasLimit($type)); |         return $types->filter(fn(VacationType $type): bool => !$this->configRetriever->hasLimit($type)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -64,6 +64,6 @@ class DoesNotExceedLimitRule implements VacationRequestRule | |||||||
|     { |     { | ||||||
|         $types = VacationType::all(); |         $types = VacationType::all(); | ||||||
|  |  | ||||||
|         return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type)); |         return $types->filter(fn(VacationType $type): bool => $this->configRetriever->hasLimit($type)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ class VacationTypeCanBeSelected implements VacationRequestRule | |||||||
|         $employmentForm = $vacationRequest->user->profile->employment_form; |         $employmentForm = $vacationRequest->user->profile->employment_form; | ||||||
|  |  | ||||||
|         $availableTypes = VacationType::all() |         $availableTypes = VacationType::all() | ||||||
|             ->filter(fn(VacationType $type) => $this->configRetriever->isAvailableFor($type, $employmentForm)); |             ->filter(fn(VacationType $type): bool => $this->configRetriever->isAvailableFor($type, $employmentForm)); | ||||||
|  |  | ||||||
|         return $availableTypes->contains($vacationRequest->type); |         return $availableTypes->contains($vacationRequest->type); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ class YearPeriodRetriever | |||||||
|  |  | ||||||
|         $years = YearPeriod::all(); |         $years = YearPeriod::all(); | ||||||
|  |  | ||||||
|         $navigation = $years->map(fn(YearPeriod $yearPeriod) => $this->toNavigation($yearPeriod)); |         $navigation = $years->map(fn(YearPeriod $yearPeriod): array => $this->toNavigation($yearPeriod)); | ||||||
|  |  | ||||||
|         return [ |         return [ | ||||||
|             "current" => $this->toNavigation($current), |             "current" => $this->toNavigation($current), | ||||||
|   | |||||||
| @@ -9,12 +9,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; | |||||||
| use Illuminate\Database\Eloquent\Model; | use Illuminate\Database\Eloquent\Model; | ||||||
| use Illuminate\Database\Eloquent\Relations\BelongsTo; | use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||||||
| use Illuminate\Notifications\Notifiable; | use Illuminate\Notifications\Notifiable; | ||||||
|  | use Toby\Domain\Notifications\Notifiable as NotifiableInterface; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @property int $id |  * @property int $id | ||||||
|  * @property User $user |  * @property User $user | ||||||
|  */ |  */ | ||||||
| class Key extends Model | class Key extends Model implements NotifiableInterface | ||||||
| { | { | ||||||
|     use HasFactory; |     use HasFactory; | ||||||
|     use Notifiable; |     use Notifiable; | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ use Illuminate\Notifications\Notifiable; | |||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use Toby\Domain\Enums\EmploymentForm; | use Toby\Domain\Enums\EmploymentForm; | ||||||
| use Toby\Domain\Enums\Role; | use Toby\Domain\Enums\Role; | ||||||
|  | use Toby\Domain\Notifications\Notifiable as NotifiableInterface; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @property int $id |  * @property int $id | ||||||
| @@ -26,7 +27,7 @@ use Toby\Domain\Enums\Role; | |||||||
|  * @property Collection $vacationRequests |  * @property Collection $vacationRequests | ||||||
|  * @property Collection $vacations |  * @property Collection $vacations | ||||||
|  */ |  */ | ||||||
| class User extends Authenticatable | class User extends Authenticatable implements NotifiableInterface | ||||||
| { | { | ||||||
|     use HasFactory; |     use HasFactory; | ||||||
|     use Notifiable; |     use Notifiable; | ||||||
| @@ -99,7 +100,7 @@ class User extends Authenticatable | |||||||
|             ->where("email", "ILIKE", "%{$text}%") |             ->where("email", "ILIKE", "%{$text}%") | ||||||
|             ->orWhereRelation( |             ->orWhereRelation( | ||||||
|                 "profile", |                 "profile", | ||||||
|                 fn(Builder $query) => $query |                 fn(Builder $query): Builder => $query | ||||||
|                     ->where("first_name", "ILIKE", "%{$text}%") |                     ->where("first_name", "ILIKE", "%{$text}%") | ||||||
|                     ->orWhere("last_name", "ILIKE", "%{$text}%"), |                     ->orWhere("last_name", "ILIKE", "%{$text}%"), | ||||||
|             ); |             ); | ||||||
|   | |||||||
| @@ -7,12 +7,13 @@ namespace Toby\Infrastructure\Console\Commands; | |||||||
| use Carbon\CarbonInterface; | use Carbon\CarbonInterface; | ||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
| use Illuminate\Support\Carbon; | use Illuminate\Support\Carbon; | ||||||
|  | use Illuminate\Support\Collection; | ||||||
| use Illuminate\Support\Facades\Http; | use Illuminate\Support\Facades\Http; | ||||||
| use Spatie\SlashCommand\Attachment; |  | ||||||
| use Toby\Domain\DailySummaryRetriever; | use Toby\Domain\DailySummaryRetriever; | ||||||
| use Toby\Eloquent\Models\Holiday; | use Toby\Eloquent\Models\Holiday; | ||||||
| use Toby\Eloquent\Models\User; | use Toby\Infrastructure\Slack\Elements\AbsencesAttachment; | ||||||
| use Toby\Eloquent\Models\Vacation; | use Toby\Infrastructure\Slack\Elements\BirthdaysAttachment; | ||||||
|  | use Toby\Infrastructure\Slack\Elements\RemotesAttachment; | ||||||
|  |  | ||||||
| class SendDailySummaryToSlack extends Command | class SendDailySummaryToSlack extends Command | ||||||
| { | { | ||||||
| @@ -27,40 +28,17 @@ class SendDailySummaryToSlack extends Command | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $absences = $dailySummaryRetriever->getAbsences($now) |         $attachments = new Collection([ | ||||||
|             ->map(fn(Vacation $vacation) => $vacation->user->profile->full_name); |             new AbsencesAttachment($dailySummaryRetriever->getAbsences($now)), | ||||||
|  |             new RemotesAttachment($dailySummaryRetriever->getRemoteDays($now)), | ||||||
|  |             new BirthdaysAttachment($dailySummaryRetriever->getBirthdays($now)), | ||||||
|  |         ]); | ||||||
|  |  | ||||||
|         $remoteDays = $dailySummaryRetriever->getRemoteDays($now) |         Http::withToken($this->getSlackClientToken()) | ||||||
|             ->map(fn(Vacation $vacation) => $vacation->user->profile->full_name); |             ->post($this->getUrl(), [ | ||||||
|  |                 "channel" => $this->getSlackChannel(), | ||||||
|         $birthdays = $dailySummaryRetriever->getBirthdays($now) |  | ||||||
|             ->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("#527aba") |  | ||||||
|             ->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()}", |                 "text" => "Podsumowanie dla dnia {$now->toDisplayString()}", | ||||||
|                 "attachments" => collect([$absencesAttachment, $remoteAttachment, $birthdayAttachment])->map( |                 "attachments" => $attachments, | ||||||
|                     fn(Attachment $attachment) => $attachment->toArray(), |  | ||||||
|                 )->toArray(), |  | ||||||
|             ]); |             ]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -78,4 +56,24 @@ class SendDailySummaryToSlack extends Command | |||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     protected function getUrl(): string | ||||||
|  |     { | ||||||
|  |         return "{$this->getSlackBaseUrl()}/chat.postMessage"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected function getSlackBaseUrl(): string | ||||||
|  |     { | ||||||
|  |         return config("services.slack.url"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected function getSlackClientToken(): string | ||||||
|  |     { | ||||||
|  |         return config("services.slack.client_token"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected function getSlackChannel(): string | ||||||
|  |     { | ||||||
|  |         return config("services.slack.default_channel"); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,6 +16,6 @@ class CalculateVacationDaysController extends Controller | |||||||
|     { |     { | ||||||
|         $days = $calculator->calculateDays($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): string => $day->toDateString())->all()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,8 +21,8 @@ class GetAvailableVacationTypesController extends Controller | |||||||
|         $user = User::query()->find($request->get("user")); |         $user = User::query()->find($request->get("user")); | ||||||
|  |  | ||||||
|         $types = VacationType::all() |         $types = VacationType::all() | ||||||
|             ->filter(fn(VacationType $type) => $configRetriever->isAvailableFor($type, $user->profile->employment_form)) |             ->filter(fn(VacationType $type): bool => $configRetriever->isAvailableFor($type, $user->profile->employment_form)) | ||||||
|             ->map(fn(VacationType $type) => [ |             ->map(fn(VacationType $type): array => [ | ||||||
|                 "label" => $type->label(), |                 "label" => $type->label(), | ||||||
|                 "value" => $type->value, |                 "value" => $type->value, | ||||||
|             ]) |             ]) | ||||||
|   | |||||||
| @@ -35,8 +35,10 @@ class TimesheetController extends Controller | |||||||
|  |  | ||||||
|         $types = VacationType::all() |         $types = VacationType::all() | ||||||
|             ->filter( |             ->filter( | ||||||
|                 fn(VacationType $type) => $configRetriever->isAvailableFor($type, EmploymentForm::EmploymentContract) |                 fn(VacationType $type): bool => $configRetriever->isAvailableFor( | ||||||
|                     && $configRetriever->isVacation($type), |                     $type, | ||||||
|  |                     EmploymentForm::EmploymentContract, | ||||||
|  |                 ) && $configRetriever->isVacation($type), | ||||||
|             ); |             ); | ||||||
|  |  | ||||||
|         $filename = "{$carbonMonth->translatedFormat("F Y")}.xlsx"; |         $filename = "{$carbonMonth->translatedFormat("F Y")}.xlsx"; | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ class VacationLimitController extends Controller | |||||||
|             ->sortBy(fn(VacationLimit $limit): string => "{$limit->user->profile->last_name} {$limit->user->profile->first_name}") |             ->sortBy(fn(VacationLimit $limit): string => "{$limit->user->profile->last_name} {$limit->user->profile->first_name}") | ||||||
|             ->values(); |             ->values(); | ||||||
|  |  | ||||||
|         $limitsResource = $limits->map(fn(VacationLimit $limit) => [ |         $limitsResource = $limits->map(fn(VacationLimit $limit): array => [ | ||||||
|             "id" => $limit->id, |             "id" => $limit->id, | ||||||
|             "user" => new UserResource($limit->user), |             "user" => new UserResource($limit->user), | ||||||
|             "hasVacation" => $limit->hasVacation(), |             "hasVacation" => $limit->hasVacation(), | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ class HandleInertiaRequests extends Middleware | |||||||
|     { |     { | ||||||
|         $user = $request->user(); |         $user = $request->user(); | ||||||
|  |  | ||||||
|         return fn() => [ |         return fn(): array => [ | ||||||
|             "user" => $user ? new UserResource($user) : null, |             "user" => $user ? new UserResource($user) : null, | ||||||
|             "can" => [ |             "can" => [ | ||||||
|                 "manageVacationLimits" => $user ? $user->can("manageVacationLimits") : false, |                 "manageVacationLimits" => $user ? $user->can("manageVacationLimits") : false, | ||||||
| @@ -45,7 +45,7 @@ class HandleInertiaRequests extends Middleware | |||||||
|  |  | ||||||
|     protected function getFlashData(Request $request): Closure |     protected function getFlashData(Request $request): Closure | ||||||
|     { |     { | ||||||
|         return fn() => [ |         return fn(): array => [ | ||||||
|             "success" => $request->session()->get("success"), |             "success" => $request->session()->get("success"), | ||||||
|             "error" => $request->session()->get("error"), |             "error" => $request->session()->get("error"), | ||||||
|             "info" => $request->session()->get("info"), |             "info" => $request->session()->get("info"), | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								app/Infrastructure/Slack/Channels/SlackApiChannel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/Infrastructure/Slack/Channels/SlackApiChannel.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Channels; | ||||||
|  |  | ||||||
|  | use Illuminate\Http\Client\Response; | ||||||
|  | use Illuminate\Notifications\Notification; | ||||||
|  | use Illuminate\Support\Facades\Http; | ||||||
|  | use Toby\Domain\Notifications\Notifiable; | ||||||
|  |  | ||||||
|  | class SlackApiChannel | ||||||
|  | { | ||||||
|  |     public function send(Notifiable $notifiable, Notification $notification): Response | ||||||
|  |     { | ||||||
|  |         $baseUrl = $this->getBaseUrl(); | ||||||
|  |         $url = "{$baseUrl}/chat.postMessage"; | ||||||
|  |         $channel = $notifiable->routeNotificationFor("slack", $notification); | ||||||
|  |  | ||||||
|  |         return Http::withToken($this->getClientToken()) | ||||||
|  |             ->post($url, [ | ||||||
|  |                 "channel" => $channel, | ||||||
|  |                 "text" => $notification->toSlack($notifiable), | ||||||
|  |             ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected function getClientToken(): string | ||||||
|  |     { | ||||||
|  |         return config("services.slack.client_token"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected function getBaseUrl(): string | ||||||
|  |     { | ||||||
|  |         return config("services.slack.url"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack; | namespace Toby\Infrastructure\Slack; | ||||||
| 
 | 
 | ||||||
| use Exception; | use Exception; | ||||||
| use Illuminate\Http\Request as IlluminateRequest; | use Illuminate\Http\Request as IlluminateRequest; | ||||||
| @@ -11,6 +11,7 @@ use Illuminate\Support\Collection; | |||||||
| use Illuminate\Validation\ValidationException; | use Illuminate\Validation\ValidationException; | ||||||
| use Spatie\SlashCommand\Attachment; | use Spatie\SlashCommand\Attachment; | ||||||
| use Spatie\SlashCommand\Controller as SlackController; | use Spatie\SlashCommand\Controller as SlackController; | ||||||
|  | use Spatie\SlashCommand\Exceptions\InvalidRequest; | ||||||
| use Spatie\SlashCommand\Exceptions\RequestCouldNotBeHandled; | use Spatie\SlashCommand\Exceptions\RequestCouldNotBeHandled; | ||||||
| use Spatie\SlashCommand\Exceptions\SlackSlashCommandException; | use Spatie\SlashCommand\Exceptions\SlackSlashCommandException; | ||||||
| use Spatie\SlashCommand\Response; | use Spatie\SlashCommand\Response; | ||||||
| @@ -18,11 +19,11 @@ use Spatie\SlashCommand\Response; | |||||||
| class Controller extends SlackController | class Controller extends SlackController | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|      * @throws RequestCouldNotBeHandled |      * @throws InvalidRequest|RequestCouldNotBeHandled | ||||||
|      */ |      */ | ||||||
|     public function getResponse(IlluminateRequest $request): IlluminateResponse |     public function getResponse(IlluminateRequest $request): IlluminateResponse | ||||||
|     { |     { | ||||||
|         $this->guardAgainstInvalidRequest($request); |         $this->verifyWithSigning($request); | ||||||
| 
 | 
 | ||||||
|         $handler = $this->determineHandler(); |         $handler = $this->determineHandler(); | ||||||
| 
 | 
 | ||||||
| @@ -43,13 +44,13 @@ class Controller extends SlackController | |||||||
|     { |     { | ||||||
|         $errors = (new Collection($exception->errors())) |         $errors = (new Collection($exception->errors())) | ||||||
|             ->map( |             ->map( | ||||||
|                 fn(array $message) => Attachment::create() |                 fn(array $message): Attachment => Attachment::create() | ||||||
|                     ->setColor("danger") |                     ->setColor("danger") | ||||||
|                     ->setText($message[0]), |                     ->setText($message[0]), | ||||||
|             ); |             ); | ||||||
| 
 | 
 | ||||||
|         return Response::create($this->request) |         return Response::create($this->request) | ||||||
|             ->withText(":x: Komenda `/{$this->request->command} {$this->request->text}` jest niepoprawna:") |             ->withText(":x: Polecenie `/{$this->request->command} {$this->request->text}` jest niepoprawna:") | ||||||
|             ->withAttachments($errors->all()); |             ->withAttachments($errors->all()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										22
									
								
								app/Infrastructure/Slack/Elements/AbsencesAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Infrastructure/Slack/Elements/AbsencesAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Elements; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Toby\Eloquent\Models\Vacation; | ||||||
|  |  | ||||||
|  | class AbsencesAttachment extends ListAttachment | ||||||
|  | { | ||||||
|  |     public function __construct(Collection $absences) | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |  | ||||||
|  |         $this | ||||||
|  |             ->setTitle("Nieobecności :palm_tree:") | ||||||
|  |             ->setColor("#eab308") | ||||||
|  |             ->setItems($absences->map(fn(Vacation $vacation): string => $vacation->user->profile->full_name)) | ||||||
|  |             ->setEmptyText("Wszyscy dzisiaj pracują :muscle:"); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								app/Infrastructure/Slack/Elements/Attachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/Infrastructure/Slack/Elements/Attachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Elements; | ||||||
|  |  | ||||||
|  | use Illuminate\Contracts\Support\Arrayable; | ||||||
|  | use Spatie\SlashCommand\Attachment as BaseAttachment; | ||||||
|  |  | ||||||
|  | class Attachment extends BaseAttachment implements Arrayable | ||||||
|  | { | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								app/Infrastructure/Slack/Elements/BirthdaysAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Infrastructure/Slack/Elements/BirthdaysAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Elements; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  |  | ||||||
|  | class BirthdaysAttachment extends ListAttachment | ||||||
|  | { | ||||||
|  |     public function __construct(Collection $birthdays) | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |  | ||||||
|  |         $this | ||||||
|  |             ->setTitle("Urodziny :birthday:") | ||||||
|  |             ->setColor("#3c5f97") | ||||||
|  |             ->setItems($birthdays->map(fn(User $user): string => $user->profile->full_name)) | ||||||
|  |             ->setEmptyText("Dzisiaj nikt nie ma urodzin :cry:"); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								app/Infrastructure/Slack/Elements/KeysAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/Infrastructure/Slack/Elements/KeysAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Elements; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Toby\Eloquent\Models\Key; | ||||||
|  |  | ||||||
|  | class KeysAttachment extends ListAttachment | ||||||
|  | { | ||||||
|  |     public function __construct(Collection $keys) | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |  | ||||||
|  |         $this | ||||||
|  |             ->setColor("#3c5f97") | ||||||
|  |             ->setItems($keys->map(fn(Key $key): string => "Klucz nr {$key->id} - <@{$key->user->profile->slack_id}>")) | ||||||
|  |             ->setEmptyText("Nie ma żadnych kluczy w tobym"); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								app/Infrastructure/Slack/Elements/ListAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/Infrastructure/Slack/Elements/ListAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Elements; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  |  | ||||||
|  | class ListAttachment extends Attachment | ||||||
|  | { | ||||||
|  |     protected Collection $items; | ||||||
|  |     protected string $emptyText = ""; | ||||||
|  |  | ||||||
|  |     public function setItems(Collection $items): static | ||||||
|  |     { | ||||||
|  |         $this->items = $items; | ||||||
|  |  | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function setEmptyText(string $emptyText): static | ||||||
|  |     { | ||||||
|  |         $this->emptyText = $emptyText; | ||||||
|  |  | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function toArray(): array | ||||||
|  |     { | ||||||
|  |         $fields = parent::toArray(); | ||||||
|  |  | ||||||
|  |         return array_merge($fields, [ | ||||||
|  |             "text" => $this->items->isNotEmpty() ? $this->items->implode("\n") : $this->emptyText, | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								app/Infrastructure/Slack/Elements/RemotesAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Infrastructure/Slack/Elements/RemotesAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Elements; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Toby\Eloquent\Models\Vacation; | ||||||
|  |  | ||||||
|  | class RemotesAttachment extends ListAttachment | ||||||
|  | { | ||||||
|  |     public function __construct(Collection $remoteDays) | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |  | ||||||
|  |         $this | ||||||
|  |             ->setTitle("Praca zdalna :house_with_garden:") | ||||||
|  |             ->setColor("#527aba") | ||||||
|  |             ->setItems($remoteDays->map(fn(Vacation $vacation): string => $vacation->user->profile->full_name)) | ||||||
|  |             ->setEmptyText("Wszyscy dzisiaj są w biurze :boom:"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Exceptions; | namespace Toby\Infrastructure\Slack\Exceptions; | ||||||
| 
 | 
 | ||||||
| use Spatie\SlashCommand\Exceptions\SlackSlashCommandException; | use Spatie\SlashCommand\Exceptions\SlackSlashCommandException; | ||||||
| 
 | 
 | ||||||
| @@ -2,13 +2,13 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Handlers; | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
| 
 | 
 | ||||||
| use Spatie\SlashCommand\Attachment; |  | ||||||
| use Spatie\SlashCommand\Handlers\BaseHandler; | use Spatie\SlashCommand\Handlers\BaseHandler; | ||||||
| use Spatie\SlashCommand\Request; | use Spatie\SlashCommand\Request; | ||||||
| use Spatie\SlashCommand\Response; | use Spatie\SlashCommand\Response; | ||||||
| use Toby\Domain\Slack\Traits\ListsHandlers; | use Toby\Infrastructure\Slack\Elements\Attachment; | ||||||
|  | use Toby\Infrastructure\Slack\Traits\ListsHandlers; | ||||||
| 
 | 
 | ||||||
| class CatchAll extends BaseHandler | class CatchAll extends BaseHandler | ||||||
| { | { | ||||||
| @@ -24,7 +24,7 @@ class CatchAll extends BaseHandler | |||||||
|         $handlers = $this->findAvailableHandlers(); |         $handlers = $this->findAvailableHandlers(); | ||||||
|         $attachmentFields = $this->mapHandlersToAttachments($handlers); |         $attachmentFields = $this->mapHandlersToAttachments($handlers); | ||||||
| 
 | 
 | ||||||
|         return $this->respondToSlack(":x: Nie rozpoznaję tej komendy. Lista wszystkich komend:") |         return $this->respondToSlack(":x: Nie rozpoznaję polecenia. Lista wszystkich poleceń:") | ||||||
|             ->withAttachment( |             ->withAttachment( | ||||||
|                 Attachment::create() |                 Attachment::create() | ||||||
|                     ->setColor("danger") |                     ->setColor("danger") | ||||||
							
								
								
									
										36
									
								
								app/Infrastructure/Slack/Handlers/DailySummary.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/Infrastructure/Slack/Handlers/DailySummary.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Carbon; | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Spatie\SlashCommand\Request; | ||||||
|  | use Spatie\SlashCommand\Response; | ||||||
|  | use Toby\Domain\DailySummaryRetriever; | ||||||
|  | use Toby\Infrastructure\Slack\Elements\AbsencesAttachment; | ||||||
|  | use Toby\Infrastructure\Slack\Elements\BirthdaysAttachment; | ||||||
|  | use Toby\Infrastructure\Slack\Elements\RemotesAttachment; | ||||||
|  |  | ||||||
|  | class DailySummary extends SignatureHandler | ||||||
|  | { | ||||||
|  |     protected $signature = "toby dzisiaj"; | ||||||
|  |     protected $description = "Codzienne podsumowanie"; | ||||||
|  |  | ||||||
|  |     public function handle(Request $request): Response | ||||||
|  |     { | ||||||
|  |         $dailySummaryRetriever = app()->make(DailySummaryRetriever::class); | ||||||
|  |  | ||||||
|  |         $now = Carbon::today(); | ||||||
|  |  | ||||||
|  |         $attachments = new Collection([ | ||||||
|  |             new AbsencesAttachment($dailySummaryRetriever->getAbsences($now)), | ||||||
|  |             new RemotesAttachment($dailySummaryRetriever->getRemoteDays($now)), | ||||||
|  |             new BirthdaysAttachment($dailySummaryRetriever->getBirthdays($now)), | ||||||
|  |         ]); | ||||||
|  |  | ||||||
|  |         return $this->respondToSlack("Podsumowanie dla dnia {$now->toDisplayString()}") | ||||||
|  |             ->withAttachments($attachments->all()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,16 +2,16 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Handlers; | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Validation\ValidationException; | use Illuminate\Validation\ValidationException; | ||||||
| use Spatie\SlashCommand\Request; | use Spatie\SlashCommand\Request; | ||||||
| use Spatie\SlashCommand\Response; | use Spatie\SlashCommand\Response; | ||||||
| use Toby\Domain\Notifications\KeyHasBeenGivenNotification; | use Toby\Domain\Notifications\KeyHasBeenGivenNotification; | ||||||
| use Toby\Domain\Slack\Exceptions\UserNotFoundException; |  | ||||||
| use Toby\Domain\Slack\Rules\SlackUserExistsRule; |  | ||||||
| use Toby\Domain\Slack\Traits\FindsUserBySlackId; |  | ||||||
| use Toby\Eloquent\Models\Key; | use Toby\Eloquent\Models\Key; | ||||||
|  | use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException; | ||||||
|  | use Toby\Infrastructure\Slack\Rules\SlackUserExistsRule; | ||||||
|  | use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId; | ||||||
| 
 | 
 | ||||||
| class GiveKeysTo extends SignatureHandler | class GiveKeysTo extends SignatureHandler | ||||||
| { | { | ||||||
| @@ -2,19 +2,19 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Handlers; | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
| 
 | 
 | ||||||
| use Spatie\SlashCommand\Attachment; |  | ||||||
| use Spatie\SlashCommand\Request; | use Spatie\SlashCommand\Request; | ||||||
| use Spatie\SlashCommand\Response; | use Spatie\SlashCommand\Response; | ||||||
| use Toby\Domain\Slack\Traits\ListsHandlers; | use Toby\Infrastructure\Slack\Elements\Attachment; | ||||||
|  | use Toby\Infrastructure\Slack\Traits\ListsHandlers; | ||||||
| 
 | 
 | ||||||
| class Help extends SignatureHandler | class Help extends SignatureHandler | ||||||
| { | { | ||||||
|     use ListsHandlers; |     use ListsHandlers; | ||||||
| 
 | 
 | ||||||
|     protected $signature = "toby pomoc"; |     protected $signature = "toby pomoc"; | ||||||
|     protected $description = "Wyświetl wszystkie dostępne komendy"; |     protected $description = "Wyświetl wszystkie dostępne polecenia"; | ||||||
| 
 | 
 | ||||||
|     public function handle(Request $request): Response |     public function handle(Request $request): Response | ||||||
|     { |     { | ||||||
| @@ -22,7 +22,7 @@ class Help extends SignatureHandler | |||||||
| 
 | 
 | ||||||
|         $attachmentFields = $this->mapHandlersToAttachments($handlers); |         $attachmentFields = $this->mapHandlersToAttachments($handlers); | ||||||
| 
 | 
 | ||||||
|         return $this->respondToSlack("Dostępne komendy:") |         return $this->respondToSlack("Dostępne polecenia:") | ||||||
|             ->withAttachment( |             ->withAttachment( | ||||||
|                 Attachment::create() |                 Attachment::create() | ||||||
|                     ->setColor("good") |                     ->setColor("good") | ||||||
| @@ -2,16 +2,16 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Handlers; | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Support\Carbon; | use Illuminate\Support\Carbon; | ||||||
| use Spatie\SlashCommand\Request; | use Spatie\SlashCommand\Request; | ||||||
| use Spatie\SlashCommand\Response; | use Spatie\SlashCommand\Response; | ||||||
| use Toby\Domain\Actions\VacationRequest\CreateAction; | use Toby\Domain\Actions\VacationRequest\CreateAction; | ||||||
| use Toby\Domain\Enums\VacationType; | use Toby\Domain\Enums\VacationType; | ||||||
| use Toby\Domain\Slack\Traits\FindsUserBySlackId; |  | ||||||
| use Toby\Eloquent\Models\User; | use Toby\Eloquent\Models\User; | ||||||
| use Toby\Eloquent\Models\YearPeriod; | use Toby\Eloquent\Models\YearPeriod; | ||||||
|  | use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId; | ||||||
| 
 | 
 | ||||||
| class HomeOffice extends SignatureHandler | class HomeOffice extends SignatureHandler | ||||||
| { | { | ||||||
| @@ -2,12 +2,12 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Handlers; | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
| 
 | 
 | ||||||
| use Spatie\SlashCommand\Attachment; |  | ||||||
| use Spatie\SlashCommand\Request; | use Spatie\SlashCommand\Request; | ||||||
| use Spatie\SlashCommand\Response; | use Spatie\SlashCommand\Response; | ||||||
| use Toby\Eloquent\Models\Key; | use Toby\Eloquent\Models\Key; | ||||||
|  | use Toby\Infrastructure\Slack\Elements\KeysAttachment; | ||||||
| 
 | 
 | ||||||
| class KeyList extends SignatureHandler | class KeyList extends SignatureHandler | ||||||
| { | { | ||||||
| @@ -18,14 +18,9 @@ class KeyList extends SignatureHandler | |||||||
|     { |     { | ||||||
|         $keys = Key::query() |         $keys = Key::query() | ||||||
|             ->orderBy("id") |             ->orderBy("id") | ||||||
|             ->get() |             ->get(); | ||||||
|             ->map(fn(Key $key) => "Klucz nr {$key->id} - <@{$key->user->profile->slack_id}>"); |  | ||||||
| 
 | 
 | ||||||
|         return $this->respondToSlack("Lista kluczy :key:") |         return $this->respondToSlack("Lista kluczy :key:") | ||||||
|             ->withAttachment( |             ->withAttachment(new KeysAttachment($keys)); | ||||||
|                 Attachment::create() |  | ||||||
|                     ->setColor("#3c5f97") |  | ||||||
|                     ->setText($keys->isNotEmpty() ? $keys->implode("\n") : "Nie ma żadnych kluczy w tobym"), |  | ||||||
|             ); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Handlers; | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Support\Facades\Validator; | use Illuminate\Support\Facades\Validator; | ||||||
| use Spatie\SlashCommand\Handlers\SignatureHandler as BaseSignatureHandler; | use Spatie\SlashCommand\Handlers\SignatureHandler as BaseSignatureHandler; | ||||||
| @@ -2,16 +2,16 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Handlers; | namespace Toby\Infrastructure\Slack\Handlers; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Validation\ValidationException; | use Illuminate\Validation\ValidationException; | ||||||
| use Spatie\SlashCommand\Request; | use Spatie\SlashCommand\Request; | ||||||
| use Spatie\SlashCommand\Response; | use Spatie\SlashCommand\Response; | ||||||
| use Toby\Domain\Notifications\KeyHasBeenTakenNotification; | use Toby\Domain\Notifications\KeyHasBeenTakenNotification; | ||||||
| use Toby\Domain\Slack\Exceptions\UserNotFoundException; |  | ||||||
| use Toby\Domain\Slack\Rules\SlackUserExistsRule; |  | ||||||
| use Toby\Domain\Slack\Traits\FindsUserBySlackId; |  | ||||||
| use Toby\Eloquent\Models\Key; | use Toby\Eloquent\Models\Key; | ||||||
|  | use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException; | ||||||
|  | use Toby\Infrastructure\Slack\Rules\SlackUserExistsRule; | ||||||
|  | use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId; | ||||||
| 
 | 
 | ||||||
| class TakeKeysFrom extends SignatureHandler | class TakeKeysFrom extends SignatureHandler | ||||||
| { | { | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Rules; | namespace Toby\Infrastructure\Slack\Rules; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Contracts\Validation\Rule; | use Illuminate\Contracts\Validation\Rule; | ||||||
| use Illuminate\Support\Str; | use Illuminate\Support\Str; | ||||||
| @@ -2,11 +2,11 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Traits; | namespace Toby\Infrastructure\Slack\Traits; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Support\Str; | use Illuminate\Support\Str; | ||||||
| use Toby\Domain\Slack\Exceptions\UserNotFoundException; |  | ||||||
| use Toby\Eloquent\Models\User; | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException; | ||||||
| 
 | 
 | ||||||
| trait FindsUserBySlackId | trait FindsUserBySlackId | ||||||
| { | { | ||||||
| @@ -2,11 +2,12 @@ | |||||||
| 
 | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace Toby\Domain\Slack\Traits; | namespace Toby\Infrastructure\Slack\Traits; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use Illuminate\Support\Str; | use Illuminate\Support\Str; | ||||||
| use Spatie\SlashCommand\AttachmentField; | use Spatie\SlashCommand\AttachmentField; | ||||||
|  | use Spatie\SlashCommand\Handlers\BaseHandler; | ||||||
| use Spatie\SlashCommand\Handlers\SignatureHandler; | use Spatie\SlashCommand\Handlers\SignatureHandler; | ||||||
| use Spatie\SlashCommand\Handlers\SignatureParts; | use Spatie\SlashCommand\Handlers\SignatureParts; | ||||||
| use Spatie\SlashCommand\HandlesSlashCommand; | use Spatie\SlashCommand\HandlesSlashCommand; | ||||||
| @@ -16,8 +17,8 @@ trait ListsHandlers | |||||||
|     protected function findAvailableHandlers(): Collection |     protected function findAvailableHandlers(): Collection | ||||||
|     { |     { | ||||||
|         return collect(config("laravel-slack-slash-command.handlers")) |         return collect(config("laravel-slack-slash-command.handlers")) | ||||||
|             ->map(fn(string $handlerClassName) => new $handlerClassName($this->request)) |             ->map(fn(string $handlerClassName): BaseHandler => new $handlerClassName($this->request)) | ||||||
|             ->filter(fn(HandlesSlashCommand $handler) => $handler instanceof SignatureHandler) |             ->filter(fn(HandlesSlashCommand $handler): bool => $handler instanceof SignatureHandler) | ||||||
|             ->filter(function (SignatureHandler $handler) { |             ->filter(function (SignatureHandler $handler) { | ||||||
|                 $signatureParts = new SignatureParts($handler->getSignature()); |                 $signatureParts = new SignatureParts($handler->getSignature()); | ||||||
| 
 | 
 | ||||||
| @@ -29,13 +30,13 @@ trait ListsHandlers | |||||||
|     { |     { | ||||||
|         return $handlers |         return $handlers | ||||||
|             ->sort( |             ->sort( | ||||||
|                 fn(SignatureHandler $handlerA, SignatureHandler $handlerB) => strcmp( |                 fn(SignatureHandler $handlerA, SignatureHandler $handlerB): int => strcmp( | ||||||
|                     $handlerA->getFullCommand(), |                     $handlerA->getFullCommand(), | ||||||
|                     $handlerB->getFullCommand(), |                     $handlerB->getFullCommand(), | ||||||
|                 ), |                 ), | ||||||
|             ) |             ) | ||||||
|             ->map( |             ->map( | ||||||
|                 fn(SignatureHandler $handler) => AttachmentField::create( |                 fn(SignatureHandler $handler): AttachmentField => AttachmentField::create( | ||||||
|                     $handler->getDescription(), |                     $handler->getDescription(), | ||||||
|                     "`/{$handler->getSignature()}`", |                     "`/{$handler->getSignature()}`", | ||||||
|                 ), |                 ), | ||||||
| @@ -2,17 +2,16 @@ | |||||||
|  |  | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
|  |  | ||||||
| use Toby\Domain\Slack\Handlers\CatchAll; | use Toby\Infrastructure\Slack\Handlers\CatchAll; | ||||||
| use Toby\Domain\Slack\Handlers\DailySummary; | use Toby\Infrastructure\Slack\Handlers\DailySummary; | ||||||
| use Toby\Domain\Slack\Handlers\GiveKeysTo; | use Toby\Infrastructure\Slack\Handlers\GiveKeysTo; | ||||||
| use Toby\Domain\Slack\Handlers\Help; | use Toby\Infrastructure\Slack\Handlers\Help; | ||||||
| use Toby\Domain\Slack\Handlers\HomeOffice; | use Toby\Infrastructure\Slack\Handlers\HomeOffice; | ||||||
| use Toby\Domain\Slack\Handlers\KeyList; | use Toby\Infrastructure\Slack\Handlers\KeyList; | ||||||
| use Toby\Domain\Slack\Handlers\TakeKeysFrom; | use Toby\Infrastructure\Slack\Handlers\TakeKeysFrom; | ||||||
|  |  | ||||||
| return [ | return [ | ||||||
|     "signing_secret" => env("SLACK_SIGNING_SECRET"), |     "signing_secret" => env("SLACK_SIGNING_SECRET"), | ||||||
|     "verify_with_signing" => true, |  | ||||||
|     "handlers" => [ |     "handlers" => [ | ||||||
|         TakeKeysFrom::class, |         TakeKeysFrom::class, | ||||||
|         GiveKeysTo::class, |         GiveKeysTo::class, | ||||||
|   | |||||||
| @@ -3,11 +3,11 @@ | |||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
|  |  | ||||||
| use Illuminate\Support\Facades\Route; | use Illuminate\Support\Facades\Route; | ||||||
| use Toby\Domain\Slack\Controller as SlackController; |  | ||||||
| use Toby\Infrastructure\Http\Controllers\Api\CalculateUserUnavailableDaysController; | use Toby\Infrastructure\Http\Controllers\Api\CalculateUserUnavailableDaysController; | ||||||
| use Toby\Infrastructure\Http\Controllers\Api\CalculateUserVacationStatsController; | use Toby\Infrastructure\Http\Controllers\Api\CalculateUserVacationStatsController; | ||||||
| use Toby\Infrastructure\Http\Controllers\Api\CalculateVacationDaysController; | use Toby\Infrastructure\Http\Controllers\Api\CalculateVacationDaysController; | ||||||
| use Toby\Infrastructure\Http\Controllers\Api\GetAvailableVacationTypesController; | use Toby\Infrastructure\Http\Controllers\Api\GetAvailableVacationTypesController; | ||||||
|  | use Toby\Infrastructure\Slack\Controller as SlackController; | ||||||
|  |  | ||||||
| Route::post("slack", [SlackController::class, "getResponse"]); | Route::post("slack", [SlackController::class, "getResponse"]); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user