feat: Implement soft deletes for customer, invoice, order, and transaction models, and add customer edit and trash management to the admin panel.

This commit is contained in:
pbao9
2026-02-16 17:04:27 +07:00
parent 4dae15ffca
commit 31cbdf323f
22 changed files with 560 additions and 34 deletions
+171 -16
View File
@@ -7,6 +7,9 @@ use App\Http\Facade\SignRSA;
use App\Http\Requests\AddPayRequest;
use App\Http\Requests\CreateCustomerRequest;
use App\Jobs\Mail\PasswordRecoverJob;
use App\Models\Invoice;
use App\Models\Order;
use App\Models\Transaction;
use App\Repositories\Customer\CustomerRepositoryInterface;
use App\Repositories\Hosting\HostingRepositoryInterface;
use App\Repositories\Invoice\InvoiceRepositoryInterface;
@@ -32,7 +35,7 @@ use Yajra\DataTables\Facades\DataTables;
class CustomerController extends Controller
{
public function __construct(
public CustomerRepositoryInterface $customerRepository,
public InvoiceItemRepositoryInterface $invoiceItemRepository,
@@ -46,7 +49,8 @@ class CustomerController extends Controller
public InvoiceRepositoryInterface $invoiceRepository,
public TransactionRepositoryInterface $transactionRepository,
public MailRepositoryInterface $mailRepository
) {}
) {
}
public function index(Request $request)
{
@@ -222,7 +226,7 @@ class CustomerController extends Controller
return redirect()->route('customer.index')->withErrors('No data found for this user');
}
$customer = $this->customerRepository->find($userid);
if (! $customer) {
if (!$customer) {
return redirect()->route('customer.index')->withErrors('Invalidated Request');
}
@@ -231,15 +235,15 @@ class CustomerController extends Controller
['customer_id' => $userid],
['server']
);
$vpsServices = $this->vmwareRepository->filter(
['customer_id' => $userid],
['ipaddress.host.datacenter.vCenter', 'os.osGroup']
);
// Kết hợp và format dữ liệu
$allService = collect();
foreach ($hostingServices as $hosting) {
$allService->push((object) [
'product_id' => $hosting->id,
@@ -248,7 +252,7 @@ class CustomerController extends Controller
'description' => $hosting->name . ' (Hosting)'
]);
}
foreach ($vpsServices as $vps) {
$allService->push((object) [
'product_id' => $vps->id,
@@ -257,7 +261,7 @@ class CustomerController extends Controller
'description' => $vps->name . ' (VPS)'
]);
}
// Lấy invoice_item cụ thể cho sản phẩm
$invoice_item = $this->invoiceItemRepository->findBy(
$userid,
@@ -267,11 +271,11 @@ class CustomerController extends Controller
'value' => $userid
]
);
$type = null;
$product = null;
$productName = '';
if ($invoice_item) {
$product_id = $invoice_item->product_id ?? null;
$product_module_id = $request->get('product') ?? $invoice_item->product_id ?? null;
@@ -326,7 +330,7 @@ class CustomerController extends Controller
public function storeCustomerProduct(Request $request)
{
if (! $request->product_type) {
if (!$request->product_type) {
return back()->with($request->except(['_token', '_method']))->withErrors('Invalid Request');
}
@@ -335,7 +339,7 @@ class CustomerController extends Controller
$rules = [];
switch ($request->product_type) {
case 3:
$rules = [
$rules = [
'product_id' => 'required',
'next_due_date' => 'required',
'next_payment' => 'required',
@@ -360,7 +364,7 @@ class CustomerController extends Controller
if ($validator->fails()) {
return back()->withErrors($validator->errors()->first());
}
if (! $product) {
if (!$product) {
return back()->withErrors('Product not found');
}
try {
@@ -418,7 +422,7 @@ class CustomerController extends Controller
return redirect()->route('customer.index')->withErrors('No data found for this user');
}
$customer = $this->customerRepository->find($userid);
if (! $customer) {
if (!$customer) {
return redirect()->route('customer.index')->withErrors('Invalid Request');
}
$domains = $this->moduleDomainRepository->filter(
@@ -542,7 +546,7 @@ class CustomerController extends Controller
$customer = $this->customerRepository->find($userid);
if (! $customer) {
if (!$customer) {
return redirect()->route('customer.index')->withErrors('Invalid Request');
}
@@ -713,7 +717,7 @@ class CustomerController extends Controller
}
$customer = $this->customerRepository->find($request->get('userid'));
if (! $customer) {
if (!$customer) {
return back()->withErrors('Invalid request');
}
Auth::guard('users')->login($customer);
@@ -739,12 +743,163 @@ class CustomerController extends Controller
);
return DataTables::eloquent($query)
->addColumn('status', function ($d) {
return view('administrator.pages.customer.datatable.status', ['row' => $d])->render();
})
->addColumn(
'action',
function ($d) {
return view('administrator.pages.customer.datatable.action', ['row' => $d])->render();
}
)
->rawColumns(['status', 'action'])
->make(true);
}
public function edit(int $id = 0)
{
$customer = $this->customerRepository->find($id);
if (!$customer) {
return back()->withErrors('Invalid request.');
}
$title = 'Edit Customer';
return view('administrator.pages.customer.edit', compact('title', 'customer'));
}
public function update(int $id = 0, CreateCustomerRequest $request)
{
$customer = $this->customerRepository->find($id);
if (!$customer) {
return back()->withErrors('Invalid request.');
}
$request->validated();
try {
DB::beginTransaction();
$data = $request->except(['_token', 'password']);
if (!empty($request->password)) {
$data['password'] = password_hash($request->password, PASSWORD_BCRYPT);
}
$this->customerRepository->update($id, $data);
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return back()->withErrors($error->getMessage());
}
return redirect()->route('customer.index')->with('success', 'Update customer successfully!');
}
public function destroy(int $id = 0)
{
$customer = $this->customerRepository->find($id);
if (!$customer) {
return back()->withErrors('Invalid request.');
}
DB::beginTransaction();
try {
Invoice::where('customer_id', $id)->delete();
Order::where('customer_id', $id)->delete();
Transaction::where('customer_id', $id)->delete();
$customer->delete();
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return back()->withErrors($error->getMessage());
}
return redirect()->route('customer.index')->with('success', 'Deleted customer successfully!');
}
public function trash()
{
$title = 'Trash Customers';
return view('administrator.pages.customer.trash', compact('title'));
}
public function datatableTrash(Request $request)
{
$query = $this->customerRepository->onlyTrashed(
[],
['hosting', 'vps', 'domain']
);
return DataTables::eloquent($query)
->addColumn('status', function ($d) {
return view('administrator.pages.customer.datatable.status', ['row' => $d])->render();
})
->addColumn(
'action',
function ($d) {
return view('administrator.pages.customer.datatable.action-trash', ['row' => $d])->render();
}
)
->rawColumns(['status', 'action'])
->make(true);
}
public function restore(int $id = 0)
{
$customer = $this->customerRepository->find($id);
if (!$customer) {
$customer = $this->customerRepository->onlyTrashed()->find($id);
}
if (!$customer) {
return back()->withErrors('Invalid request.');
}
DB::beginTransaction();
try {
$customer->restore();
Invoice::withTrashed()->where('customer_id', $id)->restore();
Order::withTrashed()->where('customer_id', $id)->restore();
Transaction::withTrashed()->where('customer_id', $id)->restore();
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return back()->withErrors($error->getMessage());
}
return back()->with('success', 'Restored customer successfully!');
}
public function forceDelete(int $id = 0)
{
$customer = $this->customerRepository->onlyTrashed()->find($id);
if (!$customer) {
return back()->withErrors('Invalid request.');
}
DB::beginTransaction();
try {
Invoice::withTrashed()->where('customer_id', $id)->forceDelete();
Order::withTrashed()->where('customer_id', $id)->forceDelete();
Transaction::withTrashed()->where('customer_id', $id)->forceDelete();
$customer->forceDelete();
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return back()->withErrors($error->getMessage());
}
return back()->with('success', 'Permanently deleted customer!');
}
}
+2 -1
View File
@@ -4,12 +4,13 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;
class Customer extends Authenticatable
{
use HasFactory, HasApiTokens, HasUuids;
use HasFactory, HasApiTokens, HasUuids, SoftDeletes;
protected $table = 'customers';
+2 -1
View File
@@ -5,10 +5,11 @@ namespace App\Models;
use App\Enums\Invoice\InvoiceStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Invoice extends Model
{
use HasFactory;
use HasFactory, SoftDeletes;
protected $table = 'invoice';
public $timestamps = true;
+2 -1
View File
@@ -4,10 +4,11 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Order extends Model
{
use HasFactory;
use HasFactory, SoftDeletes;
protected $table = 'order';
+2 -1
View File
@@ -4,10 +4,11 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Transaction extends Model
{
use HasFactory;
use HasFactory, SoftDeletes;
protected $table = 'transaction';
protected $fillable = [
@@ -67,4 +67,9 @@ class CustomerCachedRepository extends BaseCachedRepository implements CustomerR
return $this->customerRepository->findBy($key, $value);
});
}
public function onlyTrashed(array $relationships = [], array $withCount = [])
{
return $this->customerRepository->onlyTrashed($relationships, $withCount);
}
}
@@ -125,4 +125,15 @@ class CustomerRepository extends BaseRepository implements CustomerRepositoryInt
}
return $this->model->where($key, $value)->first();
}
public function onlyTrashed(array $relationships = [], array $withCount = [])
{
$query = $this->model->with($relationships);
if (count($withCount) > 0) {
$query = $query->withCount($withCount);
}
return $query->onlyTrashed();
}
}
@@ -15,4 +15,5 @@ interface CustomerRepositoryInterface extends BaseRepositoryInterface
);
public function findWithRelationships(int $id = 0, array $relationships = [],array $withCount = [], array $withSum = []);
public function findBy(string $key = '',string $value = '');
public function onlyTrashed(array $relationships = [], array $withCount = []);
}
@@ -42,6 +42,7 @@ return new class extends Migration {
$table->string('remember_token', 100)->nullable();
$table->tinyInteger('status')->default(1);
$table->timestamps();
$table->softDeletes();
$table->foreign('province_code')
->references('code')
@@ -66,6 +67,6 @@ return new class extends Migration {
public function down()
{
//
Schema::dropIfExists('customer');
Schema::dropIfExists('customers');
}
};
@@ -27,6 +27,7 @@ return new class extends Migration {
$table->string('client_ip', 100)->nullable();
$table->tinyInteger('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
@@ -31,6 +31,7 @@ return new class extends Migration {
$table->tinyInteger('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
@@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up()
{
Schema::table('customers', function (Blueprint $table) {
$table->softDeletes();
});
Schema::table('invoice', function (Blueprint $table) {
$table->softDeletes();
});
Schema::table('order', function (Blueprint $table) {
$table->softDeletes();
});
Schema::table('transaction', function (Blueprint $table) {
$table->softDeletes();
});
}
public function down()
{
Schema::table('customers', function (Blueprint $table) {
$table->dropSoftDeletes();
});
Schema::table('invoice', function (Blueprint $table) {
$table->dropSoftDeletes();
});
Schema::table('order', function (Blueprint $table) {
$table->dropSoftDeletes();
});
Schema::table('transaction', function (Blueprint $table) {
$table->dropSoftDeletes();
});
}
};
@@ -0,0 +1,21 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up()
{
Schema::table('transaction', function (Blueprint $table) {
$table->softDeletes();
});
}
public function down()
{
Schema::table('transaction', function (Blueprint $table) {
$table->dropSoftDeletes();
});
}
};
@@ -0,0 +1,2 @@
<x-button-crm type="button" variant="primary" size="sm" route="customer.create" icon="plus-circle">Add Customer</x-button-crm>
<x-button-crm type="button" variant="warning" size="sm" route="customer.trash" icon="trash-2">Trash</x-button-crm>
@@ -0,0 +1,13 @@
<div class="d-flex gap-2">
<x-button-crm type="button" variant="outline-success" size="sm" route="customer.restore" :params="['id' => $row->id]" icon="rotate-ccw" />
<x-button-crm type="button" variant="outline-danger" size="sm" icon="trash-2"
data-bs-toggle="modal" data-bs-target="#forceDeleteModal-{{ $row->id }}" />
</div>
@include('administrator.pages.customer.datatable.modal', [
'deleteRoute' => 'customer.forceDelete',
'itemLabel' => 'Customer',
'itemId' => $row->id,
'itemName' => $row->fullname,
'modalId' => 'forceDeleteModal-' . $row->id
])
@@ -0,0 +1,47 @@
<div class="dt-action-dropdown dropdown">
<button class="btn btn-sm btn-light d-flex align-items-center gap-1" type="button" data-bs-toggle="dropdown"
aria-expanded="false">
<i data-lucide="more-vertical" width="14" height="14"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="{{ route('customer.edit', ['id' => $row->id]) }}">
<i data-lucide="pencil" width="14" height="14" class="me-2"></i>
Edit
</a>
</li>
<li>
<hr class="dropdown-divider">
<li>
<button type="button" class="dropdown-item text-danger" data-bs-toggle="modal"
data-bs-target="#deleteModal">
<i data-lucide="trash-2" width="14" height="14" class="me-2 text-danger"></i>
Delete
</button>
</li>
</ul>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<form action="{{ route('customer.destroy', ['id' => $row->id]) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<input type="hidden" name="id" value="{{ $row->id }}">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Xoá khách hàng</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Bạn có chắc chắn muốn xoá khách hàng này?
<strong>{{ $row->fullname }}</strong>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Huỷ</button>
<button type="submit" class="btn btn-danger" id="confirmDeleteBtn">Xoá</button>
</div>
</div>
</form>
</div>
</div>
@@ -0,0 +1,36 @@
<!-- Delete Confirmation Modal -->
<div class="modal fade" id="{{ $modalId ?? 'deleteModal' }}" tabindex="-1"
aria-labelledby="deleteModalLabel-{{ $modalId ?? 'deleteModal' }}" aria-hidden="true" data-bs-backdrop="true">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content shadow-lg border-0">
<div class="modal-header bg-danger text-white py-2">
<h6 class="modal-title d-flex align-items-center" id="deleteModalLabel-{{ $modalId ?? 'deleteModal' }}">
<i data-lucide="trash-2" class="me-2" style="width: 16px; height: 16px;"></i>
Xác nhận xóa
</h6>
<button type="button" class="btn-close btn-close-white shadow-none" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body py-4">
<div class="text-center">
<div class="mb-3">
<i data-lucide="alert-triangle" class="text-warning" style="width: 54px; height: 54px;"></i>
</div>
<h6 class="fw-bold mb-2">Bạn có chắc chắn không?</h6>
<p class="text-muted small mb-1">Xóa {{ $itemLabel }}:</p>
<p class="fw-bold mb-3 text-dark">{{ $itemName ?? '' }}</p>
<div class="px-3 py-2 bg-danger-subtle rounded-3">
<p class="text-danger small mb-0 fw-medium">Hành động này không thể hoàn tác!</p>
</div>
</div>
</div>
<div class="modal-footer bg-light border-0 py-2 d-flex justify-content-center gap-2">
<x-button-c-r-m type="button" variant="secondary" size="sm" icon="x" data-bs-dismiss="modal">Hủy bỏ</x-button-c-r-m>
<form action="{{ route($deleteRoute, ['id' => $itemId ?? 0]) }}" method="POST" class="d-inline m-0">
@csrf
@method('DELETE')
<x-button-c-r-m type="submit" variant="danger" size="sm" icon="trash-2">Xác nhận xóa</x-button-c-r-m>
</form>
</div>
</div>
</div>
</div>
@@ -0,0 +1,13 @@
@php
$status = App\Enums\Status::tryFrom($row->status);
@endphp
@if($status)
<x-admin-badge :variant="$status->value">
{{ $status->label() }}
</x-admin-badge>
@else
<x-admin-badge variant="secondary">
Unknown
</x-admin-badge>
@endif
@@ -0,0 +1,116 @@
@extends("administrator.layout.master")
@section("content")
@if(auth()->guard('admins')->user()->can("edit customer"))
<div class="card card-outline card-primary">
<form action="{{ route('customer.update', ['id' => $customer->id]) }}" method="post">
@csrf
@method('PUT')
<div class="card-body">
<div class="row">
<div class="col">
{{--Fullname--}}
<div class="form-group row">
<label class="col-md-4" for="fullname">Fullname</label>
<div class="col-md-8">
<input type="text" id="fullname" name="fullname" placeholder="Fullname"
value="{{ old('fullname', $customer->fullname) }}" class="form-control">
</div>
</div>
{{--Company--}}
<div class="form-group row">
<label class="col-md-4" for="company">Company</label>
<div class="col-md-8">
<input type="text" id="company" name="company" placeholder="Company"
value="{{ old('company', $customer->company) }}" class="form-control">
</div>
</div>
{{--Email--}}
<div class="form-group row">
<label class="col-md-4" for="email">Email Address</label>
<div class="col-md-8">
<input type="email" id="email" name="email" placeholder="Email Address"
value="{{ old('email', $customer->email) }}" class="form-control">
</div>
</div>
{{--Phone--}}
<div class="form-group row">
<label class="col-md-4" for="phone">Phone Number</label>
<div class="col-md-8">
<input type="text" id="phone" name="phone" placeholder="(+84) 123. 456. 789)"
value="{{ old('phone', $customer->phone) }}" class="form-control">
</div>
</div>
{{--Password--}}
<div class="form-group row">
<label class="col-md-4" for="password">Password (leave blank to keep current)</label>
<div class="col-md-8">
<input type="password" id="password" name="password" placeholder="******"
value="" class="form-control">
</div>
</div>
</div>
<div class="col">
{{--Address--}}
<div class="form-group row">
<label class="col-md-4" for="address">Address</label>
<div class="col-md-8">
<input type="text" id="address" name="address" placeholder="Address"
value="{{ old('address', $customer->address) }}" class="form-control">
</div>
</div>
{{--City--}}
<div class="form-group row">
<label class="col-md-4" for="city">City</label>
<div class="col-md-8">
<input type="text" id="city" name="city" placeholder="City"
value="{{ old('city', $customer->city) }}" class="form-control">
</div>
</div>
{{--State--}}
<div class="form-group row">
<label class="col-md-4" for="state">State</label>
<div class="col-md-8">
<input type="text" id="state" name="state" placeholder="State"
value="{{ old('state', $customer->state) }}" class="form-control">
</div>
</div>
{{--Postcode--}}
<div class="form-group row">
<label class="col-md-4" for="postcode">Postcode</label>
<div class="col-md-8">
<input type="text" id="postcode" name="postcode" placeholder="Postcode"
value="{{ old('postcode', $customer->postcode) }}" class="form-control">
</div>
</div>
{{--Country--}}
<div class="form-group row">
<label class="col-md-4" for="country">Country</label>
<div class="col-md-8">
<input type="text" id="country" name="country" placeholder="Country"
value="{{ old('country', $customer->country) }}" class="form-control">
</div>
</div>
{{--Marketing Emails--}}
<div class="form-group row">
<label class="col-md-4" for="email_marketing">Marketing Emails Opt-in</label>
<div class="col-md-8">
<input type="checkbox" name="email_marketing" id="email_marketing" @checked(old('email_marketing', $customer->email_marketing) == 1)>
Send Client Marketing Emails
</div>
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-outline-primary">Update</button>
</div>
</form>
</div>
@else
<div class="alert alert-danger alert-dismissible">
<h5 class="mb-0"><i class="icon fas fa-ban"></i> Access Denied - You are not assigned to any Customer
management department</h5>
</div>
@endif
@endsection
@@ -7,9 +7,9 @@
@section('breadcrumb')
@php
$breadcrumbItems = [
['label' => 'Customers', 'active' => true],
];
$breadcrumbItems = [
['label' => 'Customers', 'active' => true],
];
@endphp
<x-admin-breadcrumb :items="$breadcrumbItems" />
@endsection
@@ -18,19 +18,20 @@
@if (auth()->guard('admins')->user()->can('manager customer'))
<div class="card card-primary card-outline rounded-3 border-primary-subtle">
<div class="card-header d-flex justify-content-end gap-2">
@include('administrator.pages.block.customer.btn')
</div>
<div class="card-body">
<x-datatable id="customerTable" ajax="{{ route('customer.datatable') }}" :columns="[
['key' => 'fullname', 'label' => 'Fullname'],
['key' => 'company', 'label' => 'Company'],
['key' => 'email', 'label' => 'Email'],
['key' => 'hosting_count', 'label' => 'Hosting'],
['key' => 'vps_count', 'label' => 'VPS'],
['key' => 'domain_count', 'label' => 'Domain'],
['key' => 'created_at', 'label' => 'Created'],
['key' => 'status', 'label' => 'Status'],
['key' => 'action', 'label' => 'Action'],
]" />
['key' => 'fullname', 'label' => 'Fullname'],
['key' => 'company', 'label' => 'Company'],
['key' => 'email', 'label' => 'Email'],
['key' => 'hosting_count', 'label' => 'Hosting'],
['key' => 'vps_count', 'label' => 'VPS'],
['key' => 'domain_count', 'label' => 'Domain'],
['key' => 'created_at', 'label' => 'Created'],
['key' => 'status', 'label' => 'Status'],
['key' => 'action', 'label' => 'Action'],
]" />
</div>
</div>
@else
@@ -0,0 +1,46 @@
@extends('administrator.layout.master')
@push('plugin-styles')
@foreach (config('assets.datatable.css') as $datatable)
<link href="{{ asset($datatable) }}" rel="stylesheet" />
@endforeach
@endpush
@section('breadcrumb')
@php
$breadcrumbItems = [
['label' => 'Customers', 'route' => route('customer.index')],
['label' => 'Trash', 'active' => true],
];
@endphp
<x-admin-breadcrumb :items="$breadcrumbItems" />
@endsection
@section('content')
@if (auth()->guard('admins')->user()->can('manager customer'))
<div class="card card-primary card-outline rounded-3 border-primary-subtle">
<div class="card-header d-flex justify-content-end gap-2">
<x-button-crm type="button" variant="secondary" size="sm" route="customer.index" icon="arrow-left">Back to List</x-button-crm>
</div>
<div class="card-body">
<x-datatable id="customerTrashTable" ajax="{{ route('customer.trash.datatable') }}" :columns="[
['key' => 'fullname', 'label' => 'Fullname'],
['key' => 'company', 'label' => 'Company'],
['key' => 'email', 'label' => 'Email'],
['key' => 'deleted_at', 'label' => 'Deleted At'],
['key' => 'action', 'label' => 'Action', 'searchable' => false],
]" />
</div>
</div>
@else
<div class="alert alert-danger alert-dismissible">
<h5 class="mb-0"><i class="icon fas fa-ban"></i> Access Denied - You are not assigned to any Customer
management department</h5>
</div>
@endif
@endsection
@push('plugin-scripts')
@foreach (config('assets.datatable.js') as $datatable)
<script src="{{ asset($datatable) }}"></script>
@endforeach
@endpush
+7
View File
@@ -110,6 +110,13 @@ Route::prefix('')->group(function () {
//View All Client
Route::prefix('customer')->controller(CustomerController::class)->group(function () {
Route::get('list-customer', 'index')->name('customer.index');
Route::get('edit/{id}', 'edit')->name('customer.edit');
Route::put('edit/{id}', 'update')->name('customer.update');
Route::delete('delete/{id}', 'destroy')->name('customer.destroy');
Route::get('trash', 'trash')->name('customer.trash');
Route::get('trash/datatable', 'datatableTrash')->name('customer.trash.datatable');
Route::post('trash/restore/{id}', 'restore')->name('customer.restore');
Route::delete('trash/force-delete/{id}', 'forceDelete')->name('customer.forceDelete');
Route::get('datatable', 'datatable')->name('customer.datatable');
Route::get('view-customer', 'getCustomerInfo')->name('customer.info');
Route::get('view-profile', 'getCustomerProfile')->name('customer.profile');