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()
{
$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);
@ -36,7 +36,7 @@ abstract class Module extends Command
session()->forget('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\RowsPreparing;
use App\Notifications\Common\ExportFailed;
use App\Utilities\Date;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings;
@ -13,16 +17,21 @@ use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle;
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 $fields;
public $user;
public function __construct($ids = null)
{
$this->ids = $ids;
$this->fields = $this->fields();
$this->user = user();
}
public function title(): string
@ -74,4 +83,14 @@ abstract class Export implements FromCollection, ShouldAutoSize, WithHeadings, W
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->company = $this->user->companies()->first();
session(['company_id' => $this->company->id]);
setting()->setExtraColumns(['company_id' => $this->company->id]);
company($this->company->id)->makeCurrent();
}
public function getCompanyUsers()

View File

@ -3,11 +3,12 @@
namespace App\Abstracts\Http;
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\Permissions;
use App\Traits\Relationships;
use Exception;
use ErrorException;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
@ -15,9 +16,6 @@ use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Exceptions\SheetNotFoundException;
use Maatwebsite\Excel\Facades\Excel;
use Throwable;
abstract class Controller extends BaseController
{
@ -78,23 +76,49 @@ abstract class Controller extends BaseController
*
* @param $class
* @param $request
* @param $url
* @param $translation
*
* @return mixed
*/
public function importExcel($class, $request)
public function importExcel($class, $request, $translation)
{
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 = [
'success' => true,
'error' => false,
'data' => null,
'message' => '',
'message' => $message,
];
} catch (SheetNotFoundException | ErrorException | Exception | Throwable $e) {
$message = $e->getMessage();
} 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();
}
$response = [
'success' => false,
@ -111,15 +135,30 @@ abstract class Controller extends BaseController
* Export the excel file or catch errors
*
* @param $class
* @param $file_name
* @param $translation
* @param $extension
*
* @return mixed
*/
public function exportExcel($class, $file_name, $extension = 'xlsx')
public function exportExcel($class, $translation, $extension = 'xlsx')
{
try {
return Excel::download($class, Str::filename($file_name) . '.' . $extension);
} catch (ErrorException | Exception | Throwable $e) {
$file_name = Str::filename($translation) . '.' . $extension;
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();
return back();

View File

@ -15,7 +15,7 @@ abstract class FormRequest extends BaseFormRequest
protected function prepareForValidation()
{
$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\Utilities\Date;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\SkipsOnError;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Validators\Failure;
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;
public $empty_field = 'empty---';
public $user;
public function __construct()
{
$this->user = user();
}
public function map($row): array
{
$row['company_id'] = session('company_id');
$row['company_id'] = company_id();
// Make enabled field integer
if (isset($row['enabled'])) {
@ -67,31 +71,6 @@ abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithChun
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)
{
return Validator::make($row, $this->rules())->fails();
@ -111,4 +90,9 @@ abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithChun
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\Relationships;
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)
{

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

View File

@ -611,7 +611,7 @@ abstract class DocumentShow extends Base
$image->make($path)->resize($width, $height)->encode();
});
} 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());
$path = base_path('public/img/company.png');
@ -651,11 +651,11 @@ abstract class DocumentShow extends Base
$route .= 'signed.' . $page . '.show';
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) {
$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;

View File

@ -213,7 +213,7 @@ abstract class DocumentTemplate extends Base
$image->make($path)->resize($width, $height)->encode();
});
} 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());
$path = base_path('public/img/company.png');