diff --git a/app/Events/AdminMenuCreated.php b/app/Events/AdminMenuCreated.php index 9883abb09..764c931bf 100644 --- a/app/Events/AdminMenuCreated.php +++ b/app/Events/AdminMenuCreated.php @@ -15,4 +15,4 @@ class AdminMenuCreated { $this->menu = $menu; } -} \ No newline at end of file +} diff --git a/app/Events/BillCreated.php b/app/Events/BillCreated.php index fc4881a74..11b29cc1e 100644 --- a/app/Events/BillCreated.php +++ b/app/Events/BillCreated.php @@ -15,4 +15,4 @@ class BillCreated { $this->bill = $bill; } -} \ No newline at end of file +} diff --git a/app/Events/BillUpdated.php b/app/Events/BillUpdated.php index 21751e17a..563eb3254 100644 --- a/app/Events/BillUpdated.php +++ b/app/Events/BillUpdated.php @@ -15,4 +15,4 @@ class BillUpdated { $this->bill = $bill; } -} \ No newline at end of file +} diff --git a/app/Events/CompanySwitched.php b/app/Events/CompanySwitched.php index 3738c8dae..2a25ec4e0 100644 --- a/app/Events/CompanySwitched.php +++ b/app/Events/CompanySwitched.php @@ -15,4 +15,4 @@ class CompanySwitched { $this->company = $company; } -} \ No newline at end of file +} diff --git a/app/Events/CustomerMenuCreated.php b/app/Events/CustomerMenuCreated.php index 5766e1ba2..b7c6fcccc 100644 --- a/app/Events/CustomerMenuCreated.php +++ b/app/Events/CustomerMenuCreated.php @@ -15,4 +15,4 @@ class CustomerMenuCreated { $this->menu = $menu; } -} \ No newline at end of file +} diff --git a/app/Events/InvoiceCreated.php b/app/Events/InvoiceCreated.php index afa2e3c62..e6ab023a8 100644 --- a/app/Events/InvoiceCreated.php +++ b/app/Events/InvoiceCreated.php @@ -15,4 +15,4 @@ class InvoiceCreated { $this->invoice = $invoice; } -} \ No newline at end of file +} diff --git a/app/Events/InvoicePrinting.php b/app/Events/InvoicePrinting.php index f775b69dc..78fb14c7d 100644 --- a/app/Events/InvoicePrinting.php +++ b/app/Events/InvoicePrinting.php @@ -15,4 +15,4 @@ class InvoicePrinting { $this->invoice = $invoice; } -} \ No newline at end of file +} diff --git a/app/Events/InvoiceUpdated.php b/app/Events/InvoiceUpdated.php index d9d6fc3ee..2f4db58e3 100644 --- a/app/Events/InvoiceUpdated.php +++ b/app/Events/InvoiceUpdated.php @@ -15,4 +15,4 @@ class InvoiceUpdated { $this->invoice = $invoice; } -} \ No newline at end of file +} diff --git a/app/Events/ModuleInstalled.php b/app/Events/ModuleInstalled.php index b581eb539..3ce3ef2b0 100644 --- a/app/Events/ModuleInstalled.php +++ b/app/Events/ModuleInstalled.php @@ -19,4 +19,4 @@ class ModuleInstalled $this->alias = $alias; $this->company_id = $company_id; } -} \ No newline at end of file +} diff --git a/app/Events/UpdateFinished.php b/app/Events/UpdateFinished.php index d221c60fd..8af0b3177 100644 --- a/app/Events/UpdateFinished.php +++ b/app/Events/UpdateFinished.php @@ -23,4 +23,4 @@ class UpdateFinished $this->old = $old; $this->new = $new; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Auth/Login.php b/app/Http/Controllers/Auth/Login.php index ea2aabbf8..68d3ca69d 100644 --- a/app/Http/Controllers/Auth/Login.php +++ b/app/Http/Controllers/Auth/Login.php @@ -79,6 +79,11 @@ class Login extends Controller return redirect($path); } + // Check wizard + if (!setting('general.wizard', false)) { + return redirect('wizard'); + } + return redirect('/'); } diff --git a/app/Http/Controllers/Common/Companies.php b/app/Http/Controllers/Common/Companies.php index 9ed22afe0..1c8efba9e 100644 --- a/app/Http/Controllers/Common/Companies.php +++ b/app/Http/Controllers/Common/Companies.php @@ -264,6 +264,11 @@ class Companies extends Controller event(new CompanySwitched($company)); } + // Check wizard + if (!setting('general.wizard', false)) { + return redirect('wizard'); + } + return redirect('/'); } diff --git a/app/Http/Controllers/Wizard/Companies.php b/app/Http/Controllers/Wizard/Companies.php new file mode 100644 index 000000000..b4f34ee11 --- /dev/null +++ b/app/Http/Controllers/Wizard/Companies.php @@ -0,0 +1,81 @@ +setSettings(); + + return view('wizard.companies.edit', compact('company')); + } + + /** + * Update the specified resource in storage. + * + * @param Company $company + * @param Request $request + * + * @return Response + */ + public function update(Request $request) + { + // Company + $company = Company::find(session('company_id')); + + $fields = $request->all(); + + $skip_keys = ['company_id', '_method', '_token']; + $file_keys = ['company_logo', 'invoice_logo']; + + foreach ($fields as $key => $value) { + // Don't process unwanted keys + if (in_array($key, $skip_keys)) { + continue; + } + + // Process file uploads + if (in_array($key, $file_keys)) { + // Upload attachment + if ($request->file($key)) { + $media = $this->getMedia($request->file($key), 'settings'); + + $company->attachMedia($media, $key); + + $value = $media->id; + } + + // Prevent reset + if (empty($value)) { + continue; + } + } + + setting()->set('general.' . $key, $value); + } + + // Save all settings + setting()->save(); + + return redirect('wizard/currencies'); + } +} diff --git a/app/Http/Controllers/Wizard/Currencies.php b/app/Http/Controllers/Wizard/Currencies.php new file mode 100644 index 000000000..8ae9e6591 --- /dev/null +++ b/app/Http/Controllers/Wizard/Currencies.php @@ -0,0 +1,311 @@ +toArray(); + + // Prepare codes + $codes = array(); + $currencies = MoneyCurrency::getCurrencies(); + foreach ($currencies as $key => $item) { + // Don't show if already available + if (in_array($key, $current)) { + continue; + } + + $codes[$key] = $key; + } + + $html = view('wizard.currencies.create', compact('codes'))->render(); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => 'null', + 'html' => $html, + ]); + } + + /** + * Store a newly created resource in storage. + * + * @param Request $request + * + * @return Response + */ + public function store(Request $request) + { + // Force the rate to be 1 for default currency + if ($request['default_currency']) { + $request['rate'] = '1'; + } + + $currency = Currency::create($request->all()); + + // Update default currency setting + if ($request['default_currency']) { + setting()->set('general.default_currency', $request['code']); + setting()->save(); + } + + $message = trans('messages.success.added', ['type' => trans_choice('general.currencies', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $currency, + ]); + } + + /** + * Show the form for editing the specified resource. + * + * @param Currency $currency + * + * @return Response + */ + public function edit(Currency $currency) + { + if (setting('general.wizard', false)) { + return redirect('/'); + } + + // Get current currencies + $current = Currency::pluck('code')->toArray(); + + // Prepare codes + $codes = array(); + $currencies = MoneyCurrency::getCurrencies(); + foreach ($currencies as $key => $item) { + // Don't show if already available + if (($key != $currency->code) && in_array($key, $current)) { + continue; + } + + $codes[$key] = $key; + } + + $item = $currency; + + $html = view('wizard.currencies.edit', compact('item', 'codes'))->render(); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => 'null', + 'html' => $html, + ]); + } + + /** + * Update the specified resource in storage. + * + * @param Currency $currency + * @param Request $request + * + * @return Response + */ + public function update(Currency $currency, Request $request) + { + // Check if we can disable or change the code + if (!$request['enabled'] || ($currency->code != $request['code'])) { + $relationships = $this->countRelationships($currency, [ + 'accounts' => 'accounts', + 'customers' => 'customers', + 'invoices' => 'invoices', + 'revenues' => 'revenues', + 'bills' => 'bills', + 'payments' => 'payments', + ]); + + if ($currency->code == setting('general.default_currency')) { + $relationships[] = strtolower(trans_choice('general.companies', 1)); + } + } + + if (empty($relationships)) { + // Force the rate to be 1 for default currency + if ($request['default_currency']) { + $request['rate'] = '1'; + } + + $currency->update($request->all()); + + // Update default currency setting + if ($request['default_currency']) { + setting()->set('general.default_currency', $request['code']); + setting()->save(); + } + + $message = trans('messages.success.updated', ['type' => trans_choice('general.currencies', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $currency, + ]); + } else { + $message = trans('messages.warning.disabled', ['name' => $currency->name, 'text' => implode(', ', $relationships)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $currency, + ]); + } + } + + /** + * Enable the specified resource. + * + * @param Currency $currency + * + * @return Response + */ + public function enable(Currency $currency) + { + $currency->enabled = 1; + $currency->save(); + + $message = trans('messages.success.enabled', ['type' => trans_choice('general.currencies', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $currency, + ]); + } + + /** + * Disable the specified resource. + * + * @param Currency $currency + * + * @return Response + */ + public function disable(Currency $currency) + { + $relationships = $this->countRelationships($currency, [ + 'accounts' => 'accounts', + 'customers' => 'customers', + 'invoices' => 'invoices', + 'revenues' => 'revenues', + 'bills' => 'bills', + 'payments' => 'payments', + ]); + + if ($currency->code == setting('general.default_currency')) { + $relationships[] = strtolower(trans_choice('general.companies', 1)); + } + + if (empty($relationships)) { + $currency->enabled = 0; + $currency->save(); + + $message = trans('messages.success.disabled', ['type' => trans_choice('general.currencies', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $currency, + ]); + } else { + $message = trans('messages.warning.disabled', ['name' => $currency->name, 'text' => implode(', ', $relationships)]); + + return response()->json([ + 'success' => false, + 'error' => true, + 'message' => $message, + 'data' => $currency, + ]); + } + } + + /** + * Remove the specified resource from storage. + * + * @param Currency $currency + * + * @return Response + */ + public function destroy(Currency $currency) + { + $relationships = $this->countRelationships($currency, [ + 'accounts' => 'accounts', + 'customers' => 'customers', + 'invoices' => 'invoices', + 'revenues' => 'revenues', + 'bills' => 'bills', + 'payments' => 'payments', + ]); + + if ($currency->code == setting('general.default_currency')) { + $relationships[] = strtolower(trans_choice('general.companies', 1)); + } + + if (empty($relationships)) { + $currency->delete(); + + $message = trans('messages.success.deleted', ['type' => trans_choice('general.currencies', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $currency, + ]); + } else { + $message = trans('messages.warning.deleted', ['name' => $currency->name, 'text' => implode(', ', $relationships)]); + + return response()->json([ + 'success' => false, + 'error' => true, + 'message' => $message, + 'data' => $currency, + ]); + } + } +} diff --git a/app/Http/Controllers/Wizard/Finish.php b/app/Http/Controllers/Wizard/Finish.php new file mode 100644 index 000000000..25a9727fb --- /dev/null +++ b/app/Http/Controllers/Wizard/Finish.php @@ -0,0 +1,39 @@ +set('general.wizard', true); + + // Save all settings + setting()->save(); + + $data = [ + 'query' => [ + 'limit' => 4 + ] + ]; + + $modules = $this->getFeaturedModules($data); + + return view('wizard.finish.index', compact('modules')); + } +} diff --git a/app/Http/Controllers/Wizard/Taxes.php b/app/Http/Controllers/Wizard/Taxes.php new file mode 100644 index 000000000..8d0ff82ab --- /dev/null +++ b/app/Http/Controllers/Wizard/Taxes.php @@ -0,0 +1,224 @@ +render(); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => 'null', + 'html' => $html, + ]); + } + + /** + * Store a newly created resource in storage. + * + * @param Request $request + * + * @return Response + */ + public function store(Request $request) + { + $tax = Tax::create($request->all()); + + $message = trans('messages.success.added', ['type' => trans_choice('general.tax_rates', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $tax, + ]); + } + + /** + * Show the form for editing the specified resource. + * + * @param Tax $tax + * + * @return Response + */ + public function edit(Tax $tax) + { + if (setting(setting('general.wizard', false))) { + return redirect('/'); + } + + $item = $tax; + + return view('wizard.taxes.edit', compact('item')); + } + + /** + * Update the specified resource in storage. + * + * @param Tax $tax + * @param Request $request + * + * @return Response + */ + public function update(Tax $tax, Request $request) + { + $relationships = $this->countRelationships($tax, [ + 'items' => 'items', + 'invoice_items' => 'invoices', + 'bill_items' => 'bills', + ]); + + if (empty($relationships) || $request['enabled']) { + $tax->update($request->all()); + + $message = trans('messages.success.updated', ['type' => trans_choice('general.tax_rates', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $tax, + ]); + } else { + $message = trans('messages.warning.disabled', ['name' => $tax->name, 'text' => implode(', ', $relationships)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $tax, + ]); + } + } + + /** + * Enable the specified resource. + * + * @param Tax $tax + * + * @return Response + */ + public function enable(Tax $tax) + { + $tax->enabled = 1; + $tax->save(); + + $message = trans('messages.success.enabled', ['type' => trans_choice('general.tax_rates', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $tax, + ]); + } + + /** + * Disable the specified resource. + * + * @param Tax $tax + * + * @return Response + */ + public function disable(Tax $tax) + { + $relationships = $this->countRelationships($tax, [ + 'items' => 'items', + 'invoice_items' => 'invoices', + 'bill_items' => 'bills', + ]); + + if (empty($relationships)) { + $tax->enabled = 0; + $tax->save(); + + $message = trans('messages.success.disabled', ['type' => trans_choice('general.tax_rates', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $tax, + ]); + } else { + $message = trans('messages.warning.disabled', ['name' => $tax->name, 'text' => implode(', ', $relationships)]); + + return response()->json([ + 'success' => false, + 'error' => true, + 'message' => $message, + 'data' => $tax, + ]); + } + } + + /** + * Remove the specified resource from storage. + * + * @param Tax $tax + * + * @return Response + */ + public function destroy(Tax $tax) + { + $relationships = $this->countRelationships($tax, [ + 'items' => 'items', + 'invoice_items' => 'invoices', + 'bill_items' => 'bills', + ]); + + if (empty($relationships)) { + $tax->delete(); + + $message = trans('messages.success.deleted', ['type' => trans_choice('general.taxes', 1)]); + + return response()->json([ + 'success' => true, + 'error' => false, + 'message' => $message, + 'data' => $tax, + ]); + } else { + $message = trans('messages.warning.deleted', ['name' => $tax->name, 'text' => implode(', ', $relationships)]); + + return response()->json([ + 'success' => false, + 'error' => true, + 'message' => $message, + 'data' => $tax, + ]); + } + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 7ce07c8a5..8f21fcc23 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -41,6 +41,13 @@ class Kernel extends HttpKernel 'company.currencies', ], + 'wizard' => [ + 'web', + 'language', + 'auth', + 'permission:read-admin-panel', + ], + 'admin' => [ 'web', 'language', diff --git a/app/Http/Middleware/AdminMenu.php b/app/Http/Middleware/AdminMenu.php index 817204b3c..2acf708a0 100644 --- a/app/Http/Middleware/AdminMenu.php +++ b/app/Http/Middleware/AdminMenu.php @@ -204,4 +204,4 @@ class AdminMenu return $next($request); } -} \ No newline at end of file +} diff --git a/app/Http/Requests/Wizard/Company.php b/app/Http/Requests/Wizard/Company.php new file mode 100644 index 000000000..114f6877f --- /dev/null +++ b/app/Http/Requests/Wizard/Company.php @@ -0,0 +1,30 @@ + 'mimes:' . setting('general.file_types') . '|between:0,' . setting('general.file_size') * 1024, + ]; + } +} diff --git a/app/Listeners/Updates/Version130.php b/app/Listeners/Updates/Version130.php index b6aa5bd1d..4696b1aaa 100644 --- a/app/Listeners/Updates/Version130.php +++ b/app/Listeners/Updates/Version130.php @@ -3,6 +3,8 @@ namespace App\Listeners\Updates; use App\Events\UpdateFinished; +use App\Models\Auth\Role; +use App\Models\Auth\Permission; use Artisan; class Version130 extends Listener @@ -24,10 +26,110 @@ class Version130 extends Listener return; } + $permissions = $this->getPermissions(); + + // Attach permission to roles + $roles = Role::all(); + + foreach ($roles as $role) { + $allowed = ['admin']; + + if (!in_array($role->name, $allowed)) { + continue; + } + + foreach ($permissions as $permission) { + $role->attachPermission($permission); + } + } + // Set new Item Reminder settings setting(['general.send_item_reminder' => '0']); setting(['general.schedule_item_stocks' => '3,5,7']); + setting(['general.wizard' => '1']); setting()->save(); } + + protected function getPermissions() + { + $permissions = []; + + // Create permissions + $permissions[] = Permission::firstOrCreate([ + 'name' => 'create-wizard-companies', + 'display_name' => 'Create Wizard Compaines', + 'description' => 'Create Wizard Compaines', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'create-wizard-currencies', + 'display_name' => 'Create Wizard Currencies', + 'description' => 'Create Wizard Currencies', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'create-wizard-taxes', + 'display_name' => 'Create Wizard Taxes', + 'description' => 'Create Wizard Taxes', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'create-wizard-finish', + 'display_name' => 'Create Wizard Finish', + 'description' => 'Create Wizard Finish', + ]); + + // Read permissions + $permissions[] = Permission::firstOrCreate([ + 'name' => 'read-wizard-companies', + 'display_name' => 'Read Wizard Compaines', + 'description' => 'Read Wizard Compaines', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'read-wizard-currencies', + 'display_name' => 'Read Wizard Currencies', + 'description' => 'Read Wizard Currencies', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'read-wizard-taxes', + 'display_name' => 'Read Wizard Taxes', + 'description' => 'Read Wizard Taxes', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'read-wizard-finish', + 'display_name' => 'Read Wizard Finish', + 'description' => 'Read Wizard Finish', + ]); + + // Update permissions + $permissions[] = Permission::firstOrCreate([ + 'name' => 'update-wizard-companies', + 'display_name' => 'Update Wizard Compaines', + 'description' => 'Update Wizard Compaines', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'update-wizard-currencies', + 'display_name' => 'Update Wizard Currencies', + 'description' => 'Update Wizard Currencies', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'update-wizard-taxes', + 'display_name' => 'Update Wizard Taxes', + 'description' => 'Update Wizard Taxes', + ]); + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'update-wizard-finish', + 'display_name' => 'Update Wizard Finish', + 'description' => 'Update Wizard Finish', + ]); + + return $permissions; + } } diff --git a/app/Providers/ViewComposerServiceProvider.php b/app/Providers/ViewComposerServiceProvider.php index 7cd15d6ac..0e690522a 100644 --- a/app/Providers/ViewComposerServiceProvider.php +++ b/app/Providers/ViewComposerServiceProvider.php @@ -31,7 +31,7 @@ class ViewComposerServiceProvider extends ServiceProvider // Add notifications to header View::composer( - ['partials.admin.header', 'partials.customer.header'], 'App\Http\ViewComposers\Header' + ['partials.wizard.header', 'partials.admin.header', 'partials.customer.header'], 'App\Http\ViewComposers\Header' ); // Add limits to index diff --git a/app/Traits/Modules.php b/app/Traits/Modules.php index 5076ecf1c..977c2a49f 100644 --- a/app/Traits/Modules.php +++ b/app/Traits/Modules.php @@ -200,6 +200,17 @@ trait Modules return []; } + public function getFeaturedModules($data = []) + { + $response = $this->getRemote('apps/featured', 'GET', $data); + + if ($response && ($response->getStatusCode() == 200)) { + return json_decode($response->getBody())->data; + } + + return []; + } + public function getCoreVersion() { $data['query'] = Info::all(); diff --git a/app/Utilities/Installer.php b/app/Utilities/Installer.php index 5d6f8116f..5fbe6c244 100644 --- a/app/Utilities/Installer.php +++ b/app/Utilities/Installer.php @@ -157,7 +157,7 @@ class Installer try { DB::connection('install_test')->getPdo(); - } catch (\Exception $e) {; + } catch (\Exception $e) { return false; } diff --git a/database/seeds/Roles.php b/database/seeds/Roles.php index b6d1b93eb..71069bd0d 100644 --- a/database/seeds/Roles.php +++ b/database/seeds/Roles.php @@ -63,6 +63,10 @@ class Roles extends Seeder 'reports-income-expense-summary' => 'r', 'reports-profit-loss' => 'r', 'reports-tax-summary' => 'r', + 'wizard-companies' => 'c,r,u', + 'wizard-currencies' => 'c,r,u', + 'wizard-taxes' => 'c,r,u', + 'wizard-finish' => 'c,r,u', ], 'manager' => [ 'admin-panel' => 'r', diff --git a/database/seeds/Settings.php b/database/seeds/Settings.php index 1c530c9b5..1746965ab 100644 --- a/database/seeds/Settings.php +++ b/database/seeds/Settings.php @@ -51,7 +51,8 @@ class Settings extends Seeder 'general.session_lifetime' => '30', 'general.file_size' => '2', 'general.file_types' => 'pdf,jpeg,jpg,png', - 'offlinepayment.methods' => '[{"code":"offlinepayment.cash.1","name":"Cash","order":"1","description":null},{"code":"offlinepayment.bank_transfer.2","name":"Bank Transfer","order":"2","description":null}]', + 'general.wizard' => '0', + 'offlinepayment.methods' => '[{"code":"offlinepayment.cash.1","name":"Cash","order":"1","description":null},{"code":"offlinepayment.bank_transfer.2","name":"Bank Transfer","order":"2","description":null}]', ]); } } diff --git a/public/css/app.css b/public/css/app.css index 0058aecdf..4374d6c64 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -772,4 +772,62 @@ input[type="number"] { #items .select2-search__field { padding-left: 15px; -} \ No newline at end of file +} + +.stepwizard-step p { + margin-top: 5px; + font-size: 16px; + color:#666; +} + +.stepwizard-row { + display: table-row; +} + +.stepwizard { + display: table; + width: 100%; + position: relative; + margin-top: 20px; +} + +.stepwizard-step button[disabled] { + /*opacity: 1 !important; + filter: alpha(opacity=100) !important;*/ +} + +.stepwizard .btn.disabled, .stepwizard .btn[disabled], .stepwizard fieldset[disabled] .btn { + opacity:1 !important; + color:#bbb; +} + +.stepwizard-row:before { + top: 26px; + bottom: 0; + position: absolute; + content:" "; + width: 100%; + height: 1px; + background-color: #ccc; + z-index: 0; +} + +.stepwizard-step { + display: table-cell; + text-align: center; + position: relative; +} + +.btn-circle.btn-success { + color: #fff; +} + +.btn-circle { + width: 50px; + height: 50px; + text-align: center; + padding: 1px 0; + font-size: 30px; + line-height: 1.428571; + border-radius: 30px; +} diff --git a/public/js/app.js b/public/js/app.js index f439f68c0..5b153e223 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -198,7 +198,9 @@ $(document).ready(function () { return true; }); - $('.input-group-invoice-text select').select2(); + if (document.getElementsByClassName('input-group-invoice-text').length) { + $('.input-group-invoice-text select').select2(); + } }); function confirmDelete(form_id, title, message, button_cancel, button_delete) { diff --git a/resources/lang/en-GB/general.php b/resources/lang/en-GB/general.php index daee66c9d..3459271b0 100644 --- a/resources/lang/en-GB/general.php +++ b/resources/lang/en-GB/general.php @@ -102,10 +102,14 @@ return [ 'partially' => 'Partially', 'partially_paid' => 'Partially Paid', 'export' => 'Export', + 'finish' => 'Finish', + 'wizard' => 'Wizard', + 'skip' => 'Skip', 'enable' => 'Enable', 'disable' => 'Disable', 'select_all' => 'Select All', 'unselect_all' => 'Unselect All', + 'go_to' => 'Go to :name', 'title' => [ 'new' => 'New :type', 'edit' => 'Edit :type', diff --git a/resources/lang/en-GB/modules.php b/resources/lang/en-GB/modules.php index 80a0bbd44..3a2a9a373 100644 --- a/resources/lang/en-GB/modules.php +++ b/resources/lang/en-GB/modules.php @@ -16,6 +16,8 @@ return [ 'no_apps' => 'There are no apps in this category, yet.', 'developer' => 'Are you a developer? Here you can learn how to create an app and start selling today!', + 'recommended_apps' => 'Recommended Apps', + 'about' => 'About', 'added' => 'Added', diff --git a/resources/views/layouts/wizard.blade.php b/resources/views/layouts/wizard.blade.php new file mode 100644 index 000000000..278b51d48 --- /dev/null +++ b/resources/views/layouts/wizard.blade.php @@ -0,0 +1,20 @@ + + @include('partials.wizard.head') + + + @stack('body_start') + + +
+ @include('partials.wizard.content') +
+ + @stack('body_end') + + + + diff --git a/resources/views/partials/wizard/content.blade.php b/resources/views/partials/wizard/content.blade.php new file mode 100644 index 000000000..4abf0d968 --- /dev/null +++ b/resources/views/partials/wizard/content.blade.php @@ -0,0 +1,39 @@ +@stack('content_start') + + +
+ @stack('content_wrapper_start') + + +
+ @stack('content_header_start') + +

