Payment summary improvements, removed invoice/payment API calls

This commit is contained in:
Deon George 2020-07-21 17:41:24 +10:00
parent 444f2cf52d
commit c97835edd1
No known key found for this signature in database
GPG Key ID: 7670E8DC27415254
10 changed files with 132 additions and 185 deletions

View File

@ -7,16 +7,6 @@ use App\User;
class UserServicesController extends Controller class UserServicesController extends Controller
{ {
public function invoices(User $o)
{
return ['data'=>$o->invoices_due->values()];
}
public function payments(User $o)
{
return ['data'=>$o->payment_history->values()];
}
public function services(User $o) public function services(User $o)
{ {
return ['data'=>$o->services_active->values()]; return ['data'=>$o->services_active->values()];

View File

@ -27,21 +27,6 @@ class Invoice extends Model
// Array of items that can be updated with PushNew // Array of items that can be updated with PushNew
protected $pushable = ['items']; protected $pushable = ['items'];
protected $appends = [
'date_due',
'due',
'invoice_id_url',
'total',
];
protected $visible = [
'date_due',
'due',
'id',
'invoice_id_url',
'total',
];
protected $with = [ protected $with = [
'account.country.currency', 'account.country.currency',
'items.taxes', 'items.taxes',
@ -97,21 +82,11 @@ class Invoice extends Model
return $this->date_orig->format('Y-m-d'); return $this->date_orig->format('Y-m-d');
} }
public function getInvoiceIdAttribute()
{
return sprintf('%06s',$this->id);
}
public function getInvoiceAccountIdAttribute() public function getInvoiceAccountIdAttribute()
{ {
return sprintf('%02s-%04s-%06s',$this->site_id,$this->account_id,$this->invoice_id); return sprintf('%02s-%04s-%06s',$this->site_id,$this->account_id,$this->invoice_id);
} }
public function getInvoiceIdUrlAttribute()
{
return sprintf('<a href="/u/invoice/%s">%s</a>',$this->id,$this->invoice_account_id);
}
public function getInvoiceTextAttribute() public function getInvoiceTextAttribute()
{ {
return sprintf('Thank you for using %s for your Internet Services.',config('SITE_SETUP')->site_name); return sprintf('Thank you for using %s for your Internet Services.',config('SITE_SETUP')->site_name);

View File

@ -20,19 +20,6 @@ class Payment extends Model
protected $dateFormat = 'U'; protected $dateFormat = 'U';
protected $with = ['account.country.currency','items']; protected $with = ['account.country.currency','items'];
protected $appends = [
'date_paid',
'payment_id_url',
'total',
];
protected $visible = [
'date_paid',
'id',
'payment_id_url',
'total',
];
public function account() public function account()
{ {
return $this->belongsTo(Account::class); return $this->belongsTo(Account::class);
@ -48,16 +35,6 @@ class Payment extends Model
return $this->date_payment->format('Y-m-d'); return $this->date_payment->format('Y-m-d');
} }
public function getPaymentIdAttribute()
{
return sprintf('%02s-%04s+%05s',$this->site_id,$this->account_id,$this->id);
}
public function getPaymentIdUrlAttribute()
{
return sprintf('<a href="/u/payment/view/%s">%s</a>',$this->id,$this->payment_id);
}
public function getTotalAttribute() public function getTotalAttribute()
{ {
return sprintf('%3.'.$this->currency()->rounding.'f',$this->total_amt); return sprintf('%3.'.$this->currency()->rounding.'f',$this->total_amt);

View File

@ -614,6 +614,32 @@ class User extends Authenticatable
->from($summary,'summary'); ->from($summary,'summary');
} }
public function query_payment_summary()
{
$payment = (new Payment)
->select([
'payment_id',
DB::raw('SUM(allocate) AS allocate'),
])
->from($this->query_payment_items(),'PI')
//->where('ab_payment.active',TRUE) // @todo To implement
->groupBy(['payment_id']);
return (new Payment)
->select([
DB::raw('payment_id AS id'),
'date_orig',
'date_payment',
'total_amt',
//'fees_amt',
DB::raw('total_amt-allocate AS balance'),
])
->join('ab_payment',['ab_payment.id'=>'payment_id'])
->whereIN('account_id',$this->all_accounts()->pluck('id')->unique()->toArray())
->from($payment,'summary');
}
public function role() public function role()
{ {
// If I have agents and no parent, I am the wholesaler // If I have agents and no parent, I am the wholesaler

View File

@ -1,59 +0,0 @@
<div class="card card-primary card-outline">
<div class="card-header">
<h4 class="card-title">Invoice History</h4>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
<button type="button" class="btn btn-tool" data-widget="remove"><i class="fa fa-remove"></i></button>
</div>
</div>
<div class="card-body">
@if ($o->invoices->count())
<table class="table table-bordered table-striped table-hover" id="invoice_history" style="width: 100%;">
<thead>
<tr>
<th>ID</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
@foreach ($o->invoices as $io)
<tr>
<td><a href="{{ url ('u/invoice',$io->id) }}">{{ $io->id }}</a></td>
<td>{{ $io->due_date ? $io->due_date->format('Y-m-d') : '&nbsp;' }}</td>
<td class="text-right">{{ number_format($io->total,2) }}</td>
</tr>
@endforeach
</tbody>
</table>
@else
<p>No payments recorded</p>
@endif
</div>
</div>
@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('/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() {
$('#invoice_history').DataTable( {
responsive: true,
order: [1, 'desc']
});
$('#invoices tbody').on('click','tr', function () {
$(this).toggleClass('selected');
});
});
</script>
@append

View File

@ -1,59 +0,0 @@
<div class="card card-primary card-outline">
<div class="card-header">
<h4 class="card-title">Payment History</h4>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
<button type="button" class="btn btn-tool" data-widget="remove"><i class="fa fa-remove"></i></button>
</div>
</div>
<div class="card-body">
@if ($o->payment_history->count())
<table class="table table-bordered table-striped table-hover" id="payments" style="width: 100%;">
<thead>
<tr>
<th>ID</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
</table>
@else
<p>No payments recorded</p>
@endif
</div>
</div>
@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('/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() {
$('#payments').DataTable( {
responsive: true,
ajax: {
url: "/api/u/payments/{{ $o->id }}"
},
columns: [
{ data: "payment_id_url" },
{ data: "date_paid" },
{ data: "total" },
],
language: {
emptyTable: "No Payments On File"
},
order: [0, 'desc']
});
$('#payments tbody').on('click','tr', function () {
$(this).toggleClass('selected');
});
});
</script>
@append

View File

@ -56,7 +56,41 @@
</div> </div>
</div> </div>
@include('common.payment.widget.history') <!-- Show last 10 invoices -->
<div class="card card-warning card-outline">
<div class="card-header">
<h4 class="card-title">Invoices - Last 12 Months</h4>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-widget="collapse"><i class="fas fa-minus"></i></button>
</div>
</div>
<div class="card-body">
@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'
])
</div>
</div>
<!-- Show last 10 invoices -->
<div class="card card-warning card-outline">
<div class="card-header">
<h4 class="card-title">Payments - Last 12 Months</h4>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-widget="collapse"><i class="fas fa-minus"></i></button>
</div>
</div>
<div class="card-body">
@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'
])
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -69,13 +69,29 @@
<div class="card-body"> <div class="card-body">
@include('widgets.invoice',[ @include('widgets.invoice',[
'o'=>$o->query_invoice_summary()->whereIN('account_id',$o->accounts()->pluck('id')->toArray())->where('due_date','>',now()->subYear()->timestamp), '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' 'widget_invoice_name'=>'widget-invoice-last'
]) ])
</div> </div>
</div> </div>
@include('common.payment.widget.history') <!-- Show last 10 invoices -->
<div class="card card-warning card-outline">
<div class="card-header">
<h4 class="card-title">Payments - Last 12 Months</h4>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-widget="collapse"><i class="fas fa-minus"></i></button>
</div>
</div>
<div class="card-body">
@include('widgets.payment',[
'o'=>$o->query_payment_summary()->where('date_payment','>',now()->subYear()->timestamp)->with(['items']),
'widget_payment_name'=>'widget-payment-last'
])
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,53 @@
@if(($x=$o->get())->count())
<table class="table table-bordered w-100" id="{{ $widget_payment_name ?? 'widget-payment'}}">
<thead>
<tr>
<th class="text-right">#</th>
<th class="text-right">Received</th>
<th class="text-right">Total</th>
{{--<th class="text-right">Balance</th>--}}
<th>Invoice(s)</th>
</tr>
</thead>
<tbody>
@foreach ($x as $oo)
<tr>
<td class="text-right"><a href="{{ url('u/payment',$oo->id) }}">{{ $oo->id }}</a></td>
<td class="text-right">{{ $oo->date_orig->format('Y-m-d') }}</td>
<td class="text-right">${{ number_format($oo->total_amt,2) }}</td>
{{--<td class="text-right">${{ number_format($oo->balance,2) }}</td>--}}
<td>{!! join(',',$oo->items
->filter(function($item) { return $item->invoice_id; })
->transform(function($item) { return sprintf('<a href="%s">%s</a>',url('u/invoice',$item->invoice_id),$item->invoice_id); })
->toArray()) !!}</td>
</tr>
@endforeach
</tbody>
</table>
@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')
<script type="text/javascript">
$(document).ready(function() {
$('#{{ $widget_payment_name ?? 'widget-payment'}}').DataTable({
responsive: true,
order: [1, 'desc']
});
$('#{{ $widget_payment_name ?? 'widget-payment'}} tbody').on('click','tr', function () {
$(this).toggleClass('selected');
});
});
</script>
@append
@else
No data to display
@endif

View File

@ -27,12 +27,6 @@ Route::group(['middleware'=>['auth:api','role:reseller']], function() {
}); });
Route::group(['middleware'=>'auth:api'], function() { Route::group(['middleware'=>'auth:api'], function() {
Route::get('/u/invoices/{o}','UserServicesController@invoices')
->where('o','[0-9]+')
->middleware('can:view,o');;
Route::get('/u/payments/{o}','UserServicesController@payments')
->where('o','[0-9]+')
->middleware('can:view,o');;
Route::get('/u/services/{o}','UserServicesController@services') Route::get('/u/services/{o}','UserServicesController@services')
->where('o','[0-9]+') ->where('o','[0-9]+')
->middleware('can:view,o');; ->middleware('can:view,o');;