improved tenant identification

This commit is contained in:
Denis Duliçi 2021-04-16 00:59:43 +03:00
parent 9635e6be5d
commit 2b07442260
126 changed files with 1719 additions and 999 deletions

View File

@ -21,9 +21,9 @@ abstract class Module extends Command
protected function changeRuntime() protected function changeRuntime()
{ {
$this->old_company_id = session('company_id'); $this->old_company_id = company_id();
session(['company_id' => $this->company_id]); company($this->company_id)->makeCurrent();
app()->setLocale($this->locale); app()->setLocale($this->locale);
@ -36,7 +36,7 @@ abstract class Module extends Command
session()->forget('company_id'); session()->forget('company_id');
if (!empty($this->old_company_id)) { if (!empty($this->old_company_id)) {
session(['company_id' => $this->old_company_id]); company($this->old_company_id)->makeCurrent();
} }
} }

View File

@ -4,8 +4,12 @@ namespace App\Abstracts;
use App\Events\Export\HeadingsPreparing; use App\Events\Export\HeadingsPreparing;
use App\Events\Export\RowsPreparing; use App\Events\Export\RowsPreparing;
use App\Notifications\Common\ExportFailed;
use App\Utilities\Date; use App\Utilities\Date;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\ShouldAutoSize; use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings; use Maatwebsite\Excel\Concerns\WithHeadings;
@ -13,16 +17,21 @@ use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle; use Maatwebsite\Excel\Concerns\WithTitle;
use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate; use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate;
abstract class Export implements FromCollection, ShouldAutoSize, WithHeadings, WithMapping, WithTitle abstract class Export implements FromCollection, HasLocalePreference, ShouldAutoSize, ShouldQueue, WithHeadings, WithMapping, WithTitle
{ {
use Exportable;
public $ids; public $ids;
public $fields; public $fields;
public $user;
public function __construct($ids = null) public function __construct($ids = null)
{ {
$this->ids = $ids; $this->ids = $ids;
$this->fields = $this->fields(); $this->fields = $this->fields();
$this->user = user();
} }
public function title(): string public function title(): string
@ -74,4 +83,14 @@ abstract class Export implements FromCollection, ShouldAutoSize, WithHeadings, W
return $rows; return $rows;
} }
public function preferredLocale()
{
return $this->user->locale;
}
public function failed(\Throwable $exception): void
{
$this->user->notify(new ExportFailed($exception));
}
} }

View File

@ -29,8 +29,7 @@ abstract class Factory extends BaseFactory
$this->user = User::first(); $this->user = User::first();
$this->company = $this->user->companies()->first(); $this->company = $this->user->companies()->first();
session(['company_id' => $this->company->id]); company($this->company->id)->makeCurrent();
setting()->setExtraColumns(['company_id' => $this->company->id]);
} }
public function getCompanyUsers() public function getCompanyUsers()

View File

@ -3,11 +3,12 @@
namespace App\Abstracts\Http; namespace App\Abstracts\Http;
use App\Abstracts\Http\Response; use App\Abstracts\Http\Response;
use App\Jobs\Auth\NotifyUser;
use App\Jobs\Common\CreateMediableForExport;
use App\Notifications\Common\ImportCompleted;
use App\Traits\Jobs; use App\Traits\Jobs;
use App\Traits\Permissions; use App\Traits\Permissions;
use App\Traits\Relationships; use App\Traits\Relationships;
use Exception;
use ErrorException;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Validation\ValidatesRequests;
@ -15,9 +16,6 @@ use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Routing\Controller as BaseController; use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Maatwebsite\Excel\Exceptions\SheetNotFoundException;
use Maatwebsite\Excel\Facades\Excel;
use Throwable;
abstract class Controller extends BaseController abstract class Controller extends BaseController
{ {
@ -78,23 +76,49 @@ abstract class Controller extends BaseController
* *
* @param $class * @param $class
* @param $request * @param $request
* @param $url * @param $translation
* *
* @return mixed * @return mixed
*/ */
public function importExcel($class, $request) public function importExcel($class, $request, $translation)
{ {
try { try {
Excel::import($class, $request->file('import')); $file = $request->file('import');
if (should_queue()) {
$class->queue($file)->onQueue('imports')->chain([
new NotifyUser(user(), new ImportCompleted),
]);
$message = trans('messages.success.import_queued', ['type' => $translation]);
} else {
$class->import($file);
$message = trans('messages.success.imported', ['type' => $translation]);
}
$response = [ $response = [
'success' => true, 'success' => true,
'error' => false, 'error' => false,
'data' => null, 'data' => null,
'message' => '', 'message' => $message,
]; ];
} catch (SheetNotFoundException | ErrorException | Exception | Throwable $e) { } catch (\Throwable $e) {
if ($e instanceof \Maatwebsite\Excel\Validators\ValidationException) {
foreach ($e->failures() as $failure) {
$message = trans('messages.error.import_column', [
'message' => collect($failure->errors())->first(),
'column' => $failure->attribute(),
'line' => $failure->row(),
]);
flash($message)->error()->important();
}
$message = '';
} else {
$message = $e->getMessage(); $message = $e->getMessage();
}
$response = [ $response = [
'success' => false, 'success' => false,
@ -111,15 +135,30 @@ abstract class Controller extends BaseController
* Export the excel file or catch errors * Export the excel file or catch errors
* *
* @param $class * @param $class
* @param $file_name * @param $translation
* @param $extension
* *
* @return mixed * @return mixed
*/ */
public function exportExcel($class, $file_name, $extension = 'xlsx') public function exportExcel($class, $translation, $extension = 'xlsx')
{ {
try { try {
return Excel::download($class, Str::filename($file_name) . '.' . $extension); $file_name = Str::filename($translation) . '.' . $extension;
} catch (ErrorException | Exception | Throwable $e) {
if (should_queue()) {
$class->queue($file_name)->onQueue('exports')->chain([
new CreateMediableForExport(user(), $file_name),
]);
$message = trans('messages.success.export_queued', ['type' => $translation]);
flash($message)->success();
return back();
} else {
return $class->download($file_name);
}
} catch (\Throwable $e) {
flash($e->getMessage())->error()->important(); flash($e->getMessage())->error()->important();
return back(); return back();

View File

@ -15,7 +15,7 @@ abstract class FormRequest extends BaseFormRequest
protected function prepareForValidation() protected function prepareForValidation()
{ {
$this->merge([ $this->merge([
'company_id' => session('company_id'), 'company_id' => company_id(),
]); ]);
} }

View File

@ -5,30 +5,34 @@ namespace App\Abstracts;
use App\Traits\Import as ImportHelper; use App\Traits\Import as ImportHelper;
use App\Utilities\Date; use App\Utilities\Date;
use Carbon\Exceptions\InvalidFormatException; use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\Importable; use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\SkipsOnError; use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\ToModel; use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithHeadingRow; use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping; use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithValidation; use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Validators\Failure;
use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate; use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate;
abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithChunkReading, WithHeadingRow, WithMapping, WithValidation abstract class Import implements HasLocalePreference, ShouldQueue, SkipsEmptyRows, WithChunkReading, WithHeadingRow, WithMapping, WithValidation, ToModel
{ {
use Importable, ImportHelper; use Importable, ImportHelper;
public $empty_field = 'empty---'; public $user;
public function __construct()
{
$this->user = user();
}
public function map($row): array public function map($row): array
{ {
$row['company_id'] = session('company_id'); $row['company_id'] = company_id();
// Make enabled field integer // Make enabled field integer
if (isset($row['enabled'])) { if (isset($row['enabled'])) {
@ -67,31 +71,6 @@ abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithChun
return 100; return 100;
} }
public function onFailure(Failure ...$failures)
{
$sheet = Str::snake((new \ReflectionClass($this))->getShortName());
foreach ($failures as $failure) {
// @todo remove after 3.2 release https://github.com/Maatwebsite/Laravel-Excel/issues/1834#issuecomment-474340743
if (collect($failure->values())->first() == $this->empty_field) {
continue;
}
$message = trans('messages.error.import_column', [
'message' => collect($failure->errors())->first(),
'sheet' => $sheet,
'line' => $failure->row(),
]);
flash($message)->error()->important();
}
}
public function onError(\Throwable $e)
{
flash($e->getMessage())->error()->important();
}
public function isNotValid($row) public function isNotValid($row)
{ {
return Validator::make($row, $this->rules())->fails(); return Validator::make($row, $this->rules())->fails();
@ -111,4 +90,9 @@ abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithChun
return false; return false;
} }
public function preferredLocale()
{
return $this->user->locale;
}
} }

View File

@ -6,14 +6,10 @@ use App\Abstracts\Http\FormRequest;
use App\Traits\Jobs; use App\Traits\Jobs;
use App\Traits\Relationships; use App\Traits\Relationships;
use App\Traits\Uploads; use App\Traits\Uploads;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
abstract class Job implements ShouldQueue abstract class Job
{ {
use InteractsWithQueue, Jobs, Queueable, Relationships, SerializesModels, Uploads; use Jobs, Relationships, Uploads;
public function getRequestInstance($request) public function getRequestInstance($request)
{ {

View File

@ -0,0 +1,49 @@
<?php
namespace App\Abstracts;
use App\Abstracts\Http\FormRequest;
use App\Traits\Jobs;
use App\Traits\Relationships;
use App\Traits\Uploads;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
abstract class JobShouldQueue implements ShouldQueue
{
use InteractsWithQueue, Jobs, Queueable, Relationships, SerializesModels, Uploads;
/**
* Check if request is array and if so, convert to a request class.
*
* @param mixed $request
* @return \Illuminate\Foundation\Http\FormRequest
*
* @deprecated Request is not serializable so can't use it with queues.
*/
public function getRequestInstance($request)
{
return $this->getRequestAsCollection($request);
}
/**
* Covert the request to collection.
*
* @param mixed $request
* @return \Illuminate\Support\Collection
*/
public function getRequestAsCollection($request)
{
if (is_array($request)) {
$data = $request;
$request = new class() extends FormRequest {};
$request->merge($data);
}
return collect($request->all());
}
}

View File

@ -2,19 +2,21 @@
namespace App\Abstracts; namespace App\Abstracts;
use App\Models\Common\EmailTemplate; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification as BaseNotification; use Illuminate\Notifications\Notification as BaseNotification;
abstract class Notification extends BaseNotification abstract class Notification extends BaseNotification implements ShouldQueue
{ {
use Queueable;
/** /**
* Create a notification instance. * Create a notification instance.
*/ */
public function __construct() public function __construct()
{ {
$this->queue = 'high'; $this->onQueue('notifications');
$this->delay = config('queue.connections.database.delay');
} }
/** /**
@ -35,24 +37,24 @@ abstract class Notification extends BaseNotification
*/ */
public function initMessage() public function initMessage()
{ {
$template = EmailTemplate::alias($this->template)->first(); app('url')->defaults(['company_id' => company_id()]);
$message = (new MailMessage) $message = (new MailMessage)
->from(config('mail.from.address'), config('mail.from.name')) ->from(config('mail.from.address'), config('mail.from.name'))
->subject($this->getSubject($template)) ->subject($this->getSubject())
->view('partials.email.body', ['body' => $this->getBody($template)]); ->view('partials.email.body', ['body' => $this->getBody()]);
return $message; return $message;
} }
public function getSubject($template) public function getSubject()
{ {
return $this->replaceTags($template->subject); return $this->replaceTags($this->template->subject);
} }
public function getBody($template) public function getBody()
{ {
return $this->replaceTags($template->body); return $this->replaceTags($this->template->body);
} }
public function replaceTags($content) public function replaceTags($content)

View File

@ -611,7 +611,7 @@ abstract class DocumentShow extends Base
$image->make($path)->resize($width, $height)->encode(); $image->make($path)->resize($width, $height)->encode();
}); });
} catch (NotReadableException | \Exception $e) { } catch (NotReadableException | \Exception $e) {
Log::info('Company ID: ' . session('company_id') . ' components/documentshow.php exception.'); Log::info('Company ID: ' . company_id() . ' components/documentshow.php exception.');
Log::info($e->getMessage()); Log::info($e->getMessage());
$path = base_path('public/img/company.png'); $path = base_path('public/img/company.png');
@ -651,11 +651,11 @@ abstract class DocumentShow extends Base
$route .= 'signed.' . $page . '.show'; $route .= 'signed.' . $page . '.show';
try { try {
route($route, [$this->document->id, 'company_id' => session('company_id')]); route($route, [$this->document->id, 'company_id' => company_id()]);
$signedUrl = URL::signedRoute($route, [$this->document->id, 'company_id' => session('company_id')]); $signedUrl = URL::signedRoute($route, [$this->document->id]);
} catch (\Exception $e) { } catch (\Exception $e) {
$signedUrl = URL::signedRoute('signed.invoices.show', [$this->document->id, 'company_id' => session('company_id')]); $signedUrl = URL::signedRoute('signed.invoices.show', [$this->document->id]);
} }
return $signedUrl; return $signedUrl;

View File

@ -213,7 +213,7 @@ abstract class DocumentTemplate extends Base
$image->make($path)->resize($width, $height)->encode(); $image->make($path)->resize($width, $height)->encode();
}); });
} catch (NotReadableException | \Exception $e) { } catch (NotReadableException | \Exception $e) {
Log::info('Company ID: ' . session('company_id') . ' components/documentshow.php exception.'); Log::info('Company ID: ' . company_id() . ' components/documentshow.php exception.');
Log::info($e->getMessage()); Log::info($e->getMessage());
$path = base_path('public/img/company.png'); $path = base_path('public/img/company.png');

View File

@ -35,7 +35,7 @@ class Companies extends BulkAction
foreach ($companies as $company) { foreach ($companies as $company) {
try { try {
$this->dispatch(new UpdateCompany($company, $request->merge(['enabled' => 1]), session('company_id'))); $this->dispatch(new UpdateCompany($company, $request->merge(['enabled' => 1])));
} catch (\Exception $e) { } catch (\Exception $e) {
flash($e->getMessage())->error()->important(); flash($e->getMessage())->error()->important();
} }
@ -48,7 +48,7 @@ class Companies extends BulkAction
foreach ($companies as $company) { foreach ($companies as $company) {
try { try {
$this->dispatch(new UpdateCompany($company, $request->merge(['enabled' => 0]), session('company_id'))); $this->dispatch(new UpdateCompany($company, $request->merge(['enabled' => 0])));
} catch (\Exception $e) { } catch (\Exception $e) {
flash($e->getMessage())->error()->important(); flash($e->getMessage())->error()->important();
} }
@ -61,7 +61,7 @@ class Companies extends BulkAction
foreach ($companies as $company) { foreach ($companies as $company) {
try { try {
$this->dispatch(new DeleteCompany($company, session('company_id'))); $this->dispatch(new DeleteCompany($company));
} catch (\Exception $e) { } catch (\Exception $e) {
flash($e->getMessage())->error()->important(); flash($e->getMessage())->error()->important();
} }

View File

@ -47,12 +47,8 @@ class BillReminder extends Command
$this->info('Sending bill reminders for ' . $company->name . ' company.'); $this->info('Sending bill reminders for ' . $company->name . ' company.');
// Set company id // Set company
session(['company_id' => $company->id]); $company->makeCurrent();
// Override settings and currencies
Overrider::load('settings');
Overrider::load('currencies');
// Don't send reminders if disabled // Don't send reminders if disabled
if (!setting('schedule.send_bill_reminder')) { if (!setting('schedule.send_bill_reminder')) {
@ -70,9 +66,7 @@ class BillReminder extends Command
} }
} }
// Unset company_id Company::forgetCurrent();
session()->forget('company_id');
setting()->forgetAll();
} }
protected function remind($day) protected function remind($day)

View File

@ -47,8 +47,7 @@ class DownloadModule extends Command
$this->alias = $this->argument('alias'); $this->alias = $this->argument('alias');
$this->company = $this->argument('company'); $this->company = $this->argument('company');
session(['company_id' => $this->company]); company($this->company)->makeCurrent();
setting()->setExtraColumns(['company_id' => $this->company]);
if (!$path = $this->download()) { if (!$path = $this->download()) {
return self::CMD_ERROR; return self::CMD_ERROR;

View File

@ -57,8 +57,7 @@ class FinishUpdate extends Command
} }
} }
session(['company_id' => $company_id]); company($company_id)->makeCurrent();
setting()->setExtraColumns(['company_id' => $company_id]);
// Disable model cache during update // Disable model cache during update
config(['laravel-model-caching.enabled' => false]); config(['laravel-model-caching.enabled' => false]);

View File

@ -47,12 +47,8 @@ class InvoiceReminder extends Command
$this->info('Sending invoice reminders for ' . $company->name . ' company.'); $this->info('Sending invoice reminders for ' . $company->name . ' company.');
// Set company id // Set company
session(['company_id' => $company->id]); $company->makeCurrent();
// Override settings and currencies
Overrider::load('settings');
Overrider::load('currencies');
// Don't send reminders if disabled // Don't send reminders if disabled
if (!setting('schedule.send_invoice_reminder')) { if (!setting('schedule.send_invoice_reminder')) {
@ -70,9 +66,7 @@ class InvoiceReminder extends Command
} }
} }
// Unset company_id Company::forgetCurrent();
session()->forget('company_id');
setting()->forgetAll();
} }
protected function remind($day) protected function remind($day)

View File

@ -7,10 +7,10 @@ use App\Events\Banking\TransactionRecurring;
use App\Events\Document\DocumentCreated; use App\Events\Document\DocumentCreated;
use App\Events\Document\DocumentRecurring; use App\Events\Document\DocumentRecurring;
use App\Models\Banking\Transaction; use App\Models\Banking\Transaction;
use App\Models\Common\Company;
use App\Models\Common\Recurring; use App\Models\Common\Recurring;
use App\Models\Document\Document; use App\Models\Document\Document;
use App\Utilities\Date; use App\Utilities\Date;
use App\Utilities\Overrider;
use Illuminate\Console\Command; use Illuminate\Console\Command;
class RecurringCheck extends Command class RecurringCheck extends Command
@ -83,12 +83,7 @@ class RecurringCheck extends Command
continue; continue;
} }
// Set company id company($recur->company_id)->makeCurrent();
session(['company_id' => $recur->company_id]);
// Override settings and currencies
Overrider::load('settings');
Overrider::load('currencies');
$today = Date::today(); $today = Date::today();
@ -121,9 +116,7 @@ class RecurringCheck extends Command
} }
} }
// Unset company_id Company::forgetCurrent();
session()->forget('company_id');
setting()->forgetAll();
} }
protected function recur($model, $type, $schedule_date) protected function recur($model, $type, $schedule_date)

