agents table updated and roles logic created

This commit is contained in:
Thekindbull 2025-04-03 17:21:05 +08:00
parent 2335820883
commit 2154ca1bec
13 changed files with 224 additions and 92 deletions

View File

@ -1,4 +1,5 @@
<?php <?php
namespace App\Http\Controllers\Company; namespace App\Http\Controllers\Company;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
@ -8,38 +9,43 @@
use App\Models\User; use App\Models\User;
class CreateAgentController extends Controller class CreateAgentController extends Controller
{ {
public function __invoke(Request $request) public function __invoke(Request $request)
{ {
$request->only(['name', 'email', 'phone']); $request->only(['name', 'email', 'phone']);
$admin = CompanyAdmin::where('user_id', auth()->id()); $admin = CompanyAdmin::where('user_id', auth()->id());
if (!$admin->count()) if (!$admin->count())
{ {
abort(404); abort(404);
return; return;
} }
$admin = $admin->first(); $admin = $admin->first();
if (!$this->isUnique($request->email, $request->phone))
$user = User::where('email', $request->email)->orWhere('phone', $request->phone)->first();
if ($user)
{
if ($user->id !== auth()->id()) //если это не текущий пользователь-админ, который хочет себя сделать агентом, то ошибка
{ {
return back()->with('error', __('Agent is not unique')); if (Agent::where('user_id', $user->id)->count()) // и если этот пользователь уже агент
{
return back()->with('error', __('Agent is not unique'));
}
} }
if ($user = User::create($request->all())) }
{ else
{
$user = $user = User::create($request->all());
$user->setForcedPassword(); $user->setForcedPassword();
$agent = Agent::create([
'user_id' => $user->id,
'company_id' => $admin->company_id
]);
}
return to_route('company.agents.table');
} }
public function isUnique($email, $phone) if ($user)
{ {
if (User::where('email', $email)->count() || User::where('phone', $phone)->count()) Agent::where('user_id', $user->id)->delete(); //на случай, если где-то этот пользователь уже был агентом
{ $agent = Agent::create([
return false; 'user_id' => $user->id,
} 'company_id' => $admin->company_id
return true; ]);
} }
return to_route('company.agents.table');
} }
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers\Company;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Company\CompanyAdmin;
use App\Models\Agent\Agent;
use App\Models\User;
class DeleteAgentController extends Controller
{
public function __invoke(Agent $agent)
{
$admin = CompanyAdmin::where('user_id', auth()->id())
->where(
'company_id',
$agent->company_id
);
if (!$admin->count())
{
abort(404);
return;
}
$agent->delete();
return to_route('company.agents.table');
}
}

View File

@ -11,29 +11,29 @@
use App\Models\Deal\Deal; use App\Models\Deal\Deal;
class AgentsTable extends Component class AgentsTable extends Component
{ {
use WithPagination; use WithPagination;
public $status; public $status;
public function mount($status = null) public function mount($status = null)
{ {
$this->status = $status; $this->status = $status;
} }
public function render() public function render()
{ {
$user = auth()->user(); $user = auth()->user();
$admin = CompanyAdmin::where('user_id', $user->id)->first(); $admin = CompanyAdmin::where('user_id', $user->id)->first();
$agents = Agent::where('company_id', $admin->company_id); $agents = Agent::where('company_id', $admin->company_id);
if ($this->status == AgentStatus::DISMISSED) if ($this->status == AgentStatus::DISMISSED)
{ {
$agents->whereNotNull('deleted_at'); $agents->onlyTrashed();
} }
return view( return view(
'livewire.agents-table', 'livewire.agents-table',
[ [
'agents' => $agents->paginate(10) 'agents' => $agents->paginate(10)
] ]
); );
}
} }
}

View File

@ -13,7 +13,7 @@
use App\Models\Deal\DealStatus; use App\Models\Deal\DealStatus;
class ClientsTable extends Component class ClientsTable extends Component
{ {
use WithPagination, WithoutUrlPagination; use WithPagination, WithoutUrlPagination;
public $status; public $status;
@ -21,58 +21,59 @@ class ClientsTable extends Component
public $mode;//short || full public $mode;//short || full
public function mount($status = null, $count = 10, $mode = 'full') public function mount($status = null, $count = 10, $mode = 'full')
{ {
$this->status = $status; $this->status = $status;
$this->count = $count; $this->count = $count;
$this->mode = $mode; $this->mode = $mode;
} }
public function getDeals() public function getDeals()
{ {
$deals = false; $deals = false;
$user = auth()->user(); $user = auth()->user();
if ($agent = Agent::where('user_id', $user->id)->first())
{ if ($admin = CompanyAdmin::where('user_id', $user->id)->first())
$deals = Deal::where('agent_id', $agent->id); {
}
elseif ($admin = CompanyAdmin::where('user_id', $user->id)->first())
{
$deals = Deal::whereIn('agent_id', function ($query) use ($admin) $deals = Deal::whereIn('agent_id', function ($query) use ($admin)
{ {
$query->select('id'); $query->select('id');
$query->from('agents'); $query->from('agents');
$query->where('company_id', $admin->company_id); $query->where('company_id', $admin->company_id);
}); });
}
return $deals;
} }
public function render() elseif ($agent = Agent::where('user_id', $user->id)->first())
{ {
$deals = Deal::where('agent_id', $agent->id);
}
return $deals;
}
public function render()
{
$deals = $this->getDeals(); $deals = $this->getDeals();
if ($this->status && $this->status == DealStatus::UNIQUE) if ($this->status && $this->status == DealStatus::UNIQUE)
{ {
$deals = $deals $deals = $deals
->whereIn('status', [DealStatus::UNIQUE]) ->whereIn('status', [DealStatus::UNIQUE])
->orderBy('id', 'desc')->paginate($this->count, ['*'], 'unique_clients'); ->orderBy('id', 'desc')->paginate($this->count, ['*'], 'unique_clients');
} }
elseif ($this->status && $this->status == DealStatus::NOT_UNIQUE) elseif ($this->status && $this->status == DealStatus::NOT_UNIQUE)
{ {
$deals = $deals $deals = $deals
->whereIn('status', [DealStatus::MODERATION, DealStatus::NEW , DealStatus::NOT_UNIQUE]) ->whereIn('status', [DealStatus::MODERATION, DealStatus::NEW , DealStatus::NOT_UNIQUE])
->orderBy('id', 'desc')->paginate($this->count, ['*'], 'not_unique_clients'); ->orderBy('id', 'desc')->paginate($this->count, ['*'], 'not_unique_clients');
} }
else else
{ {
$deals = $deals->orderBy('id', 'desc')->paginate($this->count, ['*'], 'all_clients'); $deals = $deals->orderBy('id', 'desc')->paginate($this->count, ['*'], 'all_clients');
} }
; ;
return view( return view(
'livewire.clients-table', 'livewire.clients-table',
[ [
'deals' => $deals, 'deals' => $deals,
'statuses' => DealStatus::class 'statuses' => DealStatus::class
] ]
); );
}
} }
}

View File

@ -28,11 +28,13 @@ class CreateClientForm extends Component
'client.secondName.required' => 'Необходимо указать фамилию клиента', 'client.secondName.required' => 'Необходимо указать фамилию клиента',
'client.phone.required' => 'Необходимо указать телефон без кода страны "+7" или "8"', 'client.phone.required' => 'Необходимо указать телефон без кода страны "+7" или "8"',
'client.phone.regex' => 'Телефон должен содержать 10 симвлов без указания кода страны "+7" или "8"', 'client.phone.regex' => 'Телефон должен содержать 10 симвлов без указания кода страны "+7" или "8"',
'client.phone.unique' => 'Клиент с таким телефоном уже существует' 'client.phone.unique' => 'Клиент с таким телефоном уже существует',
'agent.integer' => 'Необходимо указать агента, от которого добавляется контакт'
]; ];
protected function rules() protected function rules()
{ {
return [ return [
'agent' => ['required', 'integer'],
'client.firstName' => ['required', 'string', 'max:255'], 'client.firstName' => ['required', 'string', 'max:255'],
'client.secondName' => ['required', 'string', 'max:255'], 'client.secondName' => ['required', 'string', 'max:255'],
'client.phone' => ['required', 'string', 'regex:/\(?([0-9]{3})\)([-]{1})([0-9]{3})([-]{1})([0-9]{4})/i'] 'client.phone' => ['required', 'string', 'regex:/\(?([0-9]{3})\)([-]{1})([0-9]{3})([-]{1})([0-9]{4})/i']
@ -49,7 +51,14 @@ public function mount()
'complexId' => '' 'complexId' => ''
]; ];
$this->status = self::NEW; $this->status = self::NEW;
$this->agent = false; if ($agent = Agent::where('user_id', auth()->user()->id)->first())
{
$this->agent = $agent->id;
}
else
{
$this->agent = false;
}
} }
public function update() public function update()
{ {
@ -127,7 +136,6 @@ public function back()
public function save() public function save()
{ {
$validated = $this->validate($this->rules()); $validated = $this->validate($this->rules());
$agent = $this->agent || Agent::where('user_id', auth()->user()->id)->first()->id;
$phone = '+7' . $this->client['phone']; $phone = '+7' . $this->client['phone'];
$newUser = User::updateOrCreate( $newUser = User::updateOrCreate(
['phone' => $phone], ['phone' => $phone],
@ -137,7 +145,7 @@ public function save()
] ]
); );
$data = [ $data = [
'agent_id' => $agent 'agent_id' => $this->agent
, ,
'client_id' => $newUser->id 'client_id' => $newUser->id
, ,

View File

@ -13,55 +13,63 @@
use App\Models\User\Role; use App\Models\User\Role;
use App\Models\Deal\Deal; use App\Models\Deal\Deal;
use App\Notifications\AgentCreated;
class Agent extends Model class Agent extends Model
{ {
use HasFactory; use HasFactory;
use SoftDeletes; use SoftDeletes;
public const STATUS_ACTIVE = "ACTIVE"; public const STATUS_ACTIVE = "ACTIVE";
public const STATUS_DISMISSED = "DISMISSED"; public const STATUS_DISMISSED = "DISMISSED";
protected $fillable = [ protected $fillable = [
'user_id', 'user_id',
'company_id' 'company_id'
]; ];
public function company() public function company()
{ {
return $this->belongsTo(Company::class); return $this->belongsTo(Company::class);
} }
public function user() public function user()
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class);
} }
public function deals() public function deals()
{ {
return $this->hasMany(Deal::class); return $this->hasMany(Deal::class);
} }
protected static function booted(): void protected static function booted(): void
{ {
static::created(function (Agent $agent) static::created(function (Agent $agent)
{ {
UserRole::create([ UserRole::create([
'user_id' => $agent->user_id, 'user_id' => $agent->user_id,
'role_id' => Role::AGENT 'role_id' => Role::AGENT
]); ]);
}); $agent->notify();
});
static::updated(function (Agent $agent) static::updated(function (Agent $agent)
{ {
if ($agent->trashed()) if ($agent->trashed())
{ {
UserRole::where([ UserRole::where([
'user_id' => $agent->user_id, 'user_id' => $agent->user_id,
'role_id' => Role::AGENT 'role_id' => Role::AGENT
])->delete(); ])->delete();
} }
else else
{ {
UserRole::create([ UserRole::create([
'user_id' => $agent->user_id, 'user_id' => $agent->user_id,
'role_id' => Role::AGENT 'role_id' => Role::AGENT
]); ]);
} }
}); });
}
} }
private function notify()
{
$this->user->notify(new AgentCreated($this));
return true;
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\HtmlString;
use App\Models\Agent\Agent;
class AgentCreated extends Notification
{
use Queueable;
private $agent;
public $login;
/**
* Create a new notification instance.
*/
public function __construct(Agent $agent)
{
$this->agent = $agent;
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject(__('Agent was created'))
->line(__('Your account was attached as agent'))
->line($this->agent->company->name)
->action(__('Go to login'), url(path: '/'));
}
/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
//
];
}
}

View File

@ -30,5 +30,7 @@
"Email": "Электронная почта", "Email": "Электронная почта",
"SelfEmployer name": "ФИО полностью", "SelfEmployer name": "ФИО полностью",
"SoleProperty name": "ФИО полностью", "SoleProperty name": "ФИО полностью",
"contract status new": "Новый" "contract status new": "Новый",
"Agent was created": "Создана новая учетная запись агента",
"Your account was attached as agent": "Ваша учетная запись была привязана в качестве агента в"
} }

