Separated Checkout and Payment controllers, updates to checkout and payments
This commit is contained in:
parent
06f25d5d4d
commit
efbb3d091f
@ -3,15 +3,9 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
use App\Http\Requests\SiteEdit;
|
use App\Http\Requests\SiteEdit;
|
||||||
use App\Models\{Account,
|
use App\Models\SiteDetail;
|
||||||
Invoice,
|
|
||||||
Payment,
|
|
||||||
PaymentItem,
|
|
||||||
Service,
|
|
||||||
SiteDetail};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The AdminController governs all routes that are prefixed with 'a/'.
|
* The AdminController governs all routes that are prefixed with 'a/'.
|
||||||
@ -20,108 +14,6 @@ use App\Models\{Account,
|
|||||||
*/
|
*/
|
||||||
class AdminController extends Controller
|
class AdminController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Record payments on an account.
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
* @param Payment $o
|
|
||||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
// @todo Move to reseller
|
|
||||||
public function pay_addedit(Request $request,Payment $o)
|
|
||||||
{
|
|
||||||
if ($request->post()) {
|
|
||||||
|
|
||||||
$validation = $request->validate([
|
|
||||||
'account_id' => 'required|exists:accounts,id',
|
|
||||||
'paid_at' => 'required|date',
|
|
||||||
'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',
|
|
||||||
'pending' => 'nullable|boolean',
|
|
||||||
'notes' => 'nullable|string',
|
|
||||||
'ip' => 'nullable|ip',
|
|
||||||
'invoices' => ['required','array',function ($attribute,$value,$fail) use ($request) {
|
|
||||||
if (collect($value)->sum('id') > $request->post('total_amt'))
|
|
||||||
$fail('Allocation is greater than payment total.');
|
|
||||||
}],
|
|
||||||
'invoices.*.id' => ['required',function ($attribute,$value,$fail) {
|
|
||||||
if (! Invoice::exists(str_replace(str_replace($attribute,'invoice\.','',),'.id','')))
|
|
||||||
$fail('Invoice doesnt exist in DB');
|
|
||||||
}],
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (! $o->exists) {
|
|
||||||
$o->site_id = config('site')->site_id;
|
|
||||||
$o->active = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$o->forceFill($request->only(['account_id','paid_at','checkout_id','total_amt','fees_amt','source_id','pending','notes','ip']));
|
|
||||||
$o->save();
|
|
||||||
|
|
||||||
foreach ($validation['invoices'] as $id => $amount) {
|
|
||||||
// See if we already have a payment item that we need to update
|
|
||||||
$items = $o->items->filter(function($item) use ($id) { return $item->invoice_id == $id; });
|
|
||||||
|
|
||||||
if ($items->count() == 1) {
|
|
||||||
$oo = $items->pop();
|
|
||||||
if ($amount['id'] == 0) {
|
|
||||||
$oo->delete();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$oo = new PaymentItem;
|
|
||||||
$oo->invoice_id = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$oo->amount = ($oo->invoice->due >= 0) && ($oo->invoice->due-$amount['id'] >= 0) ? $amount['id'] : 0;
|
|
||||||
|
|
||||||
// If the amount is empty, ignore it.
|
|
||||||
if (! $oo->amount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$oo->site_id = config('site')->site_id;
|
|
||||||
$oo->active = TRUE;
|
|
||||||
$o->items()->save($oo);
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success','Payment recorded: '.$o->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('theme.backend.adminlte.a.payment.addedit')
|
|
||||||
->with('o',$o);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List unapplied payments
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
// @todo Move to reseller
|
|
||||||
public function pay_unapplied()
|
|
||||||
{
|
|
||||||
return view('theme.backend.adminlte.a.payment.unapplied');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a list of invoices to apply payments to
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
* @param Account $o
|
|
||||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
// @todo Move to reseller
|
|
||||||
public function pay_invoices(Request $request,Account $o)
|
|
||||||
{
|
|
||||||
return view('theme.backend.adminlte.a.payment.widgets.invoices')
|
|
||||||
->with('pid',$request->pid)
|
|
||||||
->with('o',$o);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Site setup
|
* Site setup
|
||||||
*
|
*
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\View\View;
|
|
||||||
|
|
||||||
use App\Http\Requests\CheckoutAddEdit;
|
use App\Http\Requests\CheckoutAddEdit;
|
||||||
use App\Models\{Checkout,Invoice};
|
use App\Models\{Checkout,Invoice};
|
||||||
@ -11,31 +11,35 @@ use App\Models\{Checkout,Invoice};
|
|||||||
class CheckoutController extends Controller
|
class CheckoutController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Update a suppliers details
|
* Update a checkout details
|
||||||
*
|
*
|
||||||
* @param CheckoutAddEdit $request
|
* @param CheckoutAddEdit $request
|
||||||
* @param Checkout $o
|
* @param Checkout $o
|
||||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
* @return RedirectResponse
|
||||||
*/
|
*/
|
||||||
public function addedit(CheckoutAddEdit $request,Checkout $o)
|
public function addedit(CheckoutAddEdit $request,Checkout $o): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->middleware(['auth','wholesaler']);
|
foreach ($request->validated() as $key => $item)
|
||||||
|
|
||||||
foreach ($request->except(['_token','active','submit']) as $key => $item)
|
|
||||||
$o->{$key} = $item;
|
$o->{$key} = $item;
|
||||||
|
|
||||||
$o->active = (bool)$request->active;
|
$o->active = (bool)$request->validated('active',FALSE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$o->save();
|
$o->save();
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()->back()->withErrors($e->getMessage())->withInput();
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->withErrors($e->getMessage())->withInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()
|
return $o->wasRecentlyCreated
|
||||||
->back()
|
? redirect()
|
||||||
->with('success','Payment saved');
|
->to('a/checkout/'.$o->id)
|
||||||
|
->with('success','Checkout added')
|
||||||
|
: redirect()
|
||||||
|
->back()
|
||||||
|
->with('success','Checkout saved');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function cart_invoice(Request $request,Invoice $o=NULL)
|
public function cart_invoice(Request $request,Invoice $o=NULL)
|
||||||
@ -57,29 +61,8 @@ class CheckoutController extends Controller
|
|||||||
return $o->fee($request->post('total',0));
|
return $o->fee($request->post('total',0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Render a specific invoice for the user
|
|
||||||
*
|
|
||||||
* @return View
|
|
||||||
*/
|
|
||||||
public function home(): View
|
|
||||||
{
|
|
||||||
return view('theme.backend.adminlte.payment.home');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function pay(Request $request,Checkout $o)
|
public function pay(Request $request,Checkout $o)
|
||||||
{
|
{
|
||||||
return redirect('pay/paypal/authorise');
|
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('theme.backend.adminlte.payment.view',['o'=>$o]);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -4,10 +4,11 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use Clarkeash\Doorman\Exceptions\{ExpiredInviteCode,InvalidInviteCode,NotYourInviteCode};
|
use Clarkeash\Doorman\Exceptions\{ExpiredInviteCode,InvalidInviteCode,NotYourInviteCode};
|
||||||
use Clarkeash\Doorman\Facades\Doorman;
|
use Clarkeash\Doorman\Facades\Doorman;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;
|
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;
|
||||||
|
|
||||||
use App\Models\Invoice;
|
use App\Models\{Account,Invoice};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class InvoiceController
|
* Class InvoiceController
|
||||||
@ -19,6 +20,21 @@ use App\Models\Invoice;
|
|||||||
*/
|
*/
|
||||||
class InvoiceController extends Controller
|
class InvoiceController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Show a list of invoices to apply payments to
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function api_account_invoices(Request $request): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
session()->flashInput($request->post('old',[]));
|
||||||
|
|
||||||
|
return view('theme.backend.adminlte.payment.widget.invoices')
|
||||||
|
->with('pid',$request->post('pid'))
|
||||||
|
->with('o',Account::findOrFail($request->post('aid')));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the invoice in PDF format, ready to download
|
* Return the invoice in PDF format, ready to download
|
||||||
*
|
*
|
||||||
|
73
app/Http/Controllers/PaymentController.php
Normal file
73
app/Http/Controllers/PaymentController.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
|
||||||
|
use App\Http\Requests\PaymentAddEdit;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use App\Models\{Payment,PaymentItem};
|
||||||
|
|
||||||
|
class PaymentController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Record payments on an account.
|
||||||
|
*
|
||||||
|
* @param PaymentAddEdit $request
|
||||||
|
* @param Payment $o
|
||||||
|
* @return RedirectResponse
|
||||||
|
*/
|
||||||
|
public function addedit(PaymentAddEdit $request,Payment $o): RedirectResponse
|
||||||
|
{
|
||||||
|
foreach (Arr::except($request->validated(),'invoices') as $k=>$v)
|
||||||
|
$o->{$k} = $v;
|
||||||
|
|
||||||
|
foreach ($request->validated('invoices',[]) as $id => $amount) {
|
||||||
|
// See if we already have a payment item that we need to update
|
||||||
|
$items = $o->items
|
||||||
|
->filter(fn($item)=>$item->invoice_id == $id);
|
||||||
|
|
||||||
|
if ($items->count() === 1) {
|
||||||
|
$oo = $items->pop();
|
||||||
|
|
||||||
|
if ($amount == 0) {
|
||||||
|
$oo->delete();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$oo = new PaymentItem;
|
||||||
|
$oo->invoice_id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oo->amount = ($oo->invoice->due >= 0) && ($oo->invoice->due-$amount >= 0)
|
||||||
|
? $amount
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
// If the amount is empty, ignore it.
|
||||||
|
if (! $oo->amount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$oo->site_id = config('site')->site_id;
|
||||||
|
$oo->active = TRUE;
|
||||||
|
$o->items->push($oo);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$o->pushNew();
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->withErrors($e->getMessage())->withInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $o->wasRecentlyCreated
|
||||||
|
? redirect()
|
||||||
|
->to('r/payment/'.$o->id)
|
||||||
|
->with('success','Payment added')
|
||||||
|
: redirect()
|
||||||
|
->back()
|
||||||
|
->with('success','Payment saved');
|
||||||
|
}
|
||||||
|
}
|
@ -90,7 +90,7 @@ class SearchController extends Controller
|
|||||||
->whereIN('account_id',$account_ids)
|
->whereIN('account_id',$account_ids)
|
||||||
->limit(10)->get() as $o)
|
->limit(10)->get() as $o)
|
||||||
{
|
{
|
||||||
$result->push(['name'=>sprintf('%s: %s $%s',$o->lid,$o->account->name,number_format($o->total,2)),'value'=>'/a/payment/addedit/'.$o->id,'category'=>'Payments']);
|
$result->push(['name'=>sprintf('%s: %s $%s',$o->lid,$o->account->name,number_format($o->total,2)),'value'=>'/r/payment/addedit/'.$o->id,'category'=>'Payments']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ namespace App\Http\Requests;
|
|||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editing Suppliers
|
* Editing Suppliers
|
||||||
@ -28,7 +29,13 @@ class CheckoutAddEdit extends FormRequest
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'required|string|min:2|max:255',
|
'name' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'min:2',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique('checkouts','name')->ignore($this->route('o')?->id),
|
||||||
|
],
|
||||||
'active' => 'sometimes|accepted',
|
'active' => 'sometimes|accepted',
|
||||||
'description' => 'nullable|string|min:2|max:255',
|
'description' => 'nullable|string|min:2|max:255',
|
||||||
];
|
];
|
||||||
|
62
app/Http/Requests/PaymentAddEdit.php
Normal file
62
app/Http/Requests/PaymentAddEdit.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
use App\Models\Invoice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Editing Suppliers
|
||||||
|
*/
|
||||||
|
class PaymentAddEdit 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 [
|
||||||
|
'account_id' => 'required|exists:accounts,id',
|
||||||
|
'paid_at' => 'required|date',
|
||||||
|
'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',
|
||||||
|
'pending' => 'nullable|boolean',
|
||||||
|
'notes' => 'nullable|string',
|
||||||
|
'ip' => 'nullable|ip',
|
||||||
|
'invoices' => [
|
||||||
|
'nullable',
|
||||||
|
'array',
|
||||||
|
function($attribute,$value,$fail) {
|
||||||
|
if (($x=collect($value)->sum()) > request()->post('total_amt'))
|
||||||
|
$fail(sprintf('Allocation %3.2f is greater than payment total %3.2f.',$x,request()->post('total_amt')));
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'invoices.*' => [
|
||||||
|
'nullable',
|
||||||
|
function($attribute,$value,$fail) {
|
||||||
|
if (! ($x=Invoice::where('id',$xx=str_replace('invoices.','',$attribute))->first()))
|
||||||
|
$fail(sprintf('Invoice [%d] doesnt exist in DB',$xx));
|
||||||
|
// @todo The due amount may be influenced by this payment (ie: payment edit)
|
||||||
|
elseif($x->due < $value)
|
||||||
|
$fail(sprintf('Invoice [%d] is over allocated by %3.2f',$x->id,$value-$x->due));
|
||||||
|
}
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -6,9 +6,11 @@ use Illuminate\Database\Eloquent\Collection;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Leenooks\Traits\ScopeActive;
|
use Leenooks\Traits\ScopeActive;
|
||||||
|
|
||||||
|
use App\Traits\SiteID;
|
||||||
|
|
||||||
class Checkout extends Model
|
class Checkout extends Model
|
||||||
{
|
{
|
||||||
use ScopeActive;
|
use ScopeActive,SiteID;
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'plugin_data'=>'json',
|
'plugin_data'=>'json',
|
||||||
|
@ -300,8 +300,7 @@ class Invoice extends Model implements IDs
|
|||||||
/**
|
/**
|
||||||
* @param \Leenooks\Carbon $start Start Date
|
* @param \Leenooks\Carbon $start Start Date
|
||||||
* @param Carbon $end End Date
|
* @param Carbon $end End Date
|
||||||
* @param int $interval Period End Date
|
* @param Collection $period
|
||||||
* @param bool $strict
|
|
||||||
* @return float
|
* @return float
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
@ -373,7 +372,7 @@ class Invoice extends Model implements IDs
|
|||||||
public function payments()
|
public function payments()
|
||||||
{
|
{
|
||||||
return $this->hasManyThrough(Payment::class,PaymentItem::class,NULL,'id',NULL,'payment_id')
|
return $this->hasManyThrough(Payment::class,PaymentItem::class,NULL,'id',NULL,'payment_id')
|
||||||
->where('active',TRUE);
|
->where('payments.active',TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,8 +7,7 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use Leenooks\Traits\ScopeActive;
|
use Leenooks\Traits\ScopeActive;
|
||||||
|
|
||||||
use App\Interfaces\IDs;
|
use App\Interfaces\IDs;
|
||||||
use App\Traits\ProviderRef;
|
use App\Traits\{ProviderRef,PushNew,SiteID};
|
||||||
use App\Traits\PushNew;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Payment
|
* Class Payment
|
||||||
@ -25,7 +24,7 @@ use App\Traits\PushNew;
|
|||||||
*/
|
*/
|
||||||
class Payment extends Model implements IDs
|
class Payment extends Model implements IDs
|
||||||
{
|
{
|
||||||
use PushNew,ScopeActive,ProviderRef;
|
use PushNew,ScopeActive,ProviderRef,SiteID;
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'paid_at'=>'datetime:Y-m-d',
|
'paid_at'=>'datetime:Y-m-d',
|
||||||
@ -106,7 +105,7 @@ class Payment extends Model implements IDs
|
|||||||
->select(['payments.id','paid_at','account_id','checkout_id','total_amt',DB::raw("SUM(ABS(amount)) as allocated")])
|
->select(['payments.id','paid_at','account_id','checkout_id','total_amt',DB::raw("SUM(ABS(amount)) as allocated")])
|
||||||
->leftJoin('payment_items',['payment_items.payment_id'=>'payments.id'])
|
->leftJoin('payment_items',['payment_items.payment_id'=>'payments.id'])
|
||||||
->groupBy(['payments.id','paid_at','total_amt','account_id','checkout_id'])
|
->groupBy(['payments.id','paid_at','total_amt','account_id','checkout_id'])
|
||||||
->having(DB::raw('ROUND(total_amt-IFNULL(allocated,0),2)'),'>',self::threshold);
|
->having(DB::raw('ROUND(CAST(total_amt-COALESCE(SUM(ABS(amount)),0) AS NUMERIC),2)'),'>',self::threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ATTRIBUTES */
|
/* ATTRIBUTES */
|
||||||
|
11
public/css/fixes.css
vendored
11
public/css/fixes.css
vendored
@ -84,8 +84,17 @@ span.select2-selection.select2-selection--single > span.select2-selection__rende
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Render the invalid red when a select container fails validation */
|
/* Render the invalid red when a select container fails vlidation */
|
||||||
.is-invalid + .select2-container--default .select2-selection--single,
|
.is-invalid + .select2-container--default .select2-selection--single,
|
||||||
.is-invalid + .select2-container--default .select2-selection--multiple {
|
.is-invalid + .select2-container--default .select2-selection--multiple {
|
||||||
border: 1px solid #dc3545;
|
border: 1px solid #dc3545;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When we have a hr after h3, show the line directly under the h3 */
|
||||||
|
h3:has(+hr) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
h3 + hr {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
@ -1,254 +0,0 @@
|
|||||||
@extends('adminlte::layouts.app')
|
|
||||||
|
|
||||||
@section('htmlheader_title')
|
|
||||||
Payment
|
|
||||||
@endsection
|
|
||||||
@section('page_title')
|
|
||||||
Payment
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('contentheader_title')
|
|
||||||
Record Payment
|
|
||||||
@endsection
|
|
||||||
@section('contentheader_description')
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('main-content')
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-6">
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header">
|
|
||||||
<h1 class="card-title">Record Payment</h1>
|
|
||||||
@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
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<form class="g-0 needs-validation" method="POST" role="form">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<!-- DATE RECEIVED -->
|
|
||||||
<div class="col-4">
|
|
||||||
<div class="form-group has-validation">
|
|
||||||
<label for="paid_at">Date Received</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fas fa-fw fa-calendar"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="date" class="form-control @error('paid_at') is-invalid @enderror" id="paid_at" name="paid_at" value="{{ old('paid_at',($o->exists ? $o->paid_at : \Carbon\Carbon::now())->format('Y-m-d')) }}" required>
|
|
||||||
<span class="invalid-feedback" role="alert">
|
|
||||||
@error('paid_at')
|
|
||||||
{{ $message }}
|
|
||||||
@else
|
|
||||||
Payment Date is required.
|
|
||||||
@enderror
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="input-helper">Date Payment Received.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- AMOUNT -->
|
|
||||||
<div class="offset-4 col-4">
|
|
||||||
<div class="form-group has-validation">
|
|
||||||
<label for="total_amt">Amount</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fas fa-fw fa-dollar-sign"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="text-right form-control @error('total_amt') is-invalid @enderror" id="total_amt" name="total_amt" value="{{ number_format(old('total_amt',$o->exists ? $o->total_amt : 0),2) }}" required>
|
|
||||||
<span class="invalid-feedback" role="alert">
|
|
||||||
@error('total_amt')
|
|
||||||
{{ $message }}
|
|
||||||
@else
|
|
||||||
Payment Amount is required.
|
|
||||||
@enderror
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="input-helper">Amount Received.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<!-- METHOD -->
|
|
||||||
<div class="col-4">
|
|
||||||
<div class="form-group has-validation">
|
|
||||||
<label for="checkout_id">Payment Method</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fas fa-fw fa-dollar-sign"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control @error('checkout_id') is-invalid @enderror" id="checkout_id" name="checkout_id" required>
|
|
||||||
<option value=""></option>
|
|
||||||
@foreach (\App\Models\Checkout::orderBy('name')->get() as $co)
|
|
||||||
<option value="{{ $co->id }}" {{ $co->id == old('checkout_id',$o->exists ? $o->checkout_id : NULL) ? 'selected' : '' }}>{{ $co->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
<span class="invalid-feedback" role="alert">
|
|
||||||
@error('checkout_id')
|
|
||||||
{{ $message }}
|
|
||||||
@else
|
|
||||||
Payment Method is required.
|
|
||||||
@enderror
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="input-helper">Payment Method.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- PAYMENT FEE -->
|
|
||||||
<div class="offset-4 col-4">
|
|
||||||
<div class="form-group has-validation">
|
|
||||||
<label for="fees_amt">Fee</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fas fa-fw fa-dollar-sign"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="text-right form-control @error('fees_amt') is-invalid @enderror" id="fees_amt" name="fees_amt" value="{{ number_format(old('fees_amt',$o->exists ? $o->fees_amt : 0),2) }}">
|
|
||||||
<span class="invalid-feedback" role="alert">
|
|
||||||
@error('fees_amt')
|
|
||||||
{{ $message }}
|
|
||||||
@else
|
|
||||||
Total Fees is required.
|
|
||||||
@enderror
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="input-helper">Amount Received.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<!-- ACCOUNT -->
|
|
||||||
<div class="col-6">
|
|
||||||
<div class="form-group has-validation">
|
|
||||||
<label for="account_id">Account</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fas fa-fw fa-user"></i></span>
|
|
||||||
</div>
|
|
||||||
<!-- @todo Only show active accounts or accounts with outstanding invoices -->
|
|
||||||
<select class="form-control @error('account_id') is-invalid @enderror" id="account_id" name="account_id" required>
|
|
||||||
<option value=""></option>
|
|
||||||
@foreach (\App\Models\Account::active()->with(['user'])->get()->sortBy('name') as $ao)
|
|
||||||
<option value="{{ $ao->id }}" {{ $ao->id == old('account_id',$o->exists ? $o->account_id : NULL) ? 'selected' : '' }}>{{ $ao->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<span class="invalid-feedback" role="alert">
|
|
||||||
@error('account_id')
|
|
||||||
{{ $message }}
|
|
||||||
@else
|
|
||||||
Account is required.
|
|
||||||
@enderror
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="input-helper">Account to add payment to.</span>
|
|
||||||
<i class="fas fa-spinner d-none"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- BALANCE -->
|
|
||||||
<div class="offset-2 col-4">
|
|
||||||
<label for="fees_amt">Balance</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fas fa-fw fa-dollar-sign"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="text-right form-control @error('fees_amt') is-invalid @enderror" id="balance" value="{{ number_format($o->exists ? $o->balance : 0,2) }}" disabled>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-3 mb-3">
|
|
||||||
<div class="col-12">
|
|
||||||
<div id="invoices"></div>
|
|
||||||
@error('invoices')
|
|
||||||
<span class="invalid-feedback d-block mt-2 mb-2" role="alert">
|
|
||||||
{{ $message }}
|
|
||||||
</span>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<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 ($site->exists)Save @else Add @endif</button>
|
|
||||||
@endcan
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('page-scripts')
|
|
||||||
@css(select2)
|
|
||||||
@js(select2,autofocus)
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
function populate(account,spinner) {
|
|
||||||
spinner.toggleClass('d-none').toggleClass('fa-spin');
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
dataType: 'html',
|
|
||||||
cache: false,
|
|
||||||
url: '{{ url('api/r/invoices') }}'+'/'+account,
|
|
||||||
data: {pid:{{ $o->id ?: 'null' }}},
|
|
||||||
timeout: 2000,
|
|
||||||
error: function(x) {
|
|
||||||
spinner.toggleClass('d-none').toggleClass('fa-spin');
|
|
||||||
alert('Failed to submit');
|
|
||||||
},
|
|
||||||
success: function(data) {
|
|
||||||
spinner.toggleClass('d-none').toggleClass('fa-spin');
|
|
||||||
$("div[id=invoices]").empty().append(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function balance() {
|
|
||||||
var alloc = 0;
|
|
||||||
|
|
||||||
$('.invoice').each(function() {
|
|
||||||
alloc += parseFloat($(this).val());
|
|
||||||
})
|
|
||||||
|
|
||||||
$('#balance').val(($('#total_amt').val()-alloc).toFixed(2))
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
if ($('#account_id').val()) {
|
|
||||||
var spinner = $('#account_id').parent().parent().find('i.fas.fa-spinner');
|
|
||||||
|
|
||||||
populate($('#account_id').val(),spinner);
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#account_id').select2({
|
|
||||||
sorter: data => data.sort((a, b) => a.text.localeCompare(b.text)),
|
|
||||||
})
|
|
||||||
.on('change',function(e) {
|
|
||||||
if (! $(this).val()) {
|
|
||||||
$("div[id=invoices]").empty();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var spinner = $(this).parent().parent().find('i.fas.fa-spinner');
|
|
||||||
|
|
||||||
populate($(this).val(),spinner);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#total_amt').on('change',balance);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('change','.invoice',balance);
|
|
||||||
</script>
|
|
||||||
@append
|
|
@ -0,0 +1,52 @@
|
|||||||
|
@use(App\Models\Checkout)
|
||||||
|
|
||||||
|
@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">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-lg-4">
|
||||||
|
<x-leenooks::form.select id="checkout_id" name="checkout_id" icon="fa-credit-card" label="Payment Name" feedback="Payment Name is required" addnew="New Payment" groupby="active" :options="Checkout::orderBy('active','DESC')->orderBy('name')->get()->map(function ($item) { $item->value = $item->name; return $item; })"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@pa(select2,autofocus)
|
||||||
|
|
||||||
|
@section('page-scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#checkout_id').select2()
|
||||||
|
.on('change',function(item) {
|
||||||
|
if (! item.target.value)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
window.location.href = '{{ url('a/checkout') }}'+(item.target.value ? '/'+item.target.value : '');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@append
|
@ -0,0 +1,37 @@
|
|||||||
|
<!-- $co=Checkout::class -->
|
||||||
|
@extends('adminlte::layouts.app')
|
||||||
|
|
||||||
|
@section('htmlheader_title')
|
||||||
|
{{ $co->name ?? 'New Checkout' }}
|
||||||
|
@endsection
|
||||||
|
@section('page_title')
|
||||||
|
{{ $co->name ?? 'New Checkout' }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('contentheader_title')
|
||||||
|
{{ $co->name ?? 'New Checkout' }}
|
||||||
|
@endsection
|
||||||
|
@section('contentheader_description')
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('main-content')
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header bg-dark 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('theme.backend.adminlte.checkout.widget.detail',['o'=>$co ?? NULL])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
@ -0,0 +1,37 @@
|
|||||||
|
<!-- $o=Checkout::class -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h3>Checkout Details <x-leenooks::button.success class="float-right"/></h3>
|
||||||
|
<hr>
|
||||||
|
<form method="POST" action="{{ url('a/checkout',$o?->id ?? '') }}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Checkout Name -->
|
||||||
|
<div class="col-10 col-md-6">
|
||||||
|
<x-leenooks::form.text name="name" icon="fa-shopping-cart" label="Checkout Name" placeholder="{{ $o?->name ?: 'Payment Name' }}" feedback="Payment Name is required" :value="$o?->name"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Checkout Active -->
|
||||||
|
<div class="col-2">
|
||||||
|
<x-leenooks::form.toggle name="active" label="Active" :value="$o?->active"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Description -->
|
||||||
|
<div class="col">
|
||||||
|
<x-leenooks::form.text name="description" label="Description" :value="$o?->description"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Buttons -->
|
||||||
|
<div class="col">
|
||||||
|
<x-leenooks::button.reset/>
|
||||||
|
<x-leenooks::button.submit class="float-right">@if($o?->exists)Update @else Add @endif</x-leenooks::button.submit>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,73 +0,0 @@
|
|||||||
@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
|
|
@ -1,3 +1,5 @@
|
|||||||
|
@use(App\Models\Payment)
|
||||||
|
|
||||||
@extends('adminlte::layouts.app')
|
@extends('adminlte::layouts.app')
|
||||||
|
|
||||||
@section('htmlheader_title')
|
@section('htmlheader_title')
|
||||||
@ -15,7 +17,7 @@
|
|||||||
|
|
||||||
@section('main-content')
|
@section('main-content')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table table-striped table-hover" id="unapplied_payments">
|
<table class="table table-striped table-hover" id="unapplied_payments">
|
||||||
@ -32,10 +34,10 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach(\App\Models\Payment::active()->unapplied()->with(['account.user','checkout','items'])->get() as $o)
|
@foreach(Payment::active()->unapplied()->with(['account.user','checkout','items'])->get() as $o)
|
||||||
@if (! $o->balance) @continue @endif
|
@continue(! $o->balance)
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ url('a/payment/addedit',$o->id) }}">{{ $o->id }}</td>
|
<td><a href="{{ url('r/payment',$o->id) }}">{{ $o->id }}</td>
|
||||||
<td>{{ $o->paid_at->format('Y-m-d') }}</td>
|
<td>{{ $o->paid_at->format('Y-m-d') }}</td>
|
||||||
<td>{{ $o->account->name }}</td>
|
<td>{{ $o->account->name }}</td>
|
||||||
<td>{{ $o->checkout->name }}</td>
|
<td>{{ $o->checkout->name }}</td>
|
||||||
@ -52,14 +54,17 @@
|
|||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('page-scripts')
|
@pa(datatables,rowgroup|conditionalpaging)
|
||||||
@css(datatables,bootstrap4)
|
|
||||||
@js(datatables,bootstrap4)
|
|
||||||
|
|
||||||
|
@section('page-scripts')
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#unapplied_payments').DataTable( {
|
$('#unapplied_payments').DataTable({
|
||||||
order: [1,'desc'],
|
order: [1,'desc'],
|
||||||
|
rowGroup: {
|
||||||
|
dataSrc: 2,
|
||||||
|
},
|
||||||
|
conditionalPaging: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
@ -1,38 +1,167 @@
|
|||||||
<!-- $o = Checkout::class -->
|
<!-- po=Payment::class -->
|
||||||
|
@use(Carbon\Carbon)
|
||||||
|
@use(App\Models\Account)
|
||||||
|
@use(App\Models\Checkout)
|
||||||
|
|
||||||
@extends('adminlte::layouts.app')
|
@extends('adminlte::layouts.app')
|
||||||
|
|
||||||
@section('htmlheader_title')
|
@section('htmlheader_title')
|
||||||
{{ $o->name ?: 'New Payment' }}
|
Payment
|
||||||
@endsection
|
@endsection
|
||||||
@section('page_title')
|
@section('page_title')
|
||||||
{{ $o->name ?: 'New Payment' }}
|
Payment
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('contentheader_title')
|
@section('contentheader_title')
|
||||||
{{ $o->name ?: 'New Payment' }}
|
Record Payment
|
||||||
@endsection
|
@endsection
|
||||||
@section('contentheader_description')
|
@section('contentheader_description')
|
||||||
@include('adminlte::widget.status')
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('main-content')
|
@section('main-content')
|
||||||
<div class="row">
|
<div class="card card-dark">
|
||||||
<div class="col-12">
|
<div class="card-body">
|
||||||
<div class="card">
|
<form method="POST" action="{{ url('r/payment',$po?->id ?? '') }}">
|
||||||
<div class="card-header bg-dark d-flex p-0">
|
@csrf
|
||||||
<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">
|
<x-leenooks::button.success class="float-right" row="true"/>
|
||||||
<div class="tab-content">
|
<div class="row">
|
||||||
<div class="tab-pane fade active show" id="details" role="tabpanel">
|
<div class="col-12 col-sm-6 col-lg-3">
|
||||||
@include('theme.backend.adminlte.payment.widget.detail')
|
<div class="row">
|
||||||
|
<div class="col-12 col-md-9 col-lg-12">
|
||||||
|
<!-- Account -->
|
||||||
|
<!-- @todo Only show active accounts or accounts with outstanding invoices -->
|
||||||
|
<x-leenooks::form.select name="account_id" icon="fa-user" label="Account" feedback="Sweep Type is required" helper="Account to add payment to." :options="Account::active()->with(['user'])->get()->sortBy('name')->map(fn($item,$key)=>['id'=>$item->id,'value'=>$item->name])" :value="$po?->account_id ?? ''"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-md-9 col-lg-12">
|
||||||
|
<!-- Received -->
|
||||||
|
<x-leenooks::form.date name="paid_at" icon="fa-calendar" label="Date Received" feedback="Payment Date is required" helper="Date payment received" :value="($po?->paid_at ?? Carbon::now())->format('Y-m-d')"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- METHOD -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-md-9 col-lg-12">
|
||||||
|
<x-leenooks::form.select name="checkout_id" icon="fa-dollar-sign" label="Payment Method" :options="Checkout::orderBy('name')->get()->map(fn($item,$key)=>['id'=>$item->id,'value'=>$item->name])" :value="$po?->checkout_id ?? ''"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-sm-6 col-log-3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<!-- Amount -->
|
||||||
|
<x-leenooks::form.text class="text-right" id="total_amt" name="total_amt" icon="fa-dollar-sign" label="Amount" helper="Amount received" :value="$po?->total_amt ?? 0"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<!-- Payment Fee -->
|
||||||
|
<x-leenooks::form.text class="text-right" id="fees_amt" name="fees_amt" icon="fa-dollar-sign" label="Fee" helper="Payment fees" :value="$po?->fees_amt ?? ''"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<!-- Balance -->
|
||||||
|
<x-leenooks::form.text class="text-right" id="balance" name="balance" icon="fa-dollar-sign" label="Balance" helper="Payment unallocated" :value="$po?->total ?? 0" disabled/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="row mt-3 mb-3">
|
||||||
|
<div class="col-12">
|
||||||
|
<div id="invoices"></div>
|
||||||
|
@error('invoices')
|
||||||
|
<span class="invalid-feedback d-block mt-2 mb-2">
|
||||||
|
{{ $message }}
|
||||||
|
</span>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Buttons -->
|
||||||
|
<div class="col">
|
||||||
|
<x-leenooks::button.cancel/>
|
||||||
|
<x-leenooks::button.submit class="float-right">@if($po?->exists ?? FALSE)Update @else Add @endif</x-leenooks::button.submit>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<x-leenooks::errors/>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@section('page-scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
function populate(account,spinner) {
|
||||||
|
spinner.toggleClass('d-none').toggleClass('fa-spin');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'html',
|
||||||
|
cache: false,
|
||||||
|
url: '{{ url('r/account/invoices') }}',
|
||||||
|
data: {
|
||||||
|
aid: account,
|
||||||
|
pid: {{ $po?->id ?? 'null' }},
|
||||||
|
errors: {!! $errors !!},
|
||||||
|
old: {!! json_encode(old()) !!}
|
||||||
|
},
|
||||||
|
timeout: 2000,
|
||||||
|
error: function(x) {
|
||||||
|
spinner.toggleClass('d-none').toggleClass('fa-spin');
|
||||||
|
alert('Failed to submit');
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
spinner.toggleClass('d-none').toggleClass('fa-spin');
|
||||||
|
$("div[id=invoices]").empty().append(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function balance() {
|
||||||
|
var alloc = 0;
|
||||||
|
|
||||||
|
$('input[id^=invoices_]').each(function() {
|
||||||
|
alloc += parseFloat($(this).val());
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#balance').val(($('#total_amt').val()-alloc).toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
if ($('#account_id').val()) {
|
||||||
|
var spinner = $('#account_id').parent().parent().find('i.fas.fa-spinner');
|
||||||
|
|
||||||
|
populate($('#account_id').val(),spinner);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#account_id').select2({
|
||||||
|
sorter: data => data.sort((a, b) => a.text.localeCompare(b.text)),
|
||||||
|
})
|
||||||
|
.on('change',function(e) {
|
||||||
|
if (! $(this).val()) {
|
||||||
|
$("div[id=invoices]").empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var spinner = $(this).parent().parent().find('i.fas.fa-spinner');
|
||||||
|
|
||||||
|
populate($(this).val(),spinner);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#total_amt').on('change',balance);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('change','input[id^=invoices_]',balance);
|
||||||
|
</script>
|
||||||
|
@append
|
@ -1,70 +0,0 @@
|
|||||||
<!-- $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>
|
|
@ -1,9 +1,10 @@
|
|||||||
<div class="form-group mb-0">
|
<!-- $o=Account::class -->
|
||||||
<label for="checkout_id">Invoices Due</label>
|
<div>
|
||||||
|
<label>Invoices Due</label>
|
||||||
@if(($x=$o->invoices()
|
@if(($x=$o->invoices()
|
||||||
->where('active',TRUE)
|
->active()
|
||||||
->orderBy('due_at')
|
->orderBy('due_at')
|
||||||
->with(['items.taxes','payment_items.payment','account'])
|
->with(['items.taxes','payments','account'])
|
||||||
->get()
|
->get()
|
||||||
->filter(function($item) use ($pid) { return $item->due > 0 || $item->payments->search(function($item) use ($pid) { return $item->id == $pid; }) !== FALSE; }))->count())
|
->filter(function($item) use ($pid) { return $item->due > 0 || $item->payments->search(function($item) use ($pid) { return $item->id == $pid; }) !== FALSE; }))->count())
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
@ -27,7 +28,7 @@
|
|||||||
<td>{{ number_format($io->total,2) }}</td>
|
<td>{{ number_format($io->total,2) }}</td>
|
||||||
<td>{{ number_format($io->due,2) }}</td>
|
<td>{{ number_format($io->due,2) }}</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<input type="text" class="text-right invoice" name="invoices[{{ $io->id }}][id]" value="{{ number_format(($x=$io->payment_items->filter(function($item) use ($pid) { return $item->payment_id == $pid; })) ? $x->sum('amount') : 0,2) }}">
|
<x-leenooks::form.text class="text-right" id="invoices_{{$io->id}}" name="invoices[{{ $io->id }}]" icon="fa-dollar-sign" old="invoices.{{$io->id}}" :value="number_format(($x=$io->payment_items->filter(fn($item)=>$item->payment_id == $pid)) ? $x->sum('amount') : 0,2)"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
@ -24,21 +24,21 @@
|
|||||||
|
|
||||||
@can('wholesaler')
|
@can('wholesaler')
|
||||||
<!-- PAYMENTS -->
|
<!-- PAYMENTS -->
|
||||||
<li @class(['nav-item','has-treeview','menu-open'=>$x=preg_match('#^a/payment/#',$path),'menu-closed'=>! $x])>
|
<li @class(['nav-item','has-treeview','menu-open'=>$x=preg_match('#^r/payment/#',$path),'menu-closed'=>! $x])>
|
||||||
<a href="#" @class(['nav-link','active'=>preg_match('#^a/payment/#',$path)])>
|
<a href="#" @class(['nav-link','active'=>preg_match('#^r/payment/#',$path)])>
|
||||||
<i class="nav-icon fas fa-receipt"></i>
|
<i class="nav-icon fas fa-receipt"></i>
|
||||||
<p>Payments <i class="fas fa-angle-left right"></i></p>
|
<p>Payments <i class="fas fa-angle-left right"></i></p>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<ul class="nav nav-treeview">
|
<ul class="nav nav-treeview">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="{{ url('a/payment/addedit') }}" @class(['nav-link','active'=>$path === 'a/payment/addedit'])>
|
<a href="{{ url('r/payment/new') }}" @class(['nav-link','active'=>$path === 'r/payment/new'])>
|
||||||
<i class="fas fa-money-bill nav-icon"></i> <p>New Payment</p>
|
<i class="fas fa-money-bill nav-icon"></i> <p>New Payment</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="{{ url('a/payment/unapplied') }}" @class(['nav-link','active'=>$path === 'a/payment/unapplied'])>
|
<a href="{{ url('r/payment/unapplied') }}" @class(['nav-link','active'=>$path === 'r/payment/unapplied'])>
|
||||||
<i class="fas fa-receipt nav-icon"></i> <p>Unapplied</p>
|
<i class="fas fa-receipt nav-icon"></i> <p>Unapplied</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -64,7 +64,7 @@
|
|||||||
<!-- CHECKOUT (PAYMENTS) -->
|
<!-- CHECKOUT (PAYMENTS) -->
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="{{ url('a/checkout') }}" @class(['nav-link','active'=>preg_match('#^a/checkout#',$path)])>
|
<a href="{{ url('a/checkout') }}" @class(['nav-link','active'=>preg_match('#^a/checkout#',$path)])>
|
||||||
<i class="nav-icon fas fa-money-check-alt"></i> <p>Payments</p>
|
<i class="nav-icon fas fa-money-check-alt"></i> <p>Checkout</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
@ -24,13 +24,6 @@ Route::group(['middleware'=>['auth:api','role:wholesaler']], function() {
|
|||||||
Route::get('a/supplier_products',[ProductController::class,'api_supplier_products']);
|
Route::get('a/supplier_products',[ProductController::class,'api_supplier_products']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reseller API calls
|
|
||||||
Route::group(['middleware'=>['auth:api','role:reseller']], function() {
|
|
||||||
Route::post('r/invoices/{o}',[AdminController::class,'pay_invoices'])
|
|
||||||
->where('o','[0-9]+')
|
|
||||||
->middleware(['theme:adminlte-be','role:wholesaler']);
|
|
||||||
});
|
|
||||||
|
|
||||||
Route::group(['middleware'=>'auth:api'], function() {
|
Route::group(['middleware'=>'auth:api'], function() {
|
||||||
Route::post('/u/checkout/fee/{o}',[CheckoutController::class,'fee'])
|
Route::post('/u/checkout/fee/{o}',[CheckoutController::class,'fee'])
|
||||||
->where('o','[0-9]+');
|
->where('o','[0-9]+');
|
||||||
|
@ -12,6 +12,7 @@ use App\Http\Controllers\{AdminController,
|
|||||||
HomeController,
|
HomeController,
|
||||||
InvoiceController,
|
InvoiceController,
|
||||||
OrderController,
|
OrderController,
|
||||||
|
PaymentController,
|
||||||
PaypalController,
|
PaypalController,
|
||||||
ProductController,
|
ProductController,
|
||||||
SearchController,
|
SearchController,
|
||||||
@ -81,9 +82,11 @@ Route::group(['middleware'=>['auth','role:wholesaler'],'prefix'=>'a'],function()
|
|||||||
Route::post('setup',[AdminController::class,'setup']);
|
Route::post('setup',[AdminController::class,'setup']);
|
||||||
|
|
||||||
// Checkout Setup (Payments)
|
// Checkout Setup (Payments)
|
||||||
Route::get('checkout',[CheckoutController::class,'home']);
|
Route::model('co',\App\Models\Checkout::class);
|
||||||
Route::get('checkout/{o?}',[CheckoutController::class,'view'])
|
Route::view('checkout','theme.backend.adminlte.checkout.choose');
|
||||||
->where('o','[0-9]+');
|
Route::view('checkout/new','theme.backend.adminlte.checkout.view');
|
||||||
|
Route::view('checkout/{co}','theme.backend.adminlte.checkout.view')
|
||||||
|
->where('co','[0-9]+');
|
||||||
Route::post('checkout/{o?}',[CheckoutController::class,'addedit'])
|
Route::post('checkout/{o?}',[CheckoutController::class,'addedit'])
|
||||||
->where('o','[0-9]+');
|
->where('o','[0-9]+');
|
||||||
|
|
||||||
@ -121,10 +124,6 @@ Route::group(['middleware'=>['auth','role:wholesaler'],'prefix'=>'a'],function()
|
|||||||
Route::get('report/products',[ReportController::class,'products']);
|
Route::get('report/products',[ReportController::class,'products']);
|
||||||
Route::view('report/services','theme.backend.adminlte.service.report');
|
Route::view('report/services','theme.backend.adminlte.service.report');
|
||||||
|
|
||||||
// Payments - @todo This should probably go to resellers
|
|
||||||
Route::match(['get','post'],'payment/addedit/{o?}',[AdminController::class,'pay_addedit']);
|
|
||||||
Route::get('payment/unapplied',[AdminController::class,'pay_unapplied']);
|
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
// @todo This should probably go to resellers - implement a change audit log first
|
// @todo This should probably go to resellers - implement a change audit log first
|
||||||
Route::post('service/update/{o}',[ServiceController::class,'update'])
|
Route::post('service/update/{o}',[ServiceController::class,'update'])
|
||||||
@ -150,12 +149,23 @@ Route::group(['middleware'=>['auth','role:reseller'],'prefix'=>'r'],function() {
|
|||||||
Route::get('hosting',[ServiceController::class,'hosting_list']);
|
Route::get('hosting',[ServiceController::class,'hosting_list']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::post('account/invoices',[InvoiceController::class,'api_account_invoices']);
|
||||||
|
|
||||||
// Charges
|
// Charges
|
||||||
Route::post('charge/addedit',[ChargeController::class,'addedit']);
|
Route::post('charge/addedit',[ChargeController::class,'addedit']);
|
||||||
Route::post('charge/delete/{o}',[ChargeController::class,'delete'])
|
Route::post('charge/delete/{o}',[ChargeController::class,'delete'])
|
||||||
->where('o','[0-9]+');
|
->where('o','[0-9]+');
|
||||||
Route::post('charge/edit',[ChargeController::class,'edit']);
|
Route::post('charge/edit',[ChargeController::class,'edit']);
|
||||||
|
|
||||||
|
// Payments
|
||||||
|
Route::model('po',\App\Models\Payment::class);
|
||||||
|
Route::view('payment/new','theme.backend.adminlte.payment.view');
|
||||||
|
Route::view('payment/{po}','theme.backend.adminlte.payment.view')
|
||||||
|
->where('po','[0-9]+');
|
||||||
|
Route::post('payment/{o?}',[PaymentController::class,'addedit'])
|
||||||
|
->where('o','[0-9]+');
|
||||||
|
Route::view('payment/unapplied','theme.backend.adminlte.payment.unapplied');
|
||||||
|
|
||||||
// Reseller API calls
|
// Reseller API calls
|
||||||
Route::post('service_change_charges/{o}',[ServiceController::class,'service_change_charges_display'])
|
Route::post('service_change_charges/{o}',[ServiceController::class,'service_change_charges_display'])
|
||||||
->where('o','[0-9]+');
|
->where('o','[0-9]+');
|
||||||
@ -170,7 +180,7 @@ Route::group(['middleware'=>['auth'],'prefix'=>'u'],function() {
|
|||||||
Route::get('home/{o}',[HomeController::class,'home'])
|
Route::get('home/{o}',[HomeController::class,'home'])
|
||||||
->where('o','[0-9]+')
|
->where('o','[0-9]+')
|
||||||
->middleware('can:view,o');
|
->middleware('can:view,o');
|
||||||
Route::post('checkout/pay',[CheckoutController::class,'pay']);
|
Route::redirect('checkout/pay','pay/paypal/authorise');
|
||||||
Route::get('invoice/{o}',[InvoiceController::class,'view'])
|
Route::get('invoice/{o}',[InvoiceController::class,'view'])
|
||||||
->where('o','[0-9]+')
|
->where('o','[0-9]+')
|
||||||
->middleware('can:view,o');
|
->middleware('can:view,o');
|
||||||
|
Loading…
Reference in New Issue
Block a user