diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 7b68709..9f9d300 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -102,20 +102,6 @@ class HomeController extends Controller return $this->invoice_pdf($o); } - /** - * Helper to redirect to the old site, when functions are not available in this one. - * - * @param $type - * @param $action - * @param $id - * @return void - * @deprecated @todo Remove once all functions added - */ - public function oldsite($type,$action,$id) - { - abort(307,sprintf('http://www.graytech.net.au/u/%s/%s/%s',$type,$action,$id)); - } - /** * Return details on the users service * diff --git a/app/Http/Controllers/UserServicesController.php b/app/Http/Controllers/UserServicesController.php deleted file mode 100644 index 4e1d9ee..0000000 --- a/app/Http/Controllers/UserServicesController.php +++ /dev/null @@ -1,13 +0,0 @@ -$o->services_active->values()]; - } -} \ No newline at end of file diff --git a/app/Interfaces/IDs.php b/app/Interfaces/IDs.php new file mode 100644 index 0000000..cd7dbe9 --- /dev/null +++ b/app/Interfaces/IDs.php @@ -0,0 +1,20 @@ +belongsTo(User::class); } - /** SCOPES */ - - /** - * Only query active categories - */ - public function scopeActive($query) - { - return $query->where('active',TRUE); - } + /* SCOPES */ /** * Search for a record @@ -118,7 +125,7 @@ class Account extends Model return $query; } - /** ATTRIBUTES **/ + /* ATTRIBUTES */ public function getActiveDisplayAttribute($value) { @@ -144,10 +151,21 @@ class Account extends Model /** * Return the Account Unique Identifier * @return string + * @deprecated use getSIDAttribute() */ public function getAIDAttribute() { - return sprintf('%02s-%04s',$this->site_id,$this->id); + return $this->getSIDAttribute(); + } + + /** + * Account Local ID + * + * @return string + */ + public function getLIDAttribute(): string + { + return sprintf('%04s',$this->id); } public function getNameAttribute() @@ -160,9 +178,19 @@ class Account extends Model return sprintf('%s /%s',$this->services()->noEagerLoads()->where('active',TRUE)->count(),$this->services()->noEagerLoads()->count()); } + /** + * Account System ID + * + * @return string + */ + public function getSIDAttribute(): string + { + return sprintf('%02s-%s',$this->site_id,$this->getLIDAttribute()); + } + public function getSwitchUrlAttribute() { - return sprintf('',$this->user_id); + return sprintf('',$this->user_id); } public function getTypeAttribute() diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index a89c4bb..be69de2 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -6,14 +6,35 @@ use Carbon\Carbon; use Clarkeash\Doorman\Facades\Doorman; use Clarkeash\Doorman\Models\Invite; use Illuminate\Database\Eloquent\Model; - -use App\Traits\NextKey; -use App\Traits\PushNew; use Illuminate\Support\Arr; +use Leenooks\Traits\ScopeActive; -class Invoice extends Model +use App\Interfaces\IDs; +use App\Traits\{NextKey,PushNew}; + +/** + * Class Invoice + * Invoices that belong to an Account + * + * Attributes for services: + * + due : Balance due on an invoice + * + due_date : Date the invoice is due + * + invoice_date : Date the invoice was created + * + lid : Local ID for invoice + * + paid : Total of payments received (excluding pending) + * + paid_date : Date the invoice was paid in full + * + paid_pending : Total of pending payments received + * + sid : System ID for invoice + * + total_sub : Invoice sub-total before taxes + * + total_tax : Invoices total of taxes + * + total : Invoice total + * + * @package App\Models + */ +class Invoice extends Model implements IDs { - use NextKey,PushNew; + use NextKey,PushNew,ScopeActive; + const RECORD_ID = 'invoice'; public $incrementing = FALSE; @@ -33,8 +54,12 @@ class Invoice extends Model 'paymentitems' ]; - private $_total = 0; - private $_total_tax = 0; + // Caching variables + private int $_paid = 0; + private int $_total = 0; + private int $_total_tax = 0; + + /* RELATIONS */ public function account() { @@ -43,7 +68,13 @@ class Invoice extends Model public function items() { - return $this->hasMany(InvoiceItem::class)->where('active',1); + return $this->hasMany(InvoiceItem::class) + ->where('active',TRUE); + } + + public function payments() + { + return $this->hasManyThrough(Payment::class,PaymentItem::class,NULL,'id',NULL,'payment_id'); } public function paymentitems() @@ -51,56 +82,114 @@ class Invoice extends Model return $this->hasMany(PaymentItem::class); } - /** SCOPES **/ + /* SCOPES */ /** * Search for a record * * @param $query * @param string $term - * @return + * @return mixed */ public function scopeSearch($query,string $term) { return $query->where('id','like','%'.$term.'%'); } - /** ATTRIBUTES **/ + /* ATTRIBUTES */ - public function getDueAttribute() + /** + * Balance due on an invoice + * @return string + */ + public function getDueAttribute(): float { - return sprintf('%3.'.$this->currency()->rounding.'f',$this->total - $this->paid); + return sprintf('%4.'.$this->currency()->rounding.'f',$this->total-$this->paid); } + /** + * @return mixed + * @deprecated use self::due_date; + */ public function getDateDueAttribute() { return $this->due_date->format('Y-m-d'); } - public function getInvoiceDateAttribute() + /** + * Date the invoices was created + * + * @return Carbon + */ + public function getInvoiceDateAttribute(): Carbon { - return $this->date_orig->format('Y-m-d'); + return $this->date_orig; } + /** + * Get account System ID + * @return string + * @deprecated use getSIDAttribute() + */ public function getInvoiceAccountIdAttribute() { - return sprintf('%02s-%04s-%06s',$this->site_id,$this->account_id,$this->invoice_id); + return $this->getSIDAttribute(); } + // @todo Move this to a site configuration public function getInvoiceTextAttribute() { return sprintf('Thank you for using %s for your Internet Services.',config('SITE_SETUP')->site_name); } - public function getPaidAttribute() + /** + * Invoice Local ID + * + * @return string + */ + public function getLIDAttribute(): string { - return $this->currency()->round( - $this->paymentitems - ->filter(function($item) { return ! $item->payment->pending_status; }) - ->sum('alloc_amt')); + return sprintf('%06s',$this->id); } - public function getPendingPaidAttribute() + /** + * Total of payments received for this invoice + * excluding pending payments + * + * @return float + */ + public function getPaidAttribute(): float + { + if (! $this->_paid) + $this->_paid = $this->currency()->round( + $this->paymentitems + ->filter(function($item) { return ! $item->payment->pending_status; }) + ->sum('alloc_amt')); + + return $this->_paid; + } + + /** + * Get the date that the invoice was paid in full. + * We assume the last payment received pays it in full. + * + * @return Carbon|null + */ + public function getPaidDateAttribute(): ?Carbon + { + $o = $this->payments + ->filter(function($item) { return ! $item->pending_status; }) + ->last(); + + return $o ? $o->date_payment : NULL; + } + + /** + * Total of pending payments received for this invoice + * + * @return mixed + */ + public function getPaidPendingAttribute(): float { return $this->currency()->round( $this->paymentitems @@ -108,35 +197,87 @@ class Invoice extends Model ->sum('alloc_amt')); } - public function getSubTotalAttribute() + /** + * Total of pending payments received for this invoice + * + * @return mixed + * @deprecated use getPaidPendingAttribute() + */ + public function getPendingPaidAttribute(): float + { + return $this->getPaidPendingAttribute(); + } + + /** + * Invoice System ID + * + * @return string + */ + public function getSIDAttribute(): string + { + return sprintf('%02s-%04s-%s',$this->site_id,$this->account_id,$this->getLIDAttribute()); + } + + /** + * Get invoice subtotal before taxes + * + * @return float + * @deprecated use getTotalSubAttribute() + */ + public function getSubTotalAttribute(): float + { + return $this->getTotalSubAttribute(); + } + + /** + * Get invoice subtotal before taxes + * + * @return float + */ + public function getTotalSubAttribute(): float { return sprintf('%3.'.$this->currency()->rounding.'f',$this->total-$this->tax_total); } - public function getTaxTotalAttribute() + /** + * Get the invoices taxes total + * + * @return float + * @deprecated use getTotalTaxAttribute(); + */ + public function getTaxTotalAttribute(): float + { + return $this->getTotalTaxAttribute(); + } + + /** + * Get the invoices taxes total + * + * @return float + */ + public function getTotalTaxAttribute(): float { if (! $this->_total_tax) - { - foreach ($this->items as $o) - { + foreach ($this->items as $o) { if ($o->active) $this->_total_tax += $this->currency()->round($o->tax); } - } return sprintf('%3.'.$this->currency()->rounding.'f',$this->_total_tax); } - public function getTotalAttribute() + /** + * Invoice total due + * + * @return string + */ + public function getTotalAttribute(): float { if (! $this->_total) - { - foreach ($this->items as $o) - { + foreach ($this->items as $o) { if ($o->active) $this->_total += $this->currency()->round($o->total); } - } return sprintf('%3.'.$this->currency()->rounding.'f',$this->_total); } diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 0e7bc46..f60280b 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -4,12 +4,25 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; -use App\Traits\PushNew; -use App\Traits\NextKey; +use App\Interfaces\IDs; +use App\Traits\{NextKey,PushNew}; -class Payment extends Model +/** + * Class Payment + * Payments that belong to an account + * + * Attributes for payments: + * + lid : Local ID for payment + * + payment_date : Date payment received + * + sid : System ID for payment + * + total : Payment total + * + * @package App\Models + */ +class Payment extends Model implements IDs { use NextKey,PushNew; + const RECORD_ID = 'payment'; public $incrementing = FALSE; @@ -24,6 +37,8 @@ class Payment extends Model // Array of items that can be updated with PushNew protected $pushable = ['items']; + /* RELATIONS */ + public function account() { return $this->belongsTo(Account::class); @@ -34,11 +49,37 @@ class Payment extends Model return $this->hasMany(PaymentItem::class); } + /* ATTRIBUTES */ + + /** + * @return mixed + * @deprecated use date_payment directly. + */ public function getDatePaidAttribute() { return $this->date_payment->format('Y-m-d'); } + /** + * Payment Local ID + * + * @return string + */ + public function getLIDattribute(): string + { + return sprintf('%06s',$this->id); + } + + /** + * Payment System ID + * + * @return string + */ + public function getSIDAttribute(): string + { + return sprintf('%02s-%04s#%s',$this->site_id,$this->account_id,$this->getLIDattribute()); + } + public function getTotalAttribute() { return sprintf('%3.'.$this->currency()->rounding.'f',$this->total_amt); diff --git a/app/Models/Product.php b/app/Models/Product.php index 0d14b0a..7280cf0 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -4,12 +4,22 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; +use App\Interfaces\IDs; use App\Traits\NextKey; -use Illuminate\Support\Facades\Log; -class Product extends Model +/** + * Class Product + * Products that are available to sale, and appear on invoices + * + * Attributes for products: + * + lid : Local ID for product (part number) + * + * @package App\Models + */ +class Product extends Model implements IDs { use NextKey; const RECORD_ID = 'product'; @@ -97,6 +107,16 @@ class Product extends Model return $this->description($this->getDefaultLanguage()); } + /** + * Product Local ID + * + * @return string + */ + public function getLIDattribute(): string + { + return sprintf('%04s',$this->id); + } + public function getMinimumCostAttribute() { $table = [ @@ -165,6 +185,16 @@ class Product extends Model return Arr::get($this->price_array,sprintf('%s.1.price_setup',$this->price_recurr_default))*1.1; } + /** + * Product System ID + * + * @return string + */ + public function getSIDattribute(): string + { + return sprintf('%02s-%s',$this->site_id,$this->getLIDattribute()); + } + /** * Return if this product captures usage data * diff --git a/app/Models/Service.php b/app/Models/Service.php index 2fcb77b..824d73b 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -12,17 +12,30 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; +use Leenooks\Carbon; use Symfony\Component\HttpKernel\Exception\HttpException; -use Leenooks\Carbon; +use App\Interfaces\IDs; use App\Traits\NextKey; -class Service extends Model +/** + * Class Service + * Services that belong to an account + * + * Attributes for services: + * + name_short : Service Product short name, eg: phone number, domain name, certificate CN + * + sid : System ID for service + * + * @package App\Models + */ +class Service extends Model implements IDs { use NextKey; + const RECORD_ID = 'service'; public $incrementing = FALSE; + protected $table = 'ab_service'; const CREATED_AT = 'date_orig'; const UPDATED_AT = 'date_last'; @@ -51,8 +64,6 @@ class Service extends Model ]; public $dateFormat = 'U'; - protected $table = 'ab_service'; - protected $visible = [ 'account_name', 'admin_service_id_url', @@ -268,6 +279,7 @@ class Service extends Model ->where('item_type','=',0) ->orderBy('date_start'); + // @todo Change to $query->active(); if ($active) $query->where('active','=',TRUE); @@ -344,7 +356,7 @@ class Service extends Model public function scopeActive($query) { return $query->where(function () use ($query) { - $query->where('active',TRUE) + $query->where($this->getTable().'.active',TRUE) ->orWhereNotIn('order_status',$this->inactive_status); }); } @@ -358,7 +370,7 @@ class Service extends Model public function scopeInActive($query) { return $query->where(function () use ($query) { - $query->where('active',FALSE) + $query->where($this->getTable().'.active',FALSE) ->orWhereIn('order_status',$this->inactive_status); }); } @@ -391,6 +403,7 @@ class Service extends Model * Name of the account for this service * * @return mixed + * @deprecated use $this->>account->name directly */ public function getAccountNameAttribute(): string { @@ -409,6 +422,7 @@ class Service extends Model * Return the auto billing details * * @return mixed + * @deprecated use billing directly? */ public function getAutoPayAttribute() { @@ -454,6 +468,7 @@ class Service extends Model * Date the service expires, also represents when it is paid up to * * @return string + * @todo */ public function getExpiresAttribute(): string { @@ -613,6 +628,16 @@ class Service extends Model return $result; } + /** + * Service Local ID + * + * @return string + */ + public function getLIDattribute(): string + { + return sprintf('%05s',$this->id); + } + public function getNameAttribute(): string { return $this->product->name_short.': '.$this->getNameShortAttribute(); @@ -670,6 +695,7 @@ class Service extends Model /** * Get the Product's Category for this service * + * @deprecated use product->category directly */ public function getProductCategoryAttribute(): string { @@ -680,6 +706,7 @@ class Service extends Model * Get the Product's Short Name for the service * * @return string + * @deprecated use product->name directly */ public function getProductNameAttribute(): string { @@ -717,13 +744,13 @@ class Service extends Model } /** - * Services Unique Identifier + * Services System ID * * @return string */ public function getSIDAttribute(): string { - return sprintf('%02s-%04s.%05s',$this->site_id,$this->account_id,$this->id); + return sprintf('%02s-%04s.%s',$this->site_id,$this->account_id,$this->getLIDattribute()); } /** @@ -849,17 +876,19 @@ class Service extends Model /* SETTERS */ + // @todo is this required? public function setDateOrigAttribute($value) { $this->attributes['date_orig'] = $value->timestamp; } + // @todo is this required? public function setDateLastAttribute($value) { $this->attributes['date_last'] = $value->timestamp; } - /* FUNCTIONS */ + /* GENERAL METHODS */ // The action methods will return: NULL for no progress|FALSE for a failed status|next stage name. diff --git a/app/Models/Site.php b/app/Models/Site.php index 0c18083..649f950 100644 --- a/app/Models/Site.php +++ b/app/Models/Site.php @@ -87,9 +87,11 @@ class Site extends Model public function getSiteLogoAttribute() { - $return = $this->getSiteDetailValue('site_logo')->value; + //$return = $this->getSiteDetailValue('site_logo')->value; + // @todo Get from DB. + $return = 'site/1/gth-horseradishfont-full.png'; - return $return ? 'storage/'.$return : '/image/generic/150/20/fff'; + return $return ? '/storage/'.$return : '/image/generic/150/20/fff'; } private function getSiteDetailValue($key) diff --git a/app/Models/User.php b/app/Models/User.php index 7dd70f9..df0ec8f 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -121,7 +121,8 @@ class User extends Authenticatable */ public function invoices() { - return $this->hasManyThrough(Invoice::class,Account::class); + return $this->hasManyThrough(Invoice::class,Account::class) + ->active(); } /** @@ -141,7 +142,8 @@ class User extends Authenticatable */ public function services() { - return $this->hasManyThrough(Service::class,Account::class); + return $this->hasManyThrough(Service::class,Account::class) + ->active(); } /** @@ -241,20 +243,6 @@ class User extends Authenticatable ->reverse(); } - /** - * The users active services - * - * @return mixed - */ - public function getServicesActiveAttribute() - { - return $this->services - ->filter(function($item) - { - return $item->isActive(); - }); - } - public function getServicesCountHtmlAttribute() { return sprintf('%s /%s',$this->services->where('active',TRUE)->count(),$this->services->count()); @@ -523,7 +511,7 @@ class User extends Authenticatable DB::raw('ROUND(ab_invoice_item_tax.amount,2) AS tax'), ]) - ->join('ab_invoice_item_tax',['ab_invoice_item_tax.invoice_item_id'=>'ab_invoice_item.id']) + ->leftjoin('ab_invoice_item_tax',['ab_invoice_item_tax.invoice_item_id'=>'ab_invoice_item.id']) ->where('active',TRUE); } @@ -548,6 +536,7 @@ class User extends Authenticatable * Return an SQL query that will summarise invoices with payments * * @return \Illuminate\Database\Query\Builder + * @todo change this to just return outstanding invoices as a collection. */ public function query_invoice_summary() { diff --git a/composer.lock b/composer.lock index a0364d1..778a461 100644 --- a/composer.lock +++ b/composer.lock @@ -2884,11 +2884,11 @@ }, { "name": "leenooks/laravel", - "version": "9.0.3", + "version": "9.0.4", "source": { "type": "git", "url": "https://dev.leenooks.net/leenooks/laravel", - "reference": "d4824ecda5187d8e9a81d5395f3f70145dff1b8d" + "reference": "9798f6aa7dcf507e7ac7179fc348320e36aa160b" }, "require": { "creativeorange/gravatar": "^1.0", @@ -2925,7 +2925,7 @@ "laravel", "leenooks" ], - "time": "2021-06-28T02:50:28+00:00" + "time": "2021-06-29T06:38:19+00:00" }, { "name": "monolog/monolog", diff --git a/public/css/custom.css b/public/css/custom.css new file mode 100644 index 0000000..0109ecc --- /dev/null +++ b/public/css/custom.css @@ -0,0 +1,8 @@ +hr.d-print-block { + border-top: 2px solid #dee2e6; + padding-bottom: 20px; +} + +.table.table-striped tbody tr:last-child td { + border-bottom: 2px solid #dee2e6; +} \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/a/service/widget/internal.blade.php b/resources/views/theme/backend/adminlte/a/service/widgets/internal.blade.php similarity index 100% rename from resources/views/theme/backend/adminlte/a/service/widget/internal.blade.php rename to resources/views/theme/backend/adminlte/a/service/widgets/internal.blade.php diff --git a/resources/views/theme/backend/adminlte/common/account/widget/summary.blade.php b/resources/views/theme/backend/adminlte/common/account/widget/summary.blade.php index fbbbea7..980619d 100644 --- a/resources/views/theme/backend/adminlte/common/account/widget/summary.blade.php +++ b/resources/views/theme/backend/adminlte/common/account/widget/summary.blade.php @@ -1,7 +1,7 @@ -@if ($o->accounts->count() > 2) +@if ($o->accounts->count() > 1)
- +
Linked Accounts @@ -11,20 +11,20 @@
@endif -
+
- +
Active Services - {{ $o->services_active->count() }} /{{ $o->services->count() }} + {{ $o->services->count() }} /{{ $o->services->count() }}
- +
Account Balance @@ -35,7 +35,7 @@
- +
Invoices Due diff --git a/resources/views/theme/backend/adminlte/common/service/widget/active.blade.php b/resources/views/theme/backend/adminlte/common/service/widget/active.blade.php deleted file mode 100644 index 7c1b038..0000000 --- a/resources/views/theme/backend/adminlte/common/service/widget/active.blade.php +++ /dev/null @@ -1,80 +0,0 @@ -
-
-