+ @yield('title') + @yield('new_button') +

+ + @stack('content_header_end') +
+ + +
+ @include('flash::message') + + @stack('content_content_start') + + @yield('content') + + @stack('content_content_end') +
+ + + @stack('content_wrapper_end') +
+ + + + +@stack('content_end') \ No newline at end of file diff --git a/resources/views/partials/wizard/head.blade.php b/resources/views/partials/wizard/head.blade.php new file mode 100644 index 000000000..594a1c98c --- /dev/null +++ b/resources/views/partials/wizard/head.blade.php @@ -0,0 +1,101 @@ + + @stack('head_start') + + + + + + + @yield('title') - @setting('general.company_name') + + + + + + + + + + + @if (setting('general.admin_theme', 'skin-green-light') == 'skin-green-light') + + @else + + + @endif + + + + + + + + + @stack('css') + + @stack('stylesheet') + + + + + + + + + + + + + + + + + + + + + + + + @stack('js') + + @stack('scripts') + + @stack('head_end') + diff --git a/resources/views/partials/wizard/pagination.blade.php b/resources/views/partials/wizard/pagination.blade.php new file mode 100644 index 000000000..395807023 --- /dev/null +++ b/resources/views/partials/wizard/pagination.blade.php @@ -0,0 +1,16 @@ +@stack('pagination_start') + +@if ($items->firstItem()) +
+ {{ trans('pagination.showing', ['first' => $items->firstItem(), 'last' => $items->lastItem(), 'total' => $items->total(), 'type' => strtolower(trans_choice('general.' . $type, 2))]) }} +
+
+ {!! $items->appends(request()->except('page'))->links() !!} +
+@else +
+ {{ trans('general.no_records') }} +
+@endif + +@stack('pagination_end') \ No newline at end of file diff --git a/resources/views/settings/settings/edit.blade.php b/resources/views/settings/settings/edit.blade.php index 8b8d99f91..37a5700bf 100644 --- a/resources/views/settings/settings/edit.blade.php +++ b/resources/views/settings/settings/edit.blade.php @@ -39,6 +39,8 @@ {{ Form::textareaGroup('company_address', trans('settings.company.address')) }} {{ Form::fileGroup('company_logo', trans('settings.company.logo')) }} + + {!! Form::hidden('wizard', null, ['id' => 'wizard']) !!}
diff --git a/resources/views/wizard/companies/edit.blade.php b/resources/views/wizard/companies/edit.blade.php new file mode 100644 index 000000000..e1d9805d5 --- /dev/null +++ b/resources/views/wizard/companies/edit.blade.php @@ -0,0 +1,131 @@ +@extends('layouts.wizard') + +@section('title', trans('general.wizard')) + +@section('content') + +
+
+
+
+
+ 1 +

