Преглед изворни кода

Merge branch 'email-template' into dev

moell пре 9 месеци
родитељ
комит
b70d74656f

+ 2 - 2
app/Http/Controllers/API/ContainerController.php

@@ -97,8 +97,6 @@ class ContainerController extends Controller
         $container->fill($formData);
         $container->save();
 
-        ActionRepository::createByContainer($container, ObjectAction::CREATED);
-
         $service->association($container->id);
 
         $files = File::query()->where('object_id', $container->id)
@@ -117,6 +115,8 @@ class ContainerController extends Controller
 
         ContainerContent::query()->create($contentFormData);
 
+        ActionRepository::createByContainer($container, ObjectAction::CREATED);
+
         return $this->created();
     }
 

+ 57 - 0
app/Mail/ContainerAction.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace App\Mail;
+
+use App\Models\Container;
+use App\Models\Enums\ObjectAction;
+use App\Models\Task;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Mail\Mailable;
+use Illuminate\Mail\Mailables\Content;
+use Illuminate\Mail\Mailables\Envelope;
+use Illuminate\Queue\SerializesModels;
+
+class ContainerAction extends Mailable
+{
+    use Queueable, SerializesModels;
+
+    /**
+     * Create a new message instance.
+     */
+    public function __construct(public Container $container, protected ObjectAction $objectAction, public array $actions = [])
+    {
+
+    }
+
+    /**
+     * Get the message envelope.
+     */
+    public function envelope(): Envelope
+    {
+        return new Envelope(
+            subject: $this->container->email_subject ?: $this->container->name,
+        );
+    }
+
+    /**
+     * Get the message content definition.
+     */
+    public function content(): Content
+    {
+        return new Content(
+            //view: 'view.name',
+            markdown: 'emails.actions.container',
+        );
+    }
+
+    /**
+     * Get the attachments for the message.
+     *
+     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
+     */
+    public function attachments(): array
+    {
+        return [];
+    }
+}

+ 3 - 3
app/Mail/RequirementAction.php

@@ -18,9 +18,9 @@ class RequirementAction extends Mailable
     /**
      * Create a new message instance.
      */
-    public function __construct(protected  Requirement $requirement, protected ObjectAction $objectAction)
+    public function __construct(public  Requirement $requirement, public ObjectAction $objectAction, public array $actions = [])
     {
-        //
+
     }
 
     /**
@@ -29,7 +29,7 @@ class RequirementAction extends Mailable
     public function envelope(): Envelope
     {
         return new Envelope(
-            subject: 'Requirement Action',
+            subject: $this->requirement->title,
         );
     }
 

+ 3 - 3
app/Mail/TaskAction.php

@@ -18,9 +18,9 @@ class TaskAction extends Mailable
     /**
      * Create a new message instance.
      */
