Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#323 - threadable emails #334

Merged
merged 3 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -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

Expand Down
2 changes: 1 addition & 1 deletion app/Domain/BenefitsReportTimesheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
85 changes: 2 additions & 83 deletions app/Domain/Notifications/VacationRequestCreatedNotification.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions app/Domain/Notifications/VacationRequestEmailTitle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Toby\Domain\Notifications;

class VacationRequestEmailTitle
{
public static function get(string $title): string
{
return __("Request :title in :application", [
"title" => $title,
"application" => config("app.name"),
]);
}
}
94 changes: 94 additions & 0 deletions app/Domain/Notifications/VacationRequestNotification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

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;

abstract class VacationRequestNotification extends QueuedNotification
{
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 VacationRequestEmailTitle::get($this->vacationRequest->name);
}

abstract protected function buildDescription(): string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.", [
Expand Down
Loading