Services

-
- -
- @if ($o->services_active->count()) - - - - - - - - - - {{-- --}} - - - - - - - - - -
IDCategoryServiceProductStatusNext InvoiceAmount
Count {{ $o->services_active->count() }} 
- - @else -

No services active

- @endif -
-
- -@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/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') - @js('//cdn.datatables.net/rowgroup/1.0.2/js/dataTables.rowGroup.min.js','dt-rowgroup-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/views/theme/backend/adminlte/r/account/widget/list.blade.php b/resources/views/theme/backend/adminlte/r/account/widgets/list.blade.php similarity index 84% rename from resources/views/theme/backend/adminlte/r/account/widget/list.blade.php rename to resources/views/theme/backend/adminlte/r/account/widgets/list.blade.php index 1897641..2e1bfcb 100644 --- a/resources/views/theme/backend/adminlte/r/account/widget/list.blade.php +++ b/resources/views/theme/backend/adminlte/r/account/widgets/list.blade.php @@ -1,11 +1,6 @@ -
+

Accounts

- -
- - -
@@ -19,6 +14,7 @@ Services + Count {{ $user->all_accounts()->count() }} @@ -26,6 +22,7 @@ + @else

No Accounts Active

@endif diff --git a/resources/views/theme/backend/adminlte/r/home.blade.php b/resources/views/theme/backend/adminlte/r/home.blade.php index 6dc9ddc..7e51647 100644 --- a/resources/views/theme/backend/adminlte/r/home.blade.php +++ b/resources/views/theme/backend/adminlte/r/home.blade.php @@ -21,122 +21,56 @@
-
+ -
-
-
-
-
- @include('common.service.widget.active') -
- -
- -
-
-

