diff --git a/app/Http/Controllers/Common/Dashboards.php b/app/Http/Controllers/Common/Dashboards.php index f255d5e36..1180d24fa 100644 --- a/app/Http/Controllers/Common/Dashboards.php +++ b/app/Http/Controllers/Common/Dashboards.php @@ -62,7 +62,7 @@ class Dashboards extends Controller $dashboard = $this->dispatch(new CreateDashboard([ 'company_id' => session('company_id'), 'name' => trans_choice('general.dashboards', 1), - 'default_widgets' => true, + 'default_widgets' => 'core', ])); } diff --git a/app/Http/Controllers/Common/Widgets.php b/app/Http/Controllers/Common/Widgets.php index 8fe25967d..8addc8dc4 100644 --- a/app/Http/Controllers/Common/Widgets.php +++ b/app/Http/Controllers/Common/Widgets.php @@ -16,7 +16,7 @@ class Widgets extends Controller */ public function index() { - $widgets = Utility::getClasses(); + $widgets = Utility::getClasses('all'); return response()->json($widgets); } diff --git a/app/Jobs/Common/CreateDashboard.php b/app/Jobs/Common/CreateDashboard.php index 36a3a72ab..8e87a5291 100644 --- a/app/Jobs/Common/CreateDashboard.php +++ b/app/Jobs/Common/CreateDashboard.php @@ -4,6 +4,7 @@ namespace App\Jobs\Common; use App\Abstracts\Job; use App\Models\Auth\User; +use App\Models\Common\Company; use App\Models\Common\Dashboard; use App\Models\Common\Widget; use App\Utilities\Widgets; @@ -55,7 +56,15 @@ class CreateDashboard extends Job { $list = []; - if ($this->request->has('users')) { + if ($this->request->has('all_users')) { + Company::find($this->request->get('company_id'))->users()->each(function ($user) use (&$list) { + if (!$this->shouldCreateDashboardFor($user)) { + return; + } + + $list[] = $user->id; + }); + } elseif ($this->request->has('users')) { $user_ids = Arr::wrap($this->request->get('users')); foreach($user_ids as $user_id) { @@ -97,7 +106,7 @@ class CreateDashboard extends Job $sort = 1; if ($this->request->has('default_widgets')) { - $widgets = Widgets::getClasses(false); + $widgets = Widgets::getClasses($this->request->get('default_widgets'), false); $this->createWidgets($widgets, $sort); } @@ -118,10 +127,11 @@ class CreateDashboard extends Job $name = (new $class())->getDefaultName(); } - Widget::create([ + Widget::firstOrCreate([ 'company_id' => $this->dashboard->company_id, 'dashboard_id' => $this->dashboard->id, 'class' => $class, + ], [ 'name' => $name, 'sort' => $sort, 'settings' => (new $class())->getDefaultSettings(), diff --git a/app/Listeners/Module/FinishUninstallation.php b/app/Listeners/Module/FinishUninstallation.php new file mode 100644 index 000000000..755b5c66c --- /dev/null +++ b/app/Listeners/Module/FinishUninstallation.php @@ -0,0 +1,62 @@ +deleteDashboards($event->alias); + $this->deleteReports($event->alias); + } + + /** + * Delete any dashboard created by the module. + * + * @param string $alias + * @return void + */ + protected function deleteDashboards($alias) + { + Dashboard::alias($alias)->get()->each(function ($dashboard) { + try { + $this->dispatch(new DeleteDashboard($dashboard)); + } catch (\Exception | \Throwable $e) { + report($e); + } + }); + } + + /** + * Delete any report created by the module. + * + * @param string $alias + * @return void + */ + protected function deleteReports($alias) + { + Report::alias($alias)->get()->each(function ($report) { + try { + $this->dispatch(new DeleteReport($report)); + } catch (\Exception | \Throwable $e) { + report($e); + } + }); + } +} diff --git a/app/Models/Common/Dashboard.php b/app/Models/Common/Dashboard.php index 93e6b19c5..3294730f6 100644 --- a/app/Models/Common/Dashboard.php +++ b/app/Models/Common/Dashboard.php @@ -5,6 +5,7 @@ namespace App\Models\Common; use App\Abstracts\Model; use Bkwld\Cloner\Cloneable; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Support\Str; class Dashboard extends Model { @@ -59,6 +60,60 @@ class Dashboard extends Model }); } + /** + * Scope to only include dashboards of a given alias. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $alias + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeAlias($query, $alias) + { + $class = ($alias == 'core') ? 'App\\\\' : 'Modules\\\\' . Str::studly($alias) . '\\\\'; + + return $query->whereHas('widgets', function ($query) use ($class) { + // Must have widgets of module + $query->where('class', 'like', $class . '%'); + })->whereDoesntHave('widgets', function ($query) use ($class) { + // Must not have widgets from other modules + $query->where('class', 'not like', $class . '%'); + }); + } + + /** + * Get the alias based on class. + * + * @return string + */ + public function getAliasAttribute() + { + $alias = ''; + + foreach ($this->widgets as $widget) { + if (Str::startsWith($widget->class, 'App\\')) { + $tmp_alias = 'core'; + } else { + $arr = explode('\\', $widget->class); + + $tmp_alias = Str::kebab($arr[1]); + } + + // First time set + if ($alias == '') { + $alias = $tmp_alias; + } + + // Must not have widgets from different modules + if ($alias != $tmp_alias) { + $alias = ''; + + break; + } + } + + return $alias; + } + /** * Create a new factory instance for the model. * diff --git a/app/Models/Common/Report.php b/app/Models/Common/Report.php index f5e597481..cd624444f 100644 --- a/app/Models/Common/Report.php +++ b/app/Models/Common/Report.php @@ -4,6 +4,7 @@ namespace App\Models\Common; use App\Abstracts\Model; use Bkwld\Cloner\Cloneable; +use Illuminate\Support\Str; class Report extends Model { @@ -26,4 +27,34 @@ class Report extends Model protected $casts = [ 'settings' => 'object', ]; + + /** + * Scope to only include reports of a given alias. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $alias + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeAlias($query, $alias) + { + $class = ($alias == 'core') ? 'App\\\\' : 'Modules\\\\' . Str::studly($alias) . '\\\\'; + + return $query->where('class', 'like', $class . '%'); + } + + /** + * Get the alias based on class. + * + * @return string + */ + public function getAliasAttribute() + { + if (Str::startsWith($this->class, 'App\\')) { + return 'core'; + } + + $arr = explode('\\', $this->class); + + return Str::kebab($arr[1]); + } } diff --git a/app/Providers/Event.php b/app/Providers/Event.php index 2b17d6de4..23ecd9fed 100644 --- a/app/Providers/Event.php +++ b/app/Providers/Event.php @@ -82,6 +82,9 @@ class Event extends Provider 'App\Listeners\Module\InstallExtraModules', 'App\Listeners\Module\FinishInstallation', ], + 'App\Events\Module\Uninstalled' => [ + 'App\Listeners\Module\FinishUninstallation', + ], ]; /** diff --git a/app/Traits/Users.php b/app/Traits/Users.php index d2e2a324f..fedc0903c 100644 --- a/app/Traits/Users.php +++ b/app/Traits/Users.php @@ -46,7 +46,7 @@ trait Users $user = user(); if (empty($user)) { - return false; + return app()->runningInConsole() ? true : false; } $dashboard = $user->dashboards()->where('id', $id)->first(); diff --git a/app/Utilities/Widgets.php b/app/Utilities/Widgets.php index f4a65e5d6..60f5d709b 100644 --- a/app/Utilities/Widgets.php +++ b/app/Utilities/Widgets.php @@ -8,24 +8,30 @@ use Illuminate\Support\Str; class Widgets { - public static function getClasses($check_permission = true) + public static function getClasses($alias = 'core', $check_permission = true) { - $classes = []; + $classes = $list = []; - $list = [ - 'App\Widgets\TotalIncome', - 'App\Widgets\TotalExpenses', - 'App\Widgets\TotalProfit', - 'App\Widgets\CashFlow', - 'App\Widgets\IncomeByCategory', - 'App\Widgets\ExpensesByCategory', - 'App\Widgets\AccountBalance', - 'App\Widgets\LatestIncome', - 'App\Widgets\LatestExpenses', - 'App\Widgets\Currencies', - ]; + if (in_array($alias, ['core', 'all'])) { + $list = [ + 'App\Widgets\TotalIncome', + 'App\Widgets\TotalExpenses', + 'App\Widgets\TotalProfit', + 'App\Widgets\CashFlow', + 'App\Widgets\IncomeByCategory', + 'App\Widgets\ExpensesByCategory', + 'App\Widgets\AccountBalance', + 'App\Widgets\LatestIncome', + 'App\Widgets\LatestExpenses', + 'App\Widgets\Currencies', + ]; + } + + Module::enabled()->each(function ($module) use (&$list, $alias) { + if (!in_array($alias, [$module->alias, 'all'])) { + return; + } - Module::enabled()->each(function ($module) use (&$list) { $m = module($module->alias); if (!$m || empty($m->get('widgets'))) { diff --git a/database/seeds/Dashboards.php b/database/seeds/Dashboards.php index afd9e316e..3d966f945 100644 --- a/database/seeds/Dashboards.php +++ b/database/seeds/Dashboards.php @@ -33,7 +33,7 @@ class Dashboards extends Seeder $this->dispatch(new CreateDashboard([ 'company_id' => $company_id, 'name' => trans_choice('general.dashboards', 1), - 'default_widgets' => true, + 'default_widgets' => 'core', 'users' => $user_id, ])); }