akaunting 3.0 (the last dance)
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Common;
|
||||
|
||||
use Akaunting\Sortable\Traits\Sortable;
|
||||
use App\Events\Common\CompanyForgettingCurrent;
|
||||
use App\Events\Common\CompanyForgotCurrent;
|
||||
use App\Events\Common\CompanyMadeCurrent;
|
||||
@ -14,15 +15,15 @@ use App\Traits\Sources;
|
||||
use App\Traits\Tenants;
|
||||
use App\Traits\Transactions;
|
||||
use App\Utilities\Overrider;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Kyslik\ColumnSortable\Sortable;
|
||||
use Laratrust\Contracts\Ownable;
|
||||
use Lorisleiva\LaravelSearchString\Concerns\SearchString;
|
||||
|
||||
class Company extends Eloquent implements Ownable
|
||||
{
|
||||
use Contacts, Media, Owners, SearchString, SoftDeletes, Sortable, Sources, Tenants, Transactions;
|
||||
use Contacts, HasFactory, Media, Owners, SearchString, SoftDeletes, Sortable, Sources, Tenants, Transactions;
|
||||
|
||||
protected $table = 'companies';
|
||||
|
||||
@ -48,33 +49,21 @@ class Company extends Eloquent implements Ownable
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $sortable = ['name', 'domain', 'email', 'enabled', 'created_at'];
|
||||
public $sortable = ['id', 'name', 'domain', 'email', 'enabled', 'created_at', 'tax_number', 'country', 'currency'];
|
||||
|
||||
/**
|
||||
* Create a new Eloquent model instance.
|
||||
* Fill the model with an array of attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\MassAssignmentException
|
||||
*/
|
||||
public function __construct(array $attributes = [])
|
||||
public function fill(array $attributes)
|
||||
{
|
||||
$this->allAttributes = $attributes;
|
||||
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the model in the database.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $options
|
||||
* @return bool
|
||||
*/
|
||||
public function update(array $attributes = [], array $options = [])
|
||||
{
|
||||
$this->allAttributes = $attributes;
|
||||
|
||||
return parent::update($attributes, $options);
|
||||
return parent::fill($attributes);
|
||||
}
|
||||
|
||||
public static function boot()
|
||||
@ -90,7 +79,7 @@ class Company extends Eloquent implements Ownable
|
||||
$model->unsetCommonSettingsFromAttributes();
|
||||
});
|
||||
} catch(\Throwable $e) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +165,7 @@ class Company extends Eloquent implements Ownable
|
||||
|
||||
public function email_templates()
|
||||
{
|
||||
return $this->hasMany('App\Models\Common\EmailTemplate');
|
||||
return $this->hasMany('App\Models\Setting\EmailTemplate');
|
||||
}
|
||||
|
||||
public function expense_transactions()
|
||||
@ -298,7 +287,7 @@ class Company extends Eloquent implements Ownable
|
||||
list($group, $key) = explode('.', $setting->getAttribute('key'));
|
||||
|
||||
// Load only general settings
|
||||
if (!in_array($group, $groups)) {
|
||||
if (! in_array($group, $groups)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -315,8 +304,13 @@ class Company extends Eloquent implements Ownable
|
||||
if ($this->getAttribute('logo') == '') {
|
||||
$this->setAttribute('logo', 'public/img/company.png');
|
||||
}
|
||||
|
||||
// Set default default company currency if empty
|
||||
if ($this->getAttribute('currency') == '') {
|
||||
$this->setAttribute('currency', config('setting.fallback.default.currency'));
|
||||
}
|
||||
} catch(\Throwable $e) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,7 +328,7 @@ class Company extends Eloquent implements Ownable
|
||||
list($group, $key) = explode('.', $setting->getAttribute('key'));
|
||||
|
||||
// Load only general settings
|
||||
if (!in_array($group, $groups)) {
|
||||
if (! in_array($group, $groups)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -343,7 +337,7 @@ class Company extends Eloquent implements Ownable
|
||||
|
||||
$this->offsetUnset('logo');
|
||||
} catch(\Throwable $e) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,6 +424,54 @@ class Company extends Eloquent implements Ownable
|
||||
->select('companies.*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort by company tax number
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param $direction
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function taxNumberSortable($query, $direction)
|
||||
{
|
||||
return $query->join('settings', 'companies.id', '=', 'settings.company_id')
|
||||
->where('key', 'company.tax_number')
|
||||
->orderBy('value', $direction)
|
||||
->select('companies.*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort by company country
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param $direction
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function countrySortable($query, $direction)
|
||||
{
|
||||
return $query->join('settings', 'companies.id', '=', 'settings.company_id')
|
||||
->where('key', 'company.country')
|
||||
->orderBy('value', $direction)
|
||||
->select('companies.*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort by company currency
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param $direction
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function currencySortable($query, $direction)
|
||||
{
|
||||
return $query->join('settings', 'companies.id', '=', 'settings.company_id')
|
||||
->where('key', 'default.currency')
|
||||
->orderBy('value', $direction)
|
||||
->select('companies.*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope autocomplete.
|
||||
*
|
||||
@ -489,6 +531,42 @@ class Company extends Eloquent implements Ownable
|
||||
return implode(', ', $location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line actions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLineActionsAttribute()
|
||||
{
|
||||
$actions = [];
|
||||
|
||||
if ($this->enabled) {
|
||||
$actions[] = [
|
||||
'title' => trans('general.switch'),
|
||||
'icon' => 'settings_ethernet',
|
||||
'url' => route('companies.switch', $this->id),
|
||||
'permission' => 'read-common-companies',
|
||||
];
|
||||
}
|
||||
|
||||
$actions[] = [
|
||||
'title' => trans('general.edit'),
|
||||
'icon' => 'edit',
|
||||
'url' => route('companies.edit', $this->id),
|
||||
'permission' => 'update-common-companies',
|
||||
];
|
||||
|
||||
$actions[] = [
|
||||
'type' => 'delete',
|
||||
'icon' => 'delete',
|
||||
'route' => 'companies.destroy',
|
||||
'permission' => 'delete-common-companies',
|
||||
'model' => $this,
|
||||
];
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
public function makeCurrent($force = false)
|
||||
{
|
||||
if (!$force && $this->isCurrent()) {
|
||||
@ -502,9 +580,6 @@ class Company extends Eloquent implements Ownable
|
||||
// Bind to container
|
||||
app()->instance(static::class, $this);
|
||||
|
||||
// Set session for backward compatibility @deprecated
|
||||
//session(['company_id' => $this->id]);
|
||||
|
||||
// Load settings
|
||||
setting()->setExtraColumns(['company_id' => $this->id]);
|
||||
setting()->forgetAll();
|
||||
@ -521,7 +596,7 @@ class Company extends Eloquent implements Ownable
|
||||
|
||||
public function isCurrent()
|
||||
{
|
||||
return optional(static::getCurrent())->id === $this->id;
|
||||
return static::getCurrent()?->id === $this->id;
|
||||
}
|
||||
|
||||
public function isNotCurrent()
|
||||
@ -551,9 +626,6 @@ class Company extends Eloquent implements Ownable
|
||||
// Remove from container
|
||||
app()->forgetInstance(static::class);
|
||||
|
||||
// Unset session for backward compatibility @deprecated
|
||||
//session()->forget('company_id');
|
||||
|
||||
// Remove settings
|
||||
setting()->forgetAll();
|
||||
|
||||
@ -590,4 +662,14 @@ class Company extends Eloquent implements Ownable
|
||||
|
||||
return $this->created_by;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new factory instance for the model.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Factories\Factory
|
||||
*/
|
||||
protected static function newFactory()
|
||||
{
|
||||
return \Database\Factories\Company::new();
|
||||
}
|
||||
}
|
||||
|
@ -2,21 +2,28 @@
|
||||
|
||||
namespace App\Models\Common;
|
||||
|
||||
use App\Traits\Media;
|
||||
use App\Abstracts\Model;
|
||||
use App\Models\Document\Document;
|
||||
use App\Scopes\Contact as Scope;
|
||||
use App\Traits\Contacts;
|
||||
use App\Traits\Currencies;
|
||||
use App\Traits\Media;
|
||||
use App\Traits\Transactions;
|
||||
use App\Scopes\Contact as Scope;
|
||||
use App\Models\Document\Document;
|
||||
use App\Utilities\Date;
|
||||
use App\Utilities\Str;
|
||||
use Bkwld\Cloner\Cloneable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
|
||||
class Contact extends Model
|
||||
{
|
||||
use Cloneable, Contacts, Currencies, HasFactory, Media, Notifiable, Transactions;
|
||||
|
||||
public const CUSTOMER_TYPE = 'customer';
|
||||
public const VENDOR_TYPE = 'vendor';
|
||||
public const EMPLOYEE_TYPE = 'employee';
|
||||
|
||||
protected $table = 'contacts';
|
||||
|
||||
/**
|
||||
@ -169,6 +176,11 @@ class Contact extends Model
|
||||
$this->user_id = null;
|
||||
}
|
||||
|
||||
public function getInitialsAttribute($value)
|
||||
{
|
||||
return Str::getInitials($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current balance.
|
||||
*
|
||||
@ -191,7 +203,35 @@ class Contact extends Model
|
||||
|
||||
$collection = $this->isCustomer() ? 'invoices' : 'bills';
|
||||
|
||||
$this->$collection->whereNotIn('status', ['draft', 'cancelled', 'paid'])->each(function ($item) use (&$amount) {
|
||||
$this->$collection->whereIn('status', ['sent', 'received', 'viewed', 'partial'])->each(function ($item) use (&$amount) {
|
||||
$amount += $this->convertToDefault($item->amount_due, $item->currency_code, $item->currency_rate);
|
||||
});
|
||||
|
||||
return $amount;
|
||||
}
|
||||
|
||||
public function getOpenAttribute()
|
||||
{
|
||||
$amount = 0;
|
||||
$today = Date::today()->toDateString();
|
||||
|
||||
$collection = $this->isCustomer() ? 'invoices' : 'bills';
|
||||
|
||||
$this->$collection->whereIn('status', ['sent', 'received', 'viewed', 'partial'])->where('due_at', '>=', $today)->each(function ($item) use (&$amount) {
|
||||
$amount += $this->convertToDefault($item->amount_due, $item->currency_code, $item->currency_rate);
|
||||
});
|
||||
|
||||
return $amount;
|
||||
}
|
||||
|
||||
public function getOverdueAttribute()
|
||||
{
|
||||
$amount = 0;
|
||||
$today = Date::today()->toDateString();
|
||||
|
||||
$collection = $this->isCustomer() ? 'invoices' : 'bills';
|
||||
|
||||
$this->$collection->whereIn('status', ['sent', 'received', 'viewed', 'partial'])->where('due_at', '<', $today)->each(function ($item) use (&$amount) {
|
||||
$amount += $this->convertToDefault($item->amount_due, $item->currency_code, $item->currency_rate);
|
||||
});
|
||||
|
||||
@ -221,6 +261,71 @@ class Contact extends Model
|
||||
return implode(', ', $location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line actions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLineActionsAttribute()
|
||||
{
|
||||
$actions = [];
|
||||
|
||||
$group = config('type.contact.' . $this->type . '.group');
|
||||
$prefix = config('type.contact.' . $this->type . '.route.prefix');
|
||||
$permission_prefix = config('type.contact.' . $this->type . '.permission.prefix');
|
||||
$translation_prefix = config('type.contact.' . $this->type . '.translation.prefix');
|
||||
|
||||
if (empty($prefix)) {
|
||||
if (in_array($this->type, (array) $this->getCustomerTypes())) {
|
||||
$prefix = config('type.contact.customer.route.prefix');
|
||||
} elseif (in_array($this->type, (array) $this->getVendorTypes())) {
|
||||
$prefix = config('type.contact.vendor.route.prefix');
|
||||
} else {
|
||||
return $actions;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$actions[] = [
|
||||
'title' => trans('general.show'),
|
||||
'icon' => 'visibility',
|
||||
'url' => route($prefix . '.show', $this->id),
|
||||
'permission' => 'read-' . $group . '-' . $permission_prefix,
|
||||
];
|
||||
} catch (\Exception $e) {}
|
||||
|
||||
try {
|
||||
$actions[] = [
|
||||
'title' => trans('general.edit'),
|
||||
'icon' => 'edit',
|
||||
'url' => route($prefix . '.edit', $this->id),
|
||||
'permission' => 'update-' . $group . '-' . $permission_prefix,
|
||||
];
|
||||
} catch (\Exception $e) {}
|
||||
|
||||
try {
|
||||
$actions[] = [
|
||||
'title' => trans('general.duplicate'),
|
||||
'icon' => 'file_copy',
|
||||
'url' => route($prefix . '.duplicate', $this->id),
|
||||
'permission' => 'create-' . $group . '-' . $permission_prefix,
|
||||
];
|
||||
} catch (\Exception $e) {}
|
||||
|
||||
try {
|
||||
$actions[] = [
|
||||
'type' => 'delete',
|
||||
'icon' => 'delete',
|
||||
'title' => $translation_prefix,
|
||||
'route' => $prefix . '.destroy',
|
||||
'permission' => 'delete-' . $group . '-' . $permission_prefix,
|
||||
'model' => $this,
|
||||
];
|
||||
} catch (\Exception $e) {}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new factory instance for the model.
|
||||
*
|
||||
|
@ -114,6 +114,42 @@ class Dashboard extends Model
|
||||
return $alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line actions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLineActionsAttribute()
|
||||
{
|
||||
$actions = [];
|
||||
|
||||
if ($this->enabled) {
|
||||
$actions[] = [
|
||||
'title' => trans('general.switch'),
|
||||
'icon' => 'settings_ethernet',
|
||||
'url' => route('dashboards.switch', $this->id),
|
||||
'permission' => 'read-common-dashboards',
|
||||
];
|
||||
}
|
||||
|
||||
$actions[] = [
|
||||
'title' => trans('general.edit'),
|
||||
'icon' => 'edit',
|
||||
'url' => route('dashboards.edit', $this->id),
|
||||
'permission' => 'update-common-dashboards',
|
||||
];
|
||||
|
||||
$actions[] = [
|
||||
'type' => 'delete',
|
||||
'icon' => 'delete',
|
||||
'route' => 'dashboards.destroy',
|
||||
'permission' => 'delete-common-dashboards',
|
||||
'model' => $this,
|
||||
];
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new factory instance for the model.
|
||||
*
|
||||
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Common;
|
||||
|
||||
use App\Abstracts\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class EmailTemplate extends Model
|
||||
{
|
||||
protected $table = 'email_templates';
|
||||
|
||||
/**
|
||||
* Attributes that should be mass-assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['company_id', 'alias', 'class', 'name', 'subject', 'body', 'params', 'created_from', 'created_by'];
|
||||
|
||||
/**
|
||||
* Scope to only include email templates of a given alias.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param mixed $alias
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeAlias($query, $alias)
|
||||
{
|
||||
return $query->where('alias', $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope to only include email templates of a given module alias (class).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $alias
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeModuleAlias($query, $alias)
|
||||
{
|
||||
$class = ($alias == 'core') ? 'App\\\\' : 'Modules\\\\' . Str::studly($alias) . '\\\\';
|
||||
|
||||
return $query->where('class', 'like', $class . '%');
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ class Item extends Model
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['company_id', 'name', 'description', 'sale_price', 'purchase_price', 'category_id', 'enabled', 'created_from', 'created_by'];
|
||||
protected $fillable = ['company_id', 'type', 'name', 'description', 'sale_price', 'purchase_price', 'category_id', 'enabled', 'created_from', 'created_by'];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
@ -45,7 +45,7 @@ class Item extends Model
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $sortable = ['name', 'category', 'sale_price', 'purchase_price', 'enabled'];
|
||||
protected $sortable = ['name', 'category.name', 'sale_price', 'purchase_price', 'enabled'];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
@ -82,6 +82,11 @@ class Item extends Model
|
||||
return $query->where('name', '=', $name);
|
||||
}
|
||||
|
||||
public function scopeBilling($query, $billing)
|
||||
{
|
||||
return $query->where($billing . '_price', '=', null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item id.
|
||||
*
|
||||
@ -149,6 +154,40 @@ class Item extends Model
|
||||
return $this->getMedia('picture')->last();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line actions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLineActionsAttribute()
|
||||
{
|
||||
$actions = [];
|
||||
|
||||
$actions[] = [
|
||||
'title' => trans('general.edit'),
|
||||
'icon' => 'edit',
|
||||
'url' => route('items.edit', $this->id),
|
||||
'permission' => 'update-common-items',
|
||||
];
|
||||
|
||||
$actions[] = [
|
||||
'title' => trans('general.duplicate'),
|
||||
'icon' => 'file_copy',
|
||||
'url' => route('items.duplicate', $this->id),
|
||||
'permission' => 'create-common-items',
|
||||
];
|
||||
|
||||
$actions[] = [
|
||||
'type' => 'delete',
|
||||
'icon' => 'delete',
|
||||
'route' => 'items.destroy',
|
||||
'permission' => 'delete-common-items',
|
||||
'model' => $this,
|
||||
];
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new factory instance for the model.
|
||||
*
|
||||
|
@ -4,11 +4,16 @@ namespace App\Models\Common;
|
||||
|
||||
use App\Abstracts\Model;
|
||||
use App\Traits\Recurring as RecurringTrait;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class Recurring extends Model
|
||||
{
|
||||
use RecurringTrait;
|
||||
|
||||
public const ACTIVE_STATUS = 'active';
|
||||
public const END_STATUS = 'ended';
|
||||
public const COMPLETE_STATUS = 'completed';
|
||||
|
||||
protected $table = 'recurring';
|
||||
|
||||
/**
|
||||
@ -16,7 +21,30 @@ class Recurring extends Model
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['company_id', 'recurable_id', 'recurable_type', 'frequency', 'interval', 'started_at', 'count', 'created_from', 'created_by'];
|
||||
protected $fillable = [
|
||||
'company_id',
|
||||
'recurable_id',
|
||||
'recurable_type',
|
||||
'frequency',
|
||||
'interval',
|
||||
'started_at',
|
||||
'status',
|
||||
'limit_by',
|
||||
'limit_count',
|
||||
'limit_date',
|
||||
'auto_send',
|
||||
'created_from',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'auto_send' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get all of the owning recurable models.
|
||||
@ -25,4 +53,19 @@ class Recurring extends Model
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function scopeActive(Builder $query): Builder
|
||||
{
|
||||
return $query->where($this->qualifyColumn('status'), '=', static::ACTIVE_STATUS);
|
||||
}
|
||||
|
||||
public function scopeEnded(Builder $query): Builder
|
||||
{
|
||||
return $query->where($this->qualifyColumn('status'), '=', static::END_STATUS);
|
||||
}
|
||||
|
||||
public function scopeCompleted(Builder $query): Builder
|
||||
{
|
||||
return $query->where($this->qualifyColumn('status'), '=', static::COMPLETE_STATUS);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user