Outstanding Invoices

- -
- -
-
- -
- @include('widgets.invoice',[ - 'o'=>$o->query_invoice_summary()->whereIN('account_id',$o->accounts()->pluck('id')->toArray())->having('balance','>',0), - 'widget_invoice_name'=>'widget-invoice-outstanding' - ]) -
-
- - -
-
-

Invoices - Last 12 Months

- -
- -
-
- -
- @include('widgets.invoice',[ - 'o'=>$o->query_invoice_summary()->whereIN('account_id',$o->accounts()->pluck('id')->toArray())->where('due_date','>',now()->subYear()->timestamp)->having('balance','=',0), - 'widget_invoice_name'=>'widget-invoice-last' - ]) -
-
- - -
-
-

Payments - Last 12 Months

- -
- -
-
- -
- @include('widgets.payment',[ - 'o'=>$o->query_payment_summary()->whereIN('account_id',$o->accounts()->pluck('id')->toArray())->where('date_payment','>',now()->subYear()->timestamp)->with(['items']), - 'widget_payment_name'=>'widget-payment-last' - ]) -
-
-
+
+
+
+
+
+ @include('u.service.widgets.active')
-
-
-
-
- @include('r.account.widget.list') -
+
+ @include('u.invoice.widgets.due') -
- @include('r.service.widget.movement') - - -
-
-

