Start of service display
This commit is contained in:
parent
a426c7b1a4
commit
6103b61265
@ -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;
|
||||
}
|
||||
}
|
@ -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]);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -57,7 +57,7 @@ class Product extends Model
|
||||
|
||||
private function getDefaultLanguage()
|
||||
{
|
||||
return config('SITE_SETUP')->language;
|
||||
return config('SITE_SETUP')->language();
|
||||
}
|
||||
|
||||
public function getDescriptionAttribute()
|
||||
|
@ -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('<span class="badge %s">%s</span>',$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[]
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -23,6 +23,9 @@ class Site extends Model
|
||||
|
||||
public function language()
|
||||
{
|
||||
if (! $this->id)
|
||||
return Language::find(1);
|
||||
|
||||
return $this->belongsTo(Language::class);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,46 @@
|
||||
<table class="table table-bordered w-100" id="invoices">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-right">#</th>
|
||||
<th class="text-right">Issued</th>
|
||||
<th class="text-right">Due</th>
|
||||
<th class="text-right">Total</th>
|
||||
<th class="text-right">Payments</th>
|
||||
<th class="text-right">Outstanding</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($o->invoices as $io)
|
||||
<tr>
|
||||
<td class="text-right"><a href="{{ url('u/invoice',$io->id) }}">{{ $io->id }}</a></td>
|
||||
<td class="text-right">{{ $io->date_orig->format('Y-m-d') }}</td>
|
||||
<td class="text-right">{{ $io->due_date->format('Y-m-d') }}</td>
|
||||
<td class="text-right">${{ number_format($io->total,2) }}</td>
|
||||
<td class="text-right">${{ number_format($io->paid,2) }}</td>
|
||||
<td class="text-right">${{ number_format($io->due,2) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@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')
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#invoices').DataTable( {
|
||||
responsive: true,
|
||||
order: [1, 'desc']
|
||||
});
|
||||
|
||||
$('#invoices tbody').on('click','tr', function () {
|
||||
$(this).toggleClass('selected');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@append
|
@ -0,0 +1,38 @@
|
||||
<div class="card card-primary card-outline">
|
||||
<div class="card-header">
|
||||
<strong>Service Information</strong>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<th>Account</th>
|
||||
<td>{{ $o->account->name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Active</th>
|
||||
<td>{!! $o->status_html !!}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Billing Period</th>
|
||||
<td>{{ $o->billing_period }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Billing Amount</th>
|
||||
<td>${{ number_format($o->billing_price,2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Invoiced To</th>
|
||||
<td>{{ $o->invoice_to ? $o->invoice_to->format('Y-m-d') : '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Next Invoice</th>
|
||||
<td>{{ $o->invoice_next ? $o->invoice_next->format('Y-m-d') : '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Current Invoices Due</th>
|
||||
<td>${{ number_format($o->invoices_due()->sum('due'),2) }} <small>({{ $o->invoices_due()->count() }})</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -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')
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Service Information</h3>
|
||||
<div class="card-header with-border">
|
||||
<h3 class="card-title">Service Information</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<div class="card-body">
|
||||
<div class="col-md-3">
|
||||
@switch($o->order_status)
|
||||
@case('ORDER-SUBMIT')
|
||||
|
129
resources/theme/backend/adminlte/u/service/adsl/ACTIVE.blade.php
Normal file
129
resources/theme/backend/adminlte/u/service/adsl/ACTIVE.blade.php
Normal file
@ -0,0 +1,129 @@
|
||||
@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')
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header p-2">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item"><a class="nav-link active" href="#tab-service" data-toggle="tab">Service</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#tab-invoice" data-toggle="tab">Invoices</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#tab-email" data-toggle="tab">Emails</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#tab-traffic" data-toggle="tab">Traffic</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="active tab-pane" id="tab-service">
|
||||
<div class="row">
|
||||
|
||||
<div class="card-group w-100">
|
||||
@include('common.service.widget.info')
|
||||
|
||||
<div class="card card-primary card-outline">
|
||||
<div class="card-header">
|
||||
<strong>Service Details</strong>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<th>Number</th>
|
||||
<td>{{ $o->type->service_number }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Address</th>
|
||||
<td>{{ $o->type->service_address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Connected</th>
|
||||
<td>{{ $o->type->service_connect_date->format('Y-m-d') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Contract</th>
|
||||
<td>{{ $o->type->contract_term }} mths <small>(until {{ $o->type->service_contract_date ? $o->type->service_contract_date->addMonths($o->type->contract_term)->format('Y-m-d') : 'N/A' }})</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<td>{{ $o->type->service_username }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Password</th>
|
||||
<td>{{ $o->type->service_password }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>IP Address</th>
|
||||
<td>{{ $o->type->ipaddress ? $o->type->ipaddress : 'Dynamic' }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary card-outline">
|
||||
<div class="card-header">
|
||||
<strong>DSL Details</strong>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<th>Speed</th>
|
||||
<td>TBA</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Peak Included Downloads</th>
|
||||
<td>TBA</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Traffic Last Month</th>
|
||||
<td>TBA</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Traffic This Month</th>
|
||||
<td>TBA</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Excess Traffic Charges to Bill</th>
|
||||
<td>TBA</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="tab-invoice">
|
||||
@include('common.invoice.widget.list')
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="tab-email">
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="tab-traffic">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@ -15,7 +15,10 @@
|
||||
<th>Account</th><td>{{ $o->account->company }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Active</th><td>{{ $o->active }} ({{ $o->order_status }})</td>
|
||||
<th>Active</th><td>{{ $o->active }} ({{ $o->order_status }}) [{{ $o->status }}]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Type</th><td>{{ $o->type->type }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Product</th><td>{{ $o->product->name }}: {{ $o->name }}</td>
|
||||
|
Loading…
Reference in New Issue
Block a user