View File

@ -88,6 +88,9 @@
@include('left-panel') @include('left-panel')
</div> </div>
<div class="col-10 px-0 px-md-4"> <div class="col-10 px-0 px-md-4">
@foreach ($errors->all() as $error)
{{ $error }}
@endforeach
@yield('content') @yield('content')
</div> </div>
</div> </div>

View File

@ -5,7 +5,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title> <title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts --> <!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net"> <link rel="preconnect" href="https://fonts.bunny.net">

View File

@ -16,6 +16,23 @@
<td class="align-middle"> <td class="align-middle">
{{ $agent->user->email }} {{ $agent->user->email }}
</td> </td>
@if (!$agent->trashed())
<td class="align-middle text-center bg-white">
<a class="btn" href="{{ route('company.agents.delete', ['agent' => $agent->id]) }}">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"
fill="currentColor" class="bi bi-person-dash" viewBox="0 0 16 16">
<path
d="M12.5 16a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7M11 12h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1 0-1m0-7a3 3 0 1 1-6 0 3 3 0 0 1 6 0M8 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4" />
<path
d="M8.256 14a4.5 4.5 0 0 1-.229-1.004H3c.001-.246.154-.986.832-1.664C4.484 10.68 5.711 10 8 10q.39 0 .74.025c.226-.341.496-.65.804-.918Q8.844 9.002 8 9c-5 0-6 3-6 4s1 1 1 1z" />
</svg>
</a>
</td>
@else
<td class="align-middle">
{{ $agent->deleted_at->diffForHumans() }}
</td>
@endif
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>