Outstanding Invoices

- -
- -
-
- -
- @include('widgets.invoice',[ - 'o'=>$o->query_invoice_summary()->having('balance','>',0), - 'widget_invoice_name'=>'widget-invoice-outstanding-client' - ]) -
-
-
-{{-- - -
- @include('r.agents') -
-
- @include('r.clients') -
---}} + @include('u.invoice.widgets.list') + @include('u.payment.widgets.list')
-
+
+
+
+ @include('r.account.widgets.list') +
+ +
+ @include('r.service.widgets.movement') + + @include('r.invoice.widgets.due') +
+{{-- + +
+ @include('r.agents') +
+
+ @include('r.clients') +
+--}} +
+
+
diff --git a/resources/views/theme/backend/adminlte/r/invoice/widget/next.blade.php b/resources/views/theme/backend/adminlte/r/invoice/widget/next.blade.php deleted file mode 100644 index f1c0a8a..0000000 --- a/resources/views/theme/backend/adminlte/r/invoice/widget/next.blade.php +++ /dev/null @@ -1,30 +0,0 @@ - - - @foreach (($x=$o->next_invoice_items($future))->groupBy('product_id') as $id => $oo) - - - - - - @foreach ($oo->groupBy('service_id') as $ooo) - - - - - - @foreach ($ooo as $io) - - - - - - - @endforeach - @endforeach - @endforeach - - - - - -
{{ $oo->first()->product->name }}${{ number_format($oo->sum('total'),2) }}
{{ $ooo->first()->service->sid }}{{ $ooo->first()->service->sname }}: {{ $ooo->first()->service->sdesc }}
  {{ $io->item_type_name }}${{ number_format($io->total,2) }}
