Code refactor work. New optimised query to get invoice status summary for an account
This commit is contained in:
@@ -2,14 +2,13 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Awobaz\Compoships\Compoships;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
use App\Models\Scopes\SiteScope;
|
||||
use App\Interfaces\IDs;
|
||||
use App\Traits\SiteID;
|
||||
|
||||
/**
|
||||
* Class Account
|
||||
@@ -20,12 +19,10 @@ use App\Traits\SiteID;
|
||||
* + sid : System ID for account
|
||||
* + name : Account Name
|
||||
* + taxes : Taxes Applicable to this account
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
class Account extends Model implements IDs
|
||||
{
|
||||
use Compoships,HasFactory,ScopeActive,SiteID;
|
||||
use HasFactory,ScopeActive;
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
@@ -41,13 +38,18 @@ class Account extends Model implements IDs
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
/**
|
||||
* Charges assigned to this account
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function charges()
|
||||
{
|
||||
return $this->hasMany(Charge::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the country the user belongs to
|
||||
* Country this account belongs to
|
||||
*/
|
||||
public function country()
|
||||
{
|
||||
@@ -65,28 +67,47 @@ class Account extends Model implements IDs
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* Invoices created for this account
|
||||
*
|
||||
* @todo This needs to be optimised, to only return outstanding invoices and invoices for a specific age (eg: 2 years worth)
|
||||
*/
|
||||
public function invoices()
|
||||
{
|
||||
return $this->hasMany(Invoice::class)
|
||||
->active()
|
||||
->with(['items.taxes','paymentitems.payment']);
|
||||
}
|
||||
|
||||
public function language()
|
||||
/**
|
||||
* Relation to only return active invoices
|
||||
*
|
||||
* @todo Only return active invoice_items
|
||||
*/
|
||||
public function invoices_active()
|
||||
{
|
||||
return $this->belongsTo(Language::class);
|
||||
return $this->invoices()
|
||||
->active();
|
||||
}
|
||||
|
||||
/**
|
||||
* Payments received and assigned to this account
|
||||
*/
|
||||
public function payments()
|
||||
{
|
||||
return $this->hasMany(Payment::class)
|
||||
->active()
|
||||
->with(['items']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Relation to only return active payments
|
||||
*
|
||||
* @todo Only return active payment_items
|
||||
*/
|
||||
public function payments_active()
|
||||
{
|
||||
return $this->payments()
|
||||
->active();
|
||||
}
|
||||
|
||||
public function providers()
|
||||
{
|
||||
return $this->belongsToMany(ProviderOauth::class,'account__provider')
|
||||
@@ -94,25 +115,33 @@ class Account extends Model implements IDs
|
||||
->withPivot('ref','synctoken','created_at','updated_at');
|
||||
}
|
||||
|
||||
public function services($active=FALSE)
|
||||
/**
|
||||
* Services assigned to this account
|
||||
*/
|
||||
public function services()
|
||||
{
|
||||
$query = $this->hasMany(Service::class,['account_id','site_id'],['id','site_id'])
|
||||
->withoutGlobalScope(SiteScope::class)
|
||||
return $this->hasMany(Service::class)
|
||||
->with(['product.translate','invoice_items']);
|
||||
|
||||
return $active ? $query->active() : $query;
|
||||
}
|
||||
|
||||
public function site()
|
||||
/**
|
||||
* Relation to only return active services
|
||||
*/
|
||||
public function services_active()
|
||||
{
|
||||
return $this->belongsTo(Site::class);
|
||||
return $this->services()
|
||||
->active();
|
||||
}
|
||||
|
||||
public function taxes()
|
||||
{
|
||||
return $this->hasMany(Tax::class,'country_id','country_id');
|
||||
return $this->hasMany(Tax::class,'country_id','country_id')
|
||||
->select(['id','zone','rate','country_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* User that owns this account
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
@@ -149,30 +178,27 @@ class Account extends Model implements IDs
|
||||
* Get the address for the account
|
||||
*
|
||||
* @return array
|
||||
* @todo Change this to return a collection
|
||||
*/
|
||||
public function getAddressAttribute(): array
|
||||
{
|
||||
return [
|
||||
$this->address1,
|
||||
$this->address2,
|
||||
sprintf('%s %s %s',$this->city.(($this->state OR $this->zip) ? ',' : ''),$this->state,$this->zip)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Account breadcrumb to render on pages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBreadcrumbAttribute(): array
|
||||
{
|
||||
return [$this->name => url('u/home',$this->user_id)];
|
||||
return collect([
|
||||
'address1' => $this->address1,
|
||||
'address2' => $this->address2,
|
||||
'location' => sprintf('%s %s %s',
|
||||
$this->city.(($this->state || $this->zip) ? ',' : ''),
|
||||
$this->state,
|
||||
$this->zip)
|
||||
])
|
||||
->filter()
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the account name
|
||||
*
|
||||
* @return mixed|string
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute(): string
|
||||
{
|
||||
@@ -184,7 +210,7 @@ class Account extends Model implements IDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTypeAttribute()
|
||||
public function getTypeAttribute(): string
|
||||
{
|
||||
return $this->company ? 'Business' : 'Private';
|
||||
}
|
||||
@@ -195,6 +221,7 @@ class Account extends Model implements IDs
|
||||
* Get the due invoices on an account
|
||||
*
|
||||
* @return mixed
|
||||
* @deprecated use invoiceSummary->filter(_balance > 0)
|
||||
*/
|
||||
public function dueInvoices()
|
||||
{
|
||||
@@ -203,6 +230,66 @@ class Account extends Model implements IDs
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* List of invoices (summary) for this account
|
||||
*
|
||||
* @param Collection|NULL $invoices
|
||||
* @return Collection
|
||||
*/
|
||||
public function invoiceSummary(Collection $invoices=NULL): Collection
|
||||
{
|
||||
return (new Invoice)
|
||||
->select([
|
||||
'invoice_id as id',
|
||||
DB::raw('SUM(item) AS _item'),
|
||||
DB::raw('SUM(tax) AS _tax'),
|
||||
DB::raw('SUM(payments) AS _payment'),
|
||||
DB::raw('SUM(discount) AS _discount'),
|
||||
DB::raw('SUM(item_total) AS _item_total'),
|
||||
DB::raw('SUM(payment_fees) AS _payment_fee'),
|
||||
DB::raw('ROUND(CAST(SUM(item_total)-SUM(COALESCE(discount,0))+COALESCE(invoices.discount_amt,0) AS NUMERIC),2) AS _total'),
|
||||
DB::raw('ROUND(CAST(SUM(item_total)-SUM(COALESCE(discount,0))+COALESCE(invoices.discount_amt,0)-SUM(payments) AS NUMERIC),2) AS _balance'),
|
||||
'due_at',
|
||||
])
|
||||
->from(
|
||||
(new Payment)
|
||||
->select([
|
||||
'invoice_id',
|
||||
DB::raw('0 as item'),
|
||||
DB::raw('0 as tax'),
|
||||
DB::raw('0 as discount'),
|
||||
DB::raw('0 as item_total'),
|
||||
DB::raw('SUM(amount) AS payments'),
|
||||
DB::raw('SUM(fees_amt) AS payment_fees'),
|
||||
])
|
||||
->join('payment_items',['payment_items.payment_id'=>'payments.id'])
|
||||
->where('payments.active',TRUE)
|
||||
->where('payment_items.active',TRUE)
|
||||
->groupBy(['payment_items.invoice_id'])
|
||||
->union(
|
||||
(new InvoiceItem)
|
||||
->select([
|
||||
'invoice_id',
|
||||
DB::raw('ROUND(CAST(SUM(quantity*price_base) AS NUMERIC),2) AS item'),
|
||||
DB::raw('ROUND(CAST(SUM(amount) AS NUMERIC),2) AS tax'),
|
||||
DB::raw('SUM(COALESCE(invoice_items.discount_amt,0)) AS discount'),
|
||||
DB::raw('ROUND(CAST(SUM(ROUND(CAST(quantity*price_base AS NUMERIC),2))+SUM(ROUND(CAST(amount AS NUMERIC),2))-SUM(COALESCE(invoice_items.discount_amt,0)) AS NUMERIC),2) AS item_total'),
|
||||
DB::raw('0 as payments'),
|
||||
DB::raw('0 as payment_fees'),
|
||||
])
|
||||
->leftjoin('invoice_item_taxes',['invoice_item_taxes.invoice_item_id'=>'invoice_items.id'])
|
||||
->rightjoin('invoices',['invoices.id'=>'invoice_items.invoice_id'])
|
||||
->where('invoice_items.active',TRUE)
|
||||
->where('invoices.active',TRUE)
|
||||
->groupBy(['invoice_items.invoice_id']),
|
||||
),'p')
|
||||
->join('invoices',['invoices.id'=>'invoice_id'])
|
||||
->where('account_id',$this->id)
|
||||
->groupBy(['p.invoice_id'])
|
||||
->groupBy(['due_at','discount_amt'])
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the taxed value of a value
|
||||
*
|
||||
|
Reference in New Issue
Block a user