View File

@ -1,6 +1,6 @@
<div> <div>
<ul class="nav flex flex-md-column "> <ul class="nav flex flex-md-column ">
@if (in_array($roles::AGENT, $userRoles)) @if (in_array($roles::AGENT, $userRoles) || in_array($roles::COMPANY_ADMIN, $userRoles))
<li class="nav-item text-center m-2"> <li class="nav-item text-center m-2">
<a href="{{ route('home') }}" <a href="{{ route('home') }}"
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" aria-current="page"> class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" aria-current="page">

View File

@ -16,49 +16,49 @@
*/ */
Route::get('/', function () Route::get('/', function ()
{ {
return view(view: 'welcome'); return view(view: 'welcome');
}); });
Auth::routes(); Auth::routes();
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request)
{ {
$request->fulfill(); $request->fulfill();
return redirect('/home'); return redirect('/home');
})->middleware(['auth', 'signed'])->name('verification.verify'); })->middleware(['auth', 'signed'])->name('verification.verify');
//Company //Company
Route::get('/company/create', App\Http\Controllers\Company\CreateCompanyFormController::class)->name('company.form.create'); Route::get('/company/create', App\Http\Controllers\Company\CreateCompanyFormController::class)->name('company.form.create');
Route::post('/company/create', CreateCompanyController::class)->name('company.create'); Route::post('/company/create', CreateCompanyController::class)->name('company.create');
Route::get('/company/confirmer', function () Route::get('/company/confirmer', function ()
{ {
return view(view: 'company.post_confirmer'); return view(view: 'company.post_confirmer');
}); });
Route::middleware(['auth'])->group(function () Route::middleware(['auth'])->group(function ()
{ {
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home'); Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/clients/table', [App\Http\Controllers\ClientsTableController::class, 'index'])->name('clients.table'); Route::get('/clients/table', [App\Http\Controllers\ClientsTableController::class, 'index'])->name('clients.table');
Route::get('/contract/{contract}', [App\Http\Controllers\Deal\ContractController::class, 'index'])->name('contract'); Route::get('/contract/{contract}', [App\Http\Controllers\Deal\ContractController::class, 'index'])->name('contract');
Route::get('/company/details/', [App\Http\Controllers\Company\DetailsController::class, 'index'])->name('company.details'); Route::get('/company/details/', [App\Http\Controllers\Company\DetailsController::class, 'index'])->name('company.details');
Route::post('/company/{company}/details/', [App\Http\Controllers\Company\DetailsController::class, 'store'])->name('company.details.store'); Route::post('/company/{company}/details/', [App\Http\Controllers\Company\DetailsController::class, 'store'])->name('company.details.store');
Route::get('/agents/table', [App\Http\Controllers\Company\AgentsTableController::class, 'index'])->name('company.agents.table'); Route::get('/agents/table', [App\Http\Controllers\Company\AgentsTableController::class, 'index'])->name('company.agents.table');
Route::post('/company/details/', App\Http\Controllers\Company\CreateAgentController::class)->name('company.agents.store'); Route::post('/company/agents/store/', App\Http\Controllers\Company\CreateAgentController::class)->name('company.agents.store');
Route::get('/company/agents/{agent}/delete', App\Http\Controllers\Company\DeleteAgentController::class)->name('company.agents.delete');
}); });
//МАКЕТЫ //МАКЕТЫ
Route::get('projects', function () Route::get('projects', function ()
{ {
return view(view: 'makets.projects'); return view(view: 'makets.projects');
}); });
Route::get('news', function () Route::get('news', function ()
{ {
return view(view: 'makets.news'); return view(view: 'makets.news');
}); });
Route::get('profile', function () Route::get('profile', function ()
{ {
return view(view: 'user.profile'); return view(view: 'user.profile');
}); });