TOTAL${{ number_format($x->sum('total'),2) }}
\ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/r/invoice/widgets/due.blade.php b/resources/views/theme/backend/adminlte/r/invoice/widgets/due.blade.php new file mode 100644 index 0000000..1c7278a --- /dev/null +++ b/resources/views/theme/backend/adminlte/r/invoice/widgets/due.blade.php @@ -0,0 +1,70 @@ + +
+
+

Invoices Due

+
+ +
+ @if($o->query_invoice_summary()->having('balance','>',0)->count()) + + + + + + + + + + + + + + + @foreach ($o->query_invoice_summary()->having('balance','>',0)->get() as $oo) + due_date->isPast()) class="table-danger" @endif> + + + + + + + + + @endforeach + +
Account#IssuedDueTotalPaymentsOutstanding
{{ $oo->account->name }}{{ $oo->sid }}{{ $oo->date_orig->format('Y-m-d') }}{{ $oo->due_date->format('Y-m-d') }}${{ number_format($oo->total,2) }}${{ number_format($oo->paid,2) }}${{ number_format($oo->due,2) }}
+ + @else +

No invoice due

+ @endif +
+
+ +@section('page-scripts') + @css('//cdn.datatables.net/1.10.25/css/dataTables.bootstrap5.min.css','jq-dt-css','jquery') + @js('//cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js','jq-dt-js','jquery') + @js('//cdn.datatables.net/1.10.25/js/dataTables.bootstrap5.min.js','jq-dt-bs5-js','jq-dt-js') + @js('//cdn.datatables.net/rowgroup/1.1.3/js/dataTables.rowGroup.min.js','jq-dt-rowgroup-js','jq-dt-js') + @css('//cdn.datatables.net/rowgroup/1.1.3/css/rowGroup.bootstrap5.min.css','jq-dt-rowgroup-css','jq-dt-jss') + + +@append \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/r/service/widget/movement.blade.php b/resources/views/theme/backend/adminlte/r/service/widgets/movement.blade.php similarity index 57% rename from resources/views/theme/backend/adminlte/r/service/widget/movement.blade.php rename to resources/views/theme/backend/adminlte/r/service/widgets/movement.blade.php index c1b2a53..f69f97b 100644 --- a/resources/views/theme/backend/adminlte/r/service/widget/movement.blade.php +++ b/resources/views/theme/backend/adminlte/r/service/widgets/movement.blade.php @@ -1,17 +1,12 @@ -
+
-

