Merge branch 'master' into title-subheading

This commit is contained in:
Cüneyt Şentürk
2023-07-19 14:43:19 +03:00
committed by GitHub
628 changed files with 65799 additions and 80258 deletions

View File

@@ -29,6 +29,35 @@ class Role extends LaratrustRole
*/
public $cloneable_relations = ['permissions'];
/**
* Scope to get all rows filtered, sorted and paginated.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param $sort
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeCollect($query, $sort = 'display_name')
{
$request = request();
$search = $request->get('search');
$limit = (int) $request->get('limit', setting('default.list_limit', '25'));
return $query->usingSearchString($search)->sortable($sort)->paginate($limit);
}
/**
* @inheritDoc
*
* @param Document $src
* @param boolean $child
*/
public function onCloning($src, $child = null)
{
$this->name = $src->name . '-' . Role::max('id') + 1;
}
/**
* Get the line actions.
*
@@ -71,33 +100,4 @@ class Role extends LaratrustRole
return $actions;
}
/**
* Scope to get all rows filtered, sorted and paginated.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param $sort
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeCollect($query, $sort = 'display_name')
{
$request = request();
$search = $request->get('search');
$limit = (int) $request->get('limit', setting('default.list_limit', '25'));
return $query->usingSearchString($search)->sortable($sort)->paginate($limit);
}
/**
* @inheritDoc
*
* @param Document $src
* @param boolean $child
*/
public function onCloning($src, $child = null)
{
$this->name = $src->name . '-' . Role::max('id') + 1;
}
}

View File

@@ -37,7 +37,11 @@ class User extends Authenticatable implements HasLocalePreference
* @var array
*/
protected $casts = [
'enabled' => 'boolean',
'enabled' => 'boolean',
'last_logged_in_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
/**
@@ -47,13 +51,6 @@ class User extends Authenticatable implements HasLocalePreference
*/
protected $hidden = ['password', 'remember_token'];
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['last_logged_in_at', 'created_at', 'updated_at', 'deleted_at'];
/**
* Sortable columns.
*
@@ -195,7 +192,7 @@ class User extends Authenticatable implements HasLocalePreference
/**
* Modules that use the sort parameter in CRUD operations cause an error,
* so this sort parameter set back to old value after the query is executed.
*
*
* for Custom Fields module
*/
$request_sort = $request->get('sort');
@@ -203,7 +200,8 @@ class User extends Authenticatable implements HasLocalePreference
$query->usingSearchString($search)->sortable($sort);
$request->merge(['sort' => $request_sort]);
$request->offsetUnset('direction');
// This line disabled because broken sortable issue.
//$request->offsetUnset('direction');
$limit = (int) $request->get('limit', setting('default.list_limit', '25'));
return $query->paginate($limit);
@@ -242,6 +240,33 @@ class User extends Authenticatable implements HasLocalePreference
return $query->wherePermissionIs('read-admin-panel');
}
/**
* Scope to only employees.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeIsEmployee($query)
{
return $query->whereHasRole('employee');
}
/**
* Scope to only users.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeIsNotEmployee($query)
{
return $query->wherePermissionIs('read-admin-panel');
}
public function scopeEmail($query, $email)
{
return $query->where('email', '=', $email);
}
/**
* Attach company_ids attribute to model.
*
@@ -286,6 +311,26 @@ class User extends Authenticatable implements HasLocalePreference
return (bool) $this->can('read-admin-panel');
}
/**
* Determine if user is a employee.
*
* @return bool
*/
public function isEmployee()
{
return (bool) $this->hasRole('employee');
}
/**
* Determine if user is not a employee.
*
* @return bool
*/
public function isNotEmployee()
{
return (bool) ! $this->hasRole('employee');
}
public function scopeSource($query, $source)
{
return $query->where($this->qualifyColumn('created_from'), $source);
@@ -333,13 +378,23 @@ class User extends Authenticatable implements HasLocalePreference
return $actions;
}
$actions[] = [
'title' => trans('general.show'),
'icon' => 'visibility',
'url' => route('users.show', $this->id),
'permission' => 'read-auth-users',
'attributes' => [
'id' => 'index-line-actions-show-user-' . $this->id,
],
];
$actions[] = [
'title' => trans('general.edit'),
'icon' => 'edit',
'url' => route('users.edit', $this->id),
'permission' => 'update-auth-users',
'attributes' => [
'id' => 'index-line-actions-show-user-' . $this->id,
'id' => 'index-line-actions-edit-user-' . $this->id,
],
];

View File

@@ -20,7 +20,7 @@ class UserInvitation extends Model
*
* @var string[]
*/
protected $fillable = ['user_id', 'token'];
protected $fillable = ['user_id', 'token', 'created_from', 'created_by'];
public function user()
{

View File

@@ -33,8 +33,9 @@ class Account extends Model
* @var array
*/
protected $casts = [
'opening_balance' => 'double',
'enabled' => 'boolean',
'opening_balance' => 'double',
'enabled' => 'boolean',
'deleted_at' => 'datetime',
];
/**
@@ -64,6 +65,11 @@ class Account extends Model
return $this->hasMany('App\Models\Banking\Transaction');
}
public function reconciliations()
{
return $this->hasMany('App\Models\Banking\Reconciliation');
}
public function scopeName($query, $name)
{
return $query->where('name', '=', $name);
@@ -96,7 +102,7 @@ class Account extends Model
*/
public function getTitleAttribute()
{
if ($this->currency->symbol) {
if (! empty($this->currency) && ! empty($this->currency->symbol)) {
return $this->name . ' (' . $this->currency->symbol . ')';
}

View File

@@ -11,8 +11,6 @@ class Reconciliation extends Model
protected $table = 'reconciliations';
protected $dates = ['deleted_at', 'started_at', 'ended_at'];
/**
* Attributes that should be mass-assignable.
*
@@ -26,9 +24,12 @@ class Reconciliation extends Model
* @var array
*/
protected $casts = [
'closing_balance' => 'double',
'reconciled' => 'boolean',
'transactions' => 'array',
'closing_balance' => 'double',
'reconciled' => 'boolean',
'transactions' => 'array',
'deleted_at' => 'datetime',
'started_at' => 'datetime',
'ended_at' => 'datetime',
];
/**
@@ -40,7 +41,7 @@ class Reconciliation extends Model
public function account()
{
return $this->belongsTo('App\Models\Banking\Account');
return $this->belongsTo('App\Models\Banking\Account')->withDefault(['name' => trans('general.na')]);
}
/**

View File

@@ -30,8 +30,6 @@ class Transaction extends Model
protected $table = 'transactions';
protected $dates = ['deleted_at', 'paid_at'];
/**
* Attributes that should be mass-assignable.
*
@@ -64,8 +62,10 @@ class Transaction extends Model
* @var array
*/
protected $casts = [
'amount' => 'double',
'currency_rate' => 'double',
'paid_at' => 'datetime',
'amount' => 'double',
'currency_rate' => 'double',
'deleted_at' => 'datetime',
];
/**
@@ -186,7 +186,10 @@ class Transaction extends Model
public function scopeIncomeRecurring(Builder $query): Builder
{
return $query->where($this->qualifyColumn('type'), '=', self::INCOME_RECURRING_TYPE);
return $query->where($this->qualifyColumn('type'), '=', self::INCOME_RECURRING_TYPE)
->whereHas('recurring', function (Builder $query) {
$query->whereNull('deleted_at');
});
}
public function scopeExpense(Builder $query): Builder
@@ -201,7 +204,10 @@ class Transaction extends Model
public function scopeExpenseRecurring(Builder $query): Builder
{
return $query->where($this->qualifyColumn('type'), '=', self::EXPENSE_RECURRING_TYPE);
return $query->where($this->qualifyColumn('type'), '=', self::EXPENSE_RECURRING_TYPE)
->whereHas('recurring', function (Builder $query) {
$query->whereNull('deleted_at');
});
}
public function scopeIsTransfer(Builder $query): Builder
@@ -298,6 +304,7 @@ class Transaction extends Model
$this->number = $this->getNextTransactionNumber($suffix);
$this->document_id = null;
$this->split_id = null;
unset($this->reconciled);
}
/**
@@ -312,7 +319,7 @@ class Transaction extends Model
// Convert amount if not same currency
if ($this->account->currency_code != $this->currency_code) {
$to_code = $this->account->currency_code;
$to_rate = config('money.' . $this->account->currency_code . '.rate');
$to_rate = config('money.currencies.' . $this->account->currency_code . '.rate');
$amount = $this->convertBetween($amount, $this->currency_code, $this->currency_rate, $to_code, $to_rate);
}

View File

@@ -27,6 +27,8 @@ class Company extends Eloquent implements Ownable
protected $table = 'companies';
//protected $with = ['settings'];
/**
* The accessors to append to the model's array form.
*
@@ -34,12 +36,11 @@ class Company extends Eloquent implements Ownable
*/
protected $appends = ['location'];
protected $dates = ['deleted_at'];
protected $fillable = ['domain', 'enabled', 'created_from', 'created_by'];
protected $casts = [
'enabled' => 'boolean',
'enabled' => 'boolean',
'deleted_at' => 'datetime',
];
public $allAttributes = [];
@@ -528,7 +529,7 @@ class Company extends Eloquent implements Ownable
$country = setting('company.country');
if ($country && in_array($country, trans('countries'))) {
if ($country && array_key_exists($country, trans('countries'))) {
$location[] = trans('countries.' . $country);
}
@@ -549,7 +550,7 @@ class Company extends Eloquent implements Ownable
'title' => trans('general.switch'),
'icon' => 'settings_ethernet',
'url' => route('companies.switch', $this->id),
'permission' => 'read-common-companies',
//'permission' => 'read-common-companies', remove this permission to allow switching to any company
'attributes' => [
'id' => 'index-line-actions-switch-company-' . $this->id,
],

View File

@@ -6,6 +6,7 @@ use App\Traits\Media;
use App\Abstracts\Model;
use App\Traits\Contacts;
use App\Traits\Currencies;
use App\Traits\Documents;
use App\Traits\Transactions;
use App\Scopes\Contact as Scope;
use App\Models\Document\Document;
@@ -15,10 +16,9 @@ use Bkwld\Cloner\Cloneable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Contact extends Model
{
use Cloneable, Contacts, Currencies, HasFactory, Media, Notifiable, Transactions;
use Cloneable, Contacts, Currencies, Documents, HasFactory, Media, Notifiable, Transactions;
public const CUSTOMER_TYPE = 'customer';
public const VENDOR_TYPE = 'vendor';
@@ -26,6 +26,13 @@ class Contact extends Model
protected $table = 'contacts';
/**
* The relationships that should always be loaded.
*
* @var array
*/
protected $with = ['media'];
/**
* The accessors to append to the model's array form.
*
@@ -59,15 +66,6 @@ class Contact extends Model
'created_by',
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'enabled' => 'boolean',
];
/**
* Sortable columns.
*
@@ -92,11 +90,31 @@ class Contact extends Model
return $this->hasMany('App\Models\Document\Document');
}
public function document_recurring()
{
return $this->documents()->whereIn('documents.type', $this->getRecurringDocumentTypes());
}
public function bills()
{
return $this->documents()->where('documents.type', Document::BILL_TYPE);
}
public function bill_recurring()
{
return $this->documents()->where('documents.type', Document::BILL_RECURRING_TYPE);
}
public function invoices()
{
return $this->documents()->where('documents.type', Document::INVOICE_TYPE);
}
public function invoice_recurring()
{
return $this->documents()->where('documents.type', Document::INVOICE_RECURRING_TYPE);
}
public function currency()
{
return $this->belongsTo('App\Models\Setting\Currency', 'currency_code', 'code');
@@ -112,11 +130,6 @@ class Contact extends Model
return $this->transactions()->whereIn('transactions.type', (array) $this->getIncomeTypes());
}
public function invoices()
{
return $this->documents()->where('documents.type', Document::INVOICE_TYPE);
}
public function transactions()
{
return $this->hasMany('App\Models\Banking\Transaction');
@@ -165,6 +178,17 @@ class Contact extends Model
return $query->whereIn($this->qualifyColumn('type'), (array) $this->getCustomerTypes());
}
/**
* Scope to include only employees.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeEmployee($query)
{
return $query->whereIn($this->qualifyColumn('type'), (array) $this->getEmployeeTypes());
}
public function scopeEmail($query, $email)
{
return $query->where('email', '=', $email);
@@ -254,7 +278,7 @@ class Contact extends Model
$location[] = $this->state;
}
if ($this->country && in_array($this->country, trans('countries'))) {
if ($this->country && array_key_exists($this->country, trans('countries'))) {
$location[] = trans('countries.' . $this->country);
}

View File

@@ -20,15 +20,6 @@ class Dashboard extends Model
*/
protected $fillable = ['company_id', 'name', 'enabled', 'created_from', 'created_by'];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'enabled' => 'boolean',
];
/**
* Sortable columns.
*

View File

@@ -16,6 +16,13 @@ class Item extends Model
protected $table = 'items';
/**
* The relationships that should always be loaded.
*
* @var array
*/
protected $with = ['taxes'];
/**
* The accessors to append to the model's array form.
*
@@ -36,9 +43,10 @@ class Item extends Model
* @var array
*/
protected $casts = [
'sale_price' => 'double',
'purchase_price' => 'double',
'enabled' => 'boolean',
'sale_price' => 'double',
'purchase_price' => 'double',
'enabled' => 'boolean',
'deleted_at' => 'datetime',
];
/**
@@ -93,6 +101,15 @@ class Item extends Model
return $query->whereNotNull($price_type . '_price');
}
public function scopeType($query, $type)
{
if (empty($type)) {
return $query;
}
return $query->where($this->qualifyColumn('type'), $type);
}
/**
* Get the item id.
*

View File

@@ -12,7 +12,9 @@ class Media extends BaseMedia
{
use Owners, SoftDeletes, Sources, Tenants;
protected $dates = ['deleted_at'];
protected $fillable = ['company_id', 'created_from', 'created_by'];
protected $casts = [
'deleted_at' => 'datetime',
];
}

View File

@@ -43,7 +43,8 @@ class Recurring extends Model
* @var array
*/
protected $casts = [
'auto_send' => 'boolean',
'auto_send' => 'boolean',
'deleted_at' => 'datetime',
];
/**

View File

@@ -25,7 +25,8 @@ class Report extends Model
* @var array
*/
protected $casts = [
'settings' => 'object',
'settings' => 'object',
'deleted_at' => 'datetime',
];
/**

View File

@@ -26,7 +26,8 @@ class Widget extends Model
* @var array
*/
protected $casts = [
'settings' => 'object',
'settings' => 'object',
'deleted_at' => 'datetime',
];
/**

View File

@@ -3,6 +3,7 @@
namespace App\Models\Document;
use App\Abstracts\Model;
use App\Interfaces\Utility\DocumentNumber;
use App\Models\Common\Media as MediaModel;
use App\Models\Setting\Tax;
use App\Scopes\Document as Scope;
@@ -30,8 +31,6 @@ class Document extends Model
protected $appends = ['attachment', 'amount_without_tax', 'discount', 'paid', 'received_at', 'status_label', 'sent_at', 'reconciled', 'contact_location'];
protected $dates = ['deleted_at', 'issued_at', 'due_at'];
protected $fillable = [
'company_id',
'type',
@@ -69,8 +68,11 @@ class Document extends Model
* @var array
*/
protected $casts = [
'amount' => 'double',
'issued_at' => 'datetime',
'due_at' => 'datetime',
'amount' => 'double',
'currency_rate' => 'double',
'deleted_at' => 'datetime',
];
/**
@@ -218,7 +220,10 @@ class Document extends Model
public function scopeInvoiceRecurring(Builder $query): Builder
{
return $query->where($this->qualifyColumn('type'), '=', self::INVOICE_RECURRING_TYPE);
return $query->where($this->qualifyColumn('type'), '=', self::INVOICE_RECURRING_TYPE)
->whereHas('recurring', function (Builder $query) {
$query->whereNull('deleted_at');
});
}
public function scopeBill(Builder $query): Builder
@@ -228,7 +233,10 @@ class Document extends Model
public function scopeBillRecurring(Builder $query): Builder
{
return $query->where($this->qualifyColumn('type'), '=', self::BILL_RECURRING_TYPE);
return $query->where($this->qualifyColumn('type'), '=', self::BILL_RECURRING_TYPE)
->whereHas('recurring', function (Builder $query) {
$query->whereNull('deleted_at');
});
}
/**
@@ -246,7 +254,7 @@ class Document extends Model
}
$this->status = 'draft';
$this->document_number = $this->getNextDocumentNumber($type);
$this->document_number = app(DocumentNumber::class)->getNextNumber($type, $src->contact);
}
public function getSentAtAttribute(string $value = null)
@@ -323,7 +331,7 @@ class Document extends Model
$code = $this->currency_code;
$rate = $this->currency_rate;
$precision = config('money.' . $code . '.precision');
$precision = config('money.currencies.' . $code . '.precision');
if ($this->transactions->count()) {
foreach ($this->transactions as $transaction) {
@@ -355,7 +363,7 @@ class Document extends Model
$code = $this->currency_code;
$rate = $this->currency_rate;
$precision = config('money.' . $code . '.precision');
$precision = config('money.currencies.' . $code . '.precision');
if ($this->transactions->count()) {
foreach ($this->transactions as $transaction) {
@@ -385,7 +393,7 @@ class Document extends Model
*/
public function getAmountDueAttribute()
{
$precision = config('money.' . $this->currency_code . '.precision');
$precision = config('money.currencies.' . $this->currency_code . '.precision');
return round($this->amount - $this->paid, $precision);
}
@@ -465,7 +473,7 @@ class Document extends Model
$location[] = $this->contact_state;
}
if ($this->contact_country && in_array($this->contact_country, trans('countries'))) {
if ($this->contact_country && array_key_exists($this->contact_country, trans('countries'))) {
$location[] = trans('countries.' . $this->contact_country);
}
@@ -532,17 +540,29 @@ class Document extends Model
if ($this->status != 'paid' && (empty($this->transactions->count()) || (! empty($this->transactions->count()) && $this->paid != $this->amount))) {
try {
$actions[] = [
'type' => 'button',
'title' => trans('invoices.add_payment'),
'icon' => 'paid',
'url' => route('modals.documents.document.transactions.create', $this->id),
'permission' => 'read-' . $group . '-' . $permission_prefix,
'attributes' => [
'id' => 'index-line-actions-payment-' . $this->type . '-' . $this->id,
'@click' => 'onAddPayment("' . route('modals.documents.document.transactions.create', $this->id) . '")',
],
];
if ($this->totals->count()) {
$actions[] = [
'type' => 'button',
'title' => trans('invoices.add_payment'),
'icon' => 'paid',
'url' => route('modals.documents.document.transactions.create', $this->id),
'permission' => 'read-' . $group . '-' . $permission_prefix,
'attributes' => [
'id' => 'index-line-actions-payment-' . $this->type . '-' . $this->id,
'@click' => 'onAddPayment("' . route('modals.documents.document.transactions.create', $this->id) . '")',
],
];
} else {
$actions[] = [
'type' => 'button',
'title' => trans('invoices.messages.totals_required', ['type' => $this->type]),
'icon' => 'paid',
'permission' => 'read-' . $group . '-' . $permission_prefix,
'attributes' => [
"disabled" => "disabled",
],
];
}
} catch (\Exception $e) {}
}
@@ -613,10 +633,10 @@ class Document extends Model
'type' => 'divider',
];
if ($this->status != 'cancelled') {
if (! in_array($this->status, ['cancelled', 'draft'])) {
try {
$actions[] = [
'title' => trans('general.cancel'),
'title' => trans('documents.actions.cancel'),
'icon' => 'cancel',
'url' => route($prefix . '.cancelled', $this->id),
'permission' => 'update-' . $group . '-' . $permission_prefix,

View File

@@ -15,6 +15,13 @@ class DocumentItem extends Model
protected $table = 'document_items';
/**
* The relationships that should always be loaded.
*
* @var array
*/
protected $with = ['taxes'];
protected $appends = ['discount'];
protected $fillable = [
@@ -40,9 +47,10 @@ class DocumentItem extends Model
* @var array
*/
protected $casts = [
'price' => 'double',
'total' => 'double',
'tax' => 'double',
'price' => 'double',
'total' => 'double',
'tax' => 'double',
'deleted_at' => 'datetime',
];
/**

View File

@@ -16,15 +16,6 @@ class DocumentItemTax extends Model
protected $fillable = ['company_id', 'type', 'document_id', 'document_item_id', 'tax_id', 'name', 'amount', 'created_from', 'created_by'];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'amount' => 'double',
];
public function document()
{
return $this->belongsTo('App\Models\Document\Document')->withoutGlobalScope('App\Scopes\Document');

View File

@@ -18,15 +18,6 @@ class DocumentTotal extends Model
protected $fillable = ['company_id', 'type', 'document_id', 'code', 'name', 'amount', 'sort_order', 'created_from', 'created_by'];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'amount' => 'double',
];
public function document()
{
return $this->belongsTo('App\Models\Document\Document')->withoutGlobalScope('App\Scopes\Document');

View File

@@ -15,15 +15,6 @@ class Module extends Model
*/
protected $fillable = ['company_id', 'alias', 'enabled', 'created_from', 'created_by'];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'enabled' => 'boolean',
];
/**
* Scope alias.
*

View File

@@ -34,15 +34,6 @@ class Category extends Model
*/
protected $fillable = ['company_id', 'name', 'type', 'color', 'enabled', 'created_from', 'created_by', 'parent_id'];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'enabled' => 'boolean',
];
/**
* Sortable columns.
*
@@ -231,7 +222,7 @@ class Category extends Model
/**
* Get the display name of the category.
*/
*/
public function getDisplayNameAttribute()
{
return $this->name . ' (' . ucfirst($this->type) . ')';

View File

@@ -40,8 +40,9 @@ class Currency extends Model
* @var array
*/
protected $casts = [
'rate' => 'double',
'enabled' => 'boolean',
'rate' => 'double',
'enabled' => 'boolean',
'deleted_at' => 'datetime',
];
/**
@@ -121,7 +122,7 @@ class Currency extends Model
public function getPrecisionAttribute($value)
{
if (is_null($value)) {
return config('money.' . $this->code . '.precision');
return config('money.currencies.' . $this->code . '.precision');
}
return (int) $value;
@@ -135,7 +136,7 @@ class Currency extends Model
public function getSymbolAttribute($value)
{
if (is_null($value)) {
return config('money.' . $this->code . '.symbol');
return config('money.currencies.' . $this->code . '.symbol');
}
return $value;
@@ -149,7 +150,7 @@ class Currency extends Model
public function getSymbolFirstAttribute($value)
{
if (is_null($value)) {
return config('money.' . $this->code . '.symbol_first');
return config('money.currencies.' . $this->code . '.symbol_first');
}
return $value;
@@ -163,7 +164,7 @@ class Currency extends Model
public function getDecimalMarkAttribute($value)
{
if (is_null($value)) {
return config('money.' . $this->code . '.decimal_mark');
return config('money.currencies.' . $this->code . '.decimal_mark');
}
return $value;
@@ -177,7 +178,7 @@ class Currency extends Model
public function getThousandsSeparatorAttribute($value)
{
if (is_null($value)) {
return config('money.' . $this->code . '.thousands_separator');
return config('money.currencies.' . $this->code . '.thousands_separator');
}
return $value;

View File

@@ -32,8 +32,9 @@ class Tax extends Model
* @var array
*/
protected $casts = [
'rate' => 'double',
'enabled' => 'boolean',
'rate' => 'double',
'enabled' => 'boolean',
'deleted_at' => 'datetime',
];
/**