-    public function __construct(protected Task $task, protected ObjectAction $objectAction)
+    public function __construct(public Task $task, protected ObjectAction $objectAction, public array $actions = [])
     {
-        //
+
     }
 
     /**
@@ -29,7 +29,7 @@ class TaskAction extends Mailable
     public function envelope(): Envelope
     {
         return new Envelope(
-            subject: 'Task Action',
+            subject: $this->task->email_subject ?: $this->task->name,
         );
     }
 

+ 4 - 0
app/Models/Enums/ObjectAction.php

@@ -95,6 +95,10 @@ enum ObjectAction: string
                 ObjectAction::DONE,
                 ObjectAction::CANCELED,
                 ObjectAction::EDITED,
+            ],
+            ActionObjectType::CONTAINER->value => [
+                ObjectAction::CREATED,
+                ObjectAction::EDITED,
             ]
         ];
     }

+ 27 - 0
app/Repositories/ActionRepository.php

@@ -147,6 +147,33 @@ class ActionRepository
         return $items;
     }
 
+    public static function objectEmailActions(ActionObjectType $actionObjectType, string $objectId, int $lastActionId): array
+    {
+        $actions = Action::query()
+            ->with(['createdBy'])
+            ->where("object_type", $actionObjectType->value)
+            ->where("object_id", $objectId)
+            ->where("id", "<=", $lastActionId)
+            ->orderByDesc("created_at")
+            ->limit(5)
+            ->get();
+
+        return self::actionsFormat($actions);
+
+    }
+
+    protected static function actionsFormat(Collection $actions): array
+    {
+        $objectNames = self::objectNamesGroupByType($actions);
+
+        $items = [];
+        foreach ($actions as $action) {
+            $items[] = self::actionFormat($action->toArray(), $objectNames);
+        }
+
+        return $items;
+    }
+
     public static function actionFormat(array $action, array $objectNames): array
     {
         $labelKey = sprintf("action-labels.label.%s", $action['action']);

+ 15 - 2
app/Services/Notification/ActionEmail/ActionEmailService.php

@@ -2,14 +2,17 @@
 
 namespace App\Services\Notification\ActionEmail;
 
+use App\Mail\ContainerAction;
 use App\Mail\RequirementAction;
 use App\Mail\TaskAction;
 use App\Models\Action;
+use App\Models\Container;
 use App\Models\Enums\ActionObjectType;
 use App\Models\Enums\ObjectAction;
 use App\Models\Requirement;
 use App\Models\Task;
 use App\Models\User;
+use App\Repositories\ActionRepository;
 use App\Repositories\ConfigRepository;
 use Illuminate\Contracts\Mail\Mailable;
 use Illuminate\Support\Facades\Mail;
@@ -18,6 +21,8 @@ class ActionEmailService
 {
     protected ObjectAction $objectAction;
 
+    protected array $actions = [];
+
     public function __construct(
         protected Action $action
     )
@@ -37,22 +42,30 @@ class ActionEmailService
 
         $actionObjectModel = $actionObjectType->modelBuilder()->find($this->action->object_id);
 
+        $this->actions = ActionRepository::objectEmailActions($actionObjectType, $actionObjectModel->id, $this->action->id);
+
         match ($actionObjectType) {
             ActionObjectType::REQUIREMENT => $this->requirement($actionObjectModel),
             ActionObjectType::TASK => $this->task($actionObjectModel),
+            ActionObjectType::CONTAINER => $this->container($actionObjectModel),
         };
     }
 
+    protected function container(Container $container)
+    {
+        $this->dispatch($container->mailto, new ContainerAction($container, $this->objectAction, $this->actions));
+    }
+
     protected function requirement(Requirement $requirement)
     {
-        $this->dispatch($requirement->mailto, new RequirementAction($requirement, $this->objectAction));
+        $this->dispatch($requirement->mailto, new RequirementAction($requirement, $this->objectAction, $this->actions));
     }
 
     protected function task(Task $task)
     {
         $userIds = array_filter([$task->assign, ...$task->mailto]);
 
-        $this->dispatch($userIds, new TaskAction($task, $this->objectAction));
+        $this->dispatch($userIds, new TaskAction($task, $this->objectAction, $this->actions));
     }
 
     protected function dispatch(array $userIds, Mailable $mailable)

+ 19 - 0
resources/views/components/email/history.blade.php

@@ -0,0 +1,19 @@
+<table  align="center" width="570" cellpadding="0" cellspacing="0" role="presentation" style="padding-bottom: 10px">
+    <tr>
+        <td  align="left">
+            <h2>History</h2>
+        </td>
+    </tr>
+    @foreach($actions as $index => $action)
+        <tr>
+            <td  align="left" style="padding: 0 0 10px 10px;">
+                {{ $index + 1 }}. {{ sprintf("%s %s by %s", $action['created_at'], $action['action_label'], data_get($action, 'created_by.name')) }}
+            </td>
+        </tr>
+    @endforeach
+    <tr>
+        <td  align="left" style="padding: 0 0 10px 10px;">
+            <a href="">More...</a>
+        </td>
+    </tr>
+</table>

+ 14 - 0
resources/views/emails/actions/container.blade.php

@@ -0,0 +1,14 @@
+<x-mail::message>
+# Container Name: {{ $container->name }}
+
+<x-mail::panel>{{ sprintf("%s %s by %s", data_get($actions, '0.created_at'), data_get($actions, '0.action_label'), data_get($actions, '0.created_by.name')) }}</x-mail::panel>
+
+## Note
+
+{{ $container->content->description }}
+
+<x-email.history :actions="$actions"></x-email.history>
+
+Thanks,<br>
+{{ config('app.name') }}
+</x-mail::message>

+ 11 - 5
resources/views/emails/actions/requirement.blade.php

@@ -1,11 +1,17 @@
 <x-mail::message>
-# Introduction
+# {{ sprintf("Requirement # %s %s", $requirement->id, $requirement->title) }}
 
-The body of your message.
+<x-mail::panel>{{ sprintf("%s %s by %s", data_get($actions, '0.created_at'), data_get($actions, '0.action_label'), data_get($actions, '0.created_by.name')) }}</x-mail::panel>
 
-<x-mail::button :url="''">
-Button Text
-</x-mail::button>
+## Requirement Status
+{{ __(sprintf("model-enums.requirement.status.%s", $requirement->status)) }}
+
+
+## Note
+
+{{ $requirement->note }}
+
+<x-email.history :actions="$actions"></x-email.history>
 
 Thanks,<br>
 {{ config('app.name') }}

+ 23 - 5
resources/views/emails/actions/task.blade.php

@@ -1,11 +1,29 @@
 <x-mail::message>
-# Introduction
+# Task Name: {{ $task->name }}
 
-The body of your message.
+<x-mail::panel>{{ sprintf("%s %s by %s", data_get($actions, '0.created_at'), data_get($actions, '0.action_label'), data_get($actions, '0.created_by.name')) }}</x-mail::panel>
 
-<x-mail::button :url="''">
-Button Text
-</x-mail::button>
+## Task Status
+{{ __(sprintf("model-enums.task.status.%s", $task->status)) }}
+
+@if($task->state)
+## State
+{{ $task->state }}
+@endif
+
+## Assign
+{{ $task?->assignTo?->name }}
+
+@if($task->suitability)
+## Suitability
+{{ $task->suitability }}
+@endif
+
+## Note
+
+{{ $task->description }}
+
+<x-email.history :actions="$actions"></x-email.history>
 
 Thanks,<br>
 {{ config('app.name') }}

+ 2 - 1
resources/views/vendor/mail/html/themes/default.css

@@ -39,13 +39,14 @@ a img {
 
 h1 {
     color: #3d4852;
-    font-size: 18px;
+    font-size: 20px;
     font-weight: bold;
     margin-top: 0;
     text-align: left;
 }
 
 h2 {
+    color: #3d4852;
     font-size: 16px;
     font-weight: bold;
     margin-top: 0;