applications permissions and notifications major update
parent
bb340b7a81
commit
abae7d79b7
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ApplicationExpertChanged {
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public Application $application;
|
||||
public ?CompanyMember $previousExpert;
|
||||
|
||||
public function __construct(Application $application, ?CompanyMember $previousExpert = null) {
|
||||
$this->application = $application;
|
||||
$this->previousExpert = $previousExpert;
|
||||
}
|
||||
|
||||
public function broadcastOn(): PrivateChannel {
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Listeners\Applications;
|
||||
|
||||
use App\Events\Applications\ApplicationExpertChanged;
|
||||
use App\Mail\Applications\NotifyApplicationExpertChanged;
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendApplicationExpertChangedNotifications {
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
public function handle(ApplicationExpertChanged $event) {
|
||||
if ($v = $event->application->submitter) $this->notify($v, $event->application);
|
||||
if ($v = $event->application->expert()->first()) $this->notify($v->user, $event->application);
|
||||
if ($v = $event->previousExpert) $this->notify($v->user, $event->application);
|
||||
}
|
||||
|
||||
public function notify(User $recipient, Application $application) {
|
||||
try {
|
||||
Mail::to($recipient->email)->send(new NotifyApplicationExpertChanged($application, $recipient));
|
||||
} catch (\Exception $exception) {}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class NotifyApplicationExpertChanged extends Mailable implements ShouldQueue {
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public Application $application;
|
||||
public User $recipient;
|
||||
|
||||
public function __construct(Application $application, User $recipient) {
|
||||
$this->application = $application;
|
||||
$this->recipient = $recipient;
|
||||
}
|
||||
|
||||
public function build(): NotifyApplicationExpertChanged {
|
||||
$expert = $this->application->expert()->first();
|
||||
$subject = "Назначен эксперт по заявке №{$this->application->number}";
|
||||
if ($this->recipient->id === ($expert->user->id ?? null)) $subject = "Вы назначены экспертом по заявке №{$this->application->number}";
|
||||
return $this->subject($subject)->view("mail.applications.expert-changed");
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Models\Applications;
|
||||
|
||||
use App\Events\Applications\ApplicationExpertChanged;
|
||||
use App\Events\Applications\ApplicationStatusChanged;
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use App\Models\Objects\Field;
|
||||
|
|
@ -95,6 +96,14 @@ class Application extends Model {
|
|||
if (!$this->number) $this->update(['number' => self::generateNumber()]);
|
||||
}
|
||||
|
||||
public function setExpert(CompanyMember $expert) {
|
||||
if ($this->expert->id !== $expert->id) {
|
||||
$previousExpert = $this->expert;
|
||||
$this->update(['expert_id' => $expert->id]);
|
||||
event(new ApplicationExpertChanged($this, $previousExpert));
|
||||
}
|
||||
}
|
||||
|
||||
public static function generateNumber($start = 100, $digits = 5): string {
|
||||
$res = intval(static::query()->max('number') ?? $start) + 1;
|
||||
while (strlen($res) < $digits) {
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ class User extends Authenticatable {
|
|||
'super_admin' => $this->isSuperAdmin,
|
||||
'admin' => $this->isAdmin,
|
||||
'expert' => $this->isExpert,
|
||||
'applications_manager' => $this->isApplicationsManager,
|
||||
'main_company_member' => $this->isMainCompanyMember
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot() {
|
||||
Carbon::setLocale(config('app.locale'));
|
||||
|
||||
if ($this->app->environment('local')) Mail::alwaysTo('test@nirgroup.ru');
|
||||
if ($v = env('MAIL_ALWAYS_TO')) Mail::alwaysTo($v);
|
||||
|
||||
Relation::enforceMorphMap([
|
||||
'asset' => Asset::class,
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Events\Applications\ApplicationExpertChanged;
|
||||
use App\Events\Applications\ApplicationStatusChanged;
|
||||
use App\Events\FeedbackSender;
|
||||
use App\Events\PasswordRecovered;
|
||||
use App\Events\UserRegistered;
|
||||
use App\Listeners\Applications\SendApplicationExpertChangedNotifications;
|
||||
use App\Listeners\Applications\SendApplicationStatusChangedNotifications;
|
||||
use App\Listeners\SendFeedbackMessage;
|
||||
use App\Listeners\SendPasswordRecoveredNotification;
|
||||
|
|
@ -31,6 +33,9 @@ class EventServiceProvider extends ServiceProvider {
|
|||
|
||||
ApplicationStatusChanged::class => [
|
||||
SendApplicationStatusChangedNotifications::class
|
||||
],
|
||||
ApplicationExpertChanged::class => [
|
||||
SendApplicationExpertChangedNotifications::class
|
||||
]
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,11 @@ class ApplicationFilters extends FiltersService {
|
|||
|
||||
public function applyPermissionsFilters(Builder $query) {
|
||||
$user = Auth::user();
|
||||
if (!$user->isExpert && !$user->isAdmin) $query->where(['submitter_id' => $user->id ?? null]);
|
||||
if (!$user->isApplicationsManager && !$user->isAdmin) $query->where(function($query) use($user) {
|
||||
$query->where(['submitter_id' => $user->id ?? null])->orWhereHas('expert', function($query) use($user) {
|
||||
$query->where(['user_id' => $user->id ?? null]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Services\Forms\Applications;
|
|||
class ApplicationFormsServices {
|
||||
public static array $services = [
|
||||
'application' => ApplicationForms::class,
|
||||
'applicationConclusion' => ConclusionForms::class
|
||||
'applicationConclusion' => ConclusionForms::class,
|
||||
'applicationExpert' => ExpertForms::class
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,14 +47,18 @@ class ConclusionForms extends FormsService {
|
|||
|
||||
public function store(array $data): ?JsonResponse {
|
||||
$application = Application::byUuid($data['application'] ?? null)->firstOrFail();
|
||||
$model = $application->conclusions()->create(['author_id' => Auth::user()->id, 'message' => $data['message'] ?? null]);
|
||||
$user = Auth::user();
|
||||
if (($application->expert->user->id ?? null) === ($user->id ?? null)) {
|
||||
$model = $application->conclusions()->create(['author_id' => $user->id ?? null , 'message' => $data['message'] ?? null]);
|
||||
$application->complete();
|
||||
}
|
||||
return fractal($model, new ConclusionTransformer())->respond();
|
||||
}
|
||||
|
||||
public function update(string $id, array $data): ?JsonResponse {
|
||||
$model = Conclusion::byUuid($id)->firstOrFail();
|
||||
$model->update(['message' => $data['message'] ?? null]);
|
||||
$user = Auth::user();
|
||||
if (($model->application->expert->user->id ?? null) === ($user->id ?? null)) $model->update(['message' => $data['message'] ?? null]);
|
||||
return fractal($model, new ConclusionTransformer())->respond();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Forms\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Applications\ApplicationStatus;
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use App\Models\Objects\Field;
|
||||
use App\Models\Objects\FieldType;
|
||||
use App\Models\Products\Product;
|
||||
use App\Services\Forms\FormsService;
|
||||
use App\Transformers\Applications\ApplicationTransformer;
|
||||
use App\Transformers\Assets\AssetTransformer;
|
||||
use App\Transformers\Companies\CompanyMemberTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Spatie\Fractal\Fractal;
|
||||
|
||||
class ExpertForms extends FormsService {
|
||||
public array $formTitles = ['create' => 'Назначение эксперта', 'update' => 'Назначение эксперта'];
|
||||
|
||||
public function form(?string $id = null, array $data = []): array {
|
||||
$model = Application::byUuid($id)->first();
|
||||
return [
|
||||
'title' => $this->formTitle($model),
|
||||
'frames' => [
|
||||
['title' => 'Общие сведения', 'groups' => $this->form1Groups($model)]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function form1Groups(?Application $model): array {
|
||||
$groups = [
|
||||
['name' => 'common', 'title' => '', 'fields' => $this->commonGroupFields($model)]
|
||||
];
|
||||
return ['data' => $groups];
|
||||
}
|
||||
|
||||
public function commonGroupFields(?Application $model): array {
|
||||
$fields = [
|
||||
[
|
||||
'name' => 'expert',
|
||||
'title' => 'Эксперт',
|
||||
'type' => FieldType::RELATION,
|
||||
'required' => true,
|
||||
'options' => $this->getExperts(),
|
||||
'value' => ($v = $model->expert ?? null) ? fractal($v, new CompanyMemberTransformer()) : null
|
||||
]
|
||||
];
|
||||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
|
||||
public function getExperts(): Fractal {
|
||||
return fractal(CompanyMember::query()->mainCompany()->whereHas('objects', function($query) {
|
||||
Field::applyFilters($query, collect(['types' => 'company-member-properties', 'moderate-permissions' => 'applications']));
|
||||
})->get(), new CompanyMemberTransformer());
|
||||
}
|
||||
|
||||
|
||||
public function store(array $data) {
|
||||
}
|
||||
|
||||
public function update(string $id, array $data): ?JsonResponse {
|
||||
$model = Application::byUuid($id)->firstOrFail();
|
||||
if ($expert = CompanyMember::byUuid($data['expert'] ?? null)->first()) $model->setExpert($expert);
|
||||
return fractal($model, new ApplicationTransformer())->respond();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
@extends('mail.layouts.layout')
|
||||
|
||||
@php
|
||||
$expert = $application->expert()->first();
|
||||
@endphp
|
||||
|
||||
@section('content')
|
||||
@if(($expert->user->id ?? null) === ($recipient->id ?? null))
|
||||
<p>Вы назначены экспертом по заявке №{{$application->number}} от {{$application->created_at->format('d.m.Y')}}</p>
|
||||
<p><b>Заявитель</b>: {{$application->applicant ?? 'не указано'}}</p>
|
||||
<p><b>Наименование продукции</b>: {{$application->product->name ?? 'не указано'}}</p>
|
||||
<p><b>Назначение продукции</b>: {{$application->product->purpose ?? 'не указано'}}</p>
|
||||
@else
|
||||
<p>Назначен эксперт по заявке №{{$application->number}} от {{$application->created_at->format('d.m.Y')}}</p>
|
||||
<p><b>Эксперт</b>: {{$application->expert->user->name ?? ''}}. {{$application->expert->position ?? ''}}</p>
|
||||
@endif
|
||||
<p><a href="{{url('/applications')}}">Перейти к журналу заявок</a></p>
|
||||
@endsection
|
||||
|
|
@ -9,6 +9,8 @@
|
|||
@elseif($status === \App\Models\Applications\ApplicationStatus::COMPLETED)
|
||||
<p><b>{{$application->title}} выполнена.</b></p>
|
||||
<p><b>Эксперт</b>: {{$application->conclusion->author->name ?? 'не указан'}}</p>
|
||||
<p><b>Мнение эксперта</b>: {{$application->conclusion->message ?? 'не указано'}}</p>
|
||||
<p><b>Мнение эксперта</b>:</p>
|
||||
{!! $application->conclusion->message ?? 'не указано' !!}
|
||||
@endif
|
||||
<p><a href="{{url('/applications')}}">Перейти к журналу заявок</a></p>
|
||||
@endsection
|
||||
Loading…
Reference in New Issue