Service Movements

- -
- - -
+

Service Movements

@if (($x=$user->client_service_movements())->count()) - +
@@ -21,10 +16,11 @@ + @foreach ($x as $o) - + @endforeach + @@ -59,19 +56,15 @@ @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/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') - @js('//cdn.datatables.net/rowgroup/1.0.2/js/dataTables.rowGroup.min.js','dt-rowgroup-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') + @css('//cdn.datatables.net/1.10.25/css/dataTables.bootstrap5.min.css','jq-dt-css','jquery') + @js('//cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js','jq-dt-js','jquery') + @js('//cdn.datatables.net/1.10.25/js/dataTables.bootstrap5.min.js','jq-dt-bs5-js','jq-dt-js') + @js('//cdn.datatables.net/rowgroup/1.1.3/js/dataTables.rowGroup.min.js','jq-dt-rowgroup-js','jq-dt-js') + @css('//cdn.datatables.net/rowgroup/1.1.3/css/rowGroup.bootstrap5.min.css','jq-dt-rowgroup-css','jq-dt-jss') -@append \ No newline at end of file +@endsection \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/u/invoice/widgets/due.blade.php b/resources/views/theme/backend/adminlte/u/invoice/widgets/due.blade.php new file mode 100644 index 0000000..69b0700 --- /dev/null +++ b/resources/views/theme/backend/adminlte/u/invoice/widgets/due.blade.php @@ -0,0 +1,70 @@ + +
+
+

Invoices Due

+
+ +
+ @if($o->invoices->where('due','>',0)->count()) +
IDProduct
{{ $o->id }}{{ $o->sid }} {{ $o->account->name }} {{ $o->name_short }} @@ -45,6 +41,7 @@
Count {{ $x->count() }}
+ + + + + + + + + + + + + + @foreach ($o->invoices->where('due','>',0) as $oo) + due_date->isPast()) class="table-danger" @endif> + + + + + + + + + @endforeach + +
Account#IssuedDueTotalPaymentsOutstanding
{{ $oo->account->name }}{{ $oo->sid }}{{ $oo->date_orig->format('Y-m-d') }}{{ $oo->due_date->format('Y-m-d') }}${{ number_format($oo->total,2) }}${{ number_format($oo->paid,2) }}${{ number_format($oo->due,2) }}
+ + @else +

No invoice due

+ @endif +
+
+ +@section('page-scripts') + @css('//cdn.datatables.net/1.10.25/css/dataTables.bootstrap5.min.css','jq-dt-css','jquery') + @js('//cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js','jq-dt-js','jquery') + @js('//cdn.datatables.net/1.10.25/js/dataTables.bootstrap5.min.js','jq-dt-bs5-js','jq-dt-js') + @js('//cdn.datatables.net/rowgroup/1.1.3/js/dataTables.rowGroup.min.js','jq-dt-rowgroup-js','jq-dt-js') + @css('//cdn.datatables.net/rowgroup/1.1.3/css/rowGroup.bootstrap5.min.css','jq-dt-rowgroup-css','jq-dt-jss') + + +@append \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/u/invoice/widgets/list.blade.php b/resources/views/theme/backend/adminlte/u/invoice/widgets/list.blade.php new file mode 100644 index 0000000..bb3fc76 --- /dev/null +++ b/resources/views/theme/backend/adminlte/u/invoice/widgets/list.blade.php @@ -0,0 +1,68 @@ + +
+
+

Past Invoices

+
+ +
+ @if($o->invoices->where('date_orig','>',($x=\Carbon\Carbon::now()->subMonths(12)))->where('due','=',0)->count()) + + + + + + + + + + + + + + @foreach ($o->invoices->where('date_orig','>',$x)->where('due','=',0) as $oo) + + + + + + + + + @endforeach + +
Account#IssuedDuePaidTotal
{{ $oo->account->name }}{{ $oo->sid }}{{ $oo->date_orig->format('Y-m-d') }}{{ $oo->due_date->format('Y-m-d') }}{{ $oo->paid_date ? $oo->paid_date->format('Y-m-d') : '' }}${{ number_format($oo->total,2) }}
+ + @else +

No invoices to list

