Update checkout, enable editing of checkout, show details on invoices
This commit is contained in:
parent
4f7a27dd8d
commit
39ded93a42
@ -96,7 +96,7 @@ class AdminController extends Controller
|
||||
$validation = $request->validate([
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'paid_at' => 'required|date',
|
||||
'checkout_id' => 'required|exists:ab_checkout,id',
|
||||
'checkout_id' => 'required|exists:checkouts,id',
|
||||
'total_amt' => 'required|numeric|min:0.01',
|
||||
'fees_amt' => 'nullable|numeric|lt:total_amt',
|
||||
'source_id' => 'nullable|exists:accounts,id',
|
||||
|
@ -2,13 +2,41 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
use App\Models\Checkout;
|
||||
use App\Http\Requests\CheckoutAddEdit;
|
||||
use App\Models\{Checkout,Invoice};
|
||||
|
||||
class CheckoutController extends Controller
|
||||
{
|
||||
/**
|
||||
* Update a suppliers details
|
||||
*
|
||||
* @param CheckoutAddEdit $request
|
||||
* @param Checkout $o
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function addedit(CheckoutAddEdit $request,Checkout $o)
|
||||
{
|
||||
$this->middleware(['auth','wholesaler']);
|
||||
|
||||
foreach ($request->except(['_token','active','submit']) as $key => $item)
|
||||
$o->{$key} = $item;
|
||||
|
||||
$o->active = (bool)$request->active;
|
||||
|
||||
try {
|
||||
$o->save();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()->withErrors($e->getMessage())->withInput();
|
||||
}
|
||||
|
||||
return redirect()->back()
|
||||
->with('success','Payment saved');
|
||||
}
|
||||
|
||||
public function cart_invoice(Request $request,Invoice $o=NULL)
|
||||
{
|
||||
if ($o) {
|
||||
@ -27,8 +55,29 @@ class CheckoutController extends Controller
|
||||
return $o->fee($request->post('total',0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a specific invoice for the user
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function home(): View
|
||||
{
|
||||
return View('payment.home');
|
||||
}
|
||||
|
||||
public function pay(Request $request,Checkout $o)
|
||||
{
|
||||
return redirect('pay/paypal/authorise');
|
||||
}
|
||||
|
||||
/**
|
||||
* View details on a specific payment method
|
||||
*
|
||||
* @param Checkout $o
|
||||
* @return View
|
||||
*/
|
||||
public function view(Checkout $o): View
|
||||
{
|
||||
return View('payment.view',['o'=>$o]);
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;
|
||||
|
||||
use App\Models\{Invoice,Service,User};
|
||||
|
||||
@ -37,28 +36,6 @@ class HomeController extends Controller
|
||||
return View('u.home',['o'=>$o]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a specific invoice for the user
|
||||
*
|
||||
* @param Invoice $o
|
||||
* @return View
|
||||
*/
|
||||
public function invoice(Invoice $o): View
|
||||
{
|
||||
return View('u.invoice.home',['o'=>$o]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the invoice in PDF format, ready to download
|
||||
*
|
||||
* @param Invoice $o
|
||||
* @return mixed
|
||||
*/
|
||||
public function invoice_pdf(Invoice $o)
|
||||
{
|
||||
return PDF::loadView('u.invoice.home',['o'=>$o])->stream(sprintf('%s.pdf',$o->sid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the user to down an invoice by providing a link in email
|
||||
*
|
||||
|
41
app/Http/Controllers/InvoiceController.php
Normal file
41
app/Http/Controllers/InvoiceController.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;
|
||||
|
||||
use App\Models\Invoice;
|
||||
|
||||
/**
|
||||
* Class InvoiceController
|
||||
* This controller manages invoices
|
||||
*
|
||||
* The methods to this controller should be projected by the route
|
||||
*
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class InvoiceController extends Controller
|
||||
{
|
||||
/**
|
||||
* Return the invoice in PDF format, ready to download
|
||||
*
|
||||
* @param Invoice $o
|
||||
* @return mixed
|
||||
*/
|
||||
public function pdf(Invoice $o)
|
||||
{
|
||||
return PDF::loadView('u.invoice.home',['o'=>$o])->stream(sprintf('%s.pdf',$o->sid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a specific invoice for the user
|
||||
*
|
||||
* @param Invoice $o
|
||||
* @return View
|
||||
*/
|
||||
public function view(Invoice $o): View
|
||||
{
|
||||
return View('invoice.view',['o'=>$o]);
|
||||
}
|
||||
}
|
36
app/Http/Requests/CheckoutAddEdit.php
Normal file
36
app/Http/Requests/CheckoutAddEdit.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* Editing Suppliers
|
||||
*/
|
||||
class CheckoutAddEdit extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::user()->isWholesaler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|min:2|max:255',
|
||||
'active' => 'sometimes|accepted',
|
||||
'description' => 'nullable|string|min:2|max:255',
|
||||
];
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ class InvoiceEmail extends Mailable
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param Invoice $o
|
||||
* @param string $notes
|
||||
*/
|
||||
public function __construct(Invoice $o)
|
||||
{
|
||||
|
@ -2,33 +2,43 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
class Checkout extends Model
|
||||
{
|
||||
protected $table = 'ab_checkout';
|
||||
public $timestamps = FALSE;
|
||||
use ScopeActive;
|
||||
|
||||
protected $casts = [
|
||||
'plugin_data'=>'json',
|
||||
];
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
public function payments()
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
}
|
||||
|
||||
/** SCOPES **/
|
||||
/* STATIC METHODS */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return
|
||||
*/
|
||||
public function scopeActive($query)
|
||||
public static function available(): Collection
|
||||
{
|
||||
return $query->where('active',TRUE);
|
||||
return self::active()->get();
|
||||
}
|
||||
|
||||
/** FUNCTIONS **/
|
||||
/* ATTRIBUTES */
|
||||
|
||||
public function getIconAttribute(): string
|
||||
{
|
||||
switch(strtolower($this->name)) {
|
||||
case 'paypal': return 'fab fa-cc-paypal';
|
||||
default: return 'fas fa-money-bill-alt';
|
||||
}
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
public function fee(float $amt,int $items=1): float
|
||||
{
|
||||
|
@ -109,7 +109,7 @@ class Invoice extends Model implements IDs
|
||||
private int $_total = 0;
|
||||
private int $_total_tax = 0;
|
||||
|
||||
/* STATIC */
|
||||
/* STATIC METHODS */
|
||||
|
||||
/**
|
||||
* This works out what multiplier to use to change billing periods
|
||||
|
@ -17,7 +17,7 @@ class SSL extends Type
|
||||
protected $public_key = NULL;
|
||||
protected $crt_parse = NULL;
|
||||
|
||||
/* STATIC */
|
||||
/* STATIC METHODS */
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
|
53
database/migrations/2022_07_29_151513_convert_checkout.php
Normal file
53
database/migrations/2022_07_29_151513_convert_checkout.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
DB::statement('RENAME TABLE ab_checkout TO checkouts');
|
||||
DB::statement('ALTER TABLE checkouts MODIFY active tinyint(1) NOT NULL,MODIFY fee_passon tinyint(1) DEFAULT NULL');
|
||||
|
||||
Schema::table('checkouts', function (Blueprint $table) {
|
||||
$table->datetime('created_at')->nullable()->after('id');
|
||||
$table->datetime('updated_at')->nullable()->after('created_at');
|
||||
|
||||
$table->dropForeign('ab_checkout_site_id_foreign');
|
||||
$table->dropIndex('ab_checkout_id_site_id_index');
|
||||
|
||||
$table->foreign(['site_id'])->references(['id'])->on('sites');
|
||||
});
|
||||
|
||||
Schema::table('payments', function (Blueprint $table) {
|
||||
$table->foreign(['checkout_id','site_id'])->references(['id','site_id'])->on('checkouts');
|
||||
});
|
||||
|
||||
foreach (\App\Models\Checkout::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
|
||||
if ($x=$o->getRawOriginal('plugin_data')) {
|
||||
Config::set('site',$o->site);
|
||||
|
||||
$o->plugin_data = unserialize($x);
|
||||
}
|
||||
|
||||
$o->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
abort(500,'Cant go back');
|
||||
}
|
||||
};
|
@ -1,3 +1,4 @@
|
||||
<!-- $o = Invoice::class -->
|
||||
@extends('adminlte::layouts.app')
|
||||
|
||||
@section('htmlheader_title')
|
||||
@ -140,14 +141,19 @@
|
||||
<!-- accepted payments column -->
|
||||
<div class="col-6">
|
||||
<p class="lead">Payment Methods:</p>
|
||||
{{--
|
||||
<img src="../../dist/img/credit/visa.png" alt="Visa">
|
||||
<img src="../../dist/img/credit/mastercard.png" alt="Mastercard">
|
||||
<img src="../../dist/img/credit/american-express.png" alt="American Express">
|
||||
<img src="../../dist/img/credit/paypal2.png" alt="Paypal">
|
||||
--}}
|
||||
|
||||
<p class="text-muted well well-sm no-shadow" style="margin-top: 10px;">
|
||||
<table class="table table-borderless">
|
||||
@foreach (\App\Models\Checkout::available() as $cho)
|
||||
<tr>
|
||||
<td style="width: 50px;"><i class="fa-2x fa-fw {{ $cho->icon }}"></i></td>
|
||||
<td>{{ $cho->name }}</td>
|
||||
<td>{{ $cho->description }}</td>
|
||||
<td class="w-25">@includeIf('payment.widget.plugin.'.strtolower($cho->plugin),['o'=>$cho])</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
<p class="text-muted well well-sm no-shadow" style="position: absolute;bottom: 0;left: 0;">
|
||||
{!! $o->invoice_text !!}
|
||||
</p>
|
||||
</div>
|
@ -0,0 +1,73 @@
|
||||
@extends('adminlte::layouts.app')
|
||||
|
||||
@section('htmlheader_title')
|
||||
Payment
|
||||
@endsection
|
||||
@section('page_title')
|
||||
Payment
|
||||
@endsection
|
||||
|
||||
@section('contentheader_title')
|
||||
Payment
|
||||
@endsection
|
||||
@section('contentheader_description')
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card card-dark">
|
||||
<div class="card-header">
|
||||
<h1 class="card-title">Payment Configuration</h1>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form class="g-0 needs-validation" method="POST" enctype="multipart/form-data" role="form">
|
||||
@csrf
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="form-group has-validation">
|
||||
<label for="name">Payment Name</label>
|
||||
<select class="form-control form-control-border" id="name" name="checkout_id">
|
||||
<option value=""></option>
|
||||
<option value="">Add New</option>
|
||||
@foreach(\App\Models\Checkout::orderBy('active','DESC')->orderBy('name')->get()->groupBy('active') as $o)
|
||||
<optgroup label="{{ $o->first()->active ? 'Active' : 'Not Active' }}">
|
||||
@foreach($o as $oo)
|
||||
<option value="{{ $oo->id }}">{{ $oo->name }}</option>
|
||||
@endforeach
|
||||
</optgroup>
|
||||
@endforeach
|
||||
</select>
|
||||
<span class="invalid-feedback" role="alert">
|
||||
@error('name')
|
||||
{{ $message }}
|
||||
@else
|
||||
Payment Name is required.
|
||||
@enderror
|
||||
</span>
|
||||
<span class="input-helper">Payment Name</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('page-scripts')
|
||||
@css(select2)
|
||||
@js(select2,autofocus)
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#name').select2()
|
||||
.on('change',function(item) {
|
||||
window.location.href = '{{ url('a/checkout') }}'+(item.target.value ? '/'+item.target.value : '');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
@ -0,0 +1,38 @@
|
||||
<!-- $o = Checkout::class -->
|
||||
@extends('adminlte::layouts.app')
|
||||
|
||||
@section('htmlheader_title')
|
||||
{{ $o->name ?: 'New Payment' }}
|
||||
@endsection
|
||||
@section('page_title')
|
||||
{{ $o->name ?: 'New Payment' }}
|
||||
@endsection
|
||||
|
||||
@section('contentheader_title')
|
||||
{{ $o->name ?: 'New Payment' }}
|
||||
@endsection
|
||||
@section('contentheader_description')
|
||||
@include('adminlte::widget.status')
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-dark d-flex p-0">
|
||||
<ul class="nav nav-pills w-100 p-2">
|
||||
<li class="nav-item"><a class="nav-link active" href="#details" data-toggle="tab">Detail</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade active show" id="details" role="tabpanel">
|
||||
@include('payment.widget.detail')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@ -0,0 +1,70 @@
|
||||
<!-- $o = Checkout::class -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h3>Checkout Details</h3>
|
||||
<hr>
|
||||
@if(session()->has('success'))
|
||||
<span class="ml-3 pt-0 pb-0 pr-1 pl-1 btn btn-outline-success"><small>{{ session()->get('success') }}</small></span>
|
||||
@endif
|
||||
|
||||
<form class="g-0 needs-validation" method="POST" enctype="multipart/form-data" role="form">
|
||||
@csrf
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="row">
|
||||
<!-- Checkout Name -->
|
||||
<div class="col-9">
|
||||
<div class="form-group has-validation">
|
||||
<label for="name">Checkout Name</label>
|
||||
<input type="text" class="form-control form-control-border @error('name') is-invalid @enderror" id="name" name="name" placeholder="Supplier Name" value="{{ old('name',$o->name) }}" required>
|
||||
<span class="invalid-feedback" role="alert">
|
||||
@error('name')
|
||||
{{ $message }}
|
||||
@else
|
||||
Payment Name required.
|
||||
@enderror
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Checkout Active -->
|
||||
<div class="col-3">
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success">
|
||||
<input type="checkbox" class="custom-control-input" id="active" name="active" {{ old('active',$o->active) ? 'checked' : '' }}>
|
||||
<label class="custom-control-label" for="active">Active</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Description -->
|
||||
<div class="col-12">
|
||||
<div class="form-group has-validation">
|
||||
<label for="description">Description</label>
|
||||
<input type="text" class="form-control form-control-border @error('description') is-invalid @enderror" id="address1" name="description" placeholder="description" value="{{ old('description',$o->description) }}">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
@error('description')
|
||||
{{ $message }}
|
||||
@enderror
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Buttons -->
|
||||
<div class="col-12">
|
||||
<a href="{{ url('/home') }}" class="btn btn-danger">Cancel</a>
|
||||
@can('wholesaler')
|
||||
<button type="submit" name="submit" class="btn btn-success mr-0 float-right">@if ($o->exists)Save @else Add @endif</button>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,15 @@
|
||||
<!-- $o=Checkout::class -->
|
||||
<table class="table table-borderless table-sm">
|
||||
<tr>
|
||||
<td>Bank</td><th>{{ Arr::get($o->plugin_data,'bankname') }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Branch</td><th>{{ Arr::get($o->plugin_data,'bankbranch') }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>BSB</td><th>{{ Arr::get($o->plugin_data,'bankbsb') }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ACC</td><th>{{ Arr::get($o->plugin_data,'bankaccount') }}</th>
|
||||
</tr>
|
||||
</table>
|
@ -77,6 +77,14 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- CHECKOUT (PAYMENTS) -->
|
||||
<li class="nav-item">
|
||||
<a href="{{ url('a/checkout') }}" class="nav-link @if(preg_match('#^a/checkout#',$path)) active @endif">
|
||||
<i class="nav-icon fas fa-money-check-alt"></i> <p>Payments</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- PRODUCTS -->
|
||||
<li class="nav-item">
|
||||
<a href="{{ url('a/product') }}" class="nav-link @if(preg_match('#^a/product#',$path)) active @endif">
|
||||
<i class="nav-icon fas fa-barcode"></i> <p>Products</p>
|
||||
@ -105,7 +113,6 @@
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="nav-item has-treeview @if(preg_match('#^a/report/(products)#',$path))menu-open @else menu-closed @endif">
|
||||
<a href="#" class="nav-link @if(preg_match('#^a/report/(products)#',$path)) active @endif">
|
||||
<i class="nav-icon fas fa-list"></i> <p>REPORT<i class="fas fa-angle-left right"></i></p>
|
||||
|
@ -6,6 +6,7 @@ use App\Http\Controllers\{AdminController,
|
||||
Auth\SocialLoginController,
|
||||
CheckoutController,
|
||||
HomeController,
|
||||
InvoiceController,
|
||||
MediaController,
|
||||
OrderController,
|
||||
PaypalController,
|
||||
@ -60,6 +61,13 @@ Route::group(['middleware'=>['theme:adminlte-be','auth','role:wholesaler'],'pref
|
||||
// Site Setup
|
||||
Route::match(['get','post'],'setup',[AdminController::class,'setup']);
|
||||
|
||||
// Checkout Setup (Payments)
|
||||
Route::get('checkout',[CheckoutController::class,'home']);
|
||||
Route::get('checkout/{o?}',[CheckoutController::class,'view'])
|
||||
->where('o','[0-9]+');
|
||||
Route::post('checkout/{o?}',[CheckoutController::class,'addedit'])
|
||||
->where('o','[0-9]+');
|
||||
|
||||
// Product Setup
|
||||
Route::match(['get'],'product',[ProductController::class,'home']);
|
||||
Route::match(['get','post'],'product/details/{o?}',[ProductController::class,'details'])
|
||||
@ -140,10 +148,10 @@ Route::group(['middleware'=>['theme:adminlte-be','auth'],'prefix'=>'u'],function
|
||||
// ->where('o','[0-9]+')
|
||||
// ->middleware('can:view,o');
|
||||
Route::post('checkout/pay',[CheckoutController::class,'pay']);
|
||||
Route::get('invoice/{o}',[HomeController::class,'invoice'])
|
||||
Route::get('invoice/{o}',[InvoiceController::class,'view'])
|
||||
->where('o','[0-9]+')
|
||||
->middleware('can:view,o');
|
||||
Route::get('invoice/{o}/pdf',[HomeController::class,'invoice_pdf'])
|
||||
Route::get('invoice/{o}/pdf',[InvoiceController::class,'pdf'])
|
||||
->where('o','[0-9]+')
|
||||
->middleware('can:view,o');
|
||||
Route::get('invoice/cart',[CheckoutController::class,'cart_invoice']);
|
||||
|
Loading…
Reference in New Issue
Block a user