{{ trans_choice('general.companies', 1) }}

+
+
+ +

{{ trans_choice('general.currencies', 2) }}

+
+
+ +

{{ trans_choice('general.taxes', 2) }}

+
+
+ +

{{ trans_choice('general.finish', 1) }}

+
+
+
+
+
+ +
+
+ + {!! Form::model($company, ['method' => 'PATCH', 'files' => true, 'url' => ['wizard/companies'], 'role' => 'form', 'class' => 'form-loading-button']) !!} + +
+

{{ trans_choice('general.companies', 1) }}

+
+ + +
+
+
+ {!! Form::label('sale_price', trans('modules.api_token'), ['class' => 'control-label']) !!} +
+ + {!! Form::text('api_token', setting('general.api_token', null), ['class' => 'form-control', 'required' => 'required', 'placeholder' => trans('general.form.enter', ['field' => trans('modules.api_token')])]) !!} +
+ {!! $errors->first('api_token', '

:message

') !!} +
+

+ {!! trans('modules.token_link') !!} +

+
+
+ + {{ Form::textGroup('company_tax_number', trans('general.tax_number'), 'percent', []) }} + + {{ Form::textGroup('company_phone', trans('settings.company.phone'), 'phone', []) }} + + {{ Form::textareaGroup('company_address', trans('settings.company.address')) }} + + {{ Form::fileGroup('company_logo', trans('settings.company.logo')) }} +
+ + + + + + {!! Form::close() !!} +
+@endsection + +@push('js') + +@endpush + +@push('css') + +@endpush + +@push('scripts') + +@endpush diff --git a/resources/views/wizard/currencies/create.blade.php b/resources/views/wizard/currencies/create.blade.php new file mode 100644 index 000000000..2dd871983 --- /dev/null +++ b/resources/views/wizard/currencies/create.blade.php @@ -0,0 +1,30 @@ + + + {{ Form::textGroup('name', trans('general.name'), 'id-card-o', ['required' => 'required'], null, '') }} + + + {{ Form::selectGroup('code', trans('currencies.code'), 'code', $codes, null, ['required' => 'required'], '') }} + + + {{ Form::textGroup('rate', trans('currencies.rate'), 'money', ['required' => 'required'], null, '') }} + + + {{ Form::radioGroup('enabled', trans('general.enabled'), trans('general.yes'), trans('general.no'), [], 'col-md-12 currency-enabled-radio-group') }} + + + {!! Form::button('', ['type' => 'button', 'class' => 'btn btn-success currency-submit', 'data-loading-text' => trans('general.loading'), 'data-href' => url('wizard/currencies/'), 'style' => 'padding: 9px 14px; margin-top: 10px;']) !!} + + + {{ Form::numberGroup('precision', trans('currencies.precision'), 'bullseye') }} + + {{ Form::textGroup('symbol', trans('currencies.symbol.symbol'), 'font') }} + + {{ Form::selectGroup('symbol_first', trans('currencies.symbol.position'), 'text-width', ['1' => trans('currencies.symbol.before'), '0' => trans('currencies.symbol.after')]) }} + + {{ Form::textGroup('decimal_mark', trans('currencies.decimal_mark'), 'columns') }} + + {{ Form::textGroup('thousands_separator', trans('currencies.thousands_separator'), 'columns', []) }} + + {{ Form::radioGroup('default_currency', trans('currencies.default')) }} + + \ No newline at end of file diff --git a/resources/views/wizard/currencies/edit.blade.php b/resources/views/wizard/currencies/edit.blade.php new file mode 100644 index 000000000..ad169fa8f --- /dev/null +++ b/resources/views/wizard/currencies/edit.blade.php @@ -0,0 +1,32 @@ + + + {{ Form::textGroup('name', trans('general.name'), 'id-card-o', [], $item->name, '') }} + + + {{ Form::selectGroup('code', trans('currencies.code'), 'code', $codes, $item->code, [], '') }} + + + {{ Form::textGroup('rate', trans('currencies.rate'), 'money', [], $item->rate, '') }} + + + {{ Form::radioGroup('enabled', trans('general.enabled'), trans('general.yes'), trans('general.no'), [], 'col-md-12') }} + + + {!! Form::button('', ['type' => 'button', 'class' => 'btn btn-success currency-updated', 'data-loading-text' => trans('general.loading'), 'data-href' => url('wizard/currencies/' . $item->id), 'style' => 'padding: 9px 14px; margin-top: 10px;']) !!} + + + {{ Form::numberGroup('precision', trans('currencies.precision'), 'bullseye', [], $item->precision) }} + + {{ Form::textGroup('symbol', trans('currencies.symbol.symbol'), 'font', [], $item->symbol, '') }} + + {{ Form::selectGroup('symbol_first', trans('currencies.symbol.position'), 'text-width', ['1' => trans('currencies.symbol.before'), '0' => trans('currencies.symbol.after')], $item->symbol_first) }} + + {{ Form::textGroup('decimal_mark', trans('currencies.decimal_mark'), 'columns', [], $item->decimal_mark, '') }} + + {{ Form::textGroup('thousands_separator', trans('currencies.thousands_separator'), 'columns', [], $item->thousands_separator) }} + + {{ Form::radioGroup('default_currency', trans('currencies.default')) }} + + {{ Form::hidden('id', $item->id) }} + + \ No newline at end of file diff --git a/resources/views/wizard/currencies/index.blade.php b/resources/views/wizard/currencies/index.blade.php new file mode 100644 index 000000000..c0dd6a73b --- /dev/null +++ b/resources/views/wizard/currencies/index.blade.php @@ -0,0 +1,379 @@ +@extends('layouts.wizard') + +@section('title', trans('general.wizard')) + +@section('content') + +
+
+
+
+
+ 1 +

{{ trans_choice('general.companies', 1) }}

+
+
+ 2 +

{{ trans_choice('general.currencies', 2) }}

+
+
+ +

{{ trans_choice('general.taxes', 2) }}

+
+
+ +

{{ trans_choice('general.finish', 1) }}

+
+
+
+
+
+ +
+
+ +
+

{{ trans_choice('general.currencies', 1) }}

+  {{ trans('general.add_new') }} +
+ + +
+
+ + + + + + + + + + + + @foreach($currencies as $item) + + + + + + + + @endforeach + +
@sortablelink('name', trans('general.name'))@sortablelink('rate', trans('currencies.rate')){{ trans('general.actions') }}
{{ $item->name }}{{ $item->rate }} +
+ + +
+
+
+
+ + + + +
+@endsection + +@push('scripts') + +@endpush diff --git a/resources/views/wizard/finish/index.blade.php b/resources/views/wizard/finish/index.blade.php new file mode 100644 index 000000000..fc3e9a26b --- /dev/null +++ b/resources/views/wizard/finish/index.blade.php @@ -0,0 +1,88 @@ +@extends('layouts.wizard') + +@section('title', trans('general.wizard')) + +@section('content') + +
+
+
+
+
+ 1 +

{{ trans_choice('general.companies', 1) }}

+
+
+ 2 +

{{ trans_choice('general.currencies', 2) }}

+
+
+ 3 +

{{ trans_choice('general.taxes', 2) }}

+
+
+ 4 +

{{ trans_choice('general.finish', 1) }}

+
+
+
+
+
+ +
+ +
+ +
+
+
+

{{ trans('modules.recommended_apps') }}

+
+ + @if ($modules) + @foreach ($modules->data as $module) + @include('partials.modules.item') + @endforeach +
+ +
+ @else +
+
+

+ {{ trans('modules.no_apps') }} +

+

+ {!! trans('modules.developer') !!} +

+
+ +
+ @endif +
+
+@endsection + +@push('css') + +@endpush + +@push('scripts') + +@endpush diff --git a/resources/views/wizard/taxes/create.blade.php b/resources/views/wizard/taxes/create.blade.php new file mode 100644 index 000000000..893cf5658 --- /dev/null +++ b/resources/views/wizard/taxes/create.blade.php @@ -0,0 +1,14 @@ + + + {{ Form::textGroup('name', trans('general.name'), 'id-card-o', ['required' => 'required'], null, '') }} + + + {{ Form::textGroup('rate', trans('currencies.rate'), 'money', ['required' => 'required'], null, '') }} + + + {{ Form::radioGroup('enabled', trans('general.enabled'), trans('general.yes'), trans('general.no'), [], 'col-md-12 tax-enabled-radio-group') }} + + + {!! Form::button('', ['type' => 'button', 'class' => 'btn btn-success tax-submit', 'data-loading-text' => trans('general.loading'), 'data-href' => url('wizard/taxes'), 'style' => 'padding: 9px 14px; margin-top: 10px;']) !!} + + \ No newline at end of file diff --git a/resources/views/wizard/taxes/edit.blade.php b/resources/views/wizard/taxes/edit.blade.php new file mode 100644 index 000000000..dda141058 --- /dev/null +++ b/resources/views/wizard/taxes/edit.blade.php @@ -0,0 +1,14 @@ + + + {{ Form::textGroup('name', trans('general.name'), 'id-card-o', ['required' => 'required'], $item->name, '') }} + + + {{ Form::textGroup('rate', trans('currencies.rate'), 'money', ['required' => 'required'], $item->rate, '') }} + + + {{ Form::radioGroup('enabled', trans('general.enabled'), trans('general.yes'), trans('general.no'), [], 'col-md-12') }} + + + {!! Form::button('', ['type' => 'button', 'class' => 'btn btn-success tax-updated', 'data-loading-text' => trans('general.loading'), 'data-href' => url('wizard/taxes/' . $item->id), 'style' => 'padding: 9px 14px; margin-top: 10px;']) !!} + + \ No newline at end of file diff --git a/resources/views/wizard/taxes/index.blade.php b/resources/views/wizard/taxes/index.blade.php new file mode 100644 index 000000000..41da4caa9 --- /dev/null +++ b/resources/views/wizard/taxes/index.blade.php @@ -0,0 +1,377 @@ +@extends('layouts.wizard') + +@section('title', trans('general.wizard')) + +@section('content') + +
+
+
+
+
+ 1 +

{{ trans_choice('general.companies', 1) }}

+
+
+ 2 +

{{ trans_choice('general.currencies', 2) }}

+
+
+ 3 +

{{ trans_choice('general.taxes', 2) }}

+
+
+ +

{{ trans_choice('general.finish', 1) }}

+
+
+
+
+
+ +
+
+ +
+

{{ trans_choice('general.taxes', 1) }}

+  {{ trans('general.add_new') }} +
+ + +
+
+ + + + + + + + + + + @foreach($taxes as $item) + + + + + + + @endforeach + +
@sortablelink('name', trans('general.name'))@sortablelink('rate', trans('taxes.rate_percent')){{ trans('general.actions') }}
{{ $item->name }}{{ $item->rate }} +
+ + +
+
+
+
+ + + + + +
+@endsection + +@push('scripts') + +@endpush diff --git a/routes/web.php b/routes/web.php index 127316e8c..b933a2634 100644 --- a/routes/web.php +++ b/routes/web.php @@ -7,6 +7,34 @@ Route::group(['middleware' => 'language'], function () { Route::get('{id}/download', 'Common\Uploads@download'); }); + Route::group(['middleware' => 'permission:read-admin-panel'], function () { + Route::group(['prefix' => 'wizard'], function () { + Route::get('/', 'Wizard\Companies@edit')->name('wizard.index'); + Route::get('companies', 'Wizard\Companies@edit')->name('wizard.companies.edit'); + Route::patch('companies', 'Wizard\Companies@update')->name('wizard.companies.update'); + + Route::get('currencies', 'Wizard\Currencies@index')->name('wizard.currencies.index'); + Route::get('currencies/create', 'Wizard\Currencies@create')->name('wizard.currencies.create'); + Route::get('currencies/{currency}/edit', 'Wizard\Currencies@edit')->name('wizard.currencies.edit'); + Route::get('currencies/{currency}/enable', 'Wizard\Currencies@enable')->name('wizard.currencies.enable'); + Route::get('currencies/{currency}/disable', 'Wizard\Currencies@disable')->name('wizard.currencies.disable'); + Route::get('currencies/{currency}/delete', 'Wizard\Currencies@destroy')->name('wizard.currencies.delete'); + Route::post('currencies', 'Wizard\Currencies@store')->name('wizard.currencies.store'); + Route::patch('currencies/{currency}', 'Wizard\Currencies@update')->name('wizard.currencies.update'); + + Route::get('taxes', 'Wizard\Taxes@index')->name('wizard.taxes.index'); + Route::get('taxes/create', 'Wizard\Taxes@create')->name('wizard.taxes.create'); + Route::get('taxes/{tax}/edit', 'Wizard\Taxes@edit')->name('wizard.taxes.edit'); + Route::get('taxes/{tax}/enable', 'Wizard\Taxes@enable')->name('wizard.taxes.enable'); + Route::get('taxes/{tax}/disable', 'Wizard\Taxes@disable')->name('wizard.taxes.disable'); + Route::get('taxes/{tax}/delete', 'Wizard\Taxes@destroy')->name('wizard.taxes.delete'); + Route::post('taxes', 'Wizard\Taxes@store')->name('wizard.taxes.store'); + Route::patch('taxes/{tax}', 'Wizard\Taxes@update')->name('wizard.taxes.upadate'); + + Route::get('finish', 'Wizard\Finish@index')->name('wizard.finish.index'); + }); + }); + Route::group(['middleware' => ['adminmenu', 'permission:read-admin-panel']], function () { Route::get('/', 'Common\Dashboard@index');