+ @endif +
+
+ +@section('page-scripts') + @css('//cdn.datatables.net/1.10.25/css/dataTables.bootstrap5.min.css','jq-dt-css','jquery') + @js('//cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js','jq-dt-js','jquery') + @js('//cdn.datatables.net/1.10.25/js/dataTables.bootstrap5.min.js','jq-dt-bs5-js','jq-dt-js') + @js('//cdn.datatables.net/rowgroup/1.1.3/js/dataTables.rowGroup.min.js','jq-dt-rowgroup-js','jq-dt-js') + @css('//cdn.datatables.net/rowgroup/1.1.3/css/rowGroup.bootstrap5.min.css','jq-dt-rowgroup-css','jq-dt-jss') + + +@append \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/u/invoice/widgets/next.blade.php b/resources/views/theme/backend/adminlte/u/invoice/widgets/next.blade.php new file mode 100644 index 0000000..3e6684b --- /dev/null +++ b/resources/views/theme/backend/adminlte/u/invoice/widgets/next.blade.php @@ -0,0 +1,40 @@ + +@if ($o->next_invoice_items($future)->count()) +
+
+ + + @foreach (($x=$o->next_invoice_items($future))->groupBy('product_id') as $id => $oo) + + + + + + @foreach ($oo->groupBy('service_id') as $ooo) + + + + + + @foreach ($ooo as $io) + + + + + + + @endforeach + @endforeach + @endforeach + + + + + +
{{ $oo->first()->product->name }}${{ number_format($oo->sum('total'),2) }}
{{ $ooo->first()->service->sid }}{{ $ooo->first()->service->sname }}: {{ $ooo->first()->service->sdesc }}
  {{ $io->item_type_name }}${{ number_format($io->total,2) }}
TOTAL${{ number_format($x->sum('total'),2) }}
+
+
+ +@else +

No items currently due to invoice.

+@endif \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/u/payment/widgets/list.blade.php b/resources/views/theme/backend/adminlte/u/payment/widgets/list.blade.php new file mode 100644 index 0000000..c4b0e1a --- /dev/null +++ b/resources/views/theme/backend/adminlte/u/payment/widgets/list.blade.php @@ -0,0 +1,73 @@ + +
+
+

Past Payments

+
+ +
+ @if($o->payments->where('date_orig','>',($x=\Carbon\Carbon::now()->subMonths(12)))->count()) + + + + + + + + {{----}} + + + + + + @foreach ($o->payments->where('date_orig','>',($x=\Carbon\Carbon::now()->subMonths(12))) as $oo) + + + + + + {{----}} + + + @endforeach + +
Account#ReceivedTotalBalanceInvoice(s)
{{ $oo->account->name }}{{ $oo->sid }}{{ $oo->date_payment->format('Y-m-d') }}${{ number_format($oo->total,2) }}${{ number_format($oo->balance,2) }} + {!! join(', ',$oo->items + ->filter(function($item) { return $item->invoice_id; }) + ->transform(function($item) { return sprintf('%s',url('u/invoice',$item->invoice_id),$item->invoice_id); }) + ->toArray()) !!} +
+ + @else +

No payments to list

+ @endif +
+
+ +@section('page-scripts') + @css('//cdn.datatables.net/1.10.25/css/dataTables.bootstrap5.min.css','jq-dt-css','jquery') + @js('//cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js','jq-dt-js','jquery') + @js('//cdn.datatables.net/1.10.25/js/dataTables.bootstrap5.min.js','jq-dt-bs5-js','jq-dt-js') + @js('//cdn.datatables.net/rowgroup/1.1.3/js/dataTables.rowGroup.min.js','jq-dt-rowgroup-js','jq-dt-js') + @css('//cdn.datatables.net/rowgroup/1.1.3/css/rowGroup.bootstrap5.min.css','jq-dt-rowgroup-css','jq-dt-jss') + + +@append \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/u/service/home.blade.php b/resources/views/theme/backend/adminlte/u/service/home.blade.php index d482f9d..7475ca0 100644 --- a/resources/views/theme/backend/adminlte/u/service/home.blade.php +++ b/resources/views/theme/backend/adminlte/u/service/home.blade.php @@ -88,7 +88,7 @@
@can('wholesaler')
- @include('a.service.widget.internal') + @include('a.service.widgets.internal')
@endcan
diff --git a/resources/views/theme/backend/adminlte/u/service/widgets/active.blade.php b/resources/views/theme/backend/adminlte/u/service/widgets/active.blade.php new file mode 100644 index 0000000..f8c8922 --- /dev/null +++ b/resources/views/theme/backend/adminlte/u/service/widgets/active.blade.php @@ -0,0 +1,79 @@ + +
+
+

Active Services

+
+ +
+ @if ($o->services->count()) + + + + + + + + + + + + + @foreach ($o->services as $oo) + + + + + + + + @endforeach + + + + + + + +
IDCategoryServiceProductNext Invoice
{{ $oo->sid }}{{ $oo->product_category }}{{ $oo->name_short }}{{ $oo->product_name }}{{ $oo->external_billing ? '-' : $oo->next_invoice->format('Y-m-d') }}
Count {{ $o->services->count() }} 
+ + @else +

No services active

+ @endif +
+
+ +@section('page-scripts') + @css('//cdn.datatables.net/1.10.25/css/dataTables.bootstrap5.min.css','jq-dt-css','jquery') + @js('//cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js','jq-dt-js','jquery') + @js('//cdn.datatables.net/1.10.25/js/dataTables.bootstrap5.min.js','jq-dt-bs5-js','jq-dt-js') + @js('//cdn.datatables.net/rowgroup/1.1.3/js/dataTables.rowGroup.min.js','jq-dt-rowgroup-js','jq-dt-js') + @css('//cdn.datatables.net/rowgroup/1.1.3/css/rowGroup.bootstrap5.min.css','jq-dt-rowgroup-css','jq-dt-jss') + + + + +@append \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/widgets/invoice.blade.php b/resources/views/theme/backend/adminlte/widgets/invoice.blade.php deleted file mode 100644 index f07c1aa..0000000 --- a/resources/views/theme/backend/adminlte/widgets/invoice.blade.php +++ /dev/null @@ -1,63 +0,0 @@ -@if(($x=$o->get())->count()) - - - - - - - - - - - - - - - @foreach ($x as $oo) - - - - - - - - - - @endforeach - -
Account#IssuedDueTotalPaymentsOutstanding
{{ $oo->account->name }}{{ $oo->id }}{{ $oo->date_orig->format('Y-m-d') }}{{ $oo->due_date->format('Y-m-d') }}${{ number_format($oo->invoice_total,2) }}${{ number_format($oo->payments,2) }}${{ number_format($oo->balance,2) }}
- -@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/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') - @js('/plugin/dataTables/dataTables.bootstrap4.js','dt-bootstrap4-js','jq-dt-js') - - -@append - -@else - No data to display -@endif \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/widgets/payment.blade.php b/resources/views/theme/backend/adminlte/widgets/payment.blade.php deleted file mode 100644 index 9987410..0000000 --- a/resources/views/theme/backend/adminlte/widgets/payment.blade.php +++ /dev/null @@ -1,53 +0,0 @@ -@if(($x=$o->get())->count()) - - - - - - - {{----}} - - - - - - @foreach ($x as $oo) - - - - - {{----}} - - - @endforeach - -
#ReceivedTotalBalanceInvoice(s)
{{ $oo->id }}{{ $oo->date_payment->format('Y-m-d') }}${{ number_format($oo->total_amt,2) }}${{ number_format($oo->balance,2) }}{!! join(',',$oo->items - ->filter(function($item) { return $item->invoice_id; }) - ->transform(function($item) { return sprintf('%s',url('u/invoice',$item->invoice_id),$item->invoice_id); }) - ->toArray()) !!}
- -@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/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') - @js('/plugin/dataTables/dataTables.bootstrap4.js','dt-bootstrap4-js','jq-dt-js') - - -@append - -@else - No data to display -@endif \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 860128b..29d1f50 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,6 +1,6 @@ get('/user', function (Request $request) { - return $request->user(); -}); -*/ - Route::group(['middleware'=>['auth:api','role:reseller']], function() { Route::get('/r/agents','ResellerServicesController@agents'); - Route::get('/r/accounts','ResellerServicesController@accounts'); + Route::get('/r/accounts',[ResellerServicesController::class,'accounts']); Route::get('/r/clients','ResellerServicesController@clients'); Route::get('/r/service_inactive','ResellerServicesController@service_inactive'); }); Route::group(['middleware'=>'auth:api'], function() { - Route::get('/u/services/{o}','UserServicesController@services') - ->where('o','[0-9]+') - ->middleware('can:view,o'); Route::post('/u/checkout/fee/{o}','CheckoutController@fee') ->where('o','[0-9]+'); }); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 03c7889..60a0364 100644 --- a/routes/web.php +++ b/routes/web.php @@ -54,24 +54,24 @@ Route::group(['middleware'=>['theme:adminlte-be','auth','role:reseller'],'prefix // Our User Routes Route::group(['middleware'=>['theme:adminlte-be','auth'],'prefix'=>'u'],function() { Route::get('home',[HomeController::class,'home']); - Route::get('home/{o}','UserHomeController@home') + Route::get('home/{o}',[HomeController::class,'home']) ->where('o','[0-9]+') ->middleware('can:view,o'); Route::get('account/{o}/invoice','User\AccountController@view_invoice_next') ->where('o','[0-9]+') ->middleware('can:view,o'); Route::post('checkout/pay','CheckoutController@pay'); - Route::get('invoice/{o}','UserHomeController@invoice') + Route::get('invoice/{o}',[HomeController::class,'invoice']) + ->where('o','[0-9]+') + ->middleware('can:view,o'); + Route::get('invoice/{o}/pdf',[HomeController::class,'invoice_pdf']) ->where('o','[0-9]+') ->middleware('can:view,o'); Route::get('invoice/cart','CheckoutController@cart_invoice'); Route::get('invoice/cart/{o}','CheckoutController@cart_invoice') ->where('o','[0-9]+') ->middleware('can:view,o'); - Route::get('invoice/{o}/pdf','UserHomeController@invoice_pdf') - ->where('o','[0-9]+') - ->middleware('can:view,o'); - Route::get('service/{o}','UserHomeController@service') + Route::get('service/{o}',[HomeController::class,'service']) ->where('o','[0-9]+') ->middleware('can:view,o'); Route::get('service/cancel/{o}','ServiceController@update') @@ -99,7 +99,6 @@ Route::group(['middleware'=>['theme:metronic-fe']],function() { Route::get('product_order/{o}','OrderController@product_order'); Route::get('product_info/{o}','OrderController@product_info'); Route::redirect('home','u/home'); -Route::get('u/{type}/{action}/{id}','UserHomeController@oldsite'); Route::get('search','SearchController@search');