diff --git a/.env.example b/.env.example index ecb23cd8..703cb736 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,6 @@ APP_NAME="Toby HR application" APP_ENV=local -APP_KEY= +APP_KEY=base64:GOwYei8d8m8gubf1JaBxjBlQjeVCG+7n4fZwcgq76V8= APP_DEBUG=true APP_URL=https://toby.blumilk.localhost diff --git a/app/Domain/BenefitsReportTimesheet.php b/app/Domain/BenefitsReportTimesheet.php index 49657ed1..808f7c2c 100644 --- a/app/Domain/BenefitsReportTimesheet.php +++ b/app/Domain/BenefitsReportTimesheet.php @@ -43,7 +43,7 @@ public function generator(): Generator { $data = Arr::where( $this->report->data, - fn(array $item): bool => in_array($item["user"], $this->userIds, false), + fn(array $item): bool => in_array($item["user"], $this->userIds, strict: false), ); $data = Arr::map($data, function (array $item): array { diff --git a/app/Domain/Notifications/VacationRequestCreatedNotification.php b/app/Domain/Notifications/VacationRequestCreatedNotification.php index ad1ff3ee..5a4be58a 100644 --- a/app/Domain/Notifications/VacationRequestCreatedNotification.php +++ b/app/Domain/Notifications/VacationRequestCreatedNotification.php @@ -5,97 +5,16 @@ namespace Toby\Domain\Notifications; use Illuminate\Bus\Queueable; -use Illuminate\Notifications\Messages\MailMessage; -use InvalidArgumentException; use Toby\Eloquent\Models\VacationRequest; -use Toby\Infrastructure\Slack\Elements\SlackMessage; -class VacationRequestCreatedNotification extends QueuedNotification +class VacationRequestCreatedNotification extends VacationRequestNotification { use Queueable; public function __construct( protected VacationRequest $vacationRequest, ) { - parent::__construct(); - } - - public function via(): array - { - return [Channels::MAIL, Channels::SLACK]; - } - - public function toSlack(): SlackMessage - { - $url = route("vacation.requests.show", ["vacationRequest" => $this->vacationRequest->id]); - $seeDetails = __("See details"); - - return (new SlackMessage()) - ->text("{$this->buildDescription()}\n <{$url}|{$seeDetails}>"); - } - - /** - * @throws InvalidArgumentException - */ - public function toMail(): MailMessage - { - $url = route( - "vacation.requests.show", - [ - "vacationRequest" => $this->vacationRequest, - ], - ); - - return $this->buildMailMessage($url); - } - - protected function buildMailMessage(string $url): MailMessage - { - $user = $this->vacationRequest->user->profile->first_name; - $type = $this->vacationRequest->type->label(); - $from = $this->vacationRequest->from; - $to = $this->vacationRequest->to; - $days = $this->vacationRequest->vacations()->count(); - - $date = $from->equalTo($to) - ? "{$from->toDisplayString()}" - : "{$from->toDisplayString()} - {$to->toDisplayString()}"; - - return (new MailMessage()) - ->greeting( - __("Hi :user!", [ - "user" => $user, - ]), - ) - ->subject($this->buildSubject()) - ->line($this->buildDescription()) - ->line( - __("Request type: :type", [ - "type" => $type, - ]), - ) - ->line( - __("Date: :date (number of days: :days)", [ - "date" => $date, - "days" => $days, - ]), - ) - ->action(__("Click here for details"), $url); - } - - protected function buildSubject(): string - { - $name = $this->vacationRequest->name; - - if ($this->vacationRequest->creator()->is($this->vacationRequest->user)) { - return __("Request :title created", [ - "title" => $name, - ]); - } - - return __("Request :title has been created on your behalf", [ - "title" => $name, - ]); + parent::__construct($this->vacationRequest, $this->vacationRequest->user); } protected function buildDescription(): string diff --git a/app/Domain/Notifications/VacationRequestEmailTitle.php b/app/Domain/Notifications/VacationRequestEmailTitle.php new file mode 100644 index 00000000..0a8990dd --- /dev/null +++ b/app/Domain/Notifications/VacationRequestEmailTitle.php @@ -0,0 +1,16 @@ + $title, + "application" => config("app.name"), + ]); + } +} diff --git a/app/Domain/Notifications/VacationRequestNotification.php b/app/Domain/Notifications/VacationRequestNotification.php new file mode 100644 index 00000000..be6749fc --- /dev/null +++ b/app/Domain/Notifications/VacationRequestNotification.php @@ -0,0 +1,94 @@ + $this->vacationRequest->id]); + $seeDetails = __("See details"); + + return (new SlackMessage()) + ->text("{$this->buildDescription()}\n <{$url}|{$seeDetails}>"); + } + + /** + * @throws InvalidArgumentException + */ + public function toMail(): MailMessage + { + $url = route( + "vacation.requests.show", + [ + "vacationRequest" => $this->vacationRequest, + ], + ); + + return $this->buildMailMessage($url); + } + + protected function buildMailMessage(string $url): MailMessage + { + $user = $this->user->profile->first_name; + $type = $this->vacationRequest->type->label(); + $from = $this->vacationRequest->from; + $to = $this->vacationRequest->to; + $days = $this->vacationRequest->vacations()->count(); + + $date = $from->equalTo($to) + ? "{$from->toDisplayString()}" + : "{$from->toDisplayString()} - {$to->toDisplayString()}"; + + return (new MailMessage()) + ->greeting( + __("Hi :user!", [ + "user" => $user, + ]), + ) + ->subject($this->buildSubject()) + ->line($this->buildDescription()) + ->line( + __("Request type: :type", [ + "type" => $type, + ]), + ) + ->line( + __("Date: :date (number of days: :days)", [ + "date" => $date, + "days" => $days, + ]), + ) + ->action(__("Click here for details"), $url); + } + + protected function buildSubject(): string + { + return VacationRequestEmailTitle::get($this->vacationRequest->name); + } + + abstract protected function buildDescription(): string; +} diff --git a/app/Domain/Notifications/VacationRequestStatusChangedNotification.php b/app/Domain/Notifications/VacationRequestStatusChangedNotification.php index a0773481..64b33efb 100644 --- a/app/Domain/Notifications/VacationRequestStatusChangedNotification.php +++ b/app/Domain/Notifications/VacationRequestStatusChangedNotification.php @@ -4,91 +4,8 @@ namespace Toby\Domain\Notifications; -use Illuminate\Bus\Queueable; -use Illuminate\Notifications\Messages\MailMessage; -use InvalidArgumentException; -use Toby\Eloquent\Models\User; -use Toby\Eloquent\Models\VacationRequest; -use Toby\Infrastructure\Slack\Elements\SlackMessage; - -class VacationRequestStatusChangedNotification extends QueuedNotification +class VacationRequestStatusChangedNotification extends VacationRequestNotification { - use Queueable; - - public function __construct( - protected VacationRequest $vacationRequest, - protected User $user, - ) { - parent::__construct(); - } - - public function via(): array - { - return [Channels::MAIL, Channels::SLACK]; - } - - public function toSlack(): SlackMessage - { - $url = route("vacation.requests.show", ["vacationRequest" => $this->vacationRequest->id]); - $seeDetails = __("See details"); - - return (new SlackMessage()) - ->text("{$this->buildDescription()}\n <{$url}|{$seeDetails}>"); - } - - /** - * @throws InvalidArgumentException - */ - public function toMail(): MailMessage - { - $url = route( - "vacation.requests.show", - [ - "vacationRequest" => $this->vacationRequest, - ], - ); - - return $this->buildMailMessage($url); - } - - protected function buildMailMessage(string $url): MailMessage - { - $user = $this->user->profile->first_name; - $type = $this->vacationRequest->type->label(); - $from = $this->vacationRequest->from; - $to = $this->vacationRequest->to; - $days = $this->vacationRequest->vacations()->count(); - - $date = $from->equalTo($to) - ? "{$from->toDisplayString()}" - : "{$from->toDisplayString()} - {$to->toDisplayString()}"; - - return (new MailMessage()) - ->greeting(__("Hi :user!", [ - "user" => $user, - ])) - ->subject($this->buildSubject()) - ->line($this->buildDescription()) - ->line(__("Request type: :type", [ - "type" => $type, - ])) - ->line( - __("Date: :date (number of days: :days)", [ - "date" => $date, - "days" => $days, - ]), - ) - ->action(__("Click here for details"), $url); - } - - protected function buildSubject(): string - { - return __("Request :title has been :status", [ - "title" => $this->vacationRequest->name, - "status" => $this->vacationRequest->state->label(), - ]); - } - protected function buildDescription(): string { return __("The request :title from user :requester has been :status.", [ diff --git a/app/Domain/Notifications/VacationRequestWaitsForApprovalNotification.php b/app/Domain/Notifications/VacationRequestWaitsForApprovalNotification.php index 76e1c28d..73935bd2 100644 --- a/app/Domain/Notifications/VacationRequestWaitsForApprovalNotification.php +++ b/app/Domain/Notifications/VacationRequestWaitsForApprovalNotification.php @@ -4,99 +4,10 @@ namespace Toby\Domain\Notifications; -use Illuminate\Bus\Queueable; -use Illuminate\Notifications\Messages\MailMessage; -use InvalidArgumentException; use Toby\Domain\States\VacationRequest\WaitingForTechnical; -use Toby\Eloquent\Models\User; -use Toby\Eloquent\Models\VacationRequest; -use Toby\Infrastructure\Slack\Elements\SlackMessage; -class VacationRequestWaitsForApprovalNotification extends QueuedNotification +class VacationRequestWaitsForApprovalNotification extends VacationRequestNotification { - use Queueable; - - public function __construct( - protected VacationRequest $vacationRequest, - protected User $user, - ) { - parent::__construct(); - } - - public function via(): array - { - return [Channels::MAIL, Channels::SLACK]; - } - - public function toSlack(): SlackMessage - { - $url = route("vacation.requests.show", ["vacationRequest" => $this->vacationRequest->id]); - $seeDetails = __("See details"); - - return (new SlackMessage()) - ->text("{$this->buildDescription()}\n <{$url}|{$seeDetails}>"); - } - - /** - * @throws InvalidArgumentException - */ - public function toMail(): MailMessage - { - $url = route( - "vacation.requests.show", - [ - "vacationRequest" => $this->vacationRequest, - ], - ); - - return $this->buildMailMessage($url); - } - - protected function buildMailMessage(string $url): MailMessage - { - $user = $this->user->profile->first_name; - $type = $this->vacationRequest->type->label(); - $from = $this->vacationRequest->from; - $to = $this->vacationRequest->to; - $days = $this->vacationRequest->vacations()->count(); - - $date = $from->equalTo($to) - ? "{$from->toDisplayString()}" - : "{$from->toDisplayString()} - {$to->toDisplayString()}"; - - return (new MailMessage()) - ->greeting(__("Hi :user!", [ - "user" => $user, - ])) - ->subject($this->buildSubject()) - ->line($this->buildDescription()) - ->line(__("Request type: :type", [ - "type" => $type, - ])) - ->line( - __("Date: :date (number of days: :days)", [ - "date" => $date, - "days" => $days, - ]), - ) - ->action(__("Click here for details"), $url); - } - - protected function buildSubject(): string - { - $title = $this->vacationRequest->name; - - if ($this->vacationRequest->state->equals(WaitingForTechnical::class)) { - return __("Request :title is waiting for your technical approval", [ - "title" => $title, - ]); - } - - return __("Request :title is waiting for your administrative approval", [ - "title" => $title, - ]); - } - protected function buildDescription(): string { $title = $this->vacationRequest->name; diff --git a/app/Eloquent/Models/Profile.php b/app/Eloquent/Models/Profile.php index b37e39a8..74dced41 100644 --- a/app/Eloquent/Models/Profile.php +++ b/app/Eloquent/Models/Profile.php @@ -16,6 +16,7 @@ /** * @property string $first_name * @property string $last_name + * @property-read string $full_name * @property string $position * @property EmploymentForm $employment_form * @property Carbon $employment_date @@ -47,7 +48,7 @@ public function getAvatar(): string ->image(); } - public function getfullNameAttribute(): string + public function getFullNameAttribute(): string { return "{$this->first_name} {$this->last_name}"; } diff --git a/app/Infrastructure/Http/Controllers/VacationRequestController.php b/app/Infrastructure/Http/Controllers/VacationRequestController.php index d6cd6839..4ac8b598 100644 --- a/app/Infrastructure/Http/Controllers/VacationRequestController.php +++ b/app/Infrastructure/Http/Controllers/VacationRequestController.php @@ -43,7 +43,7 @@ public function index(Request $request, YearPeriodRetriever $yearPeriodRetriever } $status = $request->get("status", "all"); - $withoutRemote = $request->boolean("withoutRemote", false); + $withoutRemote = $request->boolean("withoutRemote", default: false); $vacationRequests = $request->user() ->vacationRequests() @@ -173,7 +173,7 @@ public function download( VacationTypeConfigRetriever $configRetriever, ): LaravelResponse { if (!$configRetriever->isVacation($vacationRequest->type)) { - return abort(SymfonyResponse::HTTP_NOT_FOUND); + abort(SymfonyResponse::HTTP_NOT_FOUND); } $this->authorize("show", $vacationRequest); diff --git a/composer.json b/composer.json index f2b94625..c6e1b53f 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "spatie/laravel-slack-slash-command": "^1.11.4" }, "require-dev": { - "blumilksoftware/codestyle": "^2.3.0", + "blumilksoftware/codestyle": "^2.4.0", "laravel/dusk": "^7.7.1", "mockery/mockery": "^1.5.1", "nunomaduro/collision": "^7.5.2", diff --git a/composer.lock b/composer.lock index 4d25a4f3..6c55d461 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a642fdfe5c58eea0446804fc66d83535", + "content-hash": "1f315992f10f8bb55b0594918da150b0", "packages": [ { "name": "azuyalabs/yasumi", diff --git a/config/app.php b/config/app.php index 6ef5b693..c92d2011 100644 --- a/config/app.php +++ b/config/app.php @@ -3,7 +3,7 @@ declare(strict_types=1); return [ - "name" => env("APP_NAME", "Laravel"), + "name" => env("APP_NAME", "Toby HR application"), "env" => env("APP_ENV", "production"), "debug" => (bool)env("APP_DEBUG", false), "url" => env("APP_URL", "http://localhost"), diff --git a/lang/pl.json b/lang/pl.json index e8a89724..798667fc 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -54,7 +54,7 @@ "If you're having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser:": "Jeżeli masz problemy z kliknięciem przycisku \":actionText\", skopiuj i wklej poniższy adres w pasek przeglądarki:", "All rights reserved.": "Wszelkie prawa zastrzeżone", "Show request": "Pokaż wniosek", - "Request :title created" : "Wniosek :title został utworzony", + "Request :title created": "Wniosek :title został utworzony", "The request :title from user :requester created.": "Wniosek :title użytkownika :requester został utworzony pomyślnie.", "Request type: :type": "Rodzaj wniosku: :type", "Date: :date (number of days: :days)": "Data: :date (liczba dni: :days)", @@ -64,6 +64,7 @@ "The request :title from user :requester is waiting for your technical approval.": "Wniosek :title użytkownika :requester czeka na Twoją akceptację techniczną.", "The request :title from user :requester is waiting for your administrative approval.": "Wniosek :title użytkownika :requester czeka na Twoją akceptację administracyjną.", "Request :title has been :status": "Wniosek :title został :status", + "Request :title in :application": "Wniosek :title w aplikacji :application", "The request :title from user :requester has been :status.": "Wniosek :title użytkownika :requester został :status.", "Request :title has been created on your behalf": "Wniosek :title został utworzony w Twoim imieniu", "The request :title has been created by user :creator on your behalf.": "Wniosek :title został utworzony w Twoim imieniu przez użytkownika :creator.",