View File

@ -68,8 +68,7 @@ class Update extends Command
$this->old = $this->getOldVersion(); $this->old = $this->getOldVersion();
session(['company_id' => $this->company]); company($this->company)->makeCurrent();
setting()->setExtraColumns(['company_id' => $this->company]);
if (!$path = $this->download()) { if (!$path = $this->download()) {
return self::CMD_ERROR; return self::CMD_ERROR;

View File

@ -40,7 +40,7 @@ class FinishInstallation
protected function callSeeds() protected function callSeeds()
{ {
Artisan::call('company:seed', [ Artisan::call('company:seed', [
'company' => session('company_id'), 'company' => company_id(),
'--class' => 'Modules\$STUDLY_NAME$\Database\Seeds\$STUDLY_NAME$DatabaseSeeder', '--class' => 'Modules\$STUDLY_NAME$\Database\Seeds\$STUDLY_NAME$DatabaseSeeder',
]); ]);
} }

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Common;
use App\Abstracts\Event;
class CompanyForgettingCurrent extends Event
{
public $company;
/**
* Create a new event instance.
*
* @param $company
*/
public function __construct($company)
{
$this->company = $company;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Common;
use App\Abstracts\Event;
class CompanyForgotCurrent extends Event
{
public $company;
/**
* Create a new event instance.
*
* @param $company
*/
public function __construct($company)
{
$this->company = $company;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Common;
use App\Abstracts\Event;
class CompanyMadeCurrent extends Event
{
public $company;
/**
* Create a new event instance.
*
* @param $company
*/
public function __construct($company)
{
$this->company = $company;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Common;
use App\Abstracts\Event;
class CompanyMakingCurrent extends Event
{
public $company;
/**
* Create a new event instance.
*
* @param $company
*/
public function __construct($company)
{
$this->company = $company;
}
}

View File

@ -69,7 +69,7 @@ class Companies extends ApiController
public function update(Company $company, Request $request) public function update(Company $company, Request $request)
{ {
try { try {
$company = $this->dispatch(new UpdateCompany($company, $request, session('company_id'))); $company = $this->dispatch(new UpdateCompany($company, $request));
return $this->item($company->fresh(), new Transformer()); return $this->item($company->fresh(), new Transformer());
} catch (\Exception $e) { } catch (\Exception $e) {
@ -86,7 +86,7 @@ class Companies extends ApiController
public function enable(Company $company) public function enable(Company $company)
{ {
try { try {
$company = $this->dispatch(new UpdateCompany($company, request()->merge(['enabled' => 1]), session('company_id'))); $company = $this->dispatch(new UpdateCompany($company, request()->merge(['enabled' => 1])));
return $this->item($company->fresh(), new Transformer()); return $this->item($company->fresh(), new Transformer());
} catch (\Exception $e) { } catch (\Exception $e) {
@ -103,7 +103,7 @@ class Companies extends ApiController
public function disable(Company $company) public function disable(Company $company)
{ {
try { try {
$company = $this->dispatch(new UpdateCompany($company, request()->merge(['enabled' => 0]), session('company_id'))); $company = $this->dispatch(new UpdateCompany($company, request()->merge(['enabled' => 0])));
return $this->item($company->fresh(), new Transformer()); return $this->item($company->fresh(), new Transformer());
} catch (\Exception $e) { } catch (\Exception $e) {
@ -120,7 +120,7 @@ class Companies extends ApiController
public function destroy(Company $company) public function destroy(Company $company)
{ {
try { try {
$this->dispatch(new DeleteCompany($company, session('company_id'))); $this->dispatch(new DeleteCompany($company));
return $this->response->noContent(); return $this->response->noContent();
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@ -37,16 +37,14 @@ class Login extends Controller
{ {
// Attempt to login // Attempt to login
if (!auth()->attempt($request->only('email', 'password'), $request->get('remember', false))) { if (!auth()->attempt($request->only('email', 'password'), $request->get('remember', false))) {
$response = [ return response()->json([
'status' => null, 'status' => null,
'success' => false, 'success' => false,
'error' => true, 'error' => true,
'message' => trans('auth.failed'), 'message' => trans('auth.failed'),
'data' => null, 'data' => null,
'redirect' => null, 'redirect' => null,
]; ]);
return response()->json($response);
} }
// Get user object // Get user object
@ -56,49 +54,64 @@ class Login extends Controller
if (!$user->enabled) { if (!$user->enabled) {
$this->logout(); $this->logout();
$response = [ return response()->json([
'status' => null, 'status' => null,
'success' => false, 'success' => false,
'error' => true, 'error' => true,
'message' => trans('auth.disabled'), 'message' => trans('auth.disabled'),
'data' => null, 'data' => null,
'redirect' => null, 'redirect' => null,
]; ]);
return response()->json($response);
} }
// Check if is customer $company = $user->withoutEvents(function () use ($user) {
return $user->companies()->enabled()->first();
});
// Logout if no company assigned
if (!$company) {
$this->logout();
return response()->json([
'status' => null,
'success' => false,
'error' => true,
'message' => trans('auth.error.no_company'),
'data' => null,
'redirect' => null,
]);
}
// Redirect to portal if is customer
if ($user->can('read-client-portal')) { if ($user->can('read-client-portal')) {
$path = session('url.intended', 'portal'); $path = session('url.intended', '');
// Path must start with 'portal' prefix // Path must start with company id and 'portal' prefix
if (!Str::startsWith($path, 'portal')) { if (!Str::startsWith($path, $company->id . '/portal')) {
$path = 'portal'; $path = route('portal.dashboard', ['company_id' => $company->id]);
} }
$response = [ return response()->json([
'status' => null, 'status' => null,
'success' => true, 'success' => true,
'error' => false, 'error' => false,
'message' => null, 'message' => null,
'data' => null, 'data' => null,
'redirect' => url($path), 'redirect' => url($path),
]; ]);
return response()->json($response);
} }
$response = [ // Redirect to landing page if is user
$url = route($user->landing_page, ['company_id' => $company->id]);
return response()->json([
'status' => null, 'status' => null,
'success' => true, 'success' => true,
'error' => false, 'error' => false,
'message' => null, 'message' => null,
'data' => null, 'data' => null,
'redirect' => redirect()->intended(route($user->landing_page))->getTargetUrl(), 'redirect' => redirect()->intended($url)->getTargetUrl(),
]; ]);
return response()->json($response);
} }
public function destroy() public function destroy()

View File

@ -42,20 +42,16 @@ class Transactions extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.transactions', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('transactions.index'); $response['redirect'] = route('transactions.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.transactions', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['banking', 'transactions']); $response['redirect'] = route('import.create', ['banking', 'transactions']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -97,20 +97,16 @@ class Transfers extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.transfers', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('transfers.index'); $response['redirect'] = route('transfers.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.transfers', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['banking', 'transfers']); $response['redirect'] = route('import.create', ['banking', 'transfers']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -11,7 +11,6 @@ use App\Models\Common\Company;
use App\Models\Setting\Currency; use App\Models\Setting\Currency;
use App\Traits\Uploads; use App\Traits\Uploads;
use App\Traits\Users; use App\Traits\Users;
use App\Utilities\Overrider;
class Companies extends Controller class Companies extends Controller
{ {
@ -60,7 +59,7 @@ class Companies extends Controller
*/ */
public function store(Request $request) public function store(Request $request)
{ {
$company_id = session('company_id'); $current_company_id = company_id();
$response = $this->ajaxDispatch(new CreateCompany($request)); $response = $this->ajaxDispatch(new CreateCompany($request));
@ -78,9 +77,7 @@ class Companies extends Controller
flash($message)->error()->important(); flash($message)->error()->important();
} }
session(['company_id' => $company_id]); company($current_company_id)->makeCurrent();
Overrider::load('settings');
return response()->json($response); return response()->json($response);
} }
@ -94,7 +91,7 @@ class Companies extends Controller
*/ */
public function edit(Company $company) public function edit(Company $company)
{ {
if (!$this->isUserCompany($company->id)) { if ($this->isNotUserCompany($company->id)) {
return redirect()->route('companies.index'); return redirect()->route('companies.index');
} }
@ -113,9 +110,9 @@ class Companies extends Controller
*/ */
public function update(Company $company, Request $request) public function update(Company $company, Request $request)
{ {
$company_id = session('company_id'); $current_company_id = company_id();
$response = $this->ajaxDispatch(new UpdateCompany($company, $request, session('company_id'))); $response = $this->ajaxDispatch(new UpdateCompany($company, $request, company_id()));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('companies.index'); $response['redirect'] = route('companies.index');
@ -131,9 +128,7 @@ class Companies extends Controller
flash($message)->error()->important(); flash($message)->error()->important();
} }
session(['company_id' => $company_id]); company($current_company_id)->makeCurrent();
Overrider::load('settings');
return response()->json($response); return response()->json($response);
} }
@ -147,7 +142,7 @@ class Companies extends Controller
*/ */
public function enable(Company $company) public function enable(Company $company)
{ {
$response = $this->ajaxDispatch(new UpdateCompany($company, request()->merge(['enabled' => 1]), session('company_id'))); $response = $this->ajaxDispatch(new UpdateCompany($company, request()->merge(['enabled' => 1])));
if ($response['success']) { if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => trans_choice('general.companies', 1)]); $response['message'] = trans('messages.success.enabled', ['type' => trans_choice('general.companies', 1)]);
@ -165,7 +160,7 @@ class Companies extends Controller
*/ */
public function disable(Company $company) public function disable(Company $company)
{ {
$response = $this->ajaxDispatch(new UpdateCompany($company, request()->merge(['enabled' => 0]), session('company_id'))); $response = $this->ajaxDispatch(new UpdateCompany($company, request()->merge(['enabled' => 0])));
if ($response['success']) { if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => trans_choice('general.companies', 1)]); $response['message'] = trans('messages.success.disabled', ['type' => trans_choice('general.companies', 1)]);
@ -183,7 +178,7 @@ class Companies extends Controller
*/ */
public function destroy(Company $company) public function destroy(Company $company)
{ {
$response = $this->ajaxDispatch(new DeleteCompany($company, session('company_id'))); $response = $this->ajaxDispatch(new DeleteCompany($company));
$response['redirect'] = route('companies.index'); $response['redirect'] = route('companies.index');
@ -210,22 +205,21 @@ class Companies extends Controller
public function switch(Company $company) public function switch(Company $company)
{ {
if ($this->isUserCompany($company->id)) { if ($this->isUserCompany($company->id)) {
$old_company_id = session('company_id'); $old_company_id = company_id();
$company->makeCurrent();
session(['company_id' => $company->id]);
session(['dashboard_id' => user()->dashboards()->enabled()->pluck('id')->first()]); session(['dashboard_id' => user()->dashboards()->enabled()->pluck('id')->first()]);
Overrider::load('settings');
event(new \App\Events\Common\CompanySwitched($company, $old_company_id)); event(new \App\Events\Common\CompanySwitched($company, $old_company_id));
// Check wizard // Check wizard
if (!setting('wizard.completed', false)) { if (!setting('wizard.completed', false)) {
return redirect()->route('wizard.edit'); return redirect()->route('wizard.edit', ['company_id' => $company->id]);
} }
} }
return redirect()->route('dashboard'); return redirect()->route('dashboard', ['company_id' => $company->id]);
} }
public function autocomplete() public function autocomplete()

View File

@ -7,7 +7,6 @@ use App\Http\Requests\Common\Dashboard as Request;
use App\Jobs\Common\CreateDashboard; use App\Jobs\Common\CreateDashboard;
use App\Jobs\Common\DeleteDashboard; use App\Jobs\Common\DeleteDashboard;
use App\Jobs\Common\UpdateDashboard; use App\Jobs\Common\UpdateDashboard;
use App\Models\Common\Company;
use App\Models\Common\Dashboard; use App\Models\Common\Dashboard;
use App\Models\Common\Widget; use App\Models\Common\Widget;
use App\Traits\DateTime; use App\Traits\DateTime;
@ -60,7 +59,7 @@ class Dashboards extends Controller
if (empty($dashboard)) { if (empty($dashboard)) {
$dashboard = $this->dispatch(new CreateDashboard([ $dashboard = $this->dispatch(new CreateDashboard([
'company_id' => session('company_id'), 'company_id' => company_id(),
'name' => trans_choice('general.dashboards', 1), 'name' => trans_choice('general.dashboards', 1),
'default_widgets' => 'core', 'default_widgets' => 'core',
])); ]));
@ -89,7 +88,7 @@ class Dashboards extends Controller
*/ */
public function create() public function create()
{ {
$users = Company::find(session('company_id'))->users()->get()->sortBy('name'); $users = company()->users()->get()->sortBy('name');
return view('common.dashboards.create', compact('users')); return view('common.dashboards.create', compact('users'));
} }
@ -130,11 +129,11 @@ class Dashboards extends Controller
*/ */
public function edit(Dashboard $dashboard) public function edit(Dashboard $dashboard)
{ {
if (!$this->isUserDashboard($dashboard->id)) { if ($this->isNotUserDashboard($dashboard->id)) {
return redirect()->route('dashboards.index'); return redirect()->route('dashboards.index');
} }
$users = Company::find(session('company_id'))->users()->get()->sortBy('name'); $users = company()->users()->get()->sortBy('name');
return view('common.dashboards.edit', compact('dashboard', 'users')); return view('common.dashboards.edit', compact('dashboard', 'users'));
} }

View File

@ -16,7 +16,7 @@ class Import extends Controller
*/ */
public function create($group, $type, $route = null) public function create($group, $type, $route = null)
{ {
$path = $group . '/' . $type; $path = company_id() . '/' . $group . '/' . $type;
if (module($group) instanceof \Akaunting\Module\Module) { if (module($group) instanceof \Akaunting\Module\Module) {
$namespace = $group . '::'; $namespace = $group . '::';

View File

@ -111,20 +111,16 @@ class Items extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.items', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('items.index'); $response['redirect'] = route('items.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.items', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['common', 'items']); $response['redirect'] = route('import.create', ['common', 'items']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -182,7 +182,7 @@ class Uploads extends Controller
$folders = explode('/', $media->directory); $folders = explode('/', $media->directory);
// Check if company can access media // Check if company can access media
if ($folders[0] != session('company_id')) { if ($folders[0] != company_id()) {
return false; return false;
} }

View File

@ -73,7 +73,7 @@ class Updates extends Controller
Cache::forget('updates'); Cache::forget('updates');
Cache::forget('versions'); Cache::forget('versions');
event(new UpdateCacheCleared(session('company_id'))); event(new UpdateCacheCleared(company_id()));
return redirect()->back(); return redirect()->back();
} }
@ -274,7 +274,7 @@ class Updates extends Controller
set_time_limit(900); // 15 minutes set_time_limit(900); // 15 minutes
try { try {
$this->dispatch(new FinishUpdate($request['alias'], $request['version'], $request['installed'], session('company_id'))); $this->dispatch(new FinishUpdate($request['alias'], $request['version'], $request['installed'], company_id()));
$json = [ $json = [
'success' => true, 'success' => true,

View File

@ -110,7 +110,7 @@ class DocumentItemColumns extends Controller
$company_id = $request->get('company_id'); $company_id = $request->get('company_id');
if (empty($company_id)) { if (empty($company_id)) {
$company_id = session('company_id'); $company_id = company_id();
} }
foreach ($fields as $key => $value) { foreach ($fields as $key => $value) {

View File

@ -32,7 +32,7 @@ class InvoiceTemplates extends Controller
$company_id = $request->get('company_id'); $company_id = $request->get('company_id');
if (empty($company_id)) { if (empty($company_id)) {
$company_id = session('company_id'); $company_id = company_id();
} }
foreach ($fields as $key => $value) { foreach ($fields as $key => $value) {

View File

@ -56,7 +56,7 @@ class Items extends Controller
{ {
if ($request->get('type', false) == 'inline') { if ($request->get('type', false) == 'inline') {
$data = [ $data = [
'company_id' => session('company_id'), 'company_id' => company_id(),
'name' => '', 'name' => '',
'sale_price' => 0, 'sale_price' => 0,
'purchase_price' => 0, 'purchase_price' => 0,

View File

@ -204,7 +204,7 @@ class Item extends Controller
try { try {
$this->dispatch(new CopyFiles($request['alias'], $request['path'])); $this->dispatch(new CopyFiles($request['alias'], $request['path']));
event(new \App\Events\Module\Copied($request['alias'], session('company_id'))); event(new \App\Events\Module\Copied($request['alias'], company_id()));
$json = [ $json = [
'success' => true, 'success' => true,
@ -236,9 +236,9 @@ class Item extends Controller
public function install(Request $request) public function install(Request $request)
{ {
try { try {
event(new \App\Events\Module\Installing($request['alias'], session('company_id'))); event(new \App\Events\Module\Installing($request['alias'], company_id()));
$this->dispatch(new InstallModule($request['alias'], session('company_id'))); $this->dispatch(new InstallModule($request['alias'], company_id()));
$name = module($request['alias'])->getName(); $name = module($request['alias'])->getName();
@ -277,7 +277,7 @@ class Item extends Controller
try { try {
$name = module($alias)->getName(); $name = module($alias)->getName();
$this->dispatch(new UninstallModule($alias, session('company_id'))); $this->dispatch(new UninstallModule($alias, company_id()));
$message = trans('modules.uninstalled', ['module' => $name]); $message = trans('modules.uninstalled', ['module' => $name]);
@ -296,7 +296,7 @@ class Item extends Controller
try { try {
$name = module($alias)->getName(); $name = module($alias)->getName();
$this->dispatch(new EnableModule($alias, session('company_id'))); $this->dispatch(new EnableModule($alias, company_id()));
$message = trans('modules.enabled', ['module' => $name]); $message = trans('modules.enabled', ['module' => $name]);
@ -315,7 +315,7 @@ class Item extends Controller
try { try {
$name = module($alias)->getName(); $name = module($alias)->getName();
$this->dispatch(new DisableModule($alias, session('company_id'))); $this->dispatch(new DisableModule($alias, company_id()));
$message = trans('modules.disabled', ['module' => $name]); $message = trans('modules.disabled', ['module' => $name]);

View File

@ -19,7 +19,7 @@ class My extends Controller
{ {
$purchased = $this->getMyModules(); $purchased = $this->getMyModules();
$modules = $this->getInstalledModules(); $modules = $this->getInstalledModules();
$installed = Module::where('company_id', '=', session('company_id'))->pluck('enabled', 'alias')->toArray(); $installed = Module::where('company_id', '=', company_id())->pluck('enabled', 'alias')->toArray();
return $this->response('modules.my.index', compact('purchased', 'modules', 'installed')); return $this->response('modules.my.index', compact('purchased', 'modules', 'installed'));
} }

View File

@ -119,12 +119,12 @@ class Invoices extends Controller
$codes = explode('.', $payment_method_key); $codes = explode('.', $payment_method_key);
if (!isset($payment_actions[$codes[0]])) { if (!isset($payment_actions[$codes[0]])) {
$payment_actions[$codes[0]] = URL::signedRoute('signed.invoices.' . $codes[0] . '.show', [$invoice->id, 'company_id' => session('company_id')]); $payment_actions[$codes[0]] = URL::signedRoute('signed.invoices.' . $codes[0] . '.show', [$invoice->id]);
} }
} }
$print_action = URL::signedRoute('signed.invoices.print', [$invoice->id, 'company_id' => session('company_id')]); $print_action = URL::signedRoute('signed.invoices.print', [$invoice->id]);
$pdf_action = URL::signedRoute('signed.invoices.pdf', [$invoice->id, 'company_id' => session('company_id')]); $pdf_action = URL::signedRoute('signed.invoices.pdf', [$invoice->id]);
event(new \App\Events\Document\DocumentViewed($invoice)); event(new \App\Events\Document\DocumentViewed($invoice));

View File

@ -128,20 +128,16 @@ class Bills extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.bills', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('bills.index'); $response['redirect'] = route('bills.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.bills', 1)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['purchases', 'bills']); $response['redirect'] = route('import.create', ['purchases', 'bills']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -134,20 +134,16 @@ class Payments extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.payments', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('payments.index'); $response['redirect'] = route('payments.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.payments', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['purchases', 'payments']); $response['redirect'] = route('import.create', ['purchases', 'payments']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -161,20 +161,16 @@ class Vendors extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.vendors', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('vendors.index'); $response['redirect'] = route('vendors.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.vendors', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['purchases', 'vendors']); $response['redirect'] = route('import.create', ['purchases', 'vendors']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -159,20 +159,16 @@ class Customers extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.customers', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('customers.index'); $response['redirect'] = route('customers.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.customers', 1)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['sales', 'customers']); $response['redirect'] = route('import.create', ['sales', 'customers']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -127,20 +127,16 @@ class Invoices extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.invoices', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('invoices.index'); $response['redirect'] = route('invoices.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.invoices', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['sales', 'invoices']); $response['redirect'] = route('import.create', ['sales', 'invoices']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -134,20 +134,16 @@ class Revenues extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.revenues', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('revenues.index'); $response['redirect'] = route('revenues.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.revenues', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['sales', 'revenues']); $response['redirect'] = route('import.create', ['sales', 'revenues']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -92,20 +92,16 @@ class Categories extends Controller
*/ */
public function import(ImportRequest $request) public function import(ImportRequest $request)
{ {
$response = $this->importExcel(new Import, $request); $response = $this->importExcel(new Import, $request, trans_choice('general.categories', 2));
if ($response['success']) { if ($response['success']) {
$response['redirect'] = route('categories.index'); $response['redirect'] = route('categories.index');
$message = trans('messages.success.imported', ['type' => trans_choice('general.categories', 2)]); flash($response['message'])->success();
flash($message)->success();
} else { } else {
$response['redirect'] = route('import.create', ['settings', 'categories']); $response['redirect'] = route('import.create', ['settings', 'categories']);
$message = $response['message']; flash($response['message'])->error()->important();
flash($message)->error()->important();
} }
return response()->json($response); return response()->json($response);

View File

@ -16,7 +16,7 @@ class Modules extends Controller
*/ */
public function __construct() public function __construct()
{ {
$alias = request()->segment(1); $alias = request()->segment(2);
// Add CRUD permission check // Add CRUD permission check
$this->middleware('permission:create-' . $alias . '-settings')->only('create', 'store', 'duplicate', 'import'); $this->middleware('permission:create-' . $alias . '-settings')->only('create', 'store', 'duplicate', 'import');

View File

@ -80,7 +80,7 @@ class Settings extends Controller
$company_id = $request->get('company_id'); $company_id = $request->get('company_id');
if (empty($company_id)) { if (empty($company_id)) {
$company_id = session('company_id'); $company_id = company_id();
} }
$company = Company::find($company_id); $company = Company::find($company_id);

View File

@ -31,7 +31,7 @@ class Companies extends Controller
*/ */
public function edit() public function edit()
{ {
$company = Company::find(session('company_id')); $company = Company::find(company_id());
return view('wizard.companies.edit', compact('company')); return view('wizard.companies.edit', compact('company'));
} }
@ -46,7 +46,7 @@ class Companies extends Controller
public function update(Request $request) public function update(Request $request)
{ {
// Company // Company
$company = Company::find(session('company_id')); $company = Company::find(company_id());
$fields = $request->all(); $fields = $request->all();

View File

@ -36,11 +36,8 @@ class Kernel extends HttpKernel
// 'session.auth', // 'session.auth',
'session.errors', 'session.errors',
'csrf', 'csrf',
'bindings',
'install.redirect', 'install.redirect',
'header.x', 'header.x',
'company.settings',
'company.currencies',
'language', 'language',
'firewall.all', 'firewall.all',
], ],
@ -55,16 +52,16 @@ class Kernel extends HttpKernel
'auth.disabled', 'auth.disabled',
'throttle:api', 'throttle:api',
'permission:read-api', 'permission:read-api',
'api.company', 'company.identify',
'bindings', 'bindings',
'company.settings',
'company.currencies',
'language', 'language',
'firewall.all', 'firewall.all',
], ],
'common' => [ 'common' => [
'web', 'web',
'company.identify',
'bindings',
'wizard.redirect', 'wizard.redirect',
], ],
@ -77,6 +74,8 @@ class Kernel extends HttpKernel
'web', 'web',
'auth', 'auth',
'auth.disabled', 'auth.disabled',
'company.identify',
'bindings',
'wizard.redirect', 'wizard.redirect',
'menu.admin', 'menu.admin',
'permission:read-admin-panel', 'permission:read-admin-panel',
@ -86,6 +85,8 @@ class Kernel extends HttpKernel
'web', 'web',
'auth', 'auth',
'auth.disabled', 'auth.disabled',
'company.identify',
'bindings',
'permission:read-admin-panel', 'permission:read-admin-panel',
], ],
@ -93,6 +94,8 @@ class Kernel extends HttpKernel
'web', 'web',
'auth', 'auth',
'auth.disabled', 'auth.disabled',
'company.identify',
'bindings',
'menu.portal', 'menu.portal',
'permission:read-client-portal', 'permission:read-client-portal',
], ],
@ -105,11 +108,9 @@ class Kernel extends HttpKernel
'csrf', 'csrf',
'signature', 'signature',
'signed.redirect', 'signed.redirect',
'company.signed', 'company.identify',
'bindings', 'bindings',
'header.x', 'header.x',
'company.settings',
'company.currencies',
'language', 'language',
'firewall.all', 'firewall.all',
], ],
@ -141,13 +142,10 @@ class Kernel extends HttpKernel
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
// Akaunting // Akaunting
'api.company' => \App\Http\Middleware\ApiCompany::class, 'api.key' => \App\Http\Middleware\RedirectIfNoApiKey::class,
'api.key' => \App\Http\Middleware\CanApiKey::class,
'auth.disabled' => \App\Http\Middleware\LogoutIfUserDisabled::class, 'auth.disabled' => \App\Http\Middleware\LogoutIfUserDisabled::class,
'auth.redirect' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'auth.redirect' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'company.currencies' => \App\Http\Middleware\LoadCurrencies::class, 'company.identify' => \App\Http\Middleware\IdentifyCompany::class,
'company.settings' => \App\Http\Middleware\LoadSettings::class,
'company.signed' => \App\Http\Middleware\SignedCompany::class,
'dropzone' => \App\Http\Middleware\Dropzone::class, 'dropzone' => \App\Http\Middleware\Dropzone::class,
'header.x' => \App\Http\Middleware\AddXHeader::class, 'header.x' => \App\Http\Middleware\AddXHeader::class,
'menu.admin' => \App\Http\Middleware\AdminMenu::class, 'menu.admin' => \App\Http\Middleware\AdminMenu::class,

View File

@ -1,41 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
use App\Traits\Users;
class ApiCompany
{
use Users;
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$company_id = $request->get('company_id');
if (empty($company_id)) {
return $next($request);
}
// Check if user can access company
if (!$this->isUserCompany($company_id)) {
return $next($request);
}
// Set company id
session(['company_id' => $company_id]);
// Set the company settings
setting()->setExtraColumns(['company_id' => $company_id]);
setting()->load(true);
return $next($request);
}
}

View File

@ -10,7 +10,7 @@ class Authenticate extends Middleware
* Get the path the user should be redirected to when they are not authenticated. * Get the path the user should be redirected to when they are not authenticated.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @return string * @return string|null
*/ */
protected function redirectTo($request) protected function redirectTo($request)
{ {

View File

@ -0,0 +1,59 @@
<?php
namespace App\Http\Middleware;
use App\Traits\Users;
use Closure;
use Illuminate\Auth\AuthenticationException;
class IdentifyCompany
{
use Users;
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string[] ...$guards
* @return mixed
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function handle($request, Closure $next, ...$guards)
{
$company_id = $request->isApi()
? $this->getCompanyIdFromApi($request)
: $this->getCompanyIdFromWeb($request);
if (empty($company_id)) {
abort(500, 'Missing company');
}
// Check if user can access company
if ($request->isNotSigned($company_id) && $this->isNotUserCompany($company_id)) {
throw new AuthenticationException('Unauthenticated.', $guards);
}
// Set company as current
company($company_id)->makeCurrent();
// Fix routes
app('url')->defaults(['company_id' => $company_id]);
$request->route()->forgetParameter('company_id');
return $next($request);
}
protected function getCompanyIdFromWeb($request)
{
return (int) $request->route('company_id');
}
protected function getCompanyIdFromApi($request)
{
$company_id = $request->get('company_id', $request->header('X-Company'));
return $company_id ?: optional($this->getFirstCompanyOfUser())->id;
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace App\Http\Middleware;
use App\Utilities\Overrider;
use Closure;
class LoadCurrencies
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$company_id = session('company_id');
if (empty($company_id)) {
return $next($request);
}
Overrider::load('currencies');
return $next($request);
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace App\Http\Middleware;
use App\Utilities\Overrider;
use Closure;
class LoadSettings
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$company_id = session('company_id');
if (empty($company_id)) {
return $next($request);
}
Overrider::load('settings');
return $next($request);
}
}

View File

@ -20,15 +20,11 @@ class RedirectIfAuthenticated
$guards = empty($guards) ? [null] : $guards; $guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) { foreach ($guards as $guard) {
if (auth()->guard($guard)->check()) { if (!auth()->guard($guard)->check()) {
$user = user(); continue;
if ($user->contact) {
return redirect()->route('portal.dashboard');
} }
return redirect()->route($user->landing_page); return redirect(user()->getLandingPageOfUser());
}
} }
return $next($request); return $next($request);

View File

@ -4,7 +4,7 @@ namespace App\Http\Middleware;
use Closure; use Closure;
class CanApiKey class RedirectIfNoApiKey
{ {
/** /**
* Handle an incoming request. * Handle an incoming request.
@ -15,14 +15,14 @@ class CanApiKey
*/ */
public function handle($request, Closure $next) public function handle($request, Closure $next)
{ {
if ($request['alias'] != 'core') { if ($request->get('alias') == 'core') {
return $next($request);
}
if (setting('apps.api_key')) { if (setting('apps.api_key')) {
return $next($request); return $next($request);
} else {
redirect('apps/api-key/create')->send();
}
} else {
return $next($request);
} }
return redirect()->route('apps.api-key.create');
} }
} }

View File

@ -3,7 +3,6 @@
namespace App\Http\Middleware; namespace App\Http\Middleware;
use Closure; use Closure;
use Illuminate\Support\Str;
class RedirectIfNotInstalled class RedirectIfNotInstalled
{ {
@ -22,11 +21,11 @@ class RedirectIfNotInstalled
} }
// Already in the installation wizard // Already in the installation wizard
if (Str::startsWith($request->getPathInfo(), '/install')) { if ($request->isInstall()) {
return $next($request); return $next($request);
} }
// Not installed, redirect to installation wizard // Not installed, redirect to installation wizard
redirect()->route('install.requirements')->send(); return redirect()->route('install.requirements');
} }
} }

View File

@ -3,7 +3,6 @@
namespace App\Http\Middleware; namespace App\Http\Middleware;
use Closure; use Closure;
use Illuminate\Support\Str;
class RedirectIfWizardNotCompleted class RedirectIfWizardNotCompleted
{ {
@ -22,11 +21,11 @@ class RedirectIfWizardNotCompleted
} }
// Check url // Check url
if (Str::startsWith($request->getPathInfo(), '/wizard') || Str::startsWith($request->getPathInfo(), '/settings')) { if ($request->isWizard(company_id()) || $request->is(company_id() . '/settings/*')) {
return $next($request); return $next($request);
} }
// Redirect to wizard // Redirect to wizard
redirect()->route('wizard.edit')->send(); return redirect()->route('wizard.edit');
} }
} }

View File

@ -24,14 +24,14 @@ class RedirectSignedIfAuthenticated
$page = 'dashboard'; $page = 'dashboard';
$params = []; $params = [];
if ($request->segment(2) == 'invoices') { if ($request->segment(3) == 'invoices') {
$page = 'invoices.show'; $page = 'invoices.show';
$invoice = Document::find($request->segment(3)); $invoice = Document::find($request->segment(4));
$params = [$invoice->id]; $params = [$invoice->id];
} }
redirect()->route($prefix . $page, $params)->send(); return redirect()->route($prefix . $page, $params);
} }
} }

View File

@ -1,33 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
class SignedCompany
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$company_id = $request->get('company_id');
if (empty($company_id)) {
return $next($request);
}
// Set company id
session(['company_id' => $company_id]);
// Set the company settings
setting()->setExtraColumns(['company_id' => $company_id]);
setting()->load(true);
return $next($request);
}
}

View File

@ -9,7 +9,6 @@ use Illuminate\View\View;
class DocumentType class DocumentType
{ {
/** /**
* Bind data to the view. * Bind data to the view.
* *
@ -18,14 +17,15 @@ class DocumentType
*/ */
public function compose(View $view) public function compose(View $view)
{ {
if (!empty(request()->route())) {
$route = request()->route(); $route = request()->route();
if (empty($route)) {
return;
}
/** @var Invoices|Bills|PortalInvoices $controller */ /** @var Invoices|Bills|PortalInvoices $controller */
$controller = $route->getController(); $controller = $route->getController();
$view->with(['type' => $controller->type ?? '']); $view->with(['type' => $controller->type ?? '']);
} }
}
} }

View File

@ -6,7 +6,6 @@ use Illuminate\View\View;
class InvoiceText class InvoiceText
{ {
/** /**
* Bind data to the view. * Bind data to the view.
* *
@ -41,5 +40,4 @@ class InvoiceText
$view->with(['text_override' => $text_override]); $view->with(['text_override' => $text_override]);
} }
} }

View File

@ -42,7 +42,7 @@ class Logo
$image->make($path)->resize($width, $height)->encode(); $image->make($path)->resize($width, $height)->encode();
}); });
} catch (NotReadableException | \Exception $e) { } catch (NotReadableException | \Exception $e) {
Log::info('Company ID: ' . session('company_id') . ' viewcomposer/logo.php exception.'); Log::info('Company ID: ' . company_id() . ' viewcomposer/logo.php exception.');
Log::info($e->getMessage()); Log::info($e->getMessage());
$path = base_path('public/img/company.png'); $path = base_path('public/img/company.png');

View File

@ -27,6 +27,8 @@ class Notifications
return; return;
} }
$path = str_replace('{company_id}/', '', $path);
if (!$notifications = $this->getNotifications($path)) { if (!$notifications = $this->getNotifications($path)) {
return; return;
} }

View File

@ -31,6 +31,8 @@ class Suggestions
return; return;
} }
$path = str_replace('{company_id}/', '', $path);
if (!$suggestions = $this->getSuggestions($path)) { if (!$suggestions = $this->getSuggestions($path)) {
return; return;
} }

View File

@ -49,7 +49,7 @@ class Transfers extends Import
private function getExpenseTransactionId($row) private function getExpenseTransactionId($row)
{ {
$expense_transaction = Transaction::create([ $expense_transaction = Transaction::create([
'company_id' => session('company_id'), 'company_id' => company_id(),
'type' => 'expense', 'type' => 'expense',
'account_id' => $row['from_account_id'], 'account_id' => $row['from_account_id'],
'paid_at' => $row['transferred_at'], 'paid_at' => $row['transferred_at'],
@ -81,7 +81,7 @@ class Transfers extends Import
} }
$income_transaction = Transaction::create([ $income_transaction = Transaction::create([
'company_id' => session('company_id'), 'company_id' => company_id(),
'type' => 'income', 'type' => 'income',
'account_id' => $row['to_account_id'], 'account_id' => $row['to_account_id'],
'paid_at' => $row['transferred_at'], 'paid_at' => $row['transferred_at'],

View File

@ -0,0 +1,36 @@
<?php
namespace App\Jobs\Auth;
use App\Abstracts\JobShouldQueue;
class NotifyUser extends JobShouldQueue
{
protected $user;
protected $notification;
/**
* Create a new job instance.
*
* @param $user
* @param $notification
*/
public function __construct($user, $notification)
{
$this->user = $user;
$this->notification = $notification;
$this->onQueue('jobs');
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$this->user->notify($this->notification);
}
}

View File

@ -31,14 +31,14 @@ class CreateCompany extends Job
*/ */
public function handle() public function handle()
{ {
$current_company_id = company_id();
event(new CompanyCreating($this->request)); event(new CompanyCreating($this->request));
\DB::transaction(function () { \DB::transaction(function () {
$this->company = Company::create($this->request->all()); $this->company = Company::create($this->request->all());
// Clear settings $this->company->makeCurrent();
setting()->setExtraColumns(['company_id' => $this->company->id]);
setting()->forgetAll();
$this->callSeeds(); $this->callSeeds();
@ -47,6 +47,10 @@ class CreateCompany extends Job
event(new CompanyCreated($this->company)); event(new CompanyCreated($this->company));
if (!empty($current_company_id)) {
company($current_company_id)->makeCurrent();
}
return $this->company; return $this->company;
} }
@ -106,6 +110,5 @@ class CreateCompany extends Job
} }
setting()->save(); setting()->save();
setting()->forgetAll();
} }
} }

View File

@ -0,0 +1,55 @@
<?php
namespace App\Jobs\Common;
use App\Abstracts\JobShouldQueue;
use App\Notifications\Common\ExportCompleted;
use Illuminate\Support\Facades\File;
class CreateMediableForExport extends JobShouldQueue
{
protected $user;
protected $file_name;
/**
* Create a new job instance.
*
* @param $user
* @param $file_name
*/
public function __construct($user, $file_name)
{
$this->user = $user;
$this->file_name = $file_name;
$this->onQueue('jobs');
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$source = storage_path('app/uploads/' . $this->file_name);
$destination = storage_path('app/uploads/' . company_id() . '/exports/');
// Create exports directory
if (!File::isDirectory($destination)) {
File::makeDirectory($destination);
}
File::move($source, $destination . $this->file_name);
// Create the media record
$media = $this->importMedia($this->file_name, 'exports');
$this->user->attachMedia($media, 'export');
$download_url = route('uploads.download', ['id' => $media->id, 'company_id' => company_id()]);
$this->user->notify(new ExportCompleted($download_url));
}
}

View File

@ -11,17 +11,17 @@ class DeleteCompany extends Job
protected $company; protected $company;
protected $active_company_id; protected $current_company_id;
/** /**
* Create a new job instance. * Create a new job instance.
* *
* @param $request * @param $company
*/ */
public function __construct($company, $active_company_id) public function __construct($company)
{ {
$this->company = $company; $this->company = $company;
$this->active_company_id = $active_company_id; $this->current_company_id = company_id();
} }
/** /**
@ -56,14 +56,14 @@ class DeleteCompany extends Job
public function authorize() public function authorize()
{ {
// Can't delete active company // Can't delete active company
if ($this->company->id == $this->active_company_id) { if ($this->company->id == $this->current_company_id) {
$message = trans('companies.error.delete_active'); $message = trans('companies.error.delete_active');
throw new \Exception($message); throw new \Exception($message);
} }
// Check if user can access company // Check if user can access company
if (!$this->isUserCompany($this->company->id)) { if ($this->isNotUserCompany($this->company->id)) {
$message = trans('companies.error.not_user_company'); $message = trans('companies.error.not_user_company');
throw new \Exception($message); throw new \Exception($message);

View File

@ -60,7 +60,7 @@ class DeleteDashboard extends Job
} }
// Check if user can access dashboard // Check if user can access dashboard
if (!$this->isUserDashboard($this->dashboard->id)) { if ($this->isNotUserDashboard($this->dashboard->id)) {
$message = trans('dashboards.error.not_user_dashboard'); $message = trans('dashboards.error.not_user_dashboard');
throw new \Exception($message); throw new \Exception($message);

View File

@ -16,7 +16,7 @@ class UpdateCompany extends Job
protected $request; protected $request;
protected $active_company_id; protected $current_company_id;
/** /**
* Create a new job instance. * Create a new job instance.
@ -24,11 +24,11 @@ class UpdateCompany extends Job
* @param $company * @param $company
* @param $request * @param $request
*/ */
public function __construct($company, $request, $active_company_id) public function __construct($company, $request)
{ {
$this->company = $company; $this->company = $company;
$this->request = $this->getRequestInstance($request); $this->request = $this->getRequestInstance($request);
$this->active_company_id = $active_company_id; $this->current_company_id = company_id();
} }
/** /**
@ -45,10 +45,7 @@ class UpdateCompany extends Job
\DB::transaction(function () { \DB::transaction(function () {
$this->company->update($this->request->all()); $this->company->update($this->request->all());
// Clear current and load given company settings $this->company->makeCurrent();
setting()->setExtraColumns(['company_id' => $this->company->id]);
setting()->forgetAll();
setting()->load(true);
if ($this->request->has('name')) { if ($this->request->has('name')) {
setting()->set('company.name', $this->request->get('name')); setting()->set('company.name', $this->request->get('name'));
@ -89,11 +86,14 @@ class UpdateCompany extends Job
} }
setting()->save(); setting()->save();
setting()->forgetAll();
}); });
event(new CompanyUpdated($this->company, $this->request)); event(new CompanyUpdated($this->company, $this->request));
if (!empty($this->current_company_id)) {
company($this->current_company_id)->makeCurrent();
}
return $this->company; return $this->company;
} }
@ -105,14 +105,14 @@ class UpdateCompany extends Job
public function authorize() public function authorize()
{ {
// Can't disable active company // Can't disable active company
if (($this->request->get('enabled', 1) == 0) && ($this->company->id == $this->active_company_id)) { if (($this->request->get('enabled', 1) == 0) && ($this->company->id == $this->current_company_id)) {
$message = trans('companies.error.disable_active'); $message = trans('companies.error.disable_active');
throw new \Exception($message); throw new \Exception($message);
} }
// Check if user can access company // Check if user can access company
if (!$this->isUserCompany($this->company->id)) { if ($this->isNotUserCompany($this->company->id)) {
$message = trans('companies.error.not_user_company'); $message = trans('companies.error.not_user_company');
throw new \Exception($message); throw new \Exception($message);

View File

@ -77,7 +77,7 @@ class UpdateDashboard extends Job
} }
// Check if user can access dashboard // Check if user can access dashboard
if (!$this->isUserDashboard($this->dashboard->id)) { if ($this->isNotUserDashboard($this->dashboard->id)) {
$message = trans('dashboards.error.not_user_dashboard'); $message = trans('dashboards.error.not_user_dashboard');
throw new \Exception($message); throw new \Exception($message);

View File

@ -15,21 +15,6 @@ class Login
*/ */
public function handle(Event $event) public function handle(Event $event)
{ {
// Get first company
$company = $event->user->companies()->enabled()->first();
// Logout if no company assigned
if (!$company) {
app('App\Http\Controllers\Auth\Login')->logout();
flash(trans('auth.error.no_company'))->error()->important();
return;
}
// Set company id
session(['company_id' => $company->id]);
// Save user login time // Save user login time
$event->user->last_logged_in_at = Date::now(); $event->user->last_logged_in_at = Date::now();

View File

@ -29,17 +29,17 @@ class AddAdminItems
if (session('dashboard_id') != $dashboard->id) { if (session('dashboard_id') != $dashboard->id) {
$sub->route('dashboards.switch', $dashboard->name, ['dashboard' => $dashboard->id], $key, $attr); $sub->route('dashboards.switch', $dashboard->name, ['dashboard' => $dashboard->id], $key, $attr);
} else { } else {
$sub->url('/', $dashboard->name, $key, $attr); $sub->url('/' . company_id(), $dashboard->name, $key, $attr);
} }
} }
}, 10, [ }, 10, [
'url' => '/', 'url' => '/' . company_id(),
'title' => trans_choice('general.dashboards', 2), 'title' => trans_choice('general.dashboards', 2),
'icon' => 'fa fa-tachometer-alt', 'icon' => 'fa fa-tachometer-alt',
]); ]);
} else { } else {
$menu->add([ $menu->add([
'url' => '/', 'url' => '/' . company_id(),
'title' => trans_choice('general.dashboards', 1), 'title' => trans_choice('general.dashboards', 1),
'icon' => 'fa fa-tachometer-alt', 'icon' => 'fa fa-tachometer-alt',
'order' => 10, 'order' => 10,

View File

@ -51,7 +51,7 @@ class UpdateExtraModules
continue; continue;
} }
$company_id = session('company_id'); $company_id = company_id();
$command = "update {$alias} {$company_id} {$latest_version}"; $command = "update {$alias} {$company_id} {$latest_version}";

View File

@ -70,34 +70,25 @@ class Version200 extends Listener
protected function updateCompanies() protected function updateCompanies()
{ {
$company_id = session('company_id'); $company_id = company_id();
$companies = Company::cursor(); $companies = Company::cursor();
foreach ($companies as $company) { foreach ($companies as $company) {
session(['company_id' => $company->id]); $company->makeCurrent();
$this->updateSettings($company); $this->updateSettings();
$this->createEmailTemplates($company); $this->createEmailTemplates($company);
$this->createReports($company); $this->createReports($company);
} }
setting()->forgetAll(); company($company_id)->makeCurrent();
session(['company_id' => $company_id]);
Overrider::load('settings');
} }
public function updateSettings($company) public function updateSettings()
{ {
// Set the active company settings
setting()->setExtraColumns(['company_id' => $company->id]);
setting()->forgetAll();
setting()->load(true);
// Override settings // Override settings
config(['app.url' => route('dashboard')]); config(['app.url' => route('dashboard')]);
config(['app.timezone' => setting('general.timezone', 'UTC')]); config(['app.timezone' => setting('general.timezone', 'UTC')]);

View File

@ -30,30 +30,21 @@ class Version203 extends Listener
protected function updateCompanies() protected function updateCompanies()
{ {
$company_id = session('company_id'); $company_id = company_id();
$companies = Company::cursor(); $companies = Company::cursor();
foreach ($companies as $company) { foreach ($companies as $company) {
session(['company_id' => $company->id]); $company->makeCurrent();
$this->updateSettings($company); $this->updateSettings($company);
} }
setting()->forgetAll(); company($company_id)->makeCurrent();
session(['company_id' => $company_id]);
Overrider::load('settings');
} }
public function updateSettings($company) public function updateSettings($company)
{ {
// Set the active company settings
setting()->setExtraColumns(['company_id' => $company->id]);
setting()->forgetAll();
setting()->load(true);
setting()->set(['invoice.payment_terms' => setting('invoice.payment_terms', 0)]); setting()->set(['invoice.payment_terms' => setting('invoice.payment_terms', 0)]);
setting()->save(); setting()->save();

View File

@ -1031,24 +1031,20 @@ class Version210 extends Listener
protected function updateCompanies() protected function updateCompanies()
{ {
$company_id = session('company_id'); $company_id = company_id();
$companies = Company::cursor(); $companies = Company::cursor();
foreach ($companies as $company) { foreach ($companies as $company) {
session(['company_id' => $company->id]); $company->makeCurrent();
$this->updateSettings($company); $this->updateSettings();
} }
setting()->forgetAll(); company($company_id)->makeCurrent();
session(['company_id' => $company_id]);
Overrider::load('settings');
} }
public function updateSettings($company) public function updateSettings()
{ {
$income_category = Category::income()->enabled()->first(); $income_category = Category::income()->enabled()->first();
$expense_category = Category::expense()->enabled()->first(); $expense_category = Category::expense()->enabled()->first();
@ -1057,11 +1053,6 @@ class Version210 extends Listener
return; return;
} }
// Set the active company settings
setting()->setExtraColumns(['company_id' => $company->id]);
setting()->forgetAll();
setting()->load(true);
setting()->set(['default.income_category' => setting('default.income_category', $income_category->id)]); setting()->set(['default.income_category' => setting('default.income_category', $income_category->id)]);
setting()->set(['default.expense_category' => setting('default.expense_category', $expense_category->id)]); setting()->set(['default.expense_category' => setting('default.expense_category', $expense_category->id)]);

View File

@ -30,30 +30,21 @@ class Version213 extends Listener
protected function updateCompanies() protected function updateCompanies()
{ {
$company_id = session('company_id'); $company_id = company_id();
$companies = Company::cursor(); $companies = Company::cursor();
foreach ($companies as $company) { foreach ($companies as $company) {
session(['company_id' => $company->id]); $company->makeCurrent();
$this->updateSettings($company); $this->updateSettings();
} }
setting()->forgetAll(); company($company_id)->makeCurrent();
session(['company_id' => $company_id]);
Overrider::load('settings');
} }
public function updateSettings($company) public function updateSettings()
{ {
// Set the active company settings
setting()->setExtraColumns(['company_id' => $company->id]);
setting()->forgetAll();
setting()->load(true);
$company_logo = setting('company.logo'); $company_logo = setting('company.logo');
if (is_array($company_logo)) { if (is_array($company_logo)) {

View File

@ -5,7 +5,9 @@ namespace App\Models\Auth;
use App\Traits\Tenants; use App\Traits\Tenants;
use App\Notifications\Auth\Reset; use App\Notifications\Auth\Reset;
use App\Traits\Media; use App\Traits\Media;
use App\Traits\Users;
use Date; use Date;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
@ -14,9 +16,9 @@ use Kyslik\ColumnSortable\Sortable;
use Laratrust\Traits\LaratrustUserTrait; use Laratrust\Traits\LaratrustUserTrait;
use Lorisleiva\LaravelSearchString\Concerns\SearchString; use Lorisleiva\LaravelSearchString\Concerns\SearchString;
class User extends Authenticatable class User extends Authenticatable implements HasLocalePreference
{ {
use HasFactory, LaratrustUserTrait, Notifiable, SearchString, SoftDeletes, Sortable, Media, Tenants; use HasFactory, LaratrustUserTrait, Notifiable, SearchString, SoftDeletes, Sortable, Media, Tenants, Users;
protected $table = 'users'; protected $table = 'users';
@ -193,20 +195,39 @@ class User extends Authenticatable
} }
/** /**
* Convert tax to Array. * Attach company_ids attribute to model.
* *
* @return void * @return void
*/ */
public function setCompanyIds() public function setCompanyIds()
{ {
$this->setAttribute('company_ids', $this->companies->pluck('id')->toArray()); $company_ids = $this->withoutEvents(function () {
return $this->companies->pluck('id')->toArray();
});
$this->setAttribute('company_ids', $company_ids);
} }
/**
* Detach company_ids attribute from model.
*
* @return void
*/
public function unsetCompanyIds() public function unsetCompanyIds()
{ {
$this->offsetUnset('company_ids'); $this->offsetUnset('company_ids');
} }
/**
* Get the user's preferred locale.
*
* @return string
*/
public function preferredLocale()
{
return $this->locale;
}
/** /**
* Create a new factory instance for the model. * Create a new factory instance for the model.
* *

View File

@ -2,11 +2,16 @@
namespace App\Models\Common; namespace App\Models\Common;
use App\Events\Common\CompanyForgettingCurrent;
use App\Events\Common\CompanyForgotCurrent;
use App\Events\Common\CompanyMadeCurrent;
use App\Events\Common\CompanyMakingCurrent;
use App\Models\Document\Document; use App\Models\Document\Document;
use App\Traits\Contacts; use App\Traits\Contacts;
use App\Traits\Media; use App\Traits\Media;
use App\Traits\Tenants; use App\Traits\Tenants;
use App\Traits\Transactions; use App\Traits\Transactions;
use App\Utilities\Overrider;
use Illuminate\Database\Eloquent\Model as Eloquent; use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Kyslik\ColumnSortable\Sortable; use Kyslik\ColumnSortable\Sortable;
@ -435,4 +440,82 @@ class Company extends Eloquent
{ {
return $this->getMedia('company_logo')->last(); return $this->getMedia('company_logo')->last();
} }
public function makeCurrent()
{
if ($this->isCurrent()) {
return $this;
}
static::forgetCurrent();
event(new CompanyMakingCurrent($this));
// Bind to container
app()->instance(static::class, $this);
// Set session for backward compatibility @deprecated
//session(['company_id' => $this->id]);
// Load settings
setting()->setExtraColumns(['company_id' => $this->id]);
setting()->forgetAll();
setting()->load(true);
// Override settings and currencies
Overrider::load('settings');
Overrider::load('currencies');
event(new CompanyMadeCurrent($this));
return $this;
}
public function isCurrent()
{
return optional(static::getCurrent())->id === $this->id;
}
public function isNotCurrent()
{
return !$this->isCurrent();
}
public static function getCurrent()
{
if (!app()->has(static::class)) {
return null;
}
return app(static::class);
}
public static function forgetCurrent()
{
$current = static::getCurrent();
if (is_null($current)) {
return null;
}
event(new CompanyForgettingCurrent($current));
// Remove from container
app()->forgetInstance(static::class);
// Unset session for backward compatibility @deprecated
//session()->forget('company_id');
// Remove settings
setting()->forgetAll();
event(new CompanyForgotCurrent($current));
return $current;
}
public static function hasCurrent()
{
return static::getCurrent() !== null;
}
} }

View File

@ -0,0 +1,52 @@
<?php
namespace App\Notifications\Common;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ExportCompleted extends Notification implements ShouldQueue
{
use Queueable;
protected $download_url;
/**
* Create a notification instance.
*
* @param string $download_url
*/
public function __construct($download_url)
{
$this->download_url = $download_url;
$this->onQueue('notifications');
}
/**
* Get the notification's channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject(trans('notifications.export.completed.subject'))
->line(trans('notifications.export.completed.description'))
->action(trans('general.download'), $this->download_url);
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace App\Notifications\Common;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ExportFailed extends Notification implements ShouldQueue
{
use Queueable;
/**
* The error exception.
*
* @var object
*/
public $exception;
/**
* Create a notification instance.
*
* @param object $exception
*/
public function __construct($exception)
{
$this->exception = $exception;
$this->onQueue('notifications');
}
/**
* Get the notification's channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject(trans('notifications.export.failed.subject'))
->line(trans('notifications.export.failed.description'))
->line($this->exception->getMessage());
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace App\Notifications\Common;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ImportCompleted extends Notification implements ShouldQueue
{
use Queueable;
/**
* Create a notification instance.
*/
public function __construct()
{
$this->onQueue('notifications');
}
/**
* Get the notification's channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$dashboard_url = route('dashboard', ['company_id' => company_id()]);
return (new MailMessage)
->subject(trans('notifications.import.completed.subject'))
->line(trans('notifications.import.completed.description'))
->action(trans_choice('general.dashboards', 1), $dashboard_url);
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Notifications\Common;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ImportFailed extends Notification implements ShouldQueue
{
use Queueable;
/**
* The error messages.
*
* @var array
*/
public $errors;
/**
* Create a notification instance.
*
* @param object $errors
*/
public function __construct($errors)
{
$this->errors = $errors;
$this->onQueue('notifications');
}
/**
* Get the notification's channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$message = (new MailMessage)
->subject(trans('notifications.import.failed.subject'))
->line(trans('notifications.import.failed.description'));
foreach ($this->errors as $error) {
$message->line($error);
}
return $message;
}
}

View File

@ -3,6 +3,7 @@
namespace App\Notifications\Portal; namespace App\Notifications\Portal;
use App\Abstracts\Notification; use App\Abstracts\Notification;
use App\Models\Common\EmailTemplate;
use Illuminate\Support\Facades\URL; use Illuminate\Support\Facades\URL;
class PaymentReceived extends Notification class PaymentReceived extends Notification
@ -39,7 +40,7 @@ class PaymentReceived extends Notification
$this->invoice = $invoice; $this->invoice = $invoice;
$this->transaction = $transaction; $this->transaction = $transaction;
$this->template = $template; $this->template = EmailTemplate::alias($template)->first();
} }
/** /**
@ -105,7 +106,7 @@ class PaymentReceived extends Notification
money($this->invoice->amount, $this->invoice->currency_code, true), money($this->invoice->amount, $this->invoice->currency_code, true),
company_date($this->invoice->due_at), company_date($this->invoice->due_at),
trans('documents.statuses.' . $this->invoice->status), trans('documents.statuses.' . $this->invoice->status),
URL::signedRoute('signed.invoices.show', [$this->invoice->id, 'company_id' => $this->invoice->company_id]), URL::signedRoute('signed.invoices.show', [$this->invoice->id]),
route('invoices.show', $this->invoice->id), route('invoices.show', $this->invoice->id),
route('portal.invoices.show', $this->invoice->id), route('portal.invoices.show', $this->invoice->id),
money($this->transaction->amount, $this->transaction->currency_code, true), money($this->transaction->amount, $this->transaction->currency_code, true),

View File

@ -3,6 +3,7 @@
namespace App\Notifications\Purchase; namespace App\Notifications\Purchase;
use App\Abstracts\Notification; use App\Abstracts\Notification;
use App\Models\Common\EmailTemplate;
class Bill extends Notification class Bill extends Notification
{ {
@ -31,7 +32,7 @@ class Bill extends Notification
parent::__construct(); parent::__construct();
$this->bill = $bill; $this->bill = $bill;
$this->template = $template; $this->template = EmailTemplate::alias($template)->first();
} }
/** /**

View File

@ -3,6 +3,7 @@
namespace App\Notifications\Sale; namespace App\Notifications\Sale;
use App\Abstracts\Notification; use App\Abstracts\Notification;
use App\Models\Common\EmailTemplate;
use Illuminate\Support\Facades\URL; use Illuminate\Support\Facades\URL;
class Invoice extends Notification class Invoice extends Notification
@ -32,7 +33,7 @@ class Invoice extends Notification
parent::__construct(); parent::__construct();
$this->invoice = $invoice; $this->invoice = $invoice;
$this->template = $template; $this->template = EmailTemplate::alias($template)->first();
} }
/** /**
@ -95,7 +96,7 @@ class Invoice extends Notification
money($this->invoice->amount, $this->invoice->currency_code, true), money($this->invoice->amount, $this->invoice->currency_code, true),
money($this->invoice->amount_due, $this->invoice->currency_code, true), money($this->invoice->amount_due, $this->invoice->currency_code, true),
company_date($this->invoice->due_at), company_date($this->invoice->due_at),
URL::signedRoute('signed.invoices.show', [$this->invoice->id, 'company_id' => $this->invoice->company_id]), URL::signedRoute('signed.invoices.show', [$this->invoice->id]),
route('invoices.show', $this->invoice->id), route('invoices.show', $this->invoice->id),
route('portal.invoices.show', $this->invoice->id), route('portal.invoices.show', $this->invoice->id),
$this->invoice->contact_name, $this->invoice->contact_name,

View File

@ -9,6 +9,16 @@ use Illuminate\View\Factory as ViewFactory;
class Macro extends ServiceProvider class Macro extends ServiceProvider
{ {
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/** /**
* Bootstrap any application services. * Bootstrap any application services.
* *
@ -24,6 +34,59 @@ class Macro extends ServiceProvider
return !$this->isApi(); return !$this->isApi();
}); });
Request::macro('isAuth', function () {
return $this->is('auth/*');
});
Request::macro('isNotAuth', function () {
return !$this->isAuth();
});
Request::macro('isInstall', function () {
return $this->is('install/*');
});
Request::macro('isNotInstall', function () {
return !$this->isInstall();
});
Request::macro('isSigned', function ($company_id) {
return $this->is($company_id . '/signed/*');
});
Request::macro('isNotSigned', function ($company_id) {
return !$this->isSigned($company_id);
});
Request::macro('isPortal', function ($company_id) {
return $this->is($company_id . '/portal') || $this->is($company_id . '/portal/*');
});
Request::macro('isNotPortal', function ($company_id) {
return !$this->isPortal($company_id);
});
Request::macro('isWizard', function ($company_id) {
return $this->is($company_id . '/wizard') || $this->is($company_id . '/wizard/*');
});
Request::macro('isNotWizard', function ($company_id) {
return !$this->isWizard($company_id);
});
Request::macro('isAdmin', function ($company_id) {
return $this->isNotApi()
&& $this->isNotAuth()
&& $this->isNotInstall()
&& $this->isNotSigned($company_id)
&& $this->isNotPortal($company_id)
&& $this->isNotWizard($company_id);
});
Request::macro('isNotAdmin', function ($company_id) {
return !$this->isAdmin($company_id);
});
Str::macro('filename', function ($string, $separator = '-') { Str::macro('filename', function ($string, $separator = '-') {
// Replace @ with the word 'at' // Replace @ with the word 'at'
$string = str_replace('@', $separator.'at'.$separator, $string); $string = str_replace('@', $separator.'at'.$separator, $string);
@ -47,14 +110,4 @@ class Macro extends ServiceProvider
return false; return false;
}); });
} }
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
} }

View File

@ -8,17 +8,7 @@ use Illuminate\Support\ServiceProvider as Provider;
class Observer extends Provider class Observer extends Provider
{ {
/** /**
* Register bindings in the container. * Register any application services.
*
* @return void
*/
public function boot()
{
Transaction::observe('App\Observers\Transaction');
}
/**
* Register the service provider.
* *
* @return void * @return void
*/ */
@ -26,4 +16,14 @@ class Observer extends Provider
{ {
// //
} }
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Transaction::observe('App\Observers\Transaction');
}
} }

102
app/Providers/Queue.php Normal file
View File

@ -0,0 +1,102 @@
<?php
namespace App\Providers;
use App\Notifications\Common\ImportFailed;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Support\ServiceProvider as Provider;
class Queue extends Provider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
app('queue')->createPayloadUsing(function ($connection, $queue, $payload) {
$company_id = company_id();
if (empty($company_id)) {
return [];
}
return ['company_id' => $company_id];
});
app('events')->listen(JobProcessing::class, function ($event) {
$payload = $event->job->payload();
if (!array_key_exists('company_id', $payload)) {
return;
}
$company = company($payload['company_id']);
if (empty($company)) {
$event->job->delete();
}
$company->makeCurrent();
});
app('events')->listen(JobFailed::class, function ($event) {
if (!$event->exception instanceof \Maatwebsite\Excel\Validators\ValidationException) {
return;
}
$body = $event->job->getRawBody();
if (empty($body) || !is_string($body)) {
return;
}
$payload = json_decode($body);
if (empty($payload) || empty($payload->data) || empty($payload->data->command)) {
return;
}
$excel_job = unserialize($payload->data->command);
if (!$excel_job instanceof \Maatwebsite\Excel\Jobs\ReadChunk) {
return;
}
$ref = new \ReflectionProperty($excel_job, 'import');
$ref->setAccessible(true);
// Get import class
$class = $ref->getValue($excel_job);
if (!$class instanceof \App\Abstracts\Import) {
return;
}
$errors = [];
foreach ($event->exception->failures() as $failure) {
$message = trans('messages.error.import_column', [
'message' => collect($failure->errors())->first(),
'column' => $failure->attribute(),
'line' => $failure->row(),
]);
$errors[] = $message;
}
if (!empty($errors)) {
$class->user->notify(new ImportFailed($errors));
}
});
}
}

View File

@ -92,7 +92,8 @@ class Route extends Provider
*/ */
protected function mapCommonRoutes() protected function mapCommonRoutes()
{ {
Facade::middleware('common') Facade::prefix('{company_id}')
->middleware('common')
->namespace($this->namespace) ->namespace($this->namespace)
->group(base_path('routes/common.php')); ->group(base_path('routes/common.php'));
} }
@ -120,7 +121,7 @@ class Route extends Provider
*/ */
protected function mapWizardRoutes() protected function mapWizardRoutes()
{ {
Facade::prefix('wizard') Facade::prefix('{company_id}/wizard')
->middleware('wizard') ->middleware('wizard')
->namespace($this->namespace) ->namespace($this->namespace)
->group(base_path('routes/wizard.php')); ->group(base_path('routes/wizard.php'));
@ -135,7 +136,8 @@ class Route extends Provider
*/ */
protected function mapAdminRoutes() protected function mapAdminRoutes()
{ {
Facade::middleware('admin') Facade::prefix('{company_id}')
->middleware('admin')
->namespace($this->namespace) ->namespace($this->namespace)
->group(base_path('routes/admin.php')); ->group(base_path('routes/admin.php'));
} }
@ -149,7 +151,7 @@ class Route extends Provider
*/ */
protected function mapPortalRoutes() protected function mapPortalRoutes()
{ {
Facade::prefix('portal') Facade::prefix('{company_id}/portal')
->middleware('portal') ->middleware('portal')
->namespace($this->namespace) ->namespace($this->namespace)
->group(base_path('routes/portal.php')); ->group(base_path('routes/portal.php'));
@ -164,7 +166,7 @@ class Route extends Provider
*/ */
protected function mapSignedRoutes() protected function mapSignedRoutes()
{ {
Facade::prefix('signed') Facade::prefix('{company_id}/signed')
->middleware('signed') ->middleware('signed')
->namespace($this->namespace) ->namespace($this->namespace)
->group(base_path('routes/signed.php')); ->group(base_path('routes/signed.php'));

View File

@ -42,6 +42,6 @@ class Company implements Scope
} }
// Apply company scope // Apply company scope
$builder->where($table . '.company_id', '=', session('company_id')); $builder->where($table . '.company_id', '=', company_id());
} }
} }

View File

@ -116,9 +116,9 @@ trait Import
public function getAccountIdFromCurrency($row) public function getAccountIdFromCurrency($row)
{ {
return Account::firstOrCreate([ return Account::firstOrCreate([
'company_id' => company_id(),
'currency_code' => $row['currency_code'], 'currency_code' => $row['currency_code'],
], [ ], [
'company_id' => session('company_id'),
'name' => !empty($row['account_name']) ? $row['account_name'] : $row['currency_code'], 'name' => !empty($row['account_name']) ? $row['account_name'] : $row['currency_code'],
'number' => !empty($row['account_number']) ? $row['account_number'] : rand(1, 10000), 'number' => !empty($row['account_number']) ? $row['account_number'] : rand(1, 10000),
'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0, 'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0,
@ -129,9 +129,9 @@ trait Import
public function getAccountIdFromName($row) public function getAccountIdFromName($row)
{ {
return Account::firstOrCreate([ return Account::firstOrCreate([
'company_id' => company_id(),
'name' => $row['account_name'], 'name' => $row['account_name'],
], [ ], [
'company_id' => session('company_id'),
'number' => !empty($row['account_number']) ? $row['account_number'] : rand(1, 10000), 'number' => !empty($row['account_number']) ? $row['account_number'] : rand(1, 10000),
'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : setting('default.currency'), 'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : setting('default.currency'),
'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0, 'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0,
@ -142,9 +142,9 @@ trait Import
public function getAccountIdFromNumber($row) public function getAccountIdFromNumber($row)
{ {
return Account::firstOrCreate([ return Account::firstOrCreate([
'company_id' => company_id(),
'number' => $row['account_number'], 'number' => $row['account_number'],
], [ ], [
'company_id' => session('company_id'),
'name' => !empty($row['account_name']) ? $row['account_name'] : $row['account_number'], 'name' => !empty($row['account_name']) ? $row['account_name'] : $row['account_number'],
'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : setting('default.currency'), 'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : setting('default.currency'),
'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0, 'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0,
@ -155,9 +155,9 @@ trait Import
public function getCategoryIdFromName($row, $type) public function getCategoryIdFromName($row, $type)
{ {
return Category::firstOrCreate([ return Category::firstOrCreate([
'company_id' => company_id(),
'name' => $row['category_name'], 'name' => $row['category_name'],
], [ ], [
'company_id' => session('company_id'),
'type' => $type, 'type' => $type,
'color' => !empty($row['category_color']) ? $row['category_color'] : '#' . dechex(rand(0x000000, 0xFFFFFF)), 'color' => !empty($row['category_color']) ? $row['category_color'] : '#' . dechex(rand(0x000000, 0xFFFFFF)),
'enabled' => 1, 'enabled' => 1,
@ -167,9 +167,9 @@ trait Import
public function getContactIdFromEmail($row, $type) public function getContactIdFromEmail($row, $type)
{ {
return Contact::firstOrCreate([ return Contact::firstOrCreate([
'company_id' => company_id(),
'email' => $row['contact_email'], 'email' => $row['contact_email'],
], [ ], [
'company_id' => session('company_id'),
'type' => $type, 'type' => $type,
'name' => !empty($row['contact_name']) ? $row['contact_name'] : $row['contact_email'], 'name' => !empty($row['contact_name']) ? $row['contact_name'] : $row['contact_email'],
'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : setting('default.currency'), 'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : setting('default.currency'),
@ -180,9 +180,9 @@ trait Import
public function getContactIdFromName($row, $type) public function getContactIdFromName($row, $type)
{ {
return Contact::firstOrCreate([ return Contact::firstOrCreate([
'company_id' => company_id(),
'name' => $row['contact_name'], 'name' => $row['contact_name'],
], [ ], [
'company_id' => session('company_id'),
'type' => $type, 'type' => $type,
'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : setting('default.currency'), 'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : setting('default.currency'),
'enabled' => 1, 'enabled' => 1,
@ -192,9 +192,9 @@ trait Import
public function getItemIdFromName($row) public function getItemIdFromName($row)
{ {
return Item::firstOrCreate([ return Item::firstOrCreate([
'company_id' => company_id(),
'name' => $row['item_name'], 'name' => $row['item_name'],
], [ ], [
'company_id' => session('company_id'),
'sale_price' => !empty($row['sale_price']) ? $row['sale_price'] : (!empty($row['price']) ? $row['price'] : 0), 'sale_price' => !empty($row['sale_price']) ? $row['sale_price'] : (!empty($row['price']) ? $row['price'] : 0),
'purchase_price' => !empty($row['purchase_price']) ? $row['purchase_price'] : (!empty($row['price']) ? $row['price'] : 0), 'purchase_price' => !empty($row['purchase_price']) ? $row['purchase_price'] : (!empty($row['price']) ? $row['price'] : 0),
'enabled' => 1, 'enabled' => 1,
@ -204,9 +204,9 @@ trait Import
public function getTaxIdFromRate($row, $type = 'normal') public function getTaxIdFromRate($row, $type = 'normal')
{ {
return Tax::firstOrCreate([ return Tax::firstOrCreate([
'company_id' => company_id(),
'rate' => $row['tax_rate'], 'rate' => $row['tax_rate'],
], [ ], [
'company_id' => session('company_id'),
'type' => $type, 'type' => $type,
'name' => !empty($row['tax_name']) ? $row['tax_name'] : $row['tax_rate'], 'name' => !empty($row['tax_name']) ? $row['tax_name'] : $row['tax_rate'],
'enabled' => 1, 'enabled' => 1,

View File

@ -3,6 +3,7 @@
namespace App\Traits; namespace App\Traits;
use Exception; use Exception;
use Illuminate\Bus\Dispatcher;
use Throwable; use Throwable;
trait Jobs trait Jobs
@ -17,7 +18,32 @@ trait Jobs
{ {
$function = $this->getDispatchFunction(); $function = $this->getDispatchFunction();
return $function($job); return $this->$function($job);
}
/**
* Dispatch a job to its appropriate handler.
*
* @param mixed $command
* @return mixed
*/
public function dispatchQueue($job)
{
return app(Dispatcher::class)->dispatch($job);
}
/**
* Dispatch a command to its appropriate handler in the current process.
*
* Queuable jobs will be dispatched to the "sync" queue.
*
* @param mixed $command
* @param mixed $handler
* @return mixed
*/
public function dispatchSync($job, $handler = null)
{
return app(Dispatcher::class)->dispatchSync($job, $handler);
} }
/** /**
@ -26,12 +52,12 @@ trait Jobs
* @param mixed $job * @param mixed $job
* @param mixed $handler * @param mixed $handler
* @return mixed * @return mixed
*
* @deprecated Will be removed in a future Laravel version.
*/ */
public function dispatchNow($job, $handler = null) public function dispatchNow($job, $handler = null)
{ {
$result = dispatch_now($job, $handler); return app(Dispatcher::class)->dispatchNow($job, $handler);
return $result;
} }
/** /**
@ -65,8 +91,6 @@ trait Jobs
public function getDispatchFunction() public function getDispatchFunction()
{ {
$config = config('queue.default'); return should_queue() ? 'dispatchQueue' : 'dispatchSync';
return ($config == 'sync') ? 'dispatch_now' : 'dispatch';
} }
} }

View File

@ -164,7 +164,7 @@ trait Modules
public function getInstalledModules() public function getInstalledModules()
{ {
$key = 'apps.installed.' . session('company_id'); $key = 'apps.installed.' . company_id();
if ($installed = Cache::get($key)) { if ($installed = Cache::get($key)) {
return $installed; return $installed;

View File

@ -83,7 +83,7 @@ trait Scopes
return $type; return $type;
} }
$type = $request->get('type') ?: Str::singular((string) $request->segment(2)); $type = $request->get('type') ?: Str::singular((string) $request->segment(3));
if ($type == 'revenue') { if ($type == 'revenue') {
$type = 'income'; $type = 'income';

View File

@ -19,7 +19,7 @@ trait SiteApi
$headers['headers'] = [ $headers['headers'] = [
'Authorization' => 'Bearer ' . setting('apps.api_key'), 'Authorization' => 'Bearer ' . setting('apps.api_key'),
'Accept' => 'application/json', 'Accept' => 'application/json',
'Referer' => app()->runningInConsole() ? config('app.url') : route('dashboard'), 'Referer' => app()->runningInConsole() ? config('app.url') : url('/'),
'Akaunting' => version('short'), 'Akaunting' => version('short'),
'Language' => language()->getShortCode(), 'Language' => language()->getShortCode(),
'Information' => json_encode(Info::all()), 'Information' => json_encode(Info::all()),

Some files were not shown because too many files have changed in this diff Show More