Skip to content

Commit

Permalink
#323 - threadable emails (#334)
Browse files Browse the repository at this point in the history
* #323 - threadable emails

* - csf

* - cleaning up
  • Loading branch information
krzysztofrewak authored Aug 23, 2023
1 parent 912ad27 commit 171d1f3
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 266 deletions.
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

0 comments on commit 171d1f3

Please sign in to comment.