diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php
index 0d4c550..6fa5ee2 100644
--- a/app/Exceptions/Handler.php
+++ b/app/Exceptions/Handler.php
@@ -5,52 +5,64 @@ namespace App\Exceptions;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
+use Illuminate\Http\Request;
+use Illuminate\Http\Response;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
class Handler extends ExceptionHandler
{
- /**
- * A list of the exception types that are not reported.
- *
- * @var array
- */
- protected $dontReport = [
- //
- ];
+ /**
+ * A list of the exception types that are not reported.
+ *
+ * @var array
+ */
+ protected $dontReport = [
+ //
+ ];
- /**
- * A list of the inputs that are never flashed for validation exceptions.
- *
- * @var array
- */
- protected $dontFlash = [
- 'password',
- 'password_confirmation',
- ];
+ /**
+ * A list of the inputs that are never flashed for validation exceptions.
+ *
+ * @var array
+ */
+ protected $dontFlash = [
+ 'password',
+ 'password_confirmation',
+ ];
- /**
- * Report or log an exception.
- *
- * @param \Exception $exception
- * @return void
- */
- public function report(Exception $exception)
- {
- parent::report($exception);
- }
+ /**
+ * Report or log an exception.
+ *
+ * @param Exception $exception
+ * @return void
+ * @throws Exception
+ */
+ public function report(Exception $exception)
+ {
+ parent::report($exception);
+ }
- /**
- * Render an exception into an HTTP response.
- *
- * @param \Illuminate\Http\Request $request
- * @param \Exception $exception
- * @return \Illuminate\Http\Response
- */
- public function render($request, Exception $exception)
- {
- // We'll render a 404 for any authorisation exceptions to hide the fact that the resource exists
- if ($exception instanceof AuthorizationException)
- abort(404,'Not here...');
+ /**
+ * Render an exception into an HTTP response.
+ *
+ * @param Request $request
+ * @param Exception $exception
+ * @return Response
+ * @throws Exception
+ */
+ public function render($request, Exception $exception)
+ {
+ // We'll render a 404 for any authorisation exceptions to hide the fact that the resource exists
+ if ($exception instanceof AuthorizationException) {
+ Log::error('Request not authorised',['user'=>Auth::user()->id,'request'=>$request->path()]);
- return parent::render($request, $exception);
- }
-}
+ if ($request->ajax())
+ return response()->json(['data'=>[]],200);
+ else
+ abort(404,'Not here...');
+ }
+
+ return parent::render($request, $exception);
+ }
+}
\ No newline at end of file
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index b5bd328..0ccdf39 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -6,6 +6,7 @@ use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
+use App\User;
use App\Models\{Account,Invoice,Service,Service\Adsl};
class SearchController extends Controller
@@ -23,17 +24,17 @@ class SearchController extends Controller
return [];
$result = collect();
- $accounts = Auth::user()->all_accounts()->pluck('id');
+ $accounts = ($x=Auth::user()->all_accounts())->pluck('id');
+ $users = $x->transform(function($item) { return $item->user;});
# Look for Account
- foreach (Account::Search($request->input('term'))
- ->whereIN('id',$accounts)
- ->orderBy('company')
- ->orderBy('last_name')
- ->orderBy('first_name')
+ foreach (User::Search($request->input('term'))
+ ->whereIN('id',$users->pluck('id'))
+ ->orderBy('lastname')
+ ->orderBy('firstname')
->limit(10)->get() as $o)
{
- $result->push(['label'=>sprintf('AC:%s %s',$o->aid,$o->name),'value'=>'/u/account/'.$o->id]);
+ $result->push(['label'=>sprintf('US:%s %s',$o->aid,$o->name),'value'=>'/u/home/'.$o->id]);
}
# Look for a Service
diff --git a/app/Http/Controllers/UserHomeController.php b/app/Http/Controllers/UserHomeController.php
index 936b5ba..9676863 100644
--- a/app/Http/Controllers/UserHomeController.php
+++ b/app/Http/Controllers/UserHomeController.php
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
+use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;
@@ -19,22 +20,23 @@ class UserHomeController extends Controller
/**
* Logged in users home page
*
- * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ * @return Factory|View
*/
- public function home(): View
+ public function home(User $o=NULL): View
{
+ if (is_null($o))
+ $o = Auth::user();
+
switch (Auth::user()->role()) {
case 'customer':
- return View('u.home',['o'=>Auth::user()]);
+ return View('u.home',['o'=>$o]);
case 'reseller':
- return View('r.home',['o'=>Auth::user()]);
-
case 'wholesaler':
- return View('r.home',['o'=>Auth::user()]);
+ return View('r.home',['o'=>$o]);
default:
- abort(500,'Unknown role: '.Auth::user()->role());
+ abort(500,'Unknown role: '.$o->role());
}
}
@@ -83,20 +85,5 @@ class UserHomeController extends Controller
public function service(Service $o): View
{
return View('u.service',['o'=>$o]);
- foreach ([
- sprintf('u.service.%s.%s',$o->type->type,$o->status),
- sprintf('u.service.%s',$o->status),
- ] as $v)
- if (view()->exists($v))
- return View($v,['o'=>$o]);
-
- // View doesnt exist, fall back to default view
- return View('u.service',['o'=>$o]);
- }
-
- public function User(User $o)
- {
- // @todo Check authorised to see this account.
- return View('u.home',['o'=>$o]);
}
}
\ No newline at end of file
diff --git a/app/Http/Controllers/UserServicesController.php b/app/Http/Controllers/UserServicesController.php
index 52cc3d7..870fc52 100644
--- a/app/Http/Controllers/UserServicesController.php
+++ b/app/Http/Controllers/UserServicesController.php
@@ -2,22 +2,23 @@
namespace App\Http\Controllers;
-use Auth;
+use Illuminate\Support\Facades\Auth;
+use App\User;
class UserServicesController extends Controller
{
- public function invoices()
+ public function invoices(User $o)
{
- return ['data'=>Auth::user()->invoices_due->values()];
+ return ['data'=>$o->invoices_due->values()];
}
- public function payments()
+ public function payments(User $o)
{
- return ['data'=>Auth::user()->payment_history->values()];
+ return ['data'=>$o->payment_history->values()];
}
- public function services()
+ public function services(User $o)
{
- return ['data'=>Auth::user()->services_active->values()];
+ return ['data'=>$o->services_active->values()];
}
}
\ No newline at end of file
diff --git a/app/Models/Policies/AccountPolicy.php b/app/Models/Policies/AccountPolicy.php
index 1f26c48..ab2bb94 100644
--- a/app/Models/Policies/AccountPolicy.php
+++ b/app/Models/Policies/AccountPolicy.php
@@ -14,8 +14,8 @@ class AccountPolicy
/**
* Determine whether the user can view the service.
*
- * @param \App\User $user
- * @param Account $o
+ * @param User $user
+ * @param Account $o
* @return mixed
*/
public function view(User $user, Account $o)
@@ -33,7 +33,7 @@ class AccountPolicy
/**
* Determine whether the user can create services.
*
- * @param \App\User $user
+ * @param User $user
* @return mixed
*/
public function create(User $user)
@@ -44,8 +44,8 @@ class AccountPolicy
/**
* Determine whether the user can update the service.
*
- * @param \App\User $user
- * @param Account $o
+ * @param User $user
+ * @param Account $o
* @return mixed
*/
public function update(User $user, Account $o)
@@ -56,8 +56,8 @@ class AccountPolicy
/**
* Determine whether the user can delete the service.
*
- * @param \App\User $user
- * @param Account $o
+ * @param User $user
+ * @param Account $o
* @return mixed
*/
public function delete(User $user, Account $o)
@@ -68,8 +68,8 @@ class AccountPolicy
/**
* Determine whether the user can restore the service.
*
- * @param \App\User $user
- * @param Account $o
+ * @param User $user
+ * @param Account $o
* @return mixed
*/
public function restore(User $user, Account $o)
@@ -80,8 +80,8 @@ class AccountPolicy
/**
* Determine whether the user can permanently delete the service.
*
- * @param \App\User $user
- * @param Account $o
+ * @param User $user
+ * @param Account $o
* @return mixed
*/
public function forceDelete(User $user, Account $o)
diff --git a/app/Models/Product.php b/app/Models/Product.php
index 14a5485..e7d9721 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -186,12 +186,12 @@ class Product extends Model
* @param int $period
* @return mixed
*/
- public function price(int $period)
+ public function price(int $period,string $key='price_base')
{
return Arr::get(
$this->price_array,
- sprintf('%s.1.price_base',$period),
- Arr::get($this->price_array,sprintf('%s.0.price_base',$period))
+ sprintf('%s.1.%s',$period,$key),
+ Arr::get($this->price_array,sprintf('%s.0.%s',$period,$key))
);
}
diff --git a/app/Models/Service.php b/app/Models/Service.php
index 2cd7cfc..7eef306 100644
--- a/app/Models/Service.php
+++ b/app/Models/Service.php
@@ -522,6 +522,12 @@ class Service extends Model
return $this->product->name($this->account->language);
}
+ public function getRecurScheduleAttribute($value): int
+ {
+ // If recur_schedule not set, default to 2
+ return $value ?? 2;
+ }
+
/**
* @deprecated see getSIDAttribute()
*/
@@ -568,7 +574,7 @@ class Service extends Model
*/
public function getSDescAttribute(): string
{
- return $this->type->service_description;
+ return $this->type->service_description ?: 'Service Description NOT Defined for :'.$this->type->type;
}
/**
@@ -583,7 +589,7 @@ class Service extends Model
*/
public function getSNameAttribute(): string
{
- return $this->type->service_name;
+ return $this->type->service_name ?: 'Service Name NOT Defined for :'.$this->type->type;
}
/**
@@ -596,7 +602,7 @@ class Service extends Model
{
switch($this->product->model) {
case 'App\Models\Product\Adsl': return 'broadband';
- default: abort(500,'Product type not configured',['product'=>$this->product]);
+ default: return $this->type->type;
}
}
@@ -770,6 +776,23 @@ class Service extends Model
$result->push($o);
}
+ // If pending, add any connection charges
+ if ($this->isPending()) {
+ $o = new InvoiceItem;
+ $o->active = TRUE;
+ $o->service_id = $this->id;
+ $o->product_id = $this->product_id;
+ $o->item_type = 4;
+ $o->price_base = $this->price ?: $this->product->price($this->recur_schedule,'price_setup'); // @todo change to a method in this class
+ //$o->recurring_schedule = $this->recur_schedule;
+ $o->date_start = $this->invoice_next;
+ $o->date_stop = $this->invoice_next;
+ $o->quantity = 1;
+
+ $o->addTaxes();
+ $result->push($o);
+ }
+
// Add additional charges
foreach ($this->charges->filter(function($item) { return ! $item->processed; }) as $oo) {
$o = new InvoiceItem;
diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php
new file mode 100644
index 0000000..cc9a4fd
--- /dev/null
+++ b/app/Policies/UserPolicy.php
@@ -0,0 +1,90 @@
+id == $o->id)
+
+ // The user is the wholesaler
+ OR $user->isWholesaler()
+
+ // The user is the reseller
+ OR $user->all_accounts()->pluck('id')->search($o->id);
+ }
+
+ /**
+ * Determine whether the user can create services.
+ *
+ * @param User $user
+ * @return mixed
+ */
+ public function create(User $user)
+ {
+ //
+ }
+
+ /**
+ * Determine whether the user can update the service.
+ *
+ * @param User $user
+ * @param User $o
+ * @return mixed
+ */
+ public function update(User $user, User $o)
+ {
+ //
+ }
+
+ /**
+ * Determine whether the user can delete the service.
+ *
+ * @param User $user
+ * @param User $o
+ * @return mixed
+ */
+ public function delete(User $user, User $o)
+ {
+ //
+ }
+
+ /**
+ * Determine whether the user can restore the service.
+ *
+ * @param User $user
+ * @param User $o
+ * @return mixed
+ */
+ public function restore(User $user, User $o)
+ {
+ //
+ }
+
+ /**
+ * Determine whether the user can permanently delete the service.
+ *
+ * @param User $user
+ * @param User $o
+ * @return mixed
+ */
+ public function forceDelete(User $user, User $o)
+ {
+ //
+ }
+}
\ No newline at end of file
diff --git a/app/User.php b/app/User.php
index 926513b..970849e 100644
--- a/app/User.php
+++ b/app/User.php
@@ -104,7 +104,7 @@ class User extends Authenticatable
return $this->hasMany(static::class,'parent_id','id');
}
- /** Attributes **/
+ /** ATTRIBUTES **/
public function getActiveDisplayAttribute($value)
{
@@ -203,13 +203,50 @@ class User extends Authenticatable
$this->notify((new ResetPasswordNotification($token))->onQueue('high'));
}
- /** Scopes **/
+ /** SCOPES */
public function scopeActive()
{
return $this->where('active',TRUE);
}
+ /**
+ * Search for a record
+ *
+ * @param $query
+ * @param string $term
+ * @return
+ */
+ public function scopeSearch($query,string $term)
+ {
+ // Build our where clause
+ // First Name, Last name
+ if (preg_match('/\ /',$term)) {
+ list($fn,$ln) = explode(' ',$term,2);
+
+ $query->where(function($query1) use ($fn,$ln,$term) {
+ $query1->where(function($query2) use ($fn,$ln) {
+ return $query2
+ ->where('firstname','like','%'.$fn.'%')
+ ->where('lastname','like','%'.$ln.'%');
+ });
+ });
+
+ } elseif (is_numeric($term)) {
+ $query->where('id','like','%'.$term.'%');
+
+ } elseif (preg_match('/\@/',$term)) {
+ $query->where('email','like','%'.$term.'%');
+
+ } else {
+ $query
+ ->Where('firstname','like','%'.$term.'%')
+ ->orWhere('lastname','like','%'.$term.'%');
+ }
+
+ return $query;
+ }
+
/**
* Determine if the user is an admin of the account with $id
*
diff --git a/resources/theme/backend/adminlte/common/invoice/widget/due.blade.php b/resources/theme/backend/adminlte/common/invoice/widget/due.blade.php
index e1d5bee..cbfa480 100644
--- a/resources/theme/backend/adminlte/common/invoice/widget/due.blade.php
+++ b/resources/theme/backend/adminlte/common/invoice/widget/due.blade.php
@@ -4,7 +4,7 @@
- @if ($user->invoices_due->count())
+ @if ($o->invoices_due->count())
@@ -16,10 +16,10 @@
- Count {{ $user->invoices_due->count() }} |
+ Count {{ $o->invoices_due->count() }} |
{{-- @todo Number format should configured by currency --}}
- {{ number_format($user->invoices_due->sum('total'),2) }} |
- {{ number_format($user->invoices_due->sum('due'),2) }} |
+ {{ number_format($o->invoices_due->sum('total'),2) }} |
+ {{ number_format($o->invoices_due->sum('due'),2) }} |
|
@@ -31,8 +31,8 @@
@section('page-scripts')
- @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery');
- @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery');
+ @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery')
+ @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery')
@css('//cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css','dt-responsive-css','jq-dt-css')
@js('//cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js','dt-responsive-js','jq-dt-js')
@css('/plugin/dataTables/dataTables.bootstrap4.css','dt-bootstrap4-css','jq-dt-css')
@@ -43,7 +43,7 @@
$('#invoices').DataTable( {
responsive: true,
ajax: {
- url: "/api/u/invoices"
+ url: "/api/u/invoices/{{ $o->id }}"
},
columns: [
{ data: "invoice_id_url" },
diff --git a/resources/theme/backend/adminlte/common/invoice/widget/list.blade.php b/resources/theme/backend/adminlte/common/invoice/widget/list.blade.php
index fad6f39..2c0d5a5 100644
--- a/resources/theme/backend/adminlte/common/invoice/widget/list.blade.php
+++ b/resources/theme/backend/adminlte/common/invoice/widget/list.blade.php
@@ -24,8 +24,8 @@
@section('page-scripts')
- @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery');
- @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery');
+ @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery')
+ @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery')
@css('//cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css','jq-dt-r-css','jq-dt-css')
@js('//cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js','jq-dt-r-js','jq-dt-js')
@css('/plugin/dataTables/dataTables.bootstrap4.css','dt-bootstrap4-css','jq-dt-css')
diff --git a/resources/theme/backend/adminlte/common/payment/widget/history.blade.php b/resources/theme/backend/adminlte/common/payment/widget/history.blade.php
index 852e6a8..37c601a 100644
--- a/resources/theme/backend/adminlte/common/payment/widget/history.blade.php
+++ b/resources/theme/backend/adminlte/common/payment/widget/history.blade.php
@@ -9,7 +9,7 @@
- @if ($user->payment_history->count())
+ @if ($o->payment_history->count())
@@ -26,8 +26,8 @@
@section('page-scripts')
- @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery');
- @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery');
+ @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery')
+ @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery')
@css('//cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css','dt-responsive-css','jq-dt-css')
@js('//cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js','dt-responsive-js','jq-dt-js')
@css('/plugin/dataTables/dataTables.bootstrap4.css','dt-bootstrap4-css','jq-dt-css')
@@ -38,7 +38,7 @@
$('#payments').DataTable( {
responsive: true,
ajax: {
- url: "/api/u/payments"
+ url: "/api/u/payments/{{ $o->id }}"
},
columns: [
{ data: "payment_id_url" },
diff --git a/resources/theme/backend/adminlte/common/service/widget/active.blade.php b/resources/theme/backend/adminlte/common/service/widget/active.blade.php
index afcb6df..7c1b038 100644
--- a/resources/theme/backend/adminlte/common/service/widget/active.blade.php
+++ b/resources/theme/backend/adminlte/common/service/widget/active.blade.php
@@ -4,7 +4,7 @@
- @if ($user->services_active->count())
+ @if ($o->services_active->count())
@@ -20,7 +20,7 @@
- Count {{ $user->services_active->count() }} |
+ Count {{ $o->services_active->count() }} |
|
@@ -33,8 +33,8 @@
@section('page-scripts')
- @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery');
- @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery');
+ @css('//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery')
+ @js('//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery')
@css('//cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css','dt-responsive-css','jq-dt-css')
@js('//cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js','dt-responsive-js','jq-dt-js')
@css('//cdn.datatables.net/rowgroup/1.0.2/css/rowGroup.dataTables.min.css','dt-rowgroup-css','jq-dt-css')
@@ -47,7 +47,7 @@
$('#services').DataTable( {
responsive: true,
ajax: {
- url: "/api/u/services"
+ url: "/api/u/services/{{ $o->id }}"
},
columns: [
{ data: "service_id_url" },
diff --git a/resources/theme/backend/adminlte/u/service.blade.php b/resources/theme/backend/adminlte/u/service.blade.php
index e0f9c4b..cb3a94e 100644
--- a/resources/theme/backend/adminlte/u/service.blade.php
+++ b/resources/theme/backend/adminlte/u/service.blade.php
@@ -18,7 +18,7 @@
- @include('u.service.widgets.'.$o->stype.'.details',['o'=>$o->type])
+ @includeIf('u.service.widgets.'.$o->stype.'.details',['o'=>$o->type])
@include('u.service.widgets.information')
@@ -27,11 +27,15 @@