diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index 0ecd9cb..6c72a35 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -4,10 +4,8 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
-use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Facades\Log;
-use App\Models\{Account};
+use App\Models\{Account,Service\Adsl};
class SearchController extends Controller
{
@@ -26,7 +24,7 @@ class SearchController extends Controller
# Look for Account
foreach (Account::Search($request->input('term'))
- ->whereIN('id',$uo->all_clients()->pluck('id'))
+ ->whereIN('id',$uo->all_accounts()->pluck('id'))
->orderBy('company')
->orderBy('last_name')
->orderBy('first_name')
@@ -35,6 +33,15 @@ class SearchController extends Controller
$result->push(['label'=>sprintf('A:%s %s',$o->aid,$o->name),'value'=>'/u/account/'.$o->id]);
}
+ # Look for an ADSL/NBN Service
+ foreach (Adsl::Search($request->input('term'))
+ ->whereIN('account_id',$uo->all_accounts()->pluck('id'))
+ ->orderBy('service_number')
+ ->limit(10)->get() as $o)
+ {
+ $result->push(['label'=>sprintf('S:%s (%s)',$o->name,$o->service->sid),'value'=>'/u/service/'.$o->id]);
+ }
+
return $result;
}
}
\ No newline at end of file
diff --git a/app/Http/Controllers/UserHomeController.php b/app/Http/Controllers/UserHomeController.php
index 74df1f4..86929a2 100644
--- a/app/Http/Controllers/UserHomeController.php
+++ b/app/Http/Controllers/UserHomeController.php
@@ -57,6 +57,14 @@ class UserHomeController extends Controller
public function service(Service $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]);
}
diff --git a/app/Models/Account.php b/app/Models/Account.php
index 4aa5e72..b3c5be0 100644
--- a/app/Models/Account.php
+++ b/app/Models/Account.php
@@ -75,7 +75,8 @@ class Account extends Model
/**
* Search for a record
*
- * @param User $uo
+ * @param $query
+ * @param string $term
* @return
*/
public function scopeSearch($query,string $term)
diff --git a/app/Models/Base/ServiceType.php b/app/Models/Base/ServiceType.php
index 0fd2060..e5a998c 100644
--- a/app/Models/Base/ServiceType.php
+++ b/app/Models/Base/ServiceType.php
@@ -4,6 +4,8 @@ namespace App\Models\Base;
use Illuminate\Database\Eloquent\Model;
+use App\Models\Service;
+
abstract class ServiceType extends Model
{
public $timestamps = FALSE;
@@ -17,4 +19,28 @@ abstract class ServiceType extends Model
{
return $this->morphOne(Service::class,'type','model','id');
}
+
+ /** SCOPES */
+
+ /**
+ * Search for a record
+ *
+ * @param $query
+ * @param string $term
+ * @return
+ */
+ public function scopeSearch($query,string $term)
+ {
+ return $query
+ ->with(['service'])
+ ->join('ab_service','ab_service.id','=',$this->getTable().'.service_id')
+ ->Where('ab_service.id','like','%'.$term.'%');
+ }
+
+ /** ATTRIBUTES **/
+
+ public function getTypeAttribute()
+ {
+ return strtolower((new \ReflectionClass($this))->getShortName());
+ }
}
\ No newline at end of file
diff --git a/app/Models/Product.php b/app/Models/Product.php
index 5b7a071..8691356 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -57,7 +57,7 @@ class Product extends Model
private function getDefaultLanguage()
{
- return config('SITE_SETUP')->language;
+ return config('SITE_SETUP')->language();
}
public function getDescriptionAttribute()
diff --git a/app/Models/Service.php b/app/Models/Service.php
index e8a7caf..bbfd26c 100644
--- a/app/Models/Service.php
+++ b/app/Models/Service.php
@@ -2,6 +2,8 @@
namespace App\Models;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
@@ -95,6 +97,37 @@ class Service extends Model
return $this->belongsTo(Account::class);
}
+ public function invoice_items($active=TRUE)
+ {
+ $query = $this->hasMany(InvoiceItem::class)
+ ->orderBy('date_orig');
+
+ if ($active)
+ $query->where('active','=',TRUE);
+
+ return $query;
+ }
+
+ /**
+ * Invoices for this service
+ *
+ */
+ public function invoices($active=TRUE)
+ {
+ $query = $this->hasManyThrough(Invoice::class,InvoiceItem::class,NULL,'id',NULL,'invoice_id')
+ ->distinct('id')
+ ->where('ab_invoice.site_id','=',$this->site_id)
+ ->where('ab_invoice_item.site_id','=',$this->site_id)
+ ->orderBy('date_orig')
+ ->orderBy('due_date');
+
+ if ($active)
+ $query->where('ab_invoice_item.active','=',TRUE)
+ ->where('ab_invoice.active','=',TRUE);
+
+ return $query;
+ }
+
/**
* Account that ordered the service
*
@@ -105,16 +138,6 @@ class Service extends Model
return $this->belongsTo(Account::class);
}
- /**
- * Tenant that the service belongs to
- *
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
- public function site()
- {
- return $this->belongsTo(Site::class);
- }
-
/**
* Product of the service
*
@@ -125,6 +148,16 @@ class Service extends Model
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
*
@@ -180,6 +213,25 @@ class Service extends Model
return $this->getUrlAdminAttribute();
}
+ public function getBillingPriceAttribute(): float
+ {
+ if ($this->price)
+ return $this->addtax($this->price);
+
+ dd($this->product->price_group,$this);
+ return $this->cost;
+ }
+
+ /**
+ * Return the service billing period
+ *
+ * @return string
+ */
+ public function getBillingPeriodAttribute(): string
+ {
+ return Arr::get($this->product->PricePeriods(),$this->recur_schedule,'Unknown');
+ }
+
/**
* Date the service expires, also represents when it is paid up to
*
@@ -191,23 +243,24 @@ class Service extends Model
}
/**
- * Services Unique Identifier
+ * Return the date for the next invoice
*
- * @return string
+ * @todo This function negates the need for date_next_invoice
+ * @return null
*/
- public function getSIDAttribute(): string
+ public function getInvoiceNextAttribute(): Carbon
{
- return sprintf('%02s-%04s.%05s',$this->site_id,$this->account_id,$this->id);
+ $last = $this->getInvoiceToAttribute();
+
+ return $last ? $last->addDay() : now();
}
/**
- * Return the date for the next invoice
- *
- * @return null
+ * Get the date that the service has been invoiced to
*/
- public function getInvoiceNextAttribute()
+ public function getInvoiceToAttribute()
{
- return $this->date_next_invoice ? $this->date_next_invoice->format('Y-m-d') : NULL;
+ return $this->invoice_items->count() ? $this->invoice_items->last()->date_stop : NULL;
}
/**
@@ -294,6 +347,16 @@ class Service extends Model
return $this->getSIDAttribute();
}
+ /**
+ * Services Unique Identifier
+ *
+ * @return string
+ */
+ public function getSIDAttribute(): string
+ {
+ return sprintf('%02s-%04s.%05s',$this->site_id,$this->account_id,$this->id);
+ }
+
/**
* Return the Service Status
*
@@ -319,6 +382,24 @@ class Service extends Model
: '';
}
+ /**
+ * Return a HTML status box
+ *
+ * @return string
+ */
+ public function getStatusHTMLAttribute(): string
+ {
+ $class = NULL;
+ switch ($this->status)
+ {
+ case 'ACTIVE':
+ $class = 'badge-success';
+ break;
+ }
+
+ return sprintf('%s',$class,$this->status);
+ }
+
/**
* URL used by an admin to administer the record
*
@@ -353,6 +434,25 @@ class Service extends Model
/** FUNCTIONS **/
+ /**
+ * Add applicable tax to the cost
+ *
+ * @todo This needs to be calculated, not fixed at 1.1
+ * @param float $value
+ * @return float
+ */
+ public function addTax(float $value): float
+ {
+ return round($value*1.1,2);
+ }
+
+ public function invoices_due(): Collection
+ {
+ return $this->invoice_items->filter(function($item) {
+ return $item->invoice->due > 0;
+ });
+ }
+
/**
* Determine if a service is active. It is active, if active=1, or the order_status is not in inactive_status[]
*
diff --git a/app/Models/Service/Adsl.php b/app/Models/Service/Adsl.php
index 9ad4cf6..b32198f 100644
--- a/app/Models/Service/Adsl.php
+++ b/app/Models/Service/Adsl.php
@@ -12,16 +12,45 @@ class Adsl extends \App\Models\Base\ServiceType
// @todo column service_id can be removed.
protected $table = 'ab_service__adsl';
+ protected $dates = ['service_connect_date','service_contract_date'];
+ /** SCOPES */
+
+ /**
+ * Search for a record
+ *
+ * @param $query
+ * @param string $term
+ * @return
+ */
+ public function scopeSearch($query,string $term)
+ {
+ // Build our where clause
+ return parent::scopeSearch($query,$term)
+ ->orwhere('service_number','like','%'.$term.'%')
+ ->orWhere('service_address','like','%'.$term.'%')
+ ->orWhere('ipaddress','like','%'.$term.'%');
+ }
+
+ /** ATTRIBUTES **/
+
+ /**
+ * @deprecated use getNameFullAttribute()
+ */
public function getFullNameAttribute()
{
- return ($this->service_number AND $this->service_address)
- ? sprintf('%s: %s',$this->service_number, $this->service_address)
- : $this->name;
+ return $this->getNameFullAttribute();
}
public function getNameAttribute()
{
return $this->service_number ?: $this->service_address;
}
+
+ public function getNameFullAttribute()
+ {
+ return ($this->service_number AND $this->service_address)
+ ? sprintf('%s: %s',$this->service_number, $this->service_address)
+ : $this->name;
+ }
}
\ No newline at end of file
diff --git a/app/Models/Site.php b/app/Models/Site.php
index 975b406..20cdf00 100644
--- a/app/Models/Site.php
+++ b/app/Models/Site.php
@@ -23,6 +23,9 @@ class Site extends Model
public function language()
{
+ if (! $this->id)
+ return Language::find(1);
+
return $this->belongsTo(Language::class);
}
diff --git a/app/User.php b/app/User.php
index bcc1da5..cb8a5ab 100644
--- a/app/User.php
+++ b/app/User.php
@@ -225,6 +225,9 @@ class User extends Authenticatable
$result->push($o->accounts->where('active',TRUE));
}
+ // Include my accounts
+ $result->push($this->accounts);
+
return $result->flatten();
}
diff --git a/resources/theme/backend/adminlte/common/invoice/widget/list.blade.php b/resources/theme/backend/adminlte/common/invoice/widget/list.blade.php
new file mode 100644
index 0000000..ebfa1e3
--- /dev/null
+++ b/resources/theme/backend/adminlte/common/invoice/widget/list.blade.php
@@ -0,0 +1,46 @@
+
+
+
+ # |
+ Issued |
+ Due |
+ Total |
+ Payments |
+ Outstanding |
+
+
+
+ @foreach ($o->invoices as $io)
+
+ {{ $io->id }} |
+ {{ $io->date_orig->format('Y-m-d') }} |
+ {{ $io->due_date->format('Y-m-d') }} |
+ ${{ number_format($io->total,2) }} |
+ ${{ number_format($io->paid,2) }} |
+ ${{ number_format($io->due,2) }} |
+
+ @endforeach
+
+
+
+@section('page-scripts')
+ @css('https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css','jq-dt-css','jquery');
+ @js('https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js','jq-dt-js','jquery');
+ @css('https://cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css','jq-dt-r-css','jq-dt-css')
+ @js('https://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')
+ @js('/plugin/dataTables/dataTables.bootstrap4.js','dt-bootstrap4-js','jq-dt-js')
+
+
+@append
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/common/service/widget/info.blade.php b/resources/theme/backend/adminlte/common/service/widget/info.blade.php
new file mode 100644
index 0000000..a4a3736
--- /dev/null
+++ b/resources/theme/backend/adminlte/common/service/widget/info.blade.php
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ Account |
+ {{ $o->account->name }} |
+
+
+ Active |
+ {!! $o->status_html !!} |
+
+
+ Billing Period |
+ {{ $o->billing_period }} |
+
+
+ Billing Amount |
+ ${{ number_format($o->billing_price,2) }} |
+
+
+ Invoiced To |
+ {{ $o->invoice_to ? $o->invoice_to->format('Y-m-d') : '' }} |
+
+
+ Next Invoice |
+ {{ $o->invoice_next ? $o->invoice_next->format('Y-m-d') : '' }} |
+
+
+ Current Invoices Due |
+ ${{ number_format($o->invoices_due()->sum('due'),2) }} ({{ $o->invoices_due()->count() }}) |
+
+
+
+
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/service.blade.php b/resources/theme/backend/adminlte/u/service.blade.php
index 3f5cce0..bb49010 100644
--- a/resources/theme/backend/adminlte/u/service.blade.php
+++ b/resources/theme/backend/adminlte/u/service.blade.php
@@ -5,7 +5,7 @@
@endsection
@section('contentheader_title')
- Service #
+ Service #{{ $o->id }}
@endsection
@section('contentheader_description')
{{ $o->service_id }}
@@ -14,11 +14,11 @@
@section('main-content')