fix: 🛂 update claims permissions

This commit is contained in:
Alexis Gousseau 2025-10-06 16:39:50 +02:00
parent 44035c9589
commit bd343277cc
No known key found for this signature in database
GPG key ID: 4A614CB3DBBA2406
3 changed files with 133 additions and 111 deletions

View file

@ -3,6 +3,7 @@
namespace App\Policies;
use App\Enums\Users\RoleEnum;
use App\Models\Claim;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use App\Policies\Rules\UserStaticRules as USR;
@ -12,16 +13,6 @@ class ClaimPolicy
{
use HandlesAuthorization;
/**
* View a Claim.
*
* @return boolean
*/
public function view(): bool
{
return USR::everyOne();
}
/**
* View any a Claim.
*
@ -35,21 +26,25 @@ class ClaimPolicy
/**
* Preview a Claim.
*
* @param \App\Models\User $authUser
* @param \App\Models\Claim $claim
* @return boolean
*/
public function preview(): bool
public function preview(User $authUser, Claim $claim): bool
{
return USR::everyOne();
return $this->checkOnlyMinAdminOrInUserBrands($authUser, $claim);
}
/**
* Update a Claim.
*
* @param \App\Models\User $authUser
* @param \App\Models\Claim $claim
* @return boolean
*/
public function update(): bool
public function update(User $authUser, Claim $claim): bool
{
return USR::everyOne();
return $this->checkOnlyMinAdminOrInUserBrands($authUser, $claim);
}
/**
@ -66,40 +61,65 @@ class ClaimPolicy
/**
* Determine whether the user can update the associated subject of the model.
*
* @param \App\Models\User $authUser
* @param \App\Models\Claim $claim
* @return boolean
*/
public function updateSubject(): bool
public function updateSubject(User $authUser, Claim $claim): bool
{
return USR::everyOne();
return $this->checkOnlyMinAdminOrInUserBrands($authUser, $claim);
}
/**
* Update a Claim.
*
* @param \App\Models\User $authUser
* @param \App\Models\Claim $claim
* @return boolean
*/
public function updateType(): bool
public function updateType(User $authUser, Claim $claim): bool
{
return USR::everyOne();
return $this->checkOnlyMinAdminOrInUserBrands($authUser, $claim);
}
/**
* Update a Claim.
*
* @param \App\Models\User $authUser
* @param \App\Models\Claim $claim
* @return boolean
*/
public function updateStatus(): bool
public function updateStatus(User $authUser, Claim $claim): bool
{
return USR::everyOne();
return $this->checkOnlyMinAdminOrInUserBrands($authUser, $claim);
}
/**
* Update a Claim.
*
* @param \App\Models\User $authUser
* @param \App\Models\Claim $claim
* @return boolean
*/
public function updateResponseType(): bool
public function updateResponseType(User $authUser, Claim $claim): bool
{
return USR::everyOne();
return $this->checkOnlyMinAdminOrInUserBrands($authUser, $claim);
}
/**
* Check if the user an access a specific resource.
*
* @param \App\Models\User $authUser
* @param \App\Models\Claim $claim
* @return boolean
*/
private function checkOnlyMinAdminOrInUserBrands(User $authUser, Claim $claim): bool
{
$userBrandModelKeys = $authUser->brands->modelKeys();
$claimModelKey = $claim->brand->getKey();
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin) || (
UserStaticRules::atLeastRole($authUser, RoleEnum::marketing)
&& \in_array($claimModelKey, $userBrandModelKeys)
);
}
}

View file

@ -5,90 +5,101 @@
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="row w-100 mx-auto">
{{-- TITLE --}}
<div class="col-12">
<div class="d-flex align-items-start flex-row">
<a class="btn btn-primary text-decoration-none m-0" data-bs-tooltip="tooltip" href="{{ route('bo.claims.index') }}"
title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.claims')]) }}">
<i class="fa-solid fa-arrow-left"></i>
</a>
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $claimModel])
<div class="card border-0">
<div class="card-header">
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap">
<div class="d-flex align-items-start flex-row">
@can('viewAny', $claimModel)
<a class="btn btn-primary text-decoration-none me-2" data-bs-tooltip="tooltip" data-bs-placement="top"
data-bs-tooltip="tooltip" href="{{ route('bo.claims.index') }}"
title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.claims')]) }}">
<i class="fa-solid fa-arrow-left"></i>
</a>
@endcan
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $claimModel])
</div>
</div>
</div>
{{-- CLAIM AUTHOR --}}
<div class="col-12 mt-3">
<div class="card shadow-sm w-100">
<div class="card-body">
<div class="row">
<div class="col-12 col-lg-4 text-center">
<h5 class="card-title mb-1">{{ trim(sprintf('%s %s', $claimModel->first_name, $claimModel->last_name)) }}</h5>
<p class="text-muted mb-2">{{ e($claimModel->email) }}</p>
@if ($claimModel->customer && auth()->user()->can('view', $claimModel->customer))
<a href="{{ route('bo.customers.show', [
'customer' => $claimModel->customer,
'brand' => $claimModel->brand,
]) }}" target="_blank" rel="noopener">
{{ __('Lien vers la fiche client') }}
<i class="fas fa-arrow-up-right-from-square ms-1"></i>
</a>
@endif
@if ($claimModel->getFormatedAddress())
<p class="mb-0">{{ $claimModel->getFormatedAddress() ? e($claimModel->getFormatedAddress()) : null }}</p>
@endif
</div>
<div class="col-12 col-lg-8 border-top border-lg-top-0 border-lg-start border-lg-3 border-lg-primary mt-2 pt-2 mt-lg-0 pt-lg-0">
<div class="claim-message-collapse" data-json='@json(['message' => $claimModel->message])'></div>
@if($claimModel->file)
<div class="d-flex flex-row justify-content-start align-items-center">
<p class="m-0 me-2">Fichier:</p>
<a class="btn btn-sm btn-primary" href="{{ asset($claimModel->file) }}" target="_blank"
data-bs-tooltip="tooltip" title="{{ __('Ouvrir le fichier associé à cette réclamation') }}">
{{ __('Voir la pièce jointe associée') }}
<div class="card-body">
{{-- CLAIM AUTHOR --}}
<div class="col-12 mt-3">
<div class="card shadow-sm w-100">
<div class="card-body">
<div class="row">
<div class="col-12 col-lg-4 text-center">
<h5 class="card-title mb-1">
{{ trim(sprintf('%s %s', $claimModel->first_name, $claimModel->last_name)) }}
</h5>
<p class="text-muted mb-2">{{ e($claimModel->email) }}</p>
@if ($claimModel->customer && auth()->user()->can('view', $claimModel->customer))
<a href="{{ route('bo.customers.show', [
'customer' => $claimModel->customer,
'brand' => $claimModel->brand,
]) }}" target="_blank" rel="noopener">
{{ __('Lien vers la fiche client') }}
<i class="fas fa-arrow-up-right-from-square ms-1"></i>
</a>
</div>
@endif
@endif
@if ($claimModel->getFormatedAddress())
<p class="mb-0">
{{ $claimModel->getFormatedAddress() ? e($claimModel->getFormatedAddress()) : null }}
</p>
@endif
</div>
<div class="col-12 col-lg-8 border-top border-lg-top-0 border-lg-start border-lg-3 border-lg-primary mt-2 pt-2 mt-lg-0 pt-lg-0">
<div class="claim-message-collapse" data-json='@json(['message' => $claimModel->message])'></div>
@if ($claimModel->file)
<div class="d-flex flex-row justify-content-start align-items-center">
<p class="m-0 me-2">Fichier:</p>
<a class="btn btn-sm btn-primary" href="{{ asset($claimModel->file) }}"
target="_blank" data-bs-tooltip="tooltip"
title="{{ __('Ouvrir le fichier associé à cette réclamation') }}">
{{ __('Voir la pièce jointe associée') }}
</a>
</div>
@endif
</div>
</div>
</div>
</div>
</div>
</div>
{{-- ACTIONS / CONVERSATION--}}
<div class="col-12 px-0 py-3">
@php
$data = [
'authUserId' => auth('backend')->user()->getKey(),
'claimModel' => $claimModel,
'brandModels' => $brandModels ?? [],
'claimSubjectModels' => $claimSubjectModels ?? [],
'claimMessageModels' => $claimMessageModels,
'claimTemplateModels' => $claimTemplateModels,
'enums' => [
'claimType' => \App\Enums\Claims\ClaimType::toArray(),
'claimStatus' => \App\Enums\Claims\ClaimStatus::toArray(),
'claimResponseType' => \App\Enums\Claims\ClaimResponseType::toArray(),
],
'can' => [
'updateBrand' => Gate::check('updateBrand', \App\Models\Claim::class),
'updateSubject' => Gate::check('updateSubject', \App\Models\Claim::class),
'updateType' => Gate::check('updateType', \App\Models\Claim::class),
'updateStatus' => Gate::check('updateStatus', \App\Models\Claim::class),
'updateResponseType' => Gate::check('updateResponseType', \App\Models\Claim::class),
],
'allErrors' => $errors->getBag('default')->getMessages() ?? [],
];
@endphp
<div class="claim-wrapper" data-json='@json($data)'></div>
</div>
{{-- OTHER CUSTOMER CLAIMS --}}
@if ($customerClaimModels->count())
<div class="col-12 py-3">
<h3 class="h3 fw-bold">{{ __('Autres réclas du même demandeur') }}</h3>
<div class="table-responsive mb-2">
@include('bo.pages.claims.index-list', ['claimModels' => $customerClaimModels])
</div>
{!! $customerClaimModels->links() !!}
{{-- ACTIONS / CONVERSATION --}}
<div class="col-12 px-0 py-3">
@php
$data = [
'authUserId' => auth('backend')->user()->getKey(),
'claimModel' => $claimModel,
'brandModels' => $brandModels ?? [],
'claimSubjectModels' => $claimSubjectModels ?? [],
'claimMessageModels' => $claimMessageModels,
'claimTemplateModels' => $claimTemplateModels,
'enums' => [
'claimType' => \App\Enums\Claims\ClaimType::toArray(),
'claimStatus' => \App\Enums\Claims\ClaimStatus::toArray(),
'claimResponseType' => \App\Enums\Claims\ClaimResponseType::toArray(),
],
'can' => [
'updateBrand' => Gate::check('updateBrand', $claimModel),
'updateSubject' => Gate::check('updateSubject', $claimModel),
'updateType' => Gate::check('updateType', $claimModel),
'updateStatus' => Gate::check('updateStatus', $claimModel),
'updateResponseType' => Gate::check('updateResponseType', $claimModel),
],
'allErrors' => $errors->getBag('default')->getMessages() ?? [],
];
@endphp
<div class="claim-wrapper" data-json='@json($data)'></div>
</div>
@endif
{{-- OTHER CUSTOMER CLAIMS --}}
@if ($customerClaimModels->count())
<div class="col-12 py-3">
<h3 class="h3 fw-bold">{{ __('Autres réclas du même demandeur') }}</h3>
<div class="table-responsive mb-2">
@include('bo.pages.claims.index-list', ['claimModels' => $customerClaimModels])
</div>
{!! $customerClaimModels->links() !!}
</div>
@endif
</div>
</div>
@endsection

View file

@ -1,7 +1,8 @@
@extends('bo.layout')
@section('title', __('models.classes.claims'))
@section('description', __('Liste de toutes les :model', ['model' => __('models.classes.claims')]))
@section('title', sprintf('%s - %s', __('models.classes.claims'), str(__('liste'))->ucfirst()))
@section('description', __('Listage de toutes les :model', ['model' => __('models.classes.claims')]))
@section('metaIndex', 'noindex,nofollow')
@section('content')
<div class="row w-100 mx-auto">
@ -12,16 +13,6 @@
<div class="col p-0">
@include('modules.breadcrumbs.breadcrumb-body')
</div>
<div class="col-md-3 d-flex align-items-center p-0">
<div class="input-group justify-content-end">
@can('create', \App\Models\Claim::class)
<a class="btn btn-primary" data-bs-tooltip="tooltip" href="{{ route('bo.claims.create') }}"
title="{{ __('Ajouter une :model', ['model' => Str::singular(__('models.classes.claims'))]) }}">
<i class="fa-solid fa-plus"></i>
</a>
@endcan
</div>
</div>
</div>
</div>
<div class="card-body">