osb/app/Http/Controllers/AdminController.php
2022-02-01 16:45:35 +11:00

292 lines
8.7 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use App\Models\{Account,Charge,InvoiceItem,Payment,PaymentItem,Service,SiteDetail,Supplier,SupplierDetail};
/**
* The AdminController governs all routes that are prefixed with 'a/'.
*
* This is everything about the configuration of the application as a whole, or administration of a site.
*/
class AdminController extends Controller
{
// @todo Move to reseller
public function service(Service $o)
{
return View('a.service',['o'=>$o]);
}
// @todo Move to reseller
public function charge_addedit(Request $request,Charge $o)
{
if ($request->post()) {
$request->validate([
'account_id' => 'required|exists:accounts,id',
'charge_date' => 'required|date',
'service_id' => 'required|exists:ab_service,id',
'quantity' => 'required|numeric|not_in:0',
'amount' => 'required|numeric|min:0.01',
'sweep_type' => 'required|numeric|in:'.implode(',',array_keys(Charge::sweep)),
'type' => 'required|numeric|in:'.implode(',',array_keys(InvoiceItem::type)),
'taxable' => 'nullable|boolean',
'description' => 'nullable|string|max:128',
]);
if (! $o->exists) {
$o->site_id = config('site')->site_id;
$o->user_id = Auth::id();
$o->active = TRUE;
}
$o->forceFill($request->only(['account_id','charge_date','service_id','quantity','amount','sweep_type','type','taxable','description']));
$o->save();
return redirect()->back()
->with('success','Charge recorded: '.$o->id);
}
return view('a.charge.addedit')
->with('o',$o);
}
// @todo Move to reseller
public function charge_pending_account(Request $request,Account $o)
{
return view('a.charge.widgets.pending')
->with('list',$o->charges->where('active',TRUE)->where('processed',NULL)->except($request->exclude));
}
/**
* List unprocessed charges
*
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*/
// @todo Move to reseller
public function charge_unprocessed()
{
return view('a.charge.unprocessed');
}
/**
* 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',
'payment_date' => 'required|date',
'checkout_id' => 'required|exists:ab_checkout,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) use ($request) {
if (collect($value)->sum() > $request->post('total_amt'))
$fail('Allocation is greater than payment total.');
}],
'invoices.*.id' => 'nullable|exists:ab_invoice,id',
]);
if (! $o->exists) {
$o->forceFill($request->only(['account_id','payment_date','checkout_id','checkout_id','total_amt','fees_amt','source_id','pending','notes','ip']));
$o->site_id = config('site')->site_id;
$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) {
$oo->delete();
continue;
}
} else {
$oo = new PaymentItem;
$oo->invoice_id = $id;
}
$oo->alloc_amt = ($oo->invoice->due >= 0) && ($oo->invoice->due-$amount >= 0) ? $amount : 0;
$oo->site_id = config('site')->site_id;
$o->items()->save($oo);
}
return redirect()->back()
->with('success','Payment recorded: '.$o->id);
}
return view('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('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('a.payment.widgets.invoices')
->with('pid',$request->pid)
->with('o',$o);
}
/**
* Site up site wide suppliers, or a site's supplier details
*
* @note This method is protected by the routes
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*/
public function supplier()
{
return view('a.supplier');
}
/**
* Update a suppliers details
*
* @param Request $request
* @param Supplier $o
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
*/
public function supplier_addedit(Request $request,Supplier $o)
{
if ($request->post()) {
$validation = $request->validate([
'name' => 'required|string|min:2|max:255',
'active' => 'sometimes|accepted',
'address1' => 'required|string|min:2|max:255',
'address2' => 'nullable|string|min:2|max:255',
'city' => 'required|string|min:2|max:64',
'state' => 'required|string|min:2|max:32',
'postcode' => 'required|string|min:2|max:8',
'supplier_details.notes' => 'nullable|string|min:3',
'supplier_details.accounts' => 'nullable|email',
'supplier_details.support' => 'nullable|email',
'supplier_details.payments' => 'nullable|string|min:3',
]);
foreach (collect($validation)->except('supplier_details') as $key => $item)
$o->{$key} = $item;
$o->active = (bool)$request->active;
try {
$o->save();
} catch (\Exception $e) {
return redirect()->back()->withErrors($e->getMessage())->withInput();
}
$o->load(['detail']);
$oo = $o->detail ?: new SupplierDetail;
foreach (collect($validation)->get('supplier_details',[]) as $key => $item)
$oo->{$key} = $item;
$o->detail()->save($oo);
return redirect()->back()
->with('success','Supplier saved');
}
if (! $o->exists && $request->name)
$o = Supplier::where('name',$request->name)->with(['details'])->firstOrNew();
return view('a.supplierdetails')
->with('o',$o);
}
/**
* Site setup
*
* @note This method is protected by the routes
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
*/
public function setup(Request $request)
{
if ($request->post()) {
$validated = $request->validate([
'site_name' => 'required|string|min:2|max:255',
'site_email' => 'required|string|email|max:255',
'site_address1' => 'required|string|min:2|max:255',
'site_address2' => 'nullable|string|min:2|max:255',
'site_city' => 'required|string|min:2|max:64',
'site_state' => 'required|string|min:2|max:32',
'site_postcode' => 'required|string|min:2|max:8',
'site_description' => 'nullable|string|min:5',
'site_phone' => 'nullable|regex:/[0-9 ]+/|min:6|max:12',
'site_fax' => 'nullable|regex:/[0-9 ]+/|min:6|max:12',
'site_tax' => 'required|regex:/[0-9 ]+/|size:14',
'social' => 'nullable|array',
'top_menu' => 'nullable|array',
'site_logo' => 'nullable|image',
'email_logo' => 'nullable|image',
]);
$site = config('site');
// @todo - not currently rendered in the home page
$validated['social'] = [];
$validated['top_menu'] = [];
// Handle the images
foreach(['site_logo','email_logo'] as $key)
if (array_key_exists($key,$validated))
$validated[$key] = ($x=$validated[$key])->storeAs('site/'.$site->site_id,$x->getClientOriginalName(),'public');
foreach ($site->details as $oo)
if (array_key_exists($oo->key,$validated)) {
$oo->value = Arr::get($validated,$oo->key);
$oo->save();
unset($validated[$oo->key]);
}
// Left over values to be created.
foreach ($validated as $k=>$v) {
$oo = new SiteDetail;
$oo->key = $k;
$oo->value = $v ?: '';
$site->details()->save($oo);
}
return redirect()->back()
->with('success','Settings saved');
}
return view('a.setup');
}
}