From c59c71b0f96382b029e8f57dbd1183f129ab496f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Duli=C3=A7i?= Date: Tue, 7 Sep 2021 10:33:34 +0300 Subject: [PATCH] added source feature --- app/Abstracts/Commands/Module.php | 2 + app/Abstracts/Import.php | 1 + app/Abstracts/Job.php | 21 ++- app/Abstracts/Model.php | 8 +- app/Interfaces/Job/HasSource.php | 8 ++ app/Jobs/Auth/CreateRole.php | 4 +- app/Jobs/Auth/CreateUser.php | 4 +- app/Jobs/Banking/CreateAccount.php | 3 +- app/Jobs/Banking/CreateReconciliation.php | 3 +- app/Jobs/Banking/CreateTransaction.php | 3 +- app/Jobs/Banking/CreateTransfer.php | 3 +- app/Jobs/Common/CreateCompany.php | 3 +- app/Jobs/Common/CreateContact.php | 3 +- app/Jobs/Common/CreateDashboard.php | 3 +- app/Jobs/Common/CreateEmailTemplate.php | 21 +++ app/Jobs/Common/CreateItem.php | 3 +- app/Jobs/Common/CreateItemTaxes.php | 6 +- app/Jobs/Common/CreateReport.php | 3 +- app/Jobs/Common/CreateWidget.php | 3 +- app/Jobs/Document/CreateDocument.php | 3 +- app/Jobs/Document/CreateDocumentHistory.php | 6 +- app/Jobs/Document/CreateDocumentItem.php | 8 +- .../Document/CreateDocumentItemsAndTotals.php | 20 ++- app/Jobs/Setting/CreateCategory.php | 3 +- app/Jobs/Setting/CreateCurrency.php | 3 +- app/Jobs/Setting/CreateTax.php | 3 +- .../Update/CreateModuleUpdatedHistory.php | 2 + app/Models/Auth/Role.php | 2 +- app/Models/Auth/User.php | 30 ++++- app/Models/Banking/Account.php | 2 +- app/Models/Banking/Reconciliation.php | 2 +- app/Models/Banking/Transaction.php | 1 + app/Models/Banking/Transfer.php | 2 +- app/Models/Common/Company.php | 14 +- app/Models/Common/Contact.php | 1 + app/Models/Common/Dashboard.php | 2 +- app/Models/Common/EmailTemplate.php | 2 +- app/Models/Common/Item.php | 2 +- app/Models/Common/ItemTax.php | 2 +- app/Models/Common/Media.php | 6 +- app/Models/Common/Recurring.php | 2 +- app/Models/Common/Report.php | 2 +- app/Models/Common/Widget.php | 2 +- app/Models/Document/Document.php | 1 + app/Models/Document/DocumentHistory.php | 2 +- app/Models/Document/DocumentItem.php | 2 + app/Models/Document/DocumentItemTax.php | 2 +- app/Models/Module/Module.php | 2 +- app/Models/Module/ModuleHistory.php | 2 +- app/Models/Setting/Category.php | 2 +- app/Models/Setting/Currency.php | 1 + app/Models/Setting/Tax.php | 2 +- app/Traits/Modules.php | 4 +- app/Traits/Recurring.php | 23 +++- app/Traits/Sources.php | 37 ++++++ app/Traits/Uploads.php | 4 + app/Utilities/helpers.php | 22 ++- database/factories/Account.php | 1 + database/factories/Category.php | 1 + database/factories/Contact.php | 1 + database/factories/Currency.php | 1 + database/factories/Dashboard.php | 1 + database/factories/Document.php | 1 + database/factories/Item.php | 1 + database/factories/Reconciliation.php | 1 + database/factories/Role.php | 1 + database/factories/Tax.php | 1 + database/factories/Transaction.php | 1 + database/factories/Transfer.php | 1 + database/factories/User.php | 1 + database/factories/Widget.php | 1 + .../2021_09_01_000000_core_v2124.php | 125 +++++++++++++++++- database/seeds/Accounts.php | 1 + database/seeds/Categories.php | 2 + database/seeds/Currencies.php | 2 + database/seeds/Dashboards.php | 1 + database/seeds/EmailTemplates.php | 10 +- database/seeds/Reports.php | 2 + .../Commands/InstallCommand.php | 2 + tests/Feature/Common/SourcesTest.php | 46 +++++++ 80 files changed, 475 insertions(+), 63 deletions(-) create mode 100644 app/Interfaces/Job/HasSource.php create mode 100644 app/Jobs/Common/CreateEmailTemplate.php create mode 100644 app/Traits/Sources.php create mode 100644 tests/Feature/Common/SourcesTest.php diff --git a/app/Abstracts/Commands/Module.php b/app/Abstracts/Commands/Module.php index b41e7b79a..4b2539536 100644 --- a/app/Abstracts/Commands/Module.php +++ b/app/Abstracts/Commands/Module.php @@ -58,6 +58,8 @@ abstract class Module extends Command 'module_id' => $this->model->id, 'version' => $this->module->get('version'), 'description' => trans('modules.' . $action, ['module' => $this->alias]), + 'created_from' => source_name(), + 'created_by' => user_id(), ]); } diff --git a/app/Abstracts/Import.php b/app/Abstracts/Import.php index 8d709b0db..ca1da0463 100644 --- a/app/Abstracts/Import.php +++ b/app/Abstracts/Import.php @@ -36,6 +36,7 @@ abstract class Import implements HasLocalePreference, ShouldQueue, SkipsEmptyRow { $row['company_id'] = company_id(); $row['created_by'] = $this->user->id; + $row['created_from'] = 'import'; // Make enabled field integer if (isset($row['enabled'])) { diff --git a/app/Abstracts/Job.php b/app/Abstracts/Job.php index 73c99b82e..421071de3 100644 --- a/app/Abstracts/Job.php +++ b/app/Abstracts/Job.php @@ -4,18 +4,20 @@ namespace App\Abstracts; use App\Abstracts\Http\FormRequest; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Interfaces\Job\ShouldDelete; use App\Interfaces\Job\ShouldUpdate; use App\Traits\Jobs; use App\Traits\Relationships; +use App\Traits\Sources; use App\Traits\Uploads; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; abstract class Job { - use Jobs, Relationships, Uploads; + use Jobs, Relationships, Sources, Uploads; protected $model; @@ -49,6 +51,10 @@ abstract class Job if ($this instanceof HasOwner) { $this->setOwner(); } + + if ($this instanceof HasSource) { + $this->setSource(); + } } public function bootUpdate(...$arguments): void @@ -106,4 +112,17 @@ abstract class Job $this->request->merge(['created_by' => user_id()]); } + + public function setSource(): void + { + if (! $this->request instanceof Request) { + return; + } + + if ($this->request->has('created_from')) { + return; + } + + $this->request->merge(['created_from' => $this->getSourceName($this->request)]); + } } diff --git a/app/Abstracts/Model.php b/app/Abstracts/Model.php index 55de88cd1..90668a8b2 100644 --- a/app/Abstracts/Model.php +++ b/app/Abstracts/Model.php @@ -4,6 +4,7 @@ namespace App\Abstracts; use App\Traits\DateTime; use App\Traits\Owners; +use App\Traits\Sources; use App\Traits\Tenants; use GeneaLabs\LaravelModelCaching\Traits\Cachable; use Illuminate\Database\Eloquent\Model as Eloquent; @@ -14,7 +15,7 @@ use Lorisleiva\LaravelSearchString\Concerns\SearchString; abstract class Model extends Eloquent implements Ownable { - use Cachable, DateTime, Owners, SearchString, SoftDeletes, Sortable, Tenants; + use Cachable, DateTime, Owners, SearchString, SoftDeletes, Sortable, Sources, Tenants; protected $tenantable = true; @@ -211,6 +212,11 @@ abstract class Model extends Eloquent implements Ownable return $query->whereIn($this->table . '.contact_id', (array) $contacts); } + public function scopeSource($query, $source) + { + return $query->where($this->table . '.created_from', $source); + } + public function scopeIsOwner($query) { return $query->where($this->table . '.created_by', user_id()); diff --git a/app/Interfaces/Job/HasSource.php b/app/Interfaces/Job/HasSource.php new file mode 100644 index 000000000..a04e866b2 --- /dev/null +++ b/app/Interfaces/Job/HasSource.php @@ -0,0 +1,8 @@ +model = EmailTemplate::create($this->request->all()); + }); + + return $this->model; + } +} diff --git a/app/Jobs/Common/CreateItem.php b/app/Jobs/Common/CreateItem.php index b1a0aac03..f888eec63 100644 --- a/app/Jobs/Common/CreateItem.php +++ b/app/Jobs/Common/CreateItem.php @@ -4,11 +4,12 @@ namespace App\Jobs\Common; use App\Abstracts\Job; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Jobs\Common\CreateItemTaxes; use App\Models\Common\Item; -class CreateItem extends Job implements HasOwner, ShouldCreate +class CreateItem extends Job implements HasOwner, HasSource, ShouldCreate { public function handle(): Item { diff --git a/app/Jobs/Common/CreateItemTaxes.php b/app/Jobs/Common/CreateItemTaxes.php index 22c8a9835..29f69417e 100644 --- a/app/Jobs/Common/CreateItemTaxes.php +++ b/app/Jobs/Common/CreateItemTaxes.php @@ -3,11 +3,13 @@ namespace App\Jobs\Common; use App\Abstracts\Job; +use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Common\Item; use App\Models\Common\ItemTax; -class CreateItemTaxes extends Job implements ShouldCreate +class CreateItemTaxes extends Job implements HasOwner, HasSource, ShouldCreate { protected $item; @@ -44,6 +46,8 @@ class CreateItemTaxes extends Job implements ShouldCreate 'company_id' => $this->item->company_id, 'item_id' => $this->item->id, 'tax_id' => $tax_id, + 'created_from' => $this->request['created_from'], + 'created_by' => $this->request['created_by'], ]); } }); diff --git a/app/Jobs/Common/CreateReport.php b/app/Jobs/Common/CreateReport.php index d830ec00e..86cc70750 100644 --- a/app/Jobs/Common/CreateReport.php +++ b/app/Jobs/Common/CreateReport.php @@ -4,10 +4,11 @@ namespace App\Jobs\Common; use App\Abstracts\Job; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Common\Report; -class CreateReport extends Job implements HasOwner, ShouldCreate +class CreateReport extends Job implements HasOwner, HasSource, ShouldCreate { public function handle(): Report { diff --git a/app/Jobs/Common/CreateWidget.php b/app/Jobs/Common/CreateWidget.php index 11c7ee563..3b0688023 100644 --- a/app/Jobs/Common/CreateWidget.php +++ b/app/Jobs/Common/CreateWidget.php @@ -4,10 +4,11 @@ namespace App\Jobs\Common; use App\Abstracts\Job; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Common\Widget; -class CreateWidget extends Job implements HasOwner, ShouldCreate +class CreateWidget extends Job implements HasOwner, HasSource, ShouldCreate { public function handle(): Widget { diff --git a/app/Jobs/Document/CreateDocument.php b/app/Jobs/Document/CreateDocument.php index d45a08e80..921ac9f5e 100644 --- a/app/Jobs/Document/CreateDocument.php +++ b/app/Jobs/Document/CreateDocument.php @@ -6,12 +6,13 @@ use App\Abstracts\Job; use App\Events\Document\DocumentCreated; use App\Events\Document\DocumentCreating; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Jobs\Document\CreateDocumentItemsAndTotals; use App\Models\Document\Document; use Illuminate\Support\Str; -class CreateDocument extends Job implements HasOwner, ShouldCreate +class CreateDocument extends Job implements HasOwner, HasSource, ShouldCreate { public function handle(): Document { diff --git a/app/Jobs/Document/CreateDocumentHistory.php b/app/Jobs/Document/CreateDocumentHistory.php index b710a3d49..f07e8c117 100644 --- a/app/Jobs/Document/CreateDocumentHistory.php +++ b/app/Jobs/Document/CreateDocumentHistory.php @@ -3,11 +3,13 @@ namespace App\Jobs\Document; use App\Abstracts\Job; +use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Document\Document; use App\Models\Document\DocumentHistory; -class CreateDocumentHistory extends Job implements ShouldCreate +class CreateDocumentHistory extends Job implements HasOwner, HasSource, ShouldCreate { protected $document; @@ -35,6 +37,8 @@ class CreateDocumentHistory extends Job implements ShouldCreate 'status' => $this->document->status, 'notify' => $this->notify, 'description' => $description, + 'created_from' => source_name(), + 'created_by' => user_id(), ]); return $document_history; diff --git a/app/Jobs/Document/CreateDocumentItem.php b/app/Jobs/Document/CreateDocumentItem.php index 89db2a16e..8eaa69b61 100644 --- a/app/Jobs/Document/CreateDocumentItem.php +++ b/app/Jobs/Document/CreateDocumentItem.php @@ -3,6 +3,8 @@ namespace App\Jobs\Document; use App\Abstracts\Job; +use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Document\Document; use App\Models\Document\DocumentItem; @@ -10,7 +12,7 @@ use App\Models\Document\DocumentItemTax; use App\Models\Setting\Tax; use Illuminate\Support\Str; -class CreateDocumentItem extends Job implements ShouldCreate +class CreateDocumentItem extends Job implements HasOwner, HasSource, ShouldCreate { protected $document; @@ -182,6 +184,8 @@ class CreateDocumentItem extends Job implements ShouldCreate $this->request['discount_type'] = !empty($this->request['discount_type']) ? $this->request['discount_type'] : 'percentage'; $this->request['discount_rate'] = !empty($this->request['discount']) ? $this->request['discount'] : 0; $this->request['total'] = round($item_amount, $precision); + $this->request['created_from'] = source_name(); + $this->request['created_by'] = user_id(); $document_item = DocumentItem::create($this->request); @@ -197,6 +201,8 @@ class CreateDocumentItem extends Job implements ShouldCreate foreach ($item_taxes as $item_tax) { $item_tax['document_item_id'] = $document_item->id; $item_tax['amount'] = round(abs($item_tax['amount']), $precision); + $item_tax['created_from'] = $this->request['created_from']; + $item_tax['created_by'] = $this->request['created_by']; DocumentItemTax::create($item_tax); } diff --git a/app/Jobs/Document/CreateDocumentItemsAndTotals.php b/app/Jobs/Document/CreateDocumentItemsAndTotals.php index bed1acb89..45f928621 100644 --- a/app/Jobs/Document/CreateDocumentItemsAndTotals.php +++ b/app/Jobs/Document/CreateDocumentItemsAndTotals.php @@ -3,6 +3,8 @@ namespace App\Jobs\Document; use App\Abstracts\Job; +use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Jobs\Common\CreateItem; use App\Models\Document\Document; @@ -10,7 +12,7 @@ use App\Models\Document\DocumentTotal; use App\Traits\Currencies; use App\Traits\DateTime; -class CreateDocumentItemsAndTotals extends Job implements ShouldCreate +class CreateDocumentItemsAndTotals extends Job implements HasOwner, HasSource, ShouldCreate { use Currencies, DateTime; @@ -40,6 +42,8 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate 'name' => 'invoices.sub_total', 'amount' => round($sub_total, $precision), 'sort_order' => $sort_order, + 'created_from' => $this->request['created_from'], + 'created_by' => $this->request['created_by'], ]); $this->request['amount'] += $sub_total; @@ -56,6 +60,8 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate 'name' => 'invoices.item_discount', 'amount' => round($discount_amount_total, $precision), 'sort_order' => $sort_order, + 'created_from' => $this->request['created_from'], + 'created_by' => $this->request['created_by'], ]); $sort_order++; @@ -68,7 +74,7 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate $discount_total = $this->request['discount']; } - DocumentTotal::create([ + DocumentTotal::create([ 'company_id' => $this->document->company_id, 'type' => $this->document->type, 'document_id' => $this->document->id, @@ -76,6 +82,8 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate 'name' => 'invoices.discount', 'amount' => round($discount_total, $precision), 'sort_order' => $sort_order, + 'created_from' => $this->request['created_from'], + 'created_by' => $this->request['created_by'], ]); $this->request['amount'] -= $discount_total; @@ -94,6 +102,8 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate 'name' => $tax['name'], 'amount' => round(abs($tax['amount']), $precision), 'sort_order' => $sort_order, + 'created_from' => $this->request['created_from'], + 'created_by' => $this->request['created_by'], ]); $this->request['amount'] += $tax['amount']; @@ -109,6 +119,8 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate $total['type'] = $this->document->type; $total['document_id'] = $this->document->id; $total['sort_order'] = $sort_order; + $total['created_from'] = $this->request['created_from']; + $total['created_by'] = $this->request['created_by']; if (empty($total['code'])) { $total['code'] = 'extra'; @@ -140,6 +152,8 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate 'name' => 'invoices.total', 'amount' => $this->request['amount'], 'sort_order' => $sort_order, + 'created_from' => $this->request['created_from'], + 'created_by' => $this->request['created_by'], ]); } @@ -167,7 +181,7 @@ class CreateDocumentItemsAndTotals extends Job implements ShouldCreate 'description' => $item['description'], 'sale_price' => $item['price'], 'purchase_price' => $item['price'], - 'enabled' => '1' + 'enabled' => '1', ]; if (!empty($item['tax_ids'])) { diff --git a/app/Jobs/Setting/CreateCategory.php b/app/Jobs/Setting/CreateCategory.php index 2c20cf733..02dc0180d 100644 --- a/app/Jobs/Setting/CreateCategory.php +++ b/app/Jobs/Setting/CreateCategory.php @@ -4,10 +4,11 @@ namespace App\Jobs\Setting; use App\Abstracts\Job; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Setting\Category; -class CreateCategory extends Job implements HasOwner, ShouldCreate +class CreateCategory extends Job implements HasOwner, HasSource, ShouldCreate { public function handle(): Category { diff --git a/app/Jobs/Setting/CreateCurrency.php b/app/Jobs/Setting/CreateCurrency.php index 0487d7485..9015e85c9 100644 --- a/app/Jobs/Setting/CreateCurrency.php +++ b/app/Jobs/Setting/CreateCurrency.php @@ -4,10 +4,11 @@ namespace App\Jobs\Setting; use App\Abstracts\Job; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Setting\Currency; -class CreateCurrency extends Job implements HasOwner, ShouldCreate +class CreateCurrency extends Job implements HasOwner, HasSource, ShouldCreate { public function handle(): Currency { diff --git a/app/Jobs/Setting/CreateTax.php b/app/Jobs/Setting/CreateTax.php index 276cff0d6..af8784a39 100644 --- a/app/Jobs/Setting/CreateTax.php +++ b/app/Jobs/Setting/CreateTax.php @@ -4,10 +4,11 @@ namespace App\Jobs\Setting; use App\Abstracts\Job; use App\Interfaces\Job\HasOwner; +use App\Interfaces\Job\HasSource; use App\Interfaces\Job\ShouldCreate; use App\Models\Setting\Tax; -class CreateTax extends Job implements HasOwner, ShouldCreate +class CreateTax extends Job implements HasOwner, HasSource, ShouldCreate { public function handle(): Tax { diff --git a/app/Listeners/Update/CreateModuleUpdatedHistory.php b/app/Listeners/Update/CreateModuleUpdatedHistory.php index c65b9ad8f..27af0cf34 100644 --- a/app/Listeners/Update/CreateModuleUpdatedHistory.php +++ b/app/Listeners/Update/CreateModuleUpdatedHistory.php @@ -35,6 +35,8 @@ class CreateModuleUpdatedHistory 'module_id' => $model->id, 'version' => $event->new, 'description' => trans('modules.updated_2', ['module' => $module->getAlias()]), + 'created_from' => source_name(), + 'created_by' => user_id(), ]); } } diff --git a/app/Models/Auth/Role.php b/app/Models/Auth/Role.php index 31523b9ff..5c05905c3 100644 --- a/app/Models/Auth/Role.php +++ b/app/Models/Auth/Role.php @@ -20,7 +20,7 @@ class Role extends LaratrustRole * * @var array */ - protected $fillable = ['name', 'display_name', 'description']; + protected $fillable = ['name', 'display_name', 'description', 'created_from', 'created_by']; /** * Scope to get all rows filtered, sorted and paginated. diff --git a/app/Models/Auth/User.php b/app/Models/Auth/User.php index d922eeb20..40c161874 100644 --- a/app/Models/Auth/User.php +++ b/app/Models/Auth/User.php @@ -5,6 +5,8 @@ namespace App\Models\Auth; use App\Traits\Tenants; use App\Notifications\Auth\Reset; use App\Traits\Media; +use App\Traits\Owners; +use App\Traits\Sources; use App\Traits\Users; use App\Utilities\Date; use Illuminate\Contracts\Translation\HasLocalePreference; @@ -18,7 +20,7 @@ use Lorisleiva\LaravelSearchString\Concerns\SearchString; class User extends Authenticatable implements HasLocalePreference { - use HasFactory, LaratrustUserTrait, Notifiable, SearchString, SoftDeletes, Sortable, Media, Tenants, Users; + use HasFactory, LaratrustUserTrait, Media, Notifiable, Owners, SearchString, SoftDeletes, Sortable, Sources, Tenants, Users; protected $table = 'users'; @@ -27,7 +29,7 @@ class User extends Authenticatable implements HasLocalePreference * * @var array */ - protected $fillable = ['name', 'email', 'password', 'locale', 'enabled', 'landing_page']; + protected $fillable = ['name', 'email', 'password', 'locale', 'enabled', 'landing_page', 'created_from', 'created_by']; /** * The attributes that should be cast. @@ -258,6 +260,30 @@ class User extends Authenticatable implements HasLocalePreference return (bool) $this->can('read-admin-panel'); } + public function scopeSource($query, $source) + { + return $query->where($this->table . '.created_from', $source); + } + + public function scopeIsOwner($query) + { + return $query->where($this->table . '.created_by', user_id()); + } + + public function scopeIsNotOwner($query) + { + return $query->where($this->table . '.created_by', '<>', user_id()); + } + + public function ownerKey($owner) + { + if ($this->isNotOwnable()) { + return 0; + } + + return $this->created_by; + } + /** * Get the user's preferred locale. * diff --git a/app/Models/Banking/Account.php b/app/Models/Banking/Account.php index 41199c0f1..620f97dbe 100644 --- a/app/Models/Banking/Account.php +++ b/app/Models/Banking/Account.php @@ -25,7 +25,7 @@ class Account extends Model * * @var array */ - protected $fillable = ['company_id', 'name', 'number', 'currency_code', 'opening_balance', 'bank_name', 'bank_phone', 'bank_address', 'enabled', 'created_by']; + protected $fillable = ['company_id', 'name', 'number', 'currency_code', 'opening_balance', 'bank_name', 'bank_phone', 'bank_address', 'enabled', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Banking/Reconciliation.php b/app/Models/Banking/Reconciliation.php index 6fa2b1c51..3210c1e55 100644 --- a/app/Models/Banking/Reconciliation.php +++ b/app/Models/Banking/Reconciliation.php @@ -18,7 +18,7 @@ class Reconciliation extends Model * * @var array */ - protected $fillable = ['company_id', 'account_id', 'started_at', 'ended_at', 'closing_balance', 'reconciled', 'created_by']; + protected $fillable = ['company_id', 'account_id', 'started_at', 'ended_at', 'closing_balance', 'reconciled', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Banking/Transaction.php b/app/Models/Banking/Transaction.php index f6b1b778b..d1b4cb50c 100644 --- a/app/Models/Banking/Transaction.php +++ b/app/Models/Banking/Transaction.php @@ -43,6 +43,7 @@ class Transaction extends Model 'payment_method', 'reference', 'parent_id', + 'created_from', 'created_by', ]; diff --git a/app/Models/Banking/Transfer.php b/app/Models/Banking/Transfer.php index 72316a6f4..5bdad7e75 100644 --- a/app/Models/Banking/Transfer.php +++ b/app/Models/Banking/Transfer.php @@ -36,7 +36,7 @@ class Transfer extends Model * * @var array */ - protected $fillable = ['company_id', 'expense_transaction_id', 'income_transaction_id', 'created_by']; + protected $fillable = ['company_id', 'expense_transaction_id', 'income_transaction_id', 'created_from', 'created_by']; /** * Sortable columns. diff --git a/app/Models/Common/Company.php b/app/Models/Common/Company.php index 231ecada2..fdabd77ac 100644 --- a/app/Models/Common/Company.php +++ b/app/Models/Common/Company.php @@ -10,6 +10,7 @@ use App\Models\Document\Document; use App\Traits\Contacts; use App\Traits\Media; use App\Traits\Owners; +use App\Traits\Sources; use App\Traits\Tenants; use App\Traits\Transactions; use App\Utilities\Overrider; @@ -21,7 +22,7 @@ use Lorisleiva\LaravelSearchString\Concerns\SearchString; class Company extends Eloquent implements Ownable { - use Contacts, Media, Owners, SearchString, SoftDeletes, Sortable, Tenants, Transactions; + use Contacts, Media, Owners, SearchString, SoftDeletes, Sortable, Sources, Tenants, Transactions; protected $table = 'companies'; @@ -34,7 +35,7 @@ class Company extends Eloquent implements Ownable protected $dates = ['deleted_at']; - protected $fillable = ['domain', 'enabled', 'created_by']; + protected $fillable = ['domain', 'enabled', 'created_from', 'created_by']; protected $casts = [ 'enabled' => 'boolean', @@ -554,14 +555,19 @@ class Company extends Eloquent implements Ownable return static::getCurrent() !== null; } + public function scopeSource($query, $source) + { + return $query->where($this->table . '.created_from', $source); + } + public function scopeIsOwner($query) { - return $query->where('created_by', user_id()); + return $query->where($this->table . '.created_by', user_id()); } public function scopeIsNotOwner($query) { - return $query->where('created_by', '<>', user_id()); + return $query->where($this->table . '.created_by', '<>', user_id()); } public function ownerKey($owner) diff --git a/app/Models/Common/Contact.php b/app/Models/Common/Contact.php index 3cc368952..7c99f2691 100644 --- a/app/Models/Common/Contact.php +++ b/app/Models/Common/Contact.php @@ -48,6 +48,7 @@ class Contact extends Model 'currency_code', 'reference', 'enabled', + 'created_from', 'created_by', ]; diff --git a/app/Models/Common/Dashboard.php b/app/Models/Common/Dashboard.php index 7a5b33019..605a703e1 100644 --- a/app/Models/Common/Dashboard.php +++ b/app/Models/Common/Dashboard.php @@ -18,7 +18,7 @@ class Dashboard extends Model * * @var array */ - protected $fillable = ['company_id', 'name', 'enabled', 'created_by']; + protected $fillable = ['company_id', 'name', 'enabled', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Common/EmailTemplate.php b/app/Models/Common/EmailTemplate.php index ee3a084e9..74bbcecb4 100644 --- a/app/Models/Common/EmailTemplate.php +++ b/app/Models/Common/EmailTemplate.php @@ -13,7 +13,7 @@ class EmailTemplate extends Model * * @var array */ - protected $fillable = ['company_id', 'alias', 'class', 'name', 'subject', 'body', 'params']; + protected $fillable = ['company_id', 'alias', 'class', 'name', 'subject', 'body', 'params', 'created_from', 'created_by']; /** * Scope to only include contacts of a given type. diff --git a/app/Models/Common/Item.php b/app/Models/Common/Item.php index d76360eff..33288f14f 100644 --- a/app/Models/Common/Item.php +++ b/app/Models/Common/Item.php @@ -27,7 +27,7 @@ class Item extends Model * * @var array */ - protected $fillable = ['company_id', 'name', 'description', 'sale_price', 'purchase_price', 'category_id', 'enabled', 'created_by']; + protected $fillable = ['company_id', 'name', 'description', 'sale_price', 'purchase_price', 'category_id', 'enabled', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Common/ItemTax.php b/app/Models/Common/ItemTax.php index f2cce8dea..0ee85ff57 100644 --- a/app/Models/Common/ItemTax.php +++ b/app/Models/Common/ItemTax.php @@ -16,7 +16,7 @@ class ItemTax extends Model * * @var array */ - protected $fillable = ['company_id', 'item_id', 'tax_id']; + protected $fillable = ['company_id', 'item_id', 'tax_id', 'created_from', 'created_by']; public function item() { diff --git a/app/Models/Common/Media.php b/app/Models/Common/Media.php index 0a71d8774..fc80e959c 100644 --- a/app/Models/Common/Media.php +++ b/app/Models/Common/Media.php @@ -2,15 +2,17 @@ namespace App\Models\Common; +use App\Traits\Owners; +use App\Traits\Sources; use App\Traits\Tenants; use Illuminate\Database\Eloquent\SoftDeletes; use Plank\Mediable\Media as BaseMedia; class Media extends BaseMedia { - use SoftDeletes, Tenants; + use Owners, SoftDeletes, Sources, Tenants; protected $dates = ['deleted_at']; - protected $fillable = ['company_id']; + protected $fillable = ['company_id', 'created_from', 'created_by']; } diff --git a/app/Models/Common/Recurring.php b/app/Models/Common/Recurring.php index a3038f722..76f49af25 100644 --- a/app/Models/Common/Recurring.php +++ b/app/Models/Common/Recurring.php @@ -16,7 +16,7 @@ class Recurring extends Model * * @var array */ - protected $fillable = ['company_id', 'recurable_id', 'recurable_type', 'frequency', 'interval', 'started_at', 'count']; + protected $fillable = ['company_id', 'recurable_id', 'recurable_type', 'frequency', 'interval', 'started_at', 'count', 'created_from', 'created_by']; /** * Get all of the owning recurable models. diff --git a/app/Models/Common/Report.php b/app/Models/Common/Report.php index 85b6c6e7e..58060b93a 100644 --- a/app/Models/Common/Report.php +++ b/app/Models/Common/Report.php @@ -17,7 +17,7 @@ class Report extends Model * * @var array */ - protected $fillable = ['company_id', 'class', 'name', 'description', 'settings', 'created_by']; + protected $fillable = ['company_id', 'class', 'name', 'description', 'settings', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Common/Widget.php b/app/Models/Common/Widget.php index 337dbba01..71652501c 100644 --- a/app/Models/Common/Widget.php +++ b/app/Models/Common/Widget.php @@ -17,7 +17,7 @@ class Widget extends Model * * @var array */ - protected $fillable = ['company_id', 'dashboard_id', 'class', 'name', 'sort', 'settings', 'created_by']; + protected $fillable = ['company_id', 'dashboard_id', 'class', 'name', 'sort', 'settings', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Document/Document.php b/app/Models/Document/Document.php index 38c64b592..c7f4a17a9 100644 --- a/app/Models/Document/Document.php +++ b/app/Models/Document/Document.php @@ -51,6 +51,7 @@ class Document extends Model 'notes', 'footer', 'parent_id', + 'created_from', 'created_by', ]; diff --git a/app/Models/Document/DocumentHistory.php b/app/Models/Document/DocumentHistory.php index dd51b1f8c..cfb49975d 100644 --- a/app/Models/Document/DocumentHistory.php +++ b/app/Models/Document/DocumentHistory.php @@ -13,7 +13,7 @@ class DocumentHistory extends Model protected $table = 'document_histories'; - protected $fillable = ['company_id', 'type', 'document_id', 'status', 'notify', 'description']; + protected $fillable = ['company_id', 'type', 'document_id', 'status', 'notify', 'description', 'created_from', 'created_by']; public function document() { diff --git a/app/Models/Document/DocumentItem.php b/app/Models/Document/DocumentItem.php index f48a0cf9b..9ce1bf91b 100644 --- a/app/Models/Document/DocumentItem.php +++ b/app/Models/Document/DocumentItem.php @@ -30,6 +30,8 @@ class DocumentItem extends Model 'tax', 'discount_rate', 'discount_type', + 'created_from', + 'created_by', ]; /** diff --git a/app/Models/Document/DocumentItemTax.php b/app/Models/Document/DocumentItemTax.php index b927e8f07..cef7a5ccd 100644 --- a/app/Models/Document/DocumentItemTax.php +++ b/app/Models/Document/DocumentItemTax.php @@ -13,7 +13,7 @@ class DocumentItemTax extends Model protected $table = 'document_item_taxes'; - protected $fillable = ['company_id', 'type', 'document_id', 'document_item_id', 'tax_id', 'name', 'amount']; + protected $fillable = ['company_id', 'type', 'document_id', 'document_item_id', 'tax_id', 'name', 'amount', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Module/Module.php b/app/Models/Module/Module.php index e858afef5..93dd6922c 100644 --- a/app/Models/Module/Module.php +++ b/app/Models/Module/Module.php @@ -13,7 +13,7 @@ class Module extends Model * * @var array */ - protected $fillable = ['company_id', 'alias', 'enabled']; + protected $fillable = ['company_id', 'alias', 'enabled', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Models/Module/ModuleHistory.php b/app/Models/Module/ModuleHistory.php index dbd3376dd..124593a5b 100644 --- a/app/Models/Module/ModuleHistory.php +++ b/app/Models/Module/ModuleHistory.php @@ -13,5 +13,5 @@ class ModuleHistory extends Model * * @var array */ - protected $fillable = ['company_id', 'module_id', 'version', 'description']; + protected $fillable = ['company_id', 'module_id', 'version', 'description', 'created_from', 'created_by']; } diff --git a/app/Models/Setting/Category.php b/app/Models/Setting/Category.php index 3e39bb193..5f8b75c28 100644 --- a/app/Models/Setting/Category.php +++ b/app/Models/Setting/Category.php @@ -18,7 +18,7 @@ class Category extends Model * * @var array */ - protected $fillable = ['company_id', 'name', 'type', 'color', 'enabled', 'created_by']; + protected $fillable = ['company_id', 'name', 'type', 'color', 'enabled', 'created_from', 'created_by',]; /** * The attributes that should be cast. diff --git a/app/Models/Setting/Currency.php b/app/Models/Setting/Currency.php index f70c908ca..878c8c76b 100644 --- a/app/Models/Setting/Currency.php +++ b/app/Models/Setting/Currency.php @@ -30,6 +30,7 @@ class Currency extends Model 'symbol_first', 'decimal_mark', 'thousands_separator', + 'created_from', 'created_by', ]; diff --git a/app/Models/Setting/Tax.php b/app/Models/Setting/Tax.php index ddc69940a..627f19c66 100644 --- a/app/Models/Setting/Tax.php +++ b/app/Models/Setting/Tax.php @@ -24,7 +24,7 @@ class Tax extends Model * * @var array */ - protected $fillable = ['company_id', 'name', 'rate', 'type', 'enabled', 'created_by']; + protected $fillable = ['company_id', 'name', 'rate', 'type', 'enabled', 'created_from', 'created_by']; /** * The attributes that should be cast. diff --git a/app/Traits/Modules.php b/app/Traits/Modules.php index d5683d881..9818a7c1c 100644 --- a/app/Traits/Modules.php +++ b/app/Traits/Modules.php @@ -4,9 +4,9 @@ namespace App\Traits; use App\Models\Module\Module; use App\Traits\SiteApi; +use App\Utilities\Date; use App\Utilities\Info; -use Cache; -use Date; +use Illuminate\Support\Facades\Cache; trait Modules { diff --git a/app/Traits/Recurring.php b/app/Traits/Recurring.php index 9baedc337..4aa267723 100644 --- a/app/Traits/Recurring.php +++ b/app/Traits/Recurring.php @@ -18,6 +18,8 @@ trait Recurring $frequency = ($request['recurring_frequency'] != 'custom') ? $request['recurring_frequency'] : $request['recurring_custom_frequency']; $interval = (($request['recurring_frequency'] != 'custom') || ($request['recurring_interval'] < 1)) ? 1 : (int) $request['recurring_interval']; $started_at = !empty($request['paid_at']) ? $request['paid_at'] : $request['issued_at']; + $source = !empty($request['created_from']) ? $request['created_from'] : source_name(); + $owner = !empty($request['created_by']) ? $request['created_by'] : user_id(); $this->recurring()->create([ 'company_id' => $this->company_id, @@ -25,6 +27,8 @@ trait Recurring 'interval' => $interval, 'started_at' => $started_at, 'count' => (int) $request['recurring_count'], + 'created_from' => $source, + 'created_by' => $owner, ]); } @@ -40,16 +44,27 @@ trait Recurring $started_at = !empty($request['paid_at']) ? $request['paid_at'] : $request['issued_at']; $recurring = $this->recurring(); + $model_exists = $recurring->count(); - $function = $recurring->count() ? 'update' : 'create'; - - $recurring->$function([ + $data = [ 'company_id' => $this->company_id, 'frequency' => $frequency, 'interval' => $interval, 'started_at' => $started_at, 'count' => (int) $request['recurring_count'], - ]); + ]; + + if ($model_exists) { + $recurring->update($data); + } else { + $source = !empty($request['created_from']) ? $request['created_from'] : source_name(); + $owner = !empty($request['created_by']) ? $request['created_by'] : user_id(); + + $recurring->create(array_merge($data, [ + 'created_from' => $source, + 'created_by' => $owner, + ])); + } } public function getRecurringSchedule($set_until_date = true) diff --git a/app/Traits/Sources.php b/app/Traits/Sources.php new file mode 100644 index 000000000..770a2eec7 --- /dev/null +++ b/app/Traits/Sources.php @@ -0,0 +1,37 @@ +sourcable ?: true; + + return ($sourcable === true) && in_array('created_from', $this->getFillable()); + } + + public function isNotSourcable(): bool + { + return ! $this->isSourcable(); + } + + public function getSourceName($request = null): string + { + if (app()->runningInConsole()) { + $source = 'console'; + } + + if (empty($source)) { + $request = $request ?: request(); + + $source = $request->isApi() ? 'api' : null; + } + + if (empty($source)) { + $source = 'ui'; + } + + return $source; + } +} diff --git a/app/Traits/Uploads.php b/app/Traits/Uploads.php index d0b26aa31..7f0e9cb5e 100644 --- a/app/Traits/Uploads.php +++ b/app/Traits/Uploads.php @@ -22,6 +22,8 @@ trait Uploads return MediaUploader::makePrivate() ->beforeSave(function(MediaModel $media) { $media->company_id = company_id(); + $media->created_from = source_name(); + $media->created_by = user_id(); }) ->fromSource($file) ->toDirectory($path) @@ -41,6 +43,8 @@ trait Uploads return MediaUploader::makePrivate() ->beforeSave(function(MediaModel $media) { $media->company_id = company_id(); + $media->created_from = source_name(); + $media->created_by = user_id(); }) ->importPath($disk, $path); } diff --git a/app/Utilities/helpers.php b/app/Utilities/helpers.php index 12b82a177..84fbc7424 100644 --- a/app/Utilities/helpers.php +++ b/app/Utilities/helpers.php @@ -2,6 +2,7 @@ use App\Models\Common\Company; use App\Traits\DateTime; +use App\Traits\Sources; use App\Utilities\Date; use App\Utilities\Widgets; @@ -38,7 +39,7 @@ if (!function_exists('user_id')) { if (!function_exists('company_date_format')) { /** - * Format the given date based on company settings. + * Get the date format of company. * * @return string */ @@ -127,13 +128,30 @@ if (!function_exists('should_queue')) { } } +if (!function_exists('source_name')) { + /** + * Get the current source. + * + * @return string + */ + function source_name() + { + $tmp = new class() { + use Sources; + }; + + return $tmp->getSourceName(); + } +} + if (!function_exists('cache_prefix')) { /** * Cache system added company_id prefix. * * @return string */ - function cache_prefix() { + function cache_prefix() + { return company_id() . '_'; } } diff --git a/database/factories/Account.php b/database/factories/Account.php index a4e08eac6..9469448f6 100644 --- a/database/factories/Account.php +++ b/database/factories/Account.php @@ -31,6 +31,7 @@ class Account extends Factory 'bank_phone' => $this->faker->phoneNumber, 'bank_address' => $this->faker->address, 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Category.php b/database/factories/Category.php index b9d86ea64..bea7a5a9c 100644 --- a/database/factories/Category.php +++ b/database/factories/Category.php @@ -29,6 +29,7 @@ class Category extends Factory 'type' => $this->faker->randomElement($types), 'color' => $this->faker->hexColor, 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Contact.php b/database/factories/Contact.php index 2cd55e2d1..5284e7a90 100644 --- a/database/factories/Contact.php +++ b/database/factories/Contact.php @@ -39,6 +39,7 @@ class Contact extends Factory 'currency_code' => setting('default.currency'), 'reference' => $this->faker->text(5), 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Currency.php b/database/factories/Currency.php index d998cf2ea..22deec160 100644 --- a/database/factories/Currency.php +++ b/database/factories/Currency.php @@ -47,6 +47,7 @@ class Currency extends Factory 'decimal_mark' => $currency['decimal_mark'], 'thousands_separator' => $currency['thousands_separator'], 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Dashboard.php b/database/factories/Dashboard.php index a10f1b6a0..d3b591cc2 100644 --- a/database/factories/Dashboard.php +++ b/database/factories/Dashboard.php @@ -25,6 +25,7 @@ class Dashboard extends Factory 'company_id' => $this->company->id, 'name' => $this->faker->text(15), 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Document.php b/database/factories/Document.php index 6ecb0e5b0..1cc332fa7 100644 --- a/database/factories/Document.php +++ b/database/factories/Document.php @@ -45,6 +45,7 @@ class Document extends AbstractFactory 'currency_rate' => '1', 'notes' => $this->faker->text(5), 'amount' => '0', + 'created_from' => 'factory', ]; } diff --git a/database/factories/Item.php b/database/factories/Item.php index b90b43df0..54f4185f7 100644 --- a/database/factories/Item.php +++ b/database/factories/Item.php @@ -29,6 +29,7 @@ class Item extends Factory 'sale_price' => $this->faker->randomFloat(2, 10, 20), 'category_id' => $this->company->categories()->item()->get()->random(1)->pluck('id')->first(), 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Reconciliation.php b/database/factories/Reconciliation.php index 93ef46801..b915138ad 100644 --- a/database/factories/Reconciliation.php +++ b/database/factories/Reconciliation.php @@ -34,6 +34,7 @@ class Reconciliation extends Factory 'started_at' => $started_at, 'ended_at' => $ended_at, 'reconcile' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Role.php b/database/factories/Role.php index efcf0c881..b7962b82a 100644 --- a/database/factories/Role.php +++ b/database/factories/Role.php @@ -28,6 +28,7 @@ class Role extends Factory 'name' => strtolower($name), 'display_name' => $name, 'description' => $name, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Tax.php b/database/factories/Tax.php index 09f952267..4d4456e38 100644 --- a/database/factories/Tax.php +++ b/database/factories/Tax.php @@ -29,6 +29,7 @@ class Tax extends Factory 'rate' => $this->faker->randomFloat(2, 10, 20), 'type' => $this->faker->randomElement($types), 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Transaction.php b/database/factories/Transaction.php index d5e9b3933..10e505ab0 100644 --- a/database/factories/Transaction.php +++ b/database/factories/Transaction.php @@ -41,6 +41,7 @@ class Transaction extends Factory 'category_id' => $this->company->categories()->$category_type()->get()->random(1)->pluck('id')->first(), 'reference' => $this->faker->text(5), 'payment_method' => setting('default.payment_method'), + 'created_from' => 'factory', ]; } diff --git a/database/factories/Transfer.php b/database/factories/Transfer.php index 243ba52c5..4f4f0908a 100644 --- a/database/factories/Transfer.php +++ b/database/factories/Transfer.php @@ -43,6 +43,7 @@ class Transfer extends Factory 'category_id' => Category::transfer(), 'description' => $this->faker->text(20), 'reference' => $this->faker->text(20), + 'created_from' => 'factory', ]; $expense_transaction = Transaction::factory()->create(array_merge($request, [ diff --git a/database/factories/User.php b/database/factories/User.php index 8e04141bb..3e2f60b17 100644 --- a/database/factories/User.php +++ b/database/factories/User.php @@ -34,6 +34,7 @@ class User extends Factory 'companies' => ['1'], 'roles' => ['1'], 'enabled' => $this->faker->boolean ? 1 : 0, + 'created_from' => 'factory', ]; } diff --git a/database/factories/Widget.php b/database/factories/Widget.php index 6cf8ab6dc..a84fdf3e8 100644 --- a/database/factories/Widget.php +++ b/database/factories/Widget.php @@ -42,6 +42,7 @@ class Widget extends Factory 'dashboard_id' => $dashboard->id, 'name' => $this->faker->text(15), 'class' => $this->faker->randomElement($this->classes), + 'created_from' => 'factory', ]; } } diff --git a/database/migrations/2021_09_01_000000_core_v2124.php b/database/migrations/2021_09_01_000000_core_v2124.php index d7837962b..a2eedd413 100644 --- a/database/migrations/2021_09_01_000000_core_v2124.php +++ b/database/migrations/2021_09_01_000000_core_v2124.php @@ -19,6 +19,127 @@ class CoreV2124 extends Migration $table->string('zip_code')->nullable()->after('address'); $table->string('city')->nullable()->after('address'); }); + + Schema::table('accounts', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('categories', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('companies', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('contacts', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('reference'); + }); + + Schema::table('currencies', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('dashboards', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('documents', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('parent_id'); + }); + + Schema::table('document_histories', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('description'); + $table->string('created_from', 30)->nullable()->after('description'); + }); + + Schema::table('document_items', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('total'); + $table->string('created_from', 30)->nullable()->after('total'); + }); + + Schema::table('document_item_taxes', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('amount'); + $table->string('created_from', 30)->nullable()->after('amount'); + }); + + Schema::table('document_totals', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('sort_order'); + $table->string('created_from', 30)->nullable()->after('sort_order'); + }); + + Schema::table('email_templates', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('params'); + $table->string('created_from', 30)->nullable()->after('params'); + }); + + Schema::table('items', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('item_taxes', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('tax_id'); + $table->string('created_from', 30)->nullable()->after('tax_id'); + }); + + Schema::table('media', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('original_media_id'); + $table->string('created_from', 30)->nullable()->after('original_media_id'); + }); + + Schema::table('mediables', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('order'); + $table->string('created_from', 30)->nullable()->after('order'); + }); + + Schema::table('modules', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('enabled'); + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('module_histories', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('description'); + $table->string('created_from', 30)->nullable()->after('description'); + }); + + Schema::table('reconciliations', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('reconciled'); + }); + + Schema::table('recurring', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('count'); + $table->string('created_from', 30)->nullable()->after('count'); + }); + + Schema::table('reports', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('settings'); + }); + + Schema::table('roles', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('description'); + $table->string('created_from', 30)->nullable()->after('description'); + }); + + Schema::table('taxes', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('transactions', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('parent_id'); + }); + + Schema::table('transfers', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('income_transaction_id'); + }); + + Schema::table('users', function (Blueprint $table) { + $table->string('created_by', 30)->nullable()->after('enabled'); + $table->string('created_from', 30)->nullable()->after('enabled'); + }); + + Schema::table('widgets', function (Blueprint $table) { + $table->string('created_from', 30)->nullable()->after('settings'); + }); } /** @@ -28,8 +149,6 @@ class CoreV2124 extends Migration */ public function down() { - Schema::table('contacts', function (Blueprint $table) { - $table->dropColumn(['country','state', 'zip_code', 'city',]); - }); + // } } diff --git a/database/seeds/Accounts.php b/database/seeds/Accounts.php index 7caa995e1..c618f4070 100644 --- a/database/seeds/Accounts.php +++ b/database/seeds/Accounts.php @@ -36,6 +36,7 @@ class Accounts extends Seeder 'currency_code' => 'USD', 'bank_name' => trans('demo.accounts.cash'), 'enabled' => '1', + 'created_from' => 'seed', ])); setting()->set('default.account', $account->id); diff --git a/database/seeds/Categories.php b/database/seeds/Categories.php index 2c64e44cc..d60e695f3 100644 --- a/database/seeds/Categories.php +++ b/database/seeds/Categories.php @@ -70,6 +70,8 @@ class Categories extends Seeder $income_category_id = $expense_category_id = 0; foreach ($rows as $row) { + $row['created_from'] = 'seed'; + $category = $this->dispatch(new CreateCategory($row)); switch ($category->type) { diff --git a/database/seeds/Currencies.php b/database/seeds/Currencies.php index 40012985c..b37d41030 100644 --- a/database/seeds/Currencies.php +++ b/database/seeds/Currencies.php @@ -78,6 +78,8 @@ class Currencies extends Seeder ]; foreach ($rows as $row) { + $row['created_from'] = 'seed'; + $this->dispatch(new CreateCurrency($row)); } } diff --git a/database/seeds/Dashboards.php b/database/seeds/Dashboards.php index b076c377a..4f34b539a 100644 --- a/database/seeds/Dashboards.php +++ b/database/seeds/Dashboards.php @@ -45,6 +45,7 @@ class Dashboards extends Seeder 'App\Widgets\LatestExpenses', ], 'users' => $user_id, + 'created_from' => 'seed', ])); } } diff --git a/database/seeds/EmailTemplates.php b/database/seeds/EmailTemplates.php index c9eccdebf..e57dfa66f 100644 --- a/database/seeds/EmailTemplates.php +++ b/database/seeds/EmailTemplates.php @@ -3,11 +3,14 @@ namespace Database\Seeds; use App\Abstracts\Model; -use App\Models\Common\EmailTemplate; +use App\Jobs\Common\CreateEmailTemplate; +use App\Traits\Jobs; use Illuminate\Database\Seeder; class EmailTemplates extends Seeder { + use Jobs; + /** * Run the database seeds. * @@ -80,14 +83,15 @@ class EmailTemplates extends Seeder ]; foreach ($templates as $template) { - EmailTemplate::create([ + $this->dispatch(new CreateEmailTemplate([ 'company_id' => $company_id, 'alias' => $template['alias'], 'class' => $template['class'], 'name' => $template['name'], 'subject' => trans('email_templates.' . $template['alias'] . '.subject'), 'body' => trans('email_templates.' . $template['alias'] . '.body'), - ]); + 'created_from' => 'seed', + ])); } } } diff --git a/database/seeds/Reports.php b/database/seeds/Reports.php index 73f9ca963..34638914f 100644 --- a/database/seeds/Reports.php +++ b/database/seeds/Reports.php @@ -68,6 +68,8 @@ class Reports extends Seeder ]; foreach ($rows as $row) { + $row['created_from'] = 'seed'; + $this->dispatch(new CreateReport($row)); } } diff --git a/overrides/akaunting/laravel-module/Commands/InstallCommand.php b/overrides/akaunting/laravel-module/Commands/InstallCommand.php index 60e3c0320..65794c52d 100644 --- a/overrides/akaunting/laravel-module/Commands/InstallCommand.php +++ b/overrides/akaunting/laravel-module/Commands/InstallCommand.php @@ -43,6 +43,8 @@ class InstallCommand extends Command 'company_id' => $this->company_id, 'alias' => $this->alias, 'enabled' => '1', + 'created_from' => source_name(), + 'created_by' => user_id(), ]); $this->createHistory('installed'); diff --git a/tests/Feature/Common/SourcesTest.php b/tests/Feature/Common/SourcesTest.php new file mode 100644 index 000000000..1decf8f8f --- /dev/null +++ b/tests/Feature/Common/SourcesTest.php @@ -0,0 +1,46 @@ +getRequest(); + + $category = $this->dispatch(new CreateCategory($request)); + + $this->assertDatabaseHas('categories', [ + 'id' => $category->id, + 'created_from' => 'console', + ]); + } + + public function testItShouldHaveManualSource() + { + $request = $this->getRequest(); + + $request['created_from'] = 'manual'; + + $category = $this->dispatch(new CreateCategory($request)); + + $this->assertDatabaseHas('categories', [ + 'id' => $category->id, + 'created_from' => 'manual', + ]); + } + + public function getRequest() + { + return [ + 'company_id' => $this->company->id, + 'name' => $this->faker->text(15), + 'type' => 'income', + 'color' => $this->faker->hexColor, + 'enabled' => $this->faker->boolean ? 1 : 0, + ]; + } +}