Merge branch 'master' of https://bitbucket.org/Panabonic/faufcc-api
commit
eaa9d73e80
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ApplicationStatusChanged {
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public Application $application;
|
||||
public string $status;
|
||||
|
||||
public function __construct(Application $application, $status = null) {
|
||||
$this->application = $application;
|
||||
$this->status = $status ?? $application->status;
|
||||
}
|
||||
|
||||
public function broadcastOn(): PrivateChannel {
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Applications;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Applications\Application;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use App\Transformers\Applications\ApplicationTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApplicationsController extends Controller {
|
||||
protected Application $model;
|
||||
|
||||
public function __construct(Application $model) {
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse {
|
||||
$filters = collect($request->has('filters') ? json_decode($request->get('filters'), true) : [])->filter(function($val) {return $val;});
|
||||
$query = $this->model->query();
|
||||
$service = FiltersService::getService('applications');
|
||||
$service->applyFilters($query, $filters);
|
||||
$query->orderBy('id', 'desc');
|
||||
$paginator = $query->paginate(config('app.pagination_limit'));
|
||||
return fractal($paginator, new ApplicationTransformer())->respond();
|
||||
}
|
||||
|
||||
public function show(Request $request, $id): JsonResponse {
|
||||
$query = $this->model->query();
|
||||
$model = $query->byUuid($id)->firstOrFail();
|
||||
return fractal($model, new ApplicationTransformer())->respond();
|
||||
}
|
||||
|
||||
public function store(Request $request) {
|
||||
}
|
||||
|
||||
public function update(Request $request, $uuid) {
|
||||
}
|
||||
|
||||
public function destroy(Request $request, $uuid): JsonResponse {
|
||||
$model = $this->model->byUuid($uuid)->firstOrFail();
|
||||
$model->delete();
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ class MembersController extends Controller {
|
|||
$query = $this->model->query();
|
||||
$service = FiltersService::getService('companyMembers');
|
||||
$service->applyFilters($query, $filters);
|
||||
$paginator = $query->paginate(2);
|
||||
$paginator = $query->paginate(config('app.pagination_limit'));
|
||||
return fractal($paginator, new CompanyMemberTransformer())->respond();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,16 @@ use App\Services\Forms\FormsService;
|
|||
use App\Transformers\Objects\ObjectTransformer;
|
||||
use App\Transformers\Objects\ObjectTypeTransformer;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FormsController extends Controller {
|
||||
public function get(Request $request, $target, $type = null, $id = null) {
|
||||
if ($target === 'model') {
|
||||
return FormsService::getService($type)->form($id, json_decode($request->get('extra_props'), true) ?? []);
|
||||
$service = FormsService::getService($type);
|
||||
if ($request->user() || $service->unprotected) return $service->form($id, json_decode($request->get('extra_props'), true) ?? []);
|
||||
else return response()->json(['error' => 'Unauthenticated.'], 401);
|
||||
//return FormsService::getService($type)->form($id, json_decode($request->get('extra_props'), true) ?? []);
|
||||
} elseif ($object = NirObject::byUuid($id)->first()) {
|
||||
return fractal($object, new ObjectTransformer())->respond();
|
||||
} elseif ($objectType = ObjectType::byUuidOrName($type)->first()) {
|
||||
|
|
@ -43,6 +47,14 @@ class FormsController extends Controller {
|
|||
}
|
||||
}
|
||||
|
||||
public function getFeedbackFormSupport(Request $request): ?JsonResponse {
|
||||
return ($objectType = ObjectType::byName('feedback-form-support')->first()) ? fractal($objectType, new ObjectTypeTransformer())->respond() : null;
|
||||
}
|
||||
public function saveFeedbackFormSupport(Request $request): ?JsonResponse {
|
||||
return FormsService::getService('feedback-form-support')->save($request->all());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function filters(Request $request, $type) {
|
||||
$filters = collect(json_decode($request->get('filters', []), true));
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
|||
use App\Models\Objects\Field;
|
||||
use App\Models\Objects\NirObject;
|
||||
use App\Models\Objects\ObjectType;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use App\Transformers\Objects\ObjectTransformer;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
|
@ -19,7 +20,11 @@ class ObjectsController extends Controller {
|
|||
}
|
||||
|
||||
public function index(Request $request): JsonResponse {
|
||||
$filters = collect($request->has('filters') ? json_decode($request->get('filters'), true) : [])->filter(function($val) {return $val;});
|
||||
$query = $this->model->query();
|
||||
$service = FiltersService::getService('objects');
|
||||
$service->applyFilters($query, $filters);
|
||||
/*
|
||||
if (($val = $request->get('type')) && ($type = ObjectType::query()->where(['name' => $val])->first())) {
|
||||
$query->whereHas('type', function ($query) use ($val) {
|
||||
$query->where('name', $val)->orWhereHas('parent', function ($query) use ($val) {
|
||||
|
|
@ -36,6 +41,7 @@ class ObjectsController extends Controller {
|
|||
elseif ($field = Field::byUuidOrName($prop)->first()) $field->applyFilter($query, $value);
|
||||
});
|
||||
$query->orderBy('created_at', 'desc');
|
||||
*/
|
||||
$paginator = $query->paginate(config('app.pagination_limit'));
|
||||
return fractal($paginator, new ObjectTransformer())->respond();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\Pages;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Pages\Page;
|
||||
use App\Models\Publications\Publication;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use App\Transformers\Pages\PageTransformer;
|
||||
use App\Transformers\Publications\PublicationTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
|
@ -31,7 +32,10 @@ class PagesController extends Controller {
|
|||
}
|
||||
|
||||
public function index(Request $request): JsonResponse {
|
||||
$filters = collect($request->has('filters') ? json_decode($request->get('filters'), true) : [])->filter(function($val) {return $val;});
|
||||
$query = $this->model->query();
|
||||
$service = FiltersService::getService('pages');
|
||||
$service->applyFilters($query, $filters);
|
||||
$paginator = $query->paginate(config('app.pagination_limit'));
|
||||
return fractal($paginator, new PageTransformer())->respond();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
|||
use App\Models\Pages\Page;
|
||||
use App\Models\Publications\Publication;
|
||||
use App\Models\Publications\PublicationType;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use App\Transformers\Publications\PublicationTransformer;
|
||||
use App\Transformers\Registries\RegistryTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
|
@ -26,18 +27,10 @@ class PublicationsController extends Controller {
|
|||
}
|
||||
|
||||
public function index(Request $request): JsonResponse {
|
||||
$filters = collect($request->has('filters') ? json_decode($request->get('filters'), true) : [])->filter(function($val) {return $val;});
|
||||
$query = $this->model->query()->orderBy('published_at', 'desc');
|
||||
$user = Auth::user();
|
||||
if (!($user->isAdmin ?? null)) {
|
||||
$query->where(['is_published' => true]);
|
||||
$query->where('published_at', '<=', now());
|
||||
}
|
||||
|
||||
if ($page = Page::byUuid($request->get('page_id'))->first()) {
|
||||
$query->where(['page_id' => $page->id]);
|
||||
} elseif ($page = Page::query()->where(['sub_type' => $request->get('sub_type')])->first()) {
|
||||
$query->where('page_id', $page->id);
|
||||
}
|
||||
$service = FiltersService::getService('publications');
|
||||
$service->applyFilters($query, $filters);
|
||||
$paginator = $query->paginate(config('app.pagination_limit'));
|
||||
return fractal($paginator, new PublicationTransformer())->respond();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,82 +5,71 @@ namespace App\Http\Controllers\Api\Users;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Transformers\Users\UserTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
protected $model;
|
||||
class UsersController extends Controller {
|
||||
protected User $model;
|
||||
|
||||
public function __construct(User $model)
|
||||
{
|
||||
public function __construct(User $model) {
|
||||
$this->model = $model;
|
||||
/*
|
||||
$this->middleware('permission:List users')->only('index');
|
||||
$this->middleware('permission:List users')->only('show');
|
||||
$this->middleware('permission:Create users')->only('store');
|
||||
$this->middleware('permission:Update users')->only('update');
|
||||
$this->middleware('permission:Delete users')->only('destroy');
|
||||
*/
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
||||
public function checkEmail(Request $request): JsonResponse {
|
||||
$this->validate($request, ['email' => 'required|email|unique:users,email']);
|
||||
return response()->json(null);
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse {
|
||||
$paginator = $this->model->with('roles.permissions')->paginate($request->get('limit', config('app.pagination_limit', 20)));
|
||||
if ($request->has('limit')) {
|
||||
$paginator->appends('limit', $request->get('limit'));
|
||||
}
|
||||
|
||||
//if ($request->has('limit')) $paginator->appends('limit', $request->get('limit'));
|
||||
return fractal($paginator, new UserTransformer())->respond();
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
public function show($id): JsonResponse {
|
||||
$user = $this->model->with('roles.permissions')->byUuid($id)->firstOrFail();
|
||||
|
||||
return fractal($user, new UserTransformer())->respond();
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
public function store(Request $request): JsonResponse {
|
||||
$this->validate($request, [
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|unique:users,email',
|
||||
'password' => 'required|min:8|confirmed',
|
||||
]);
|
||||
$user = $this->model->create($request->all());
|
||||
if ($request->has('roles')) {
|
||||
$user->syncRoles($request['roles']);
|
||||
}
|
||||
|
||||
$user->assignRole('User');
|
||||
//if ($request->has('roles')) $user->syncRoles($request['roles']);
|
||||
return fractal($user, new UserTransformer())->respond(201);
|
||||
}
|
||||
|
||||
public function update(Request $request, $uuid)
|
||||
{
|
||||
public function update(Request $request, $uuid): JsonResponse {
|
||||
$user = $this->model->byUuid($uuid)->firstOrFail();
|
||||
$rules = [
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|unique:users,email,'.$user->id,
|
||||
];
|
||||
if ($request->method() == 'PATCH') {
|
||||
$rules = [
|
||||
if ($request->method() == 'PATCH') $rules = [
|
||||
'name' => 'sometimes|required',
|
||||
'email' => 'sometimes|required|email|unique:users,email,'.$user->id,
|
||||
];
|
||||
}
|
||||
$this->validate($request, $rules);
|
||||
// Except password as we don't want to let the users change a password from this endpoint
|
||||
$user->update($request->except('_token', 'password'));
|
||||
if ($request->has('roles')) {
|
||||
$user->syncRoles($request['roles']);
|
||||
}
|
||||
|
||||
//if ($request->has('roles')) $user->syncRoles($request['roles']);
|
||||
return fractal($user->fresh(), new UserTransformer())->respond();
|
||||
}
|
||||
|
||||
public function destroy(Request $request, $uuid)
|
||||
{
|
||||
public function destroy(Request $request, $uuid): JsonResponse {
|
||||
$user = $this->model->byUuid($uuid)->firstOrFail();
|
||||
$user->delete();
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Listeners\Applications;
|
||||
|
||||
use App\Events\Applications\ApplicationStatusChanged;
|
||||
use App\Mail\Applications\NotifyApplicationStatusChanged;
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Applications\ApplicationStatus;
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendApplicationStatusChangedNotifications {
|
||||
public array $notifiableStatuses = [
|
||||
'applicant' => [ApplicationStatus::COMPLETED],
|
||||
'addresses' => [ApplicationStatus::PROCESSING]
|
||||
];
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
public function handle(ApplicationStatusChanged $event) {
|
||||
if (in_array($event->status, $this->notifiableStatuses['addresses'])) $this->notifyAddressees($event->application, $event->status);
|
||||
if (in_array($event->status, $this->notifiableStatuses['applicant'])) $this->notifyApplicant($event->application, $event->status);
|
||||
}
|
||||
|
||||
public function notifyAddressees(Application $application, $status) {
|
||||
$application->addressees->each(function(CompanyMember $member) use($application, $status) {
|
||||
$this->notify($member->user, $application, $status);
|
||||
});
|
||||
}
|
||||
|
||||
public function notifyApplicant(Application $application, $status) {
|
||||
$this->notify($application->submitter, $application, $status);
|
||||
}
|
||||
|
||||
public function notify(User $recipient, Application $application, $status) {
|
||||
try {
|
||||
Mail::to($recipient->email)->send(new NotifyApplicationStatusChanged($application, $recipient, $status));
|
||||
} 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 NotifyApplicationStatusChanged extends Mailable implements ShouldQueue {
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public Application $application;
|
||||
public User $recipient;
|
||||
public string $status;
|
||||
|
||||
public function __construct(Application $application, User $recipient, $status) {
|
||||
$this->application = $application;
|
||||
$this->recipient = $recipient;
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
public function build(): NotifyApplicationStatusChanged {
|
||||
$subject = $this->application->title;
|
||||
return $this->subject($subject)->view("mail.applications.status-changed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Applications;
|
||||
|
||||
use App\Events\Applications\ApplicationStatusChanged;
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use App\Models\Objects\Field;
|
||||
use App\Models\Products\Product;
|
||||
use App\Models\User;
|
||||
use App\Support\HasObjectsTrait;
|
||||
use App\Support\RelationValuesTrait;
|
||||
use App\Support\UuidScopeTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Application extends Model {
|
||||
use UuidScopeTrait, SoftDeletes, HasObjectsTrait, RelationValuesTrait;
|
||||
|
||||
protected $dates = [
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'submitter_id',
|
||||
'product_id',
|
||||
'status',
|
||||
'number',
|
||||
'applicant'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'id'
|
||||
];
|
||||
|
||||
|
||||
|
||||
public function submitter(): BelongsTo {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function product(): BelongsTo {
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
|
||||
public function conclusions(): HasMany {
|
||||
return $this->hasMany(Conclusion::class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getTitleAttribute(): string {
|
||||
return "Заявка №{$this->number} от " . $this->created_at->format('d.m.Y');
|
||||
}
|
||||
|
||||
public function getParsedStatusAttribute(): array {
|
||||
return ['name' => $this->status, 'title' => ApplicationStatus::TITLES[$this->status] ?? null];
|
||||
}
|
||||
|
||||
public function getPropertiesAttribute(): ?Model {
|
||||
return $this->getObject('application-properties', 'properties');
|
||||
}
|
||||
|
||||
public function getAddresseesAttribute() {
|
||||
return CompanyMember::query()->mainCompany()->whereHas('objects', function($query) {
|
||||
Field::applyFilters($query, collect(['types' => 'company-member-properties', 'moderate-permissions' => 'applications']));
|
||||
})->get();
|
||||
}
|
||||
|
||||
|
||||
public function submit(): bool {
|
||||
$res = $this->update(['status' => ApplicationStatus::PROCESSING]);
|
||||
event(new ApplicationStatusChanged($this));
|
||||
return $res;
|
||||
}
|
||||
public function complete(): bool {
|
||||
$res = $this->update(['status' => ApplicationStatus::COMPLETED]);
|
||||
event(new ApplicationStatusChanged($this));
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
public function setNumber() {
|
||||
if (!$this->number) $this->update(['number' => self::generateNumber()]);
|
||||
}
|
||||
|
||||
public static function generateNumber($start = 100, $digits = 5): string {
|
||||
$res = intval(static::query()->max('number') ?? $start) + 1;
|
||||
while (strlen($res) < $digits) {
|
||||
$res = "0{$res}";
|
||||
}
|
||||
return trim($res);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Applications;
|
||||
|
||||
class ApplicationStatus {
|
||||
public const SUBMITTED = 'submitted';
|
||||
public const PROCESSING = 'processing';
|
||||
public const COMPLETED = 'completed';
|
||||
public const CANCELED = 'canceled';
|
||||
|
||||
public const TITLES = [
|
||||
self::SUBMITTED => 'Направлено',
|
||||
self::PROCESSING => 'В работе',
|
||||
self::COMPLETED => 'Выполнено',
|
||||
self::CANCELED =>'Отозвана заявителем'
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Applications;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Support\UuidScopeTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Conclusion extends Model {
|
||||
use UuidScopeTrait, SoftDeletes;
|
||||
|
||||
public $table = 'application_conclusions';
|
||||
|
||||
protected $dates = [
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'application_id',
|
||||
'author_id',
|
||||
'message'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'id'
|
||||
];
|
||||
|
||||
|
||||
public function application(): BelongsTo {
|
||||
return $this->belongsTo(Application::class);
|
||||
}
|
||||
|
||||
public function author(): BelongsTo {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ namespace App\Models\Companies;
|
|||
|
||||
use App\Models\Advisories\AdvisoryMember;
|
||||
use App\Models\User;
|
||||
use App\Support\HasObjectsTrait;
|
||||
use App\Support\RelationValuesTrait;
|
||||
use App\Support\UuidScopeTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
|
@ -13,7 +14,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CompanyMember extends Model {
|
||||
use UuidScopeTrait, SoftDeletes, RelationValuesTrait;
|
||||
use UuidScopeTrait, SoftDeletes, HasObjectsTrait, RelationValuesTrait;
|
||||
|
||||
protected $dates = [
|
||||
'deleted_at',
|
||||
|
|
@ -55,6 +56,17 @@ class CompanyMember extends Model {
|
|||
}
|
||||
|
||||
|
||||
public function scopeMainCompany($query) {
|
||||
return $query->whereHas('company', function($query) {
|
||||
$query->where(['is_main' => 1]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getPropertiesAttribute(): ?Model {
|
||||
return $this->getObject('company-member-properties');
|
||||
}
|
||||
|
||||
public function getIsMeAttribute(): ?bool {
|
||||
return ($user = Auth::user()) ? ($user->id === $this->user_id) : null;
|
||||
|
|
|
|||
|
|
@ -144,13 +144,14 @@ class Field extends Model {
|
|||
|
||||
public static function applyFilters(Builder $query, Collection $filters, ?FiltersService $service = null) {
|
||||
if ($types = $filters->get('types')) {
|
||||
$types = is_array($types) ? $types : [$types];
|
||||
$filters->forget('types');
|
||||
$query->whereHas('type', function($query) use($types) {
|
||||
$query->whereIn('uuid', is_array($types) ? $types : [$types]);
|
||||
$query->whereIn('uuid', $types)->orWhereIn('name', $types);
|
||||
});
|
||||
$filters->filter(function($value) {return $value;})->each(function($value, $prop) use($query, $types, $service) {
|
||||
$field = Field::query()->where(['name' => $prop])->whereHas('groups.objectType', function($query) use($types) {
|
||||
$query->whereIn('uuid', is_array($types) ? $types : [$types]);
|
||||
$query->whereIn('uuid', $types)->orWhereIn('name', $types);
|
||||
})->first();
|
||||
if ($field) $field->applyFilter($query, $value);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ use App\Models\Objects\Values\BooleanValue;
|
|||
use App\Models\Objects\Values\DateValue;
|
||||
use App\Models\Objects\Values\DocumentValue;
|
||||
use App\Models\Objects\Values\FloatValue;
|
||||
use App\Models\Objects\Values\HtmlValue;
|
||||
use App\Models\Objects\Values\ImageValue;
|
||||
use App\Models\Objects\Values\IntegerValue;
|
||||
use App\Models\Objects\Values\RelationValue;
|
||||
use App\Models\Objects\Values\StringValue;
|
||||
use App\Models\Objects\Values\TextValue;
|
||||
use App\Models\Pages\Page;
|
||||
use App\Models\Registries\Entry;
|
||||
use App\Models\User;
|
||||
use App\Support\UuidScopeTrait;
|
||||
|
|
@ -46,6 +48,10 @@ class NirObject extends Model {
|
|||
return $this->morphedByMany(Entry::class, 'objectable');
|
||||
}
|
||||
|
||||
public function pages(): MorphToMany {
|
||||
return $this->morphedByMany(Page::class, 'objectable');
|
||||
}
|
||||
|
||||
public function objects(): MorphToMany {
|
||||
return $this->morphToMany(NirObject::class, 'objectable');
|
||||
}
|
||||
|
|
@ -76,6 +82,9 @@ class NirObject extends Model {
|
|||
public function textValues(): HasMany {
|
||||
return $this->hasMany(TextValue::class, 'object_id');
|
||||
}
|
||||
public function htmlValues(): HasMany {
|
||||
return $this->hasMany(HtmlValue::class, 'object_id');
|
||||
}
|
||||
public function integerValues(): HasMany {
|
||||
return $this->hasMany(IntegerValue::class, 'object_id');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace App\Models\Pages;
|
||||
|
||||
use App\Models\Objects\Field;
|
||||
use App\Models\Publications\Publication;
|
||||
use App\Models\Registries\Registry;
|
||||
use App\Models\User;
|
||||
use App\Support\HasObjectsTrait;
|
||||
use App\Support\RelationValuesTrait;
|
||||
use App\Support\UuidScopeTrait;
|
||||
|
|
@ -94,6 +96,12 @@ class Page extends Model {
|
|||
|
||||
|
||||
|
||||
public function isEditable(User $user): bool {
|
||||
return $user->isModerator && $user->membership()->whereHas('objects', function($query) {
|
||||
Field::applyFilters($query, collect(['types' => 'company-member-properties', 'moderate-pages' => $this->parents->add($this)->pluck('uuid')->all()]));
|
||||
})->exists();
|
||||
}
|
||||
|
||||
public function addSection($typeName, $ord = null): ?Model {
|
||||
return $this->createObject($typeName, $ord, 'sections');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Products;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Support\UuidScopeTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Product extends Model {
|
||||
use UuidScopeTrait, SoftDeletes;
|
||||
|
||||
protected $dates = [
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'purpose',
|
||||
'usage',
|
||||
'normative',
|
||||
'producer'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'id'
|
||||
];
|
||||
|
||||
|
||||
public function applications(): HasMany {
|
||||
return $this->hasMany(Application::class);
|
||||
}
|
||||
|
||||
|
||||
public function getApplicationAttribute() {
|
||||
return $this->applications()->first();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,13 +4,23 @@ namespace App\Models;
|
|||
|
||||
use App\Events\UserRegistered;
|
||||
use App\Mail\PasswordResetRequested;
|
||||
use App\Models\Advisories\Advisory;
|
||||
use App\Models\Advisories\AdvisoryMember;
|
||||
use App\Models\Advisories\AdvisoryMemberRank;
|
||||
use App\Models\Applications\Conclusion;
|
||||
use App\Models\Companies\Company;
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use App\Models\Companies\CompanyMemberRole;
|
||||
use App\Models\Objects\Field;
|
||||
use App\Support\HasRolesUuid;
|
||||
use App\Support\HasSocialLogin;
|
||||
use App\Support\RelationValuesTrait;
|
||||
use App\Support\UuidScopeTrait;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
|
@ -55,6 +65,22 @@ class User extends Authenticatable {
|
|||
return $this->belongsTo(Asset::class, 'asset_id');
|
||||
}
|
||||
|
||||
public function companies(): BelongsToMany {
|
||||
return $this->belongsToMany(Company::class, 'company_members');
|
||||
}
|
||||
|
||||
public function membership(): HasMany {
|
||||
return $this->hasMany(CompanyMember::class);
|
||||
}
|
||||
public function advisoryMembership(): HasManyThrough {
|
||||
return $this->hasManyThrough(AdvisoryMember::class, CompanyMember::class);
|
||||
}
|
||||
|
||||
|
||||
public function applicationConclusions(): HasMany {
|
||||
return $this->hasMany(Conclusion::class, 'author_id');
|
||||
}
|
||||
|
||||
|
||||
public function getInitialsAttribute(): string {
|
||||
return collect(explode(' ', $this->name))->slice(0, 2)->map(function($item) {
|
||||
|
|
@ -67,14 +93,34 @@ class User extends Authenticatable {
|
|||
}
|
||||
|
||||
public function getIsAdminAttribute(): bool {
|
||||
return $this->hasRole('Administrator');
|
||||
return $this->hasRole('Administrator') || $this->isMainCompanyAdmin;
|
||||
}
|
||||
public function getIsModeratorAttribute(): bool {
|
||||
return $this->membership()->where(['role' => CompanyMemberRole::MODERATOR])->mainCompany()->exists();
|
||||
}
|
||||
public function getIsMainCompanyAdminAttribute(): bool {
|
||||
return $this->membership()->where(['role' => CompanyMemberRole::ADMINISTRATOR])->mainCompany()->exists();
|
||||
}
|
||||
public function getIsMainCompanyMemberAttribute(): bool {
|
||||
return $this->companies()->where(['is_main' => 1])->exists();
|
||||
}
|
||||
public function getIsExpertAttribute(): bool {
|
||||
return $this->membership()->mainCompany()->whereHas('objects', function($query) {
|
||||
Field::applyFilters($query, collect(['types' => 'company-member-properties', 'moderate-permissions' => 'applications']));
|
||||
})->exists();
|
||||
}
|
||||
|
||||
public function getIsPrivilegedAttribute() {
|
||||
return $this->isAdmin;
|
||||
public function getPrivilegesAttribute(): array {
|
||||
return [
|
||||
'admin' => $this->isAdmin,
|
||||
'expert' => $this->isExpert,
|
||||
'main_company_member' => $this->isMainCompanyMember
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function getByData($data, $triggerEvent = false) {
|
||||
$result = false;
|
||||
if ($email = trim($data['email'] ?? null)) {
|
||||
|
|
@ -108,6 +154,14 @@ class User extends Authenticatable {
|
|||
}
|
||||
|
||||
|
||||
public function setPassword(string $password): bool {
|
||||
return $this->update(['password' => Hash::make($password)]);
|
||||
}
|
||||
|
||||
public function checkPassword(string $password): bool {
|
||||
return Hash::check($password, $this->password);
|
||||
}
|
||||
|
||||
public function sendPasswordResetNotification($token) {
|
||||
Mail::to($this->email)->send(new PasswordResetRequested($this, $token));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace App\Providers;
|
|||
use App\Models\Advisories\Advisory;
|
||||
use App\Models\Advisories\AdvisoryCompany;
|
||||
use App\Models\Advisories\AdvisoryMember;
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Applications\Conclusion;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Companies\Address;
|
||||
use App\Models\Companies\BankDetails;
|
||||
|
|
@ -20,6 +22,7 @@ use App\Models\Objects\NirObject;
|
|||
use App\Models\Objects\ObjectType;
|
||||
use App\Models\Pages\Page;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Products\Product;
|
||||
use App\Models\Publications\Publication;
|
||||
use App\Models\Registries\Category;
|
||||
use App\Models\Registries\Entry;
|
||||
|
|
@ -51,7 +54,7 @@ class AppServiceProvider extends ServiceProvider
|
|||
public function boot() {
|
||||
Carbon::setLocale(config('app.locale'));
|
||||
|
||||
// if ($this->app->environment('local')) Mail::alwaysTo('panabonic@yandex.ru');
|
||||
if ($this->app->environment('local')) Mail::alwaysTo('test@nirgroup.ru');
|
||||
|
||||
Relation::enforceMorphMap([
|
||||
'asset' => Asset::class,
|
||||
|
|
@ -84,7 +87,11 @@ class AppServiceProvider extends ServiceProvider
|
|||
|
||||
'advisory' => Advisory::class,
|
||||
'advisory-member' => AdvisoryMember::class,
|
||||
'advisory-company' => AdvisoryCompany::class
|
||||
'advisory-company' => AdvisoryCompany::class,
|
||||
|
||||
'application' => Application::class,
|
||||
'application-conclusion' => Conclusion::class,
|
||||
'product' => Product::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Events\Applications\ApplicationStatusChanged;
|
||||
use App\Events\FeedbackSender;
|
||||
use App\Events\PasswordRecovered;
|
||||
use App\Events\UserRegistered;
|
||||
use App\Listeners\Applications\SendApplicationStatusChangedNotifications;
|
||||
use App\Listeners\SendFeedbackMessage;
|
||||
use App\Listeners\SendPasswordRecoveredNotification;
|
||||
use App\Listeners\SendRegistrationNotification;
|
||||
|
|
@ -25,6 +27,10 @@ class EventServiceProvider extends ServiceProvider {
|
|||
],
|
||||
FeedbackSender::class => [
|
||||
SendFeedbackMessage::class
|
||||
],
|
||||
|
||||
ApplicationStatusChanged::class => [
|
||||
SendApplicationStatusChangedNotifications::class
|
||||
]
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Applications\ApplicationStatus;
|
||||
use App\Models\Objects\FieldType;
|
||||
use App\Models\User;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use App\Transformers\Users\UserTransformer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Spatie\Fractal\Fractal;
|
||||
|
||||
class ApplicationFilters extends FiltersService {
|
||||
public function get(Collection $filters): array {
|
||||
$groups = [
|
||||
[
|
||||
'name' => 'common',
|
||||
'title' => 'Общие параметры',
|
||||
'fields' => $this->nativeFields($filters)
|
||||
]
|
||||
];
|
||||
$query = Application::query();
|
||||
$this->applyFilters($query, $filters);
|
||||
return ['groups' => ['data' => $groups], 'total' => $query->count()];
|
||||
}
|
||||
|
||||
public function nativeFields(Collection $filters): array {
|
||||
return [
|
||||
[
|
||||
'name' => 'created_at',
|
||||
'title' => 'Дата формирования заявки',
|
||||
'type' => FieldType::DATE,
|
||||
'range' => $this->getDatesRange('created_at', $filters),
|
||||
'value' => $filters->get('created_at')
|
||||
],
|
||||
[
|
||||
'name' => 'status',
|
||||
'title' => 'Статус',
|
||||
'type' => FieldType::RELATION,
|
||||
'represented' => $this->getStatuses($filters),
|
||||
'value' => $this->getRelationValue($filters->get('status'), ApplicationStatus::TITLES)
|
||||
],
|
||||
[
|
||||
'name' => 'expert',
|
||||
'title' => 'Эксперт',
|
||||
'type' => FieldType::RELATION,
|
||||
'represented' => $this->getExperts($filters),
|
||||
'value' => ($val = $filters->get('expert')) ? fractal(User::byUuids($val)->get(), new UserTransformer()) : null
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function getDatesRange($prop, Collection $filters): array {
|
||||
$query = Application::query();
|
||||
$this->applyFilters($query, $filters->except($prop));
|
||||
return ['min' => ($v = $query->min($prop)) ? Date::create($v)->format('Y-m-d') : null, 'max' => ($v = $query->max($prop)) ? Date::create($v)->format('Y-m-d') : null];
|
||||
}
|
||||
|
||||
|
||||
public function getStatuses(Collection $filters): array {
|
||||
$query = Application::query()->whereNotNull('status')->distinct('status');
|
||||
$this->applyFilters($query, $filters->except('status'));
|
||||
$res = $query->get('status')->map(function($item) {return $item->status;})->all();
|
||||
return $this->getRelationItems(collect(ApplicationStatus::TITLES)->only($res)->all());
|
||||
}
|
||||
|
||||
|
||||
public function getExperts(Collection $filters): Fractal {
|
||||
return fractal(User::query()->whereHas('applicationConclusions.application', function($query) use($filters) {
|
||||
$this->applyFilters($query, $filters->except('expert'));
|
||||
})->orderBy('name')->get(), new UserTransformer());
|
||||
}
|
||||
|
||||
|
||||
public function applyFilters(Builder $query, Collection $filters) {
|
||||
$this->applyNativeFilters($query, $filters);
|
||||
$this->applyPermissionsFilters($query);
|
||||
}
|
||||
|
||||
public function applyNativeFilters(Builder $query, Collection $filters) {
|
||||
$filters->each(function($value, $prop) use($query) {
|
||||
$this->applyNativeFilter($query, $prop, $value);
|
||||
});
|
||||
}
|
||||
|
||||
public function applyNativeFilter(Builder $query, $prop, $value) {
|
||||
if ($value) {
|
||||
if ($prop === 'search') $this->applySearchFilter($query, $value, ['number', 'applicant', ['submitter' => ['name']], ['product' => ['name', 'purpose', 'normative', 'producer']]]);
|
||||
elseif ($prop === 'created_at') $this->applyDateFilter($query, 'created_at', $value);
|
||||
elseif ($prop === 'status') $query->whereIn('status', is_array($value) ? $value : [$value]);
|
||||
elseif ($prop === 'expert') $this->applyRelationFilter($query, 'conclusions.author', $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyPermissionsFilters(Builder $query) {
|
||||
$user = Auth::user();
|
||||
if (!$user->isExpert && !$user->isAdmin) $query->where(['submitter_id' => $user->id ?? null]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Applications;
|
||||
|
||||
class ApplicationFiltersServices {
|
||||
public static array $services = [
|
||||
'applications' => ApplicationFilters::class
|
||||
];
|
||||
}
|
||||
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
namespace App\Services\Filters;
|
||||
|
||||
use App\Services\Filters\Applications\ApplicationFiltersServices;
|
||||
use App\Services\Filters\Companies\CompanyFiltersServices;
|
||||
use App\Services\Filters\Objects\ObjectFiltersServices;
|
||||
use App\Services\Filters\Pages\PageFiltersServices;
|
||||
use App\Services\Filters\Publications\PublicationFiltersServices;
|
||||
use App\Services\Filters\Registries\RegistryFiltersServices;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
|
@ -10,8 +14,12 @@ use Illuminate\Support\Facades\Date;
|
|||
|
||||
class FiltersService {
|
||||
public static array $services = [
|
||||
PageFiltersServices::class,
|
||||
PublicationFiltersServices::class,
|
||||
RegistryFiltersServices::class,
|
||||
CompanyFiltersServices::class
|
||||
CompanyFiltersServices::class,
|
||||
ApplicationFiltersServices::class,
|
||||
ObjectFiltersServices::class
|
||||
];
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Objects;
|
||||
|
||||
use App\Models\Objects\Field;
|
||||
use App\Models\Objects\NirObject;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ObjectFilters extends FiltersService {
|
||||
public function get(Collection $filters): array {
|
||||
$groups = [
|
||||
];
|
||||
$query = NirObject::query();
|
||||
$this->applyFilters($query, $filters);
|
||||
return ['groups' => ['data' => $groups], 'total' => $query->count()];
|
||||
}
|
||||
|
||||
|
||||
public function applyFilters(Builder $query, Collection $filters) {
|
||||
$this->applyNativeFilters($query, $filters);
|
||||
$this->applyObjectFilters($query, $filters);
|
||||
$this->applyPermissionsFilters($query);
|
||||
}
|
||||
|
||||
public function applyNativeFilters(Builder $query, Collection $filters) {
|
||||
$filters->each(function($value, $prop) use($query) {
|
||||
$this->applyNativeFilter($query, $prop, $value);
|
||||
});
|
||||
}
|
||||
|
||||
public function applyNativeFilter(Builder $query, $prop, $value) {
|
||||
if ($value) {
|
||||
if ($prop === 'search') $this->applySearchFilter($query, $value, ['name', ['pages' => ['name']], ['stringValues' => ['value']], ['textValues' => ['value']], ['htmlValues' => ['value']]]);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyObjectFilters(Builder $query, Collection $filters) {
|
||||
Field::applyFilters($query, $filters);
|
||||
}
|
||||
|
||||
public function applyCompanyFilter(Builder $query, $value) {
|
||||
$query->whereHas('company', function($query) use($value) {
|
||||
($value === 'main') ? $query->where(['is_main' => 1]) : $query->whereIn('uuid', is_array($value) ? $value : [$value]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function applyPermissionsFilters(Builder $query) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Objects;
|
||||
|
||||
class ObjectFiltersServices {
|
||||
public static array $services = [
|
||||
'objects' => ObjectFilters::class
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Pages;
|
||||
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class PageFilters extends FiltersService {
|
||||
public function get(Collection $filters): array {
|
||||
$groups = [
|
||||
[
|
||||
'name' => 'common',
|
||||
'title' => 'Общие параметры',
|
||||
'fields' => $this->nativeFields($filters)
|
||||
]
|
||||
];
|
||||
$query = CompanyMember::query();
|
||||
$this->applyFilters($query, $filters);
|
||||
return ['groups' => ['data' => $groups], 'total' => $query->count()];
|
||||
}
|
||||
|
||||
public function nativeFields(Collection $filters): array {
|
||||
return [
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function applyFilters(Builder $query, Collection $filters) {
|
||||
$this->applyNativeFilters($query, $filters);
|
||||
$this->applyPermissionsFilters($query);
|
||||
}
|
||||
|
||||
public function applyNativeFilters(Builder $query, Collection $filters) {
|
||||
$filters->each(function($value, $prop) use($query) {
|
||||
$this->applyNativeFilter($query, $prop, $value);
|
||||
});
|
||||
}
|
||||
|
||||
public function applyNativeFilter(Builder $query, $prop, $value) {
|
||||
if ($value) {
|
||||
if ($prop === 'search') $this->applySearchFilter($query, $value, ['name']);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyPermissionsFilters(Builder $query) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Pages;
|
||||
|
||||
class PageFiltersServices {
|
||||
public static array $services = [
|
||||
'pages' => PageFilters::class
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Publications;
|
||||
|
||||
use App\Models\Companies\CompanyMember;
|
||||
use App\Services\Filters\FiltersService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PublicationFilters extends FiltersService {
|
||||
public function get(Collection $filters): array {
|
||||
$groups = [
|
||||
[
|
||||
'name' => 'common',
|
||||
'title' => 'Общие параметры',
|
||||
'fields' => $this->nativeFields($filters)
|
||||
]
|
||||
];
|
||||
$query = CompanyMember::query();
|
||||
$this->applyFilters($query, $filters);
|
||||
return ['groups' => ['data' => $groups], 'total' => $query->count()];
|
||||
}
|
||||
|
||||
public function nativeFields(Collection $filters): array {
|
||||
return [
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function applyFilters(Builder $query, Collection $filters) {
|
||||
$this->applyNativeFilters($query, $filters);
|
||||
$this->applyPermissionsFilters($query);
|
||||
}
|
||||
|
||||
public function applyNativeFilters(Builder $query, Collection $filters) {
|
||||
$filters->each(function($value, $prop) use($query) {
|
||||
$this->applyNativeFilter($query, $prop, $value);
|
||||
});
|
||||
}
|
||||
|
||||
public function applyNativeFilter(Builder $query, $prop, $value) {
|
||||
if ($value) {
|
||||
if ($prop === 'search') $this->applySearchFilter($query, $value, ['name', 'excerpt']);
|
||||
elseif ($prop === 'page') $this->applyRelationFilter($query, 'page', $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyPermissionsFilters(Builder $query) {
|
||||
$user = Auth::user();
|
||||
if (!($user->isAdmin ?? null)) $query->where(['is_published' => true])->where('published_at', '<=', now());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Filters\Publications;
|
||||
|
||||
class PublicationFiltersServices {
|
||||
public static array $services = [
|
||||
'publications' => PublicationFilters::class
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Forms\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Applications\ApplicationStatus;
|
||||
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 Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ApplicationForms 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)],
|
||||
['title' => 'Документация', 'groups' => $this->form2Groups($model)]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function form1Groups(?Application $model): array {
|
||||
$groups = [
|
||||
['name' => 'common', 'title' => '', 'fields' => $this->commonGroupFields($model)]
|
||||
];
|
||||
return ['data' => $groups];
|
||||
}
|
||||
|
||||
public function form2Groups(?Application $model): array {
|
||||
$groups = [
|
||||
['name' => 'documents', 'title' => '', 'fields' => $this->documentsGroupFields($model)]
|
||||
];
|
||||
return ['data' => $groups];
|
||||
}
|
||||
|
||||
public function commonGroupFields(?Application $model): array {
|
||||
$fields = [
|
||||
[
|
||||
'name' => 'applicant',
|
||||
'title' => 'Организация-заявитель',
|
||||
'type' => FieldType::STRING,
|
||||
'required' => true,
|
||||
'value' => $model->applicant ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'product_name',
|
||||
'title' => 'Hаименование продукции',
|
||||
'type' => FieldType::TEXT,
|
||||
'required' => true,
|
||||
'value' => $model->product->name ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'product_purpose',
|
||||
'title' => 'Hазначение продукции',
|
||||
'type' => FieldType::TEXT,
|
||||
'required' => true,
|
||||
'value' => $model->product->purpose ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'product_usage',
|
||||
'title' => 'Область применения продукции',
|
||||
'type' => FieldType::TEXT,
|
||||
'required' => true,
|
||||
'value' => $model->product->usage ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'normative',
|
||||
'title' => 'Нормативно-технический документ',
|
||||
'type' => FieldType::STRING,
|
||||
'value' => $model->product->normative ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'producer',
|
||||
'title' => 'Изготовитель/разработчик',
|
||||
'type' => FieldType::TEXT,
|
||||
'required' => true,
|
||||
'value' => $model->product->producer ?? null
|
||||
]
|
||||
];
|
||||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
public function documentsGroupFields(?Application $model): array {
|
||||
$fields = [
|
||||
[
|
||||
'name' => 'documents',
|
||||
'title' => 'Документация',
|
||||
'type' => FieldType::DOCUMENT,
|
||||
'multiple' => true,
|
||||
'value' => $model ? fractal($model->properties->getValue('documents'), new AssetTransformer()) : null
|
||||
]
|
||||
];
|
||||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function store(array $data): ?JsonResponse {
|
||||
$product = Product::create();
|
||||
$model = Application::create(['submitter_id' => Auth::user()->id, 'product_id' => $product->id, 'number' => Application::generateNumber(), 'status' => ApplicationStatus::PROCESSING]);
|
||||
$this->updateData($model, $data);
|
||||
$model->submit();
|
||||
return fractal($model, new ApplicationTransformer())->respond();
|
||||
}
|
||||
|
||||
public function update(string $id, array $data): ?JsonResponse {
|
||||
$model = Application::byUuid($id)->firstOrFail();
|
||||
$this->updateData($model, $data);
|
||||
return fractal($model, new ApplicationTransformer())->respond();
|
||||
}
|
||||
|
||||
public function updateData(Application $model, array $data) {
|
||||
$model->update(['applicant' => $data['applicant'] ?? null]);
|
||||
$model->product->update(['name' => $data['product_name'] ?? null, 'purpose' => $data['product_purpose'] ?? null, 'usage' => $data['product_usage'] ?? null,
|
||||
'normative' => $data['normative'] ?? null, 'producer' => $data['producer'] ?? null]);
|
||||
$model->properties->setValue('documents', $data['documents'] ?? null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Forms\Applications;
|
||||
|
||||
class ApplicationFormsServices {
|
||||
public static array $services = [
|
||||
'application' => ApplicationForms::class,
|
||||
'applicationConclusion' => ConclusionForms::class
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Forms\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Applications\Conclusion;
|
||||
use App\Models\Objects\FieldType;
|
||||
use App\Services\Forms\FormsService;
|
||||
use App\Transformers\Applications\ConclusionTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ConclusionForms extends FormsService {
|
||||
public array $formTitles = ['create' => 'Ответ на заявку', 'update' => 'Редактирование ответа'];
|
||||
|
||||
public function form(?string $id = null, array $data = []): array {
|
||||
$model = Conclusion::byUuid($id)->first();
|
||||
return [
|
||||
'title' => $this->formTitle($model),
|
||||
'frames' => [
|
||||
['title' => 'Общие сведения', 'groups' => $this->form1Groups($model)],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function form1Groups(?Conclusion $model): array {
|
||||
$groups = [
|
||||
['name' => 'common', 'title' => '', 'fields' => $this->commonGroupFields($model)]
|
||||
];
|
||||
return ['data' => $groups];
|
||||
}
|
||||
|
||||
public function commonGroupFields(?Conclusion $model): array {
|
||||
$fields = [
|
||||
[
|
||||
'name' => 'message',
|
||||
'title' => 'Мнение эксперта',
|
||||
'type' => FieldType::HTML,
|
||||
'required' => true,
|
||||
'value' => $model->message ?? null
|
||||
]
|
||||
];
|
||||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
|
||||
|
||||
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]);
|
||||
$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]);
|
||||
return fractal($model, new ConclusionTransformer())->respond();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,12 +6,14 @@ use App\Models\Companies\CompanyMember;
|
|||
use App\Models\Companies\CompanyMemberRank;
|
||||
use App\Models\Companies\CompanyMemberRole;
|
||||
use App\Models\Companies\Department;
|
||||
use App\Models\Dictionaries\Dictionary;
|
||||
use App\Models\Objects\FieldType;
|
||||
use App\Models\Pages\Page;
|
||||
use App\Models\User;
|
||||
use App\Services\Forms\FormsService;
|
||||
use App\Transformers\Companies\CompanyMemberTransformer;
|
||||
use App\Transformers\Companies\DepartmentTransformer;
|
||||
use App\Transformers\Dictionaries\DictionaryItemTransformer;
|
||||
use App\Transformers\Pages\PageTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -20,20 +22,35 @@ class CompanyMemberForms extends FormsService {
|
|||
public array $formTitles = ['create' => 'Добавление сотрудника организации', 'update' => 'Редактирование сотрудника'];
|
||||
|
||||
public function form(?string $id = null, array $data = []): array {
|
||||
$department = Department::byUuid($data['department'] ?? null)->first();
|
||||
$model = CompanyMember::byUuid($id)->first();
|
||||
$company = $model->company ?? $department->company;
|
||||
$user = Auth::user();
|
||||
$frames = [['title' => 'Общие сведения', 'groups' => $this->form1Groups($model)]];
|
||||
if (($company->is_main ?? null) && $user->isAdmin) $frames[] = ['title' => 'Полномочия', 'groups' => $this->form2Groups($model)];
|
||||
return ['title' => $this->formTitle($model), 'frames' => $frames];
|
||||
}
|
||||
|
||||
public function form1Groups(?CompanyMember $model): array {
|
||||
$groups = [
|
||||
[
|
||||
'name' => 'common',
|
||||
'fields' => $this->commonGroupFields($model),
|
||||
['name' => 'common', 'title' => '', 'fields' => $this->commonGroupFields($model)]
|
||||
];
|
||||
return ['data' => $groups];
|
||||
}
|
||||
|
||||
public function form2Groups(?CompanyMember $model): array {
|
||||
$groups = [
|
||||
['name' => 'permissions', 'title' => '', 'fields' => $this->permissionsGroupFields($model),
|
||||
'dynamic' => [
|
||||
['field' => 'role', 'hide' => ['pages']],
|
||||
['field' => 'role', 'value' => CompanyMemberRole::MODERATOR, 'show' => ['pages']]
|
||||
['field' => 'role', 'hide' => ['moderate-pages']],
|
||||
['field' => 'role', 'value' => CompanyMemberRole::MODERATOR, 'show' => ['moderate-pages']]
|
||||
]
|
||||
]
|
||||
];
|
||||
return ['title' => $this->formTitle($model), 'data' => $groups];
|
||||
return ['data' => $groups];
|
||||
}
|
||||
|
||||
|
||||
public function commonGroupFields(?CompanyMember $model): array {
|
||||
$fields = [
|
||||
[
|
||||
|
|
@ -47,7 +64,7 @@ class CompanyMemberForms extends FormsService {
|
|||
[
|
||||
'name' => 'name',
|
||||
'title' => 'ФИО',
|
||||
'type' => FieldType::TEXT,
|
||||
'type' => FieldType::STRING,
|
||||
'required' => true,
|
||||
'value' => $model->user->name ?? null
|
||||
],
|
||||
|
|
@ -75,23 +92,6 @@ class CompanyMemberForms extends FormsService {
|
|||
'title' => 'Внутренний телефон',
|
||||
'type' => FieldType::STRING,
|
||||
'value' => $model->intercom ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'role',
|
||||
'title' => 'Роль',
|
||||
'type' => FieldType::RELATION,
|
||||
'required' => true,
|
||||
'appearance' => 'radio',
|
||||
'options' => $this->getRelationItems(CompanyMemberRole::TITLES),
|
||||
'value' => $this->getRelationValue(CompanyMemberRole::TITLES, $model->role ?? null)
|
||||
],
|
||||
[
|
||||
'name' => 'pages',
|
||||
'title' => 'Разделы сайта',
|
||||
'type' => FieldType::RELATION,
|
||||
'multiple' => true,
|
||||
'options' => fractal(Page::all(), new PageTransformer()),
|
||||
'value' => null
|
||||
]
|
||||
/*
|
||||
[
|
||||
|
|
@ -124,12 +124,46 @@ class CompanyMemberForms extends FormsService {
|
|||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
public function permissionsGroupFields(?CompanyMember $model): array {
|
||||
$fields = [
|
||||
[
|
||||
'name' => 'role',
|
||||
'title' => 'Роль',
|
||||
'type' => FieldType::RELATION,
|
||||
'required' => true,
|
||||
'appearance' => 'radio',
|
||||
'options' => $this->getRelationItems(CompanyMemberRole::TITLES),
|
||||
'value' => $this->getRelationValue(CompanyMemberRole::TITLES, $model->role ?? null)
|
||||
],
|
||||
[
|
||||
'name' => 'moderate-pages',
|
||||
'title' => 'Разделы сайта',
|
||||
'type' => FieldType::RELATION,
|
||||
'multiple' => true,
|
||||
'options' => fractal(Page::all(), new PageTransformer()),
|
||||
'value' => $model ? fractal($model->properties->getValue('moderate-pages'), new PageTransformer()) : null
|
||||
],
|
||||
[
|
||||
'name' => 'moderate-permissions',
|
||||
'title' => 'Права',
|
||||
'type' => FieldType::RELATION,
|
||||
'multiple' => true,
|
||||
'appearance' => 'checkbox',
|
||||
'options' => fractal(Dictionary::byName('moderate-permissions')->first()->items, new DictionaryItemTransformer()),
|
||||
'value' => $model ? fractal($model->properties->getValue('moderate-permissions'), new DictionaryItemTransformer()) : null
|
||||
],
|
||||
];
|
||||
|
||||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function store(array $data): ?JsonResponse {
|
||||
if (($department = Department::byUuid($data['department'] ?? null)->first()) && ($user = User::getByData(collect($data)->except('role')->all(), true))) {
|
||||
$model = $department->addMember($user, $data['position'] ?? null);
|
||||
$model->update(['position' => $data['position'] ?? null, 'role' => $data['role'] ?? null, 'room' => $data['room'] ?? null, 'intercom' => $data['intercom'] ?? null]);
|
||||
$model->properties->setValues($data);
|
||||
return fractal($model, new CompanyMemberTransformer())->respond();
|
||||
}
|
||||
}
|
||||
|
|
@ -140,6 +174,7 @@ class CompanyMemberForms extends FormsService {
|
|||
if ($department = Department::byUuid($data['department'] ?? null)->first()) $model->update(['department_id' => $department->id]);
|
||||
$model->user->update(['name' => $data['name'] ?? null, 'phone' => $data['phone'] ?? null]);
|
||||
if (($email = $data['email'] ?? null) && !User::query()->where(['email' => $email])->exists()) $model->user->update(['email' => $data['email']]);
|
||||
$model->properties->setValues($data);
|
||||
return fractal($model->fresh(), new CompanyMemberTransformer())->respond();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Services\Forms;
|
||||
|
||||
use App\Services\Forms\Advisories\AdvisoryFormsServices;
|
||||
use App\Services\Forms\Applications\ApplicationFormsServices;
|
||||
use App\Services\Forms\Companies\CompanyFormsServices;
|
||||
use App\Services\Forms\Feedback\FeedbackFormsServices;
|
||||
use App\Services\Forms\Pages\PageFormsServices;
|
||||
|
|
@ -12,6 +13,7 @@ use App\Services\Forms\Users\UserFormsServices;
|
|||
|
||||
class FormsService {
|
||||
public array $formTitles = ['create' => '', 'update' => ''];
|
||||
public array $errors = [];
|
||||
|
||||
public static array $services = [
|
||||
PageFormsServices::class,
|
||||
|
|
@ -20,7 +22,8 @@ class FormsService {
|
|||
UserFormsServices::class,
|
||||
FeedbackFormsServices::class,
|
||||
AdvisoryFormsServices::class,
|
||||
CompanyFormsServices::class
|
||||
CompanyFormsServices::class,
|
||||
ApplicationFormsServices::class
|
||||
];
|
||||
|
||||
public function __construct() {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace App\Services\Forms\Users;
|
|||
|
||||
class UserFormsServices {
|
||||
public static array $services = [
|
||||
'user' => UserForms::class
|
||||
'user' => UserForms::class,
|
||||
'userProfile' => UserProfileForms::class,
|
||||
'userPassword' => UserPasswordForms::class
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Forms\Users;
|
||||
|
||||
use App\Models\Objects\FieldType;
|
||||
use App\Models\User;
|
||||
use App\Services\Forms\FormsService;
|
||||
use App\Transformers\Users\UserTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UserPasswordForms extends FormsService {
|
||||
public array $formTitles = ['create' => '', 'update' => 'Изменение пароля'];
|
||||
|
||||
public function form(?string $id = null, array $data = []): array {
|
||||
$model = User::byUuid($id)->first();
|
||||
$groups = [
|
||||
['name' => 'common', 'fields' => $this->commonGroupFields($model)]
|
||||
];
|
||||
return ['title' => $this->formTitle($model), 'data' => $groups];
|
||||
}
|
||||
|
||||
public function commonGroupFields(?User $model): array {
|
||||
$fields = [
|
||||
[
|
||||
'name' => 'current_password',
|
||||
'title' => 'Текущий пароль',
|
||||
'type' => FieldType::STRING,
|
||||
'appearance' => 'password',
|
||||
'required' => true
|
||||
],
|
||||
[
|
||||
'name' => 'password',
|
||||
'title' => 'Новый пароль',
|
||||
'type' => FieldType::STRING,
|
||||
'appearance' => 'password',
|
||||
'required' => true
|
||||
],
|
||||
[
|
||||
'name' => 'confirmation',
|
||||
'title' => 'Подтверждение пароля',
|
||||
'type' => FieldType::STRING,
|
||||
'appearance' => 'password',
|
||||
'required' => true
|
||||
]
|
||||
];
|
||||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function store(array $data): void {
|
||||
}
|
||||
|
||||
public function update(string $id, array $data): ?JsonResponse {
|
||||
$model = User::byUuid($id)->firstOrFail();
|
||||
//Validator::make($data, []);
|
||||
if (!$model->checkPassword($data['current_password'])) $this->error('current_password', 'Текущий пароль указан неверно');
|
||||
if (($data['password']) !== ($data['confirmation'])) $this->error('confirmation', 'Пароль и подтверждение пароля не совпадают');
|
||||
if (!$this->errors) {
|
||||
$model->setPassword($data['password']);
|
||||
return fractal($model, new UserTransformer())->respond();
|
||||
} else return response()->json($this->errors, 422);
|
||||
}
|
||||
|
||||
public function error($field, $message) {
|
||||
$this->errors[$field][] = $message;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Forms\Users;
|
||||
|
||||
use App\Models\Objects\FieldType;
|
||||
use App\Models\User;
|
||||
use App\Services\Forms\FormsService;
|
||||
use App\Transformers\Assets\AssetTransformer;
|
||||
use App\Transformers\Users\UserTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UserProfileForms extends FormsService {
|
||||
public array $formTitles = ['create' => '', 'update' => 'Редактирование профиля'];
|
||||
|
||||
public function form(?string $id = null, array $data = []): array {
|
||||
$model = User::byUuid($id)->first();
|
||||
$groups = [
|
||||
['name' => 'common', 'fields' => $this->commonGroupFields($model)]
|
||||
];
|
||||
return ['title' => $this->formTitle($model), 'data' => $groups];
|
||||
}
|
||||
|
||||
public function commonGroupFields(?User $model): array {
|
||||
$fields = [
|
||||
[
|
||||
'name' => 'name',
|
||||
'title' => 'Фамилия, имя, отчество',
|
||||
'type' => FieldType::STRING,
|
||||
'required' => true,
|
||||
'value' => $model->name ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'phone',
|
||||
'title' => 'Телефон',
|
||||
'type' => FieldType::STRING,
|
||||
'value' => $model->phone ?? null
|
||||
],
|
||||
[
|
||||
'name' => 'avatar',
|
||||
'title' => 'Фотография',
|
||||
'type' => FieldType::IMAGE,
|
||||
'value' => ($model->avatar ?? null) ? fractal($model->avatar, new AssetTransformer()) : null
|
||||
]
|
||||
];
|
||||
return ['data' => $fields];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function store(array $data): void {
|
||||
}
|
||||
|
||||
public function update(string $id, array $data): ?JsonResponse {
|
||||
$model = User::byUuid($id)->firstOrFail();
|
||||
$model->update($data);
|
||||
$model->setAvatar($data['avatar'] ?? null);
|
||||
return fractal($model->fresh(), new UserTransformer())->respond();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Models\Objects\NirObject;
|
||||
use App\Models\Pages\Page;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -12,7 +14,9 @@ class PermissionsService {
|
|||
private ?User $user;
|
||||
|
||||
private array $rules = [
|
||||
NirObject::class => 'nirObject'
|
||||
NirObject::class => 'nirObject',
|
||||
Application::class => 'application',
|
||||
Page::class => 'page'
|
||||
];
|
||||
|
||||
public function __construct(Model $model, ?User $user = null) {
|
||||
|
|
@ -21,11 +25,14 @@ class PermissionsService {
|
|||
}
|
||||
|
||||
public function get(): array {
|
||||
$result = [];
|
||||
if ($this->user) {
|
||||
$rule = $this->rules[get_class($this->model)] ?? null;
|
||||
$func = "{$rule}Permissions";
|
||||
if ($this->user->isPrivileged) return ['anything' => true];
|
||||
elseif (method_exists($this, $func)) return $this->$func();
|
||||
else return [];
|
||||
$result = method_exists($this, $func) ? $this->$func() : [];
|
||||
if ($this->user->isAdmin) $result['anything'] = true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -33,4 +40,12 @@ class PermissionsService {
|
|||
return ['edit' => $this->model->owner_id === $this->user->id];
|
||||
}
|
||||
|
||||
public function applicationPermissions(): array {
|
||||
return ['edit' => $this->model->submitter_id === $this->user->id, 'reply' => $this->user->isExpert];
|
||||
}
|
||||
|
||||
public function pagePermissions(): array {
|
||||
return ['edit' => $this->model->isEditable($this->user)];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Transformers\Applications;
|
||||
|
||||
use App\Models\Applications\Application;
|
||||
use App\Services\PermissionsService;
|
||||
use App\Transformers\Objects\ObjectTransformer;
|
||||
use App\Transformers\Products\ProductTransformer;
|
||||
use App\Transformers\Users\UserTransformer;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Resource\Primitive;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
class ApplicationTransformer extends TransformerAbstract {
|
||||
protected array $defaultIncludes = [];
|
||||
|
||||
protected array $availableIncludes = [
|
||||
'submitter', 'product', 'properties', 'conclusions', 'permissions'
|
||||
];
|
||||
|
||||
public function transform(Application $model): array {
|
||||
return [
|
||||
'id' => $model->uuid,
|
||||
'title' => $model->title,
|
||||
'status' => $model->parsedStatus,
|
||||
'number' => $model->number,
|
||||
'applicant' => $model->applicant,
|
||||
'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null,
|
||||
'updated_at' => $model->updated_at ? $model->updated_at->toIso8601String() : null
|
||||
];
|
||||
}
|
||||
|
||||
public function includeSubmitter(Application $model): ?Item {
|
||||
return $model->submitter ? $this->item($model->submitter, new UserTransformer()) : null;
|
||||
}
|
||||
|
||||
public function includeProduct(Application $model): ?Item {
|
||||
return $model->product ? $this->item($model->product, new ProductTransformer()) : null;
|
||||
}
|
||||
|
||||
public function includeProperties(Application $model): ?Item {
|
||||
return $model->properties ? $this->item($model->properties, new ObjectTransformer()) : null;
|
||||
}
|
||||
|
||||
public function includeConclusions(Application $model): Collection {
|
||||
return $this->collection($model->conclusions, new ConclusionTransformer());
|
||||
}
|
||||
|
||||
public function includePermissions(Application $model): Primitive {
|
||||
return $this->primitive((new PermissionsService($model))->get());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Transformers\Applications;
|
||||
|
||||
use App\Models\Applications\Conclusion;
|
||||
use App\Transformers\Users\UserTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
class ConclusionTransformer extends TransformerAbstract {
|
||||
protected array $defaultIncludes = [];
|
||||
|
||||
protected array $availableIncludes = [
|
||||
'author', 'application'
|
||||
];
|
||||
|
||||
public function transform(Conclusion $model): array {
|
||||
return [
|
||||
'id' => $model->uuid,
|
||||
'message' => $model->message,
|
||||
'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null,
|
||||
'updated_at' => $model->updated_at ? $model->updated_at->toIso8601String() : null
|
||||
];
|
||||
}
|
||||
|
||||
public function includeAuthor(Conclusion $model): ?Item {
|
||||
return $model->author ? $this->item($model->author, new UserTransformer()) : null;
|
||||
}
|
||||
|
||||
public function includeApplication(Conclusion $model): ?Item {
|
||||
return $model->application ? $this->item($model->application, new ApplicationTransformer()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ namespace App\Transformers\Objects;
|
|||
|
||||
use App\Models\Objects\NirObject;
|
||||
use App\Services\PermissionsService;
|
||||
use App\Transformers\Pages\PageTransformer;
|
||||
use App\Transformers\Users\UserTransformer;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
|
@ -16,7 +17,7 @@ class ObjectTransformer extends TransformerAbstract {
|
|||
];
|
||||
|
||||
protected array $availableIncludes = [
|
||||
'groups', 'type', 'owner', 'permissions'
|
||||
'groups', 'type', 'owner', 'pages', 'permissions'
|
||||
];
|
||||
|
||||
public function transform(NirObject $model): array {
|
||||
|
|
@ -42,6 +43,10 @@ class ObjectTransformer extends TransformerAbstract {
|
|||
return $model->owner ? $this->item($model->owner, new UserTransformer()) : null;
|
||||
}
|
||||
|
||||
public function includePages(NirObject $model): Collection {
|
||||
return $this->collection($model->pages, new PageTransformer());
|
||||
}
|
||||
|
||||
public function includePermissions(NirObject $model): Primitive {
|
||||
return $this->primitive((new PermissionsService($model))->get());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Transformers\Products;
|
||||
|
||||
use App\Models\Products\Product;
|
||||
use App\Transformers\Applications\ApplicationTransformer;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
class ProductTransformer extends TransformerAbstract {
|
||||
protected array $defaultIncludes = [];
|
||||
|
||||
protected array $availableIncludes = [
|
||||
'applications'
|
||||
];
|
||||
|
||||
public function transform(Product $model): array {
|
||||
return [
|
||||
'id' => $model->uuid,
|
||||
'name' => $model->name,
|
||||
'purpose' => $model->purpose,
|
||||
'usage' => $model->usage,
|
||||
'normative' => $model->normative,
|
||||
'producer' => $model->producer
|
||||
];
|
||||
}
|
||||
|
||||
public function includeApplications(Product $model): Collection {
|
||||
return $this->collection($model->applications, new ApplicationTransformer());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,13 +4,15 @@ namespace App\Transformers\Users;
|
|||
|
||||
use App\Models\User;
|
||||
use App\Transformers\Assets\AssetTransformer;
|
||||
use App\Transformers\Companies\CompanyMemberTransformer;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Resource\Primitive;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
class UserTransformer extends TransformerAbstract {
|
||||
protected array $defaultIncludes = [];
|
||||
protected array $availableIncludes = ['avatar', 'roles'];
|
||||
protected array $availableIncludes = ['avatar', 'roles', 'membership', 'privileges'];
|
||||
|
||||
public function transform(User $model): array {
|
||||
return [
|
||||
|
|
@ -33,4 +35,12 @@ class UserTransformer extends TransformerAbstract {
|
|||
return $this->collection($model->roles, new RoleTransformer());
|
||||
}
|
||||
|
||||
public function includeMembership(User $model): Collection {
|
||||
return $this->collection($model->membership, new CompanyMemberTransformer());
|
||||
}
|
||||
|
||||
public function includePrivileges(User $model): Primitive {
|
||||
return $this->primitive($model->privileges);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateApplicationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('applications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->char('uuid', 36)->index()->unique();
|
||||
$table->integer('submitter_id')->index()->nullable();
|
||||
$table->integer('product_id')->index()->nullable();
|
||||
$table->string('status')->index()->nullable();
|
||||
$table->string('number')->index()->nullable();
|
||||
$table->string('applicant', 750)->index()->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('applications');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('products', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->char('uuid', 36)->index()->unique();
|
||||
$table->text('name')->nullable();
|
||||
$table->text('purpose')->nullable();
|
||||
$table->text('usage')->nullable();
|
||||
$table->text('normative')->nullable();
|
||||
$table->text('producer')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('products');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateApplicationConclusionsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('application_conclusions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->char('uuid', 36)->index()->unique();
|
||||
$table->integer('application_id')->index()->nullable();
|
||||
$table->integer('author_id')->index()->nullable();
|
||||
$table->text('message')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('application_conclusions');
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,10 @@ class DictionariesTableSeeder extends Seeder {
|
|||
'research-types' => [
|
||||
'title' => 'Виды исследовательских работ',
|
||||
'items' => ['nir' => 'НИР', 'niokr' => 'НИОКР']
|
||||
],
|
||||
'moderate-permissions' => [
|
||||
'title' => 'Права',
|
||||
'items' => ['applications' => 'Рассмотрение предварительных заявок']
|
||||
]
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ use App\Models\Dictionaries\DictionaryItem;
|
|||
use App\Models\Objects\Field;
|
||||
use App\Models\Objects\FieldType;
|
||||
use App\Models\Objects\ObjectType;
|
||||
use App\Models\Pages\Page;
|
||||
use App\Transformers\Dictionaries\DictionaryItemTransformer;
|
||||
use App\Transformers\Objects\ObjectTypeTransformer;
|
||||
use App\Transformers\Pages\PageTransformer;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class FieldsTableSeeder extends Seeder {
|
||||
|
|
@ -331,6 +333,26 @@ class FieldsTableSeeder extends Seeder {
|
|||
'type' => FieldType::STRING,
|
||||
'required' => true,
|
||||
],
|
||||
|
||||
'moderate-pages' => [
|
||||
'title' => 'Модерируемые разделы сайта',
|
||||
'type' => FieldType::RELATION,
|
||||
'multiple' => true,
|
||||
'params' => [
|
||||
'related' => Page::class, 'transformer' => PageTransformer::class,
|
||||
'options' => ['show' => true]
|
||||
]
|
||||
],
|
||||
'moderate-permissions' => [
|
||||
'title' => 'Права',
|
||||
'type' => FieldType::RELATION,
|
||||
'multiple' => true,
|
||||
'params' => [
|
||||
'appearance' => 'checkbox',
|
||||
'related' => DictionaryItem::class, 'transformer' => DictionaryItemTransformer::class,
|
||||
'options' => ['show' => true, 'whereHas' => ['dictionary' => ['name' => 'moderate-permissions']]]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function run() {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,18 @@ class ObjectTypeFieldsTableSeeder extends Seeder {
|
|||
'common' => [
|
||||
'fields' => ['operation-type', 'order-name', 'order-date', 'order-document', 'listings', 'active-since', 'active-till', 'developer']
|
||||
]
|
||||
],
|
||||
|
||||
'company-member-properties' => [
|
||||
'common' => [
|
||||
'fields' => ['moderate-pages', 'moderate-permissions']
|
||||
]
|
||||
],
|
||||
|
||||
'application-properties' => [
|
||||
'common' => [
|
||||
'fields' => ['documents']
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,14 @@ class ObjectTypesTableSeeder extends Seeder {
|
|||
'title' => 'Действие со сводом правил'
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
'company-member-properties' => [
|
||||
'title' => 'Параметры сотрудника организации'
|
||||
],
|
||||
|
||||
'application-properties' => [
|
||||
'title' => 'Параметры заявки'
|
||||
]
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
@extends('mail.layouts.layout')
|
||||
|
||||
@section('content')
|
||||
@if($status === \App\Models\Applications\ApplicationStatus::PROCESSING)
|
||||
<p><b>{{$application->title}} поступила на рассмотрение</b></p>
|
||||
<p><b>Заявитель</b>: {{$application->applicant ?? 'не указано'}}</p>
|
||||
<p><b>Наименование продукции</b>: {{$application->product->name ?? 'не указано'}}</p>
|
||||
<p><b>Назначение продукции</b>: {{$application->product->purpose ?? 'не указано'}}</p>
|
||||
@elseif($status === \App\Models\Applications\ApplicationStatus::COMPLETED)
|
||||
<p><b>{{$application->title}} выполнена.</b></p>
|
||||
@endif
|
||||
@endsection
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
@extends('mail.layouts.layout')
|
||||
|
||||
@section('content')
|
||||
<p>Вы запросили сброс пароля на интернет-потрале {{\App\Models\Advisories\Advisory::main()->caption}}</p>
|
||||
<p>Вы запросили сброс пароля на сайте ФАУ ФЦС</p>
|
||||
<p><a class="btn" href="{{url('password/reset', [$token, $recipient->email])}}">Сбросить пароль</a></p>
|
||||
<p>Ссылка на сброс пароля действительна в течение 60 минут.</p>
|
||||
<p>Если вы не запрашивали сброс пароля, никаких дальнейших действий не требуется.</p>
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@ Route::get('assets/{uuid}', 'Api\Assets\RenderFileController@open');
|
|||
Route::get('assets/{uuid}/render', 'Api\Assets\RenderFileController@show');
|
||||
Route::get('assets/{uuid}/download', 'Api\Assets\RenderFileController@download');
|
||||
|
||||
Route::post('register', 'Api\Auth\RegisterController@store');
|
||||
Route::post('signup', 'Api\Users\UsersController@store');
|
||||
Route::get('users/check-email', 'Api\Users\UsersController@checkEmail');
|
||||
Route::post('passwords/reset', 'Api\Auth\PasswordsController@store');
|
||||
Route::put('passwords/reset', 'Api\Auth\PasswordsController@update');
|
||||
|
||||
Route::get('/check-email', 'Api\Auth\RegisterController@checkEmail');
|
||||
|
||||
Route::get('pages', 'Api\Pages\PagesController@index');
|
||||
Route::get('pages/root', 'Api\Pages\PagesController@root');
|
||||
Route::get('pages/find', 'Api\Pages\PagesController@find');
|
||||
|
|
@ -23,13 +22,10 @@ Route::get('publications', 'Api\Publications\PublicationsController@index');
|
|||
Route::get('publications/find', 'Api\Publications\PublicationsController@find');
|
||||
Route::get('publications/{id}', 'Api\Publications\PublicationsController@show');
|
||||
|
||||
Route::apiResource('object-types', 'Api\Objects\ObjectTypesController');
|
||||
|
||||
Route::group(['prefix' => 'forms'], function() {
|
||||
Route::get('/{target}/{type?}/{id?}', 'Api\Forms\FormsController@get');
|
||||
Route::post('/{target}/{type?}/{id?}', 'Api\Forms\FormsController@save');
|
||||
});
|
||||
Route::apiResource('object-types', 'Api\Objects\ObjectTypesController', []);
|
||||
|
||||
Route::put('objects/move/{id}', 'Api\Objects\ObjectsController@move');
|
||||
Route::apiResource('objects', 'Api\Objects\ObjectsController');
|
||||
|
||||
Route::group(['prefix' => 'registries'], function() {
|
||||
Route::get('/categories', 'Api\Registries\CategoriesController@index');
|
||||
|
|
@ -47,6 +43,10 @@ Route::group(['prefix' => 'registries'], function() {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
Route::get('forms/object/feedback-form-support', 'Api\Forms\FormsController@getFeedbackFormSupport');
|
||||
Route::post('forms/model/feedback-form-support', 'Api\Forms\FormsController@saveFeedbackFormSupport');
|
||||
|
||||
Route::get('filters/{type}', 'Api\Forms\FormsController@filters');
|
||||
|
||||
Route::group(['middleware' => ['auth:api']], function() {
|
||||
|
|
@ -71,8 +71,11 @@ Route::group(['middleware' => ['auth:api']], function() {
|
|||
Route::post('/', 'Api\Assets\UploadFileController@store');
|
||||
});
|
||||
|
||||
Route::put('objects/move/{id}', 'Api\Objects\ObjectsController@move');
|
||||
Route::apiResource('objects', 'Api\Objects\ObjectsController');
|
||||
|
||||
Route::group(['prefix' => 'forms'], function() {
|
||||
Route::get('/{target}/{type?}/{id?}', 'Api\Forms\FormsController@get');
|
||||
Route::post('/{target}/{type?}/{id?}', 'Api\Forms\FormsController@save');
|
||||
});
|
||||
|
||||
Route::get('dadata/{inn}', 'Api\Companies\CompaniesController@getDataByInn');
|
||||
|
||||
|
|
@ -88,4 +91,5 @@ Route::group(['middleware' => ['auth:api']], function() {
|
|||
Route::apiResource('advisory-companies', 'Api\Advisories\AdvisoryCompaniesController');
|
||||
Route::apiResource('advisory-members', 'Api\Advisories\AdvisoryMembersController');
|
||||
|
||||
Route::apiResource('applications', 'Api\Applications\ApplicationsController');
|
||||
});
|
||||
Loading…
Reference in New Issue