diff --git a/app/Http/Controllers/UserHomeController.php b/app/Http/Controllers/UserHomeController.php
index 97772b7..936b5ba 100644
--- a/app/Http/Controllers/UserHomeController.php
+++ b/app/Http/Controllers/UserHomeController.php
@@ -3,10 +3,11 @@
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
+use Illuminate\View\View;
+use Barryvdh\Snappy\Facades\SnappyPdf as PDF;
use App\Models\{Invoice,Service};
use App\User;
-use PDF;
class UserHomeController extends Controller
{
@@ -15,7 +16,12 @@ class UserHomeController extends Controller
$this->middleware('auth');
}
- public function home()
+ /**
+ * Logged in users home page
+ *
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ */
+ public function home(): View
{
switch (Auth::user()->role()) {
case 'customer':
@@ -32,11 +38,23 @@ class UserHomeController extends Controller
}
}
- public function invoice(Invoice $o)
+ /**
+ * Render a specific invoice for the user
+ *
+ * @param Invoice $o
+ * @return View
+ */
+ public function invoice(Invoice $o): View
{
return View('u.invoice',['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', ['o'=>$o])->stream(sprintf('%s.pdf',$o->invoice_account_id));
@@ -56,8 +74,15 @@ class UserHomeController extends Controller
abort(307,sprintf('http://www.graytech.net.au/u/%s/%s/%s',$type,$action,$id));
}
- public function service(Service $o)
+ /**
+ * Return details on the users service
+ *
+ * @param Service $o
+ * @return View
+ */
+ 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),
diff --git a/app/Interfaces/ServiceItem.php b/app/Interfaces/ServiceItem.php
new file mode 100644
index 0000000..d15897a
--- /dev/null
+++ b/app/Interfaces/ServiceItem.php
@@ -0,0 +1,20 @@
+'array',
@@ -91,17 +96,27 @@ class Service extends Model
/**
* Account the service belongs to
*
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ * @return BelongsTo
*/
public function account()
{
return $this->belongsTo(Account::class);
}
+ /**
+ * Return automatic billing details
+ *
+ * @return HasOne
+ */
+ public function billing()
+ {
+ return $this->hasOne(AccountBilling::class);
+ }
+
/**
* Return Charges associated with this Service
*
- * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ * @return HasMany
*/
public function charges()
{
@@ -146,10 +161,9 @@ class Service extends Model
/**
* Account that ordered the service
*
- * @todo changed to orderedby
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ * @return BelongsTo
*/
- public function orderby()
+ public function orderedby()
{
return $this->belongsTo(Account::class);
}
@@ -157,30 +171,23 @@ class Service extends Model
/**
* Product of the service
*
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ * @return BelongsTo
*/
public function product()
{
return $this->belongsTo(Product::class);
}
- /**
- * Tenant that the service belongs to
- *
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
- public function site()
- {
- return $this->belongsTo(Site::class);
- }
-
/**
* Return a child model with details of the service
*
- * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+ * @return MorphTo
*/
public function type()
{
+ if (! $this->model)
+ abort(500,'Missing Model in',['service'=>$this]);
+
return $this->morphTo(null,'model','id','service_id');
}
@@ -192,7 +199,8 @@ class Service extends Model
public function scopeActive($query)
{
return $query->where(function () use ($query) {
- $query->where('active',TRUE)->orWhereNotIn('order_status',$this->inactive_status);
+ $query->where('active',TRUE)
+ ->orWhereNotIn('order_status',$this->inactive_status);
});
}
@@ -205,7 +213,8 @@ class Service extends Model
public function scopeInActive($query)
{
return $query->where(function () use ($query) {
- $query->where('active',FALSE)->orWhereIn('order_status',$this->inactive_status);
+ $query->where('active',FALSE)
+ ->orWhereIn('order_status',$this->inactive_status);
});
}
@@ -251,6 +260,16 @@ class Service extends Model
return $this->getUrlAdminAttribute();
}
+ /**
+ * Return the auto billing details
+ *
+ * @return mixed
+ */
+ public function getAutoPayAttribute()
+ {
+ return $this->billing;
+ }
+
public function getBillingPriceAttribute(): float
{
// @todo Temporary for services that dont have recur_schedule set.
@@ -337,6 +356,7 @@ class Service extends Model
* EG:
* For ADSL, this would be the phone number,
* For Hosting, this would be the domain name, etc
+ * @deprecated
*/
public function getNameShortAttribute()
{
@@ -372,6 +392,25 @@ class Service extends Model
return $result;
}
+ /**
+ * Work out when this service has been paid to.
+ *
+ * @todo This might need to be optimised
+ */
+ public function getPaidToAttribute()
+ {
+ foreach ($this->invoices->reverse() as $o) {
+ if ($o->due == 0) {
+ return $o->items
+ ->filter(function($item) {
+ return $item->item_type === 0;
+ })
+ ->last()
+ ->date_stop;
+ }
+ }
+ }
+
/**
* Get the Product's Category for this service
*
@@ -392,9 +431,9 @@ class Service extends Model
}
/**
- * @deprecated see getServiceIdAttribute()
+ * @deprecated see getSIDAttribute()
*/
- public function getServiceIdAttribute()
+ public function getServiceIdAttribute(): string
{
return $this->getSIDAttribute();
}
@@ -425,6 +464,50 @@ class Service extends Model
return sprintf('%02s-%04s.%05s',$this->site_id,$this->account_id,$this->id);
}
+ /**
+ * Return the service description.
+ * For:
+ * + Broadband, this is the service address
+ * + Domains, blank
+ * + Hosting, blank
+ * + SSL, blank
+ *
+ * @return string
+ */
+ public function getSDescAttribute(): string
+ {
+ return $this->type->service_description;
+ }
+
+ /**
+ * Return the service name.
+ * For:
+ * + Broadband, this is the service number
+ * + Domains, this is the full domain name
+ * + Hosting, this is the full domain name
+ * + SSL, this is the DN
+ *
+ * @return string
+ */
+ public function getSNameAttribute(): string
+ {
+ return $this->type->service_name;
+ }
+
+ /**
+ * Return the service product type
+ * This is used for view specific details
+ *
+ * @return string
+ */
+ public function getSTypeAttribute(): string
+ {
+ switch($this->product->model) {
+ case 'App\Models\Product\Adsl': return 'broadband';
+ default: abort(500,'Product type not configured',['product'=>$this->product]);
+ }
+ }
+
/**
* Return the Service Status
*
@@ -545,6 +628,16 @@ class Service extends Model
return (! $this->external_billing) AND (! $this->suspend_billing) AND $this->getInvoiceNextAttribute()->lessThan(now()->addDays($days));
}
+ /**
+ * Identify if a service is being ordered
+ *
+ * @return bool
+ */
+ public function isPending(): bool
+ {
+ return ! $this->active AND ! in_array($this->order_status,$this->inactive_status);
+ }
+
public function next_invoice_items(): \Illuminate\Support\Collection
{
$result = collect();
diff --git a/app/Models/Service/Adsl.php b/app/Models/Service/Adsl.php
index b32198f..dca9b77 100644
--- a/app/Models/Service/Adsl.php
+++ b/app/Models/Service/Adsl.php
@@ -2,17 +2,35 @@
namespace App\Models\Service;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\MorphOne;
+
+use App\Interfaces\ServiceItem;
+use App\Models\Base\ServiceType;
+use App\Models\Service;
use App\Traits\NextKey;
-class Adsl extends \App\Models\Base\ServiceType
+class Adsl extends ServiceType implements ServiceItem
{
use NextKey;
-
const RECORD_ID = 'service__adsl';
// @todo column service_id can be removed.
protected $table = 'ab_service__adsl';
- protected $dates = ['service_connect_date','service_contract_date'];
+ protected $dates = [
+ 'service_connect_date',
+ 'service_contract_date'
+ ];
+
+ /**
+ * The service this belongs to
+ *
+ * @return BelongsTo|MorphOne
+ */
+ public function service()
+ {
+ return $this->belongsTo(Service::class);
+ }
/** SCOPES */
@@ -35,22 +53,41 @@ class Adsl extends \App\Models\Base\ServiceType
/** ATTRIBUTES **/
/**
- * @deprecated use getNameFullAttribute()
+ * @deprecated use $o->type()->service_name;
+ * @return mixed|string
*/
- public function getFullNameAttribute()
- {
- return $this->getNameFullAttribute();
- }
-
public function getNameAttribute()
{
return $this->service_number ?: $this->service_address;
}
- public function getNameFullAttribute()
+ /**
+ * Return the service address
+ *
+ * @return string
+ */
+ public function getServiceDescriptionAttribute(): string
{
- return ($this->service_number AND $this->service_address)
- ? sprintf('%s: %s',$this->service_number, $this->service_address)
- : $this->name;
+ return $this->service_address ?: 'NO Service Address';
+ }
+
+ /**
+ * Return the service number
+ *
+ * @return string
+ */
+ public function getServiceNameAttribute(): string
+ {
+ return $this->service_number ?: 'NO Service Number';
+ }
+
+ /**
+ * Is this service currently in a contract
+ *
+ * @return bool
+ */
+ public function inContract(): bool
+ {
+ return $this->service_contract_date AND $this->service_contract_date->addMonths($this->contract_term)->isFuture();
}
}
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/r/home.blade.php b/resources/theme/backend/adminlte/r/home.blade.php
index bf3b1d1..898028a 100644
--- a/resources/theme/backend/adminlte/r/home.blade.php
+++ b/resources/theme/backend/adminlte/r/home.blade.php
@@ -3,11 +3,11 @@
@section('htmlheader_title')
Reseller Home
@endsection
-
-@section('contentheader_title')
+@section('page_title')
{{ $o->full_name }}
@endsection
-@section('page_title')
+
+@section('contentheader_title')
{{ $o->full_name }}
@endsection
@section('contentheader_description')
@@ -59,9 +59,6 @@
@include('r.agents')
-
- @include('r.service_inactive')
-
@include('r.clients')
diff --git a/resources/theme/backend/adminlte/r/service_inactive.blade.php b/resources/theme/backend/adminlte/r/service_inactive.blade.php
deleted file mode 100644
index 44a91da..0000000
--- a/resources/theme/backend/adminlte/r/service_inactive.blade.php
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
- @if ($user->all_client_service_inactive()->count())
-
-
-
- ID |
- Account |
- Name |
- Status |
- Product |
-
-
-
-
- Count {{ $user->all_client_service_inactive()->count() }} |
- |
-
-
-
- @else
-
No Inactive Services
- @endif
-
-
-
-@section('page-scripts')
- @css('https://cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css')
- @css('https://cdn.datatables.net/rowgroup/1.0.2/css/rowGroup.dataTables.min.css')
- @js('https://cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js')
- @js('https://cdn.datatables.net/rowgroup/1.0.2/js/dataTables.rowGroup.min.js')
-
-
-
-@append
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/home.blade.php b/resources/theme/backend/adminlte/u/home.blade.php
index cf359f3..3de3c0d 100644
--- a/resources/theme/backend/adminlte/u/home.blade.php
+++ b/resources/theme/backend/adminlte/u/home.blade.php
@@ -3,11 +3,11 @@
@section('htmlheader_title')
Client Home
@endsection
-
-@section('contentheader_title')
+@section('page_title')
{{ $o->full_name }}
@endsection
-@section('page_title')
+
+@section('contentheader_title')
{{ $o->full_name }}
@endsection
@section('contentheader_description')
diff --git a/resources/theme/backend/adminlte/u/service.blade.php b/resources/theme/backend/adminlte/u/service.blade.php
index bb49010..e3c4636 100644
--- a/resources/theme/backend/adminlte/u/service.blade.php
+++ b/resources/theme/backend/adminlte/u/service.blade.php
@@ -1,38 +1,95 @@
@extends('adminlte::layouts.app')
@section('htmlheader_title')
- Service #{{ $o->id }}
+ {{ $o->sid }}
+@endsection
+@section('page_title')
+ {{ $o->sid }}
@endsection
@section('contentheader_title')
- Service #{{ $o->id }}
+ Service: {{ $o->sid }} NBN-50/20-100
@endsection
@section('contentheader_description')
- {{ $o->service_id }}
+ {{ $o->sname }}: {{ $o->sdesc }}
@endsection
@section('main-content')
-
-
-
+
+
+
+ @include('u.service.widgets.'.$o->stype.'.details',['o'=>$o->type])
+ @include('u.service.widgets.information')
+
-
-
- @switch($o->order_status)
- @case('ORDER-SUBMIT')
- @case('ORDER-SENT')
- @case('ORDER-HOLD')
- @case('ORDERED')
- @include('u.widgets.service.order.sent')
- @break
+
+
+
+
+
+
+
+ Traffic.
+
+
+ Product.
+
+
+ Invoice Next.
+
+
+ Invoices.
+
+
+ Email.
+
+
+
-@endsection
\ No newline at end of file
+@endsection
+
+@section('page-scripts')
+
+@append
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/service/adsl/ACTIVE.blade.php b/resources/theme/backend/adminlte/u/service/adsl/ACTIVE.blade.php
deleted file mode 100644
index 3f7e3c2..0000000
--- a/resources/theme/backend/adminlte/u/service/adsl/ACTIVE.blade.php
+++ /dev/null
@@ -1,152 +0,0 @@
-@extends('adminlte::layouts.app')
-
-@section('htmlheader_title')
- {{ $o->SID }}
-@endsection
-
-@section('contentheader_title')
- Service: {{ $o->SID }}
-@endsection
-@section('page_title')
- {{ $o->SID }}
-@endsection
-@section('contentheader_description')
- {{ $o->type->name_full }}
-@endsection
-
-@section('main-content')
-
-
-
-
-
-
-
-
-
-
-
-
- @include('common.service.widget.info')
-
-
-
-
-
-
-
- Number |
- {{ $o->type->service_number }} |
-
-
- Address |
- {{ $o->type->service_address }} |
-
-
- Connected |
- {{ $o->type->service_connect_date->format('Y-m-d') }} |
-
-
- Contract |
- {{ $o->type->contract_term }} mths (until {{ $o->type->service_contract_date ? $o->type->service_contract_date->addMonths($o->type->contract_term)->format('Y-m-d') : 'N/A' }}) |
-
-
- Username |
- {{ $o->type->service_username }} |
-
-
- Password |
- {{ $o->type->service_password }} |
-
-
- IP Address |
- {{ $o->type->ipaddress ? $o->type->ipaddress : 'Dynamic' }} |
-
-
-
-
-
-
-
-
-
-
-
- Speed |
- {{ $o->product->type->speed }} |
-
- @if ($o->product->type->base_down_peak)
-
- Peak Included Downloads |
- {{ number_format($o->product->type->base_down_peak,0) }}GB |
-
- @endif
- @if ($o->product->type->base_down_offpeak)
-
- Peak Included Downloads |
- {{ number_format($o->product->type->base_down_offpeak,0) }}MB |
-
- @endif
-
- Traffic Last Month |
- TBA |
-
-
- Traffic This Month |
- TBA |
-
-
- Excess Traffic Charges to Bill |
- TBA |
-
-
-
-
-
-
-
-
-
-
-
-
- @include('common.service.widget.invoice')
-
- {{-- @todo show list of outstanding invoices --}}
-
-
- {{-- Workaround since col-offset-x is not in our CSS? --}}
-
-
-
-
-
- @include('common.invoice.widget.list')
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-@endsection
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/service/widgets/broadband/details.blade.php b/resources/theme/backend/adminlte/u/service/widgets/broadband/details.blade.php
new file mode 100644
index 0000000..263c48f
--- /dev/null
+++ b/resources/theme/backend/adminlte/u/service/widgets/broadband/details.blade.php
@@ -0,0 +1,70 @@
+
+
+ @if($o->service->isPending())
+
+ @endif
+
+
+
+
+
+
+ Address |
+ {{ $o->service_description }} |
+
+
+ Service Number |
+ {{ $o->service_name }} |
+
+
+ Service Username |
+ {{ $o->service_username }} |
+
+
+ Service Password |
+ {{ $o->service_password }} |
+
+ @if($o->service_connect_date)
+
+ Connected |
+ {{ $o->service_connect_date->format('Y-m-d') }} |
+
+ @endif
+
+ @if(FALSE)
+
+ Speed |
+ {{ 'xxx/YY' }} Mbps |
+
+
+ Traffic |
+ {{ 'xxx' }} GB (YY GB used month) |
+
+ @endif
+
+ IP Address |
+ {{ $o->ipaddress ?: 'Dynamic' }} |
+
+ @if ($o->inContract())
+
+ Contract |
+ {{ $o->contract_term }} months ({{ ($x=$o->service_contract_date->addMonths($o->contract_term))->diffForHumans() }}) |
+
+
+ Contract End |
+ {{ $x->format('Y-m-d') }} |
+
+ @endif
+
+ Cancel Notice |
+ 1 month @if($o->inContract())(after {{ $o->service_contract_date->addMonths($o->contract_term-1)->format('Y-m-d') }})@endif |
+
+
+
+
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/service/widgets/information.blade.php b/resources/theme/backend/adminlte/u/service/widgets/information.blade.php
new file mode 100644
index 0000000..98f4aeb
--- /dev/null
+++ b/resources/theme/backend/adminlte/u/service/widgets/information.blade.php
@@ -0,0 +1,39 @@
+
+
+
+
+
+ Status |
+ {{ $o->status }} |
+
+ @if ($o->active)
+
+ Billed |
+ {{ $o->billing_period }} |
+
+
+ Invoiced To |
+ {{ $o->invoice_to->format('Y-m-d') }} |
+
+
+ Paid Until |
+ {{ $o->paid_to->format('Y-m-d') }} |
+
+
+ Next Invoice |
+ {{ $o->invoice_next->format('Y-m-d') }} |
+
+
+ Estimated Invoice |
+ ${{ number_format($o->billing_price,2) }} |
+
+ @endif
+
+ Payment Method |
+ @if ($o->autopay)Direct Debit @else Invoice @endif |
+
+
+
+
\ No newline at end of file