Implement adequate report filtering for lesser permissioned users
This commit is contained in:
parent
b21c182eda
commit
16a380972f
|
|
@ -115,6 +115,8 @@ class ActivityExport extends BaseExport
|
|||
|
||||
$query = $this->addDateRange($query, 'activities');
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['activity_type_id'] ?? false) {
|
||||
$query->where('activity_type_id', $this->input['activity_type_id']);
|
||||
}
|
||||
|
|
@ -133,12 +135,10 @@ class ActivityExport extends BaseExport
|
|||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($entity) {
|
||||
|
||||
/** @var \App\Models\Activity $entity */
|
||||
|
||||
$this->buildRow($entity);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1710,4 +1710,77 @@ $products = str_getcsv($this->input['product_key'], ',', "'");
|
|||
return $entity;
|
||||
|
||||
}
|
||||
|
||||
public function filterByUserPermissions(Builder $query): Builder
|
||||
{
|
||||
|
||||
$user = User::withTrashed()->where('id', $this->input['user_id'])->where('account_id', $this->company->account_id)->first();
|
||||
|
||||
if ($user->isAdmin() || $user->hasExactPermission('view_all') || $user->hasExactPermission('edit_all')) { // No State? Do we need to ensure -> isAdmin() binds to the correct company?
|
||||
return $query;
|
||||
}
|
||||
|
||||
if($user->hasExactPermission('create_all')){
|
||||
return $query->where('user_id', $user->id);
|
||||
}
|
||||
|
||||
return $this->resolveEntityFilters($user, $query);
|
||||
|
||||
}
|
||||
|
||||
private function resolveEntityFilters(User $user, Builder $query): Builder
|
||||
{
|
||||
$model = get_class($query->getModel());
|
||||
$column_listing = \Illuminate\Support\Facades\Schema::getColumnListing($query->getModel()->getTable());
|
||||
|
||||
$model_string = match($model) {
|
||||
'App\Models\Client' => 'client',
|
||||
'App\Models\ClientContact' => 'client',
|
||||
'App\Models\Invoice' => 'invoice',
|
||||
'App\Models\Quote' => 'quote',
|
||||
'App\Models\Credit' => 'credit',
|
||||
'App\Models\PurchaseOrder' => 'purchase_order',
|
||||
'App\Models\RecurringInvoice' => 'recurring_invoice',
|
||||
'App\Models\RecurringExpense' => 'recurring_expense',
|
||||
'App\Models\Task' => 'task',
|
||||
'App\Models\Vendor' => 'vendor',
|
||||
'App\Models\VendorContact' => 'vendor_contact',
|
||||
'App\Models\Product' => 'product',
|
||||
'App\Models\Payment' => 'payment',
|
||||
'App\Models\Expense' => 'expense',
|
||||
'App\Models\Document' => 'document',
|
||||
'App\Models\Activity' => 'activity',
|
||||
'App\Models\Task' => 'task',
|
||||
'App\Models\Project' => 'project',
|
||||
default => false,
|
||||
};
|
||||
|
||||
/** If the User can view or edit the entity, then return the query unfiltered */
|
||||
if($user->hasIntersectPermissions(["view_{$model_string}", "edit_{$model_string}"])){
|
||||
return $query;
|
||||
}
|
||||
|
||||
//Handle Child Models Like ClientContact or VendorContact
|
||||
if(in_array($model, ['App\Models\ClientContact', 'App\Models\VendorContact'])){
|
||||
|
||||
$query->whereHas($model_string, function ($_q) use ($user){
|
||||
$_q->where('user_id', $user->id)->orWhere('assigned_user_id', $user->id);
|
||||
});
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
||||
return $query->where(function ($q) use ($user, $column_listing){
|
||||
|
||||
if(in_array('user_id', $column_listing)){
|
||||
$q->where('user_id', $user->id);
|
||||
}
|
||||
|
||||
if(in_array('assigned_user_id', $column_listing)){
|
||||
$q->orWhere('assigned_user_id', $user->id);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ class ClientExport extends BaseExport
|
|||
|
||||
$query = $this->addDateRange($query, ' clients');
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ class ContactExport extends BaseExport
|
|||
});
|
||||
|
||||
$query = $this->addDateRange($query, 'client_contacts');
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
return $query;
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ class CreditExport extends BaseExport
|
|||
$query = $this->addCreditStatusFilter($query, $this->input['status']);
|
||||
}
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ class DocumentExport extends BaseExport
|
|||
|
||||
$query = $this->addDateRange($query, 'documents');
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ class ExpenseExport extends BaseExport
|
|||
$query = $this->addCategoryFilter($query, $this->input['categories']);
|
||||
}
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ class InvoiceExport extends BaseExport
|
|||
$query = $this->addInvoiceStatusFilter($query, $this->input['status']);
|
||||
}
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ class InvoiceItemExport extends BaseExport
|
|||
$query = $this->addInvoiceStatusFilter($query, $this->input['status']);
|
||||
}
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query = $this->applyProductFilters($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class PaymentExport extends BaseExport
|
|||
}
|
||||
|
||||
$query = $this->addPaymentStatusFilters($query, $this->input['status'] ?? '');
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ class ProductExport extends BaseExport
|
|||
}
|
||||
|
||||
$query = $this->addDateRange($query, 'products');
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ class ProductSalesExport extends BaseExport
|
|||
|
||||
$query = $this->filterByClients($query);
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query = $this->filterByProducts($query);
|
||||
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ class PurchaseOrderExport extends BaseExport
|
|||
if ($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query = $this->addPurchaseOrderStatusFilter($query, $this->input['status'] ?? '');
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ class PurchaseOrderItemExport extends BaseExport
|
|||
if ($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query = $this->addPurchaseOrderStatusFilter($query, $this->input['status'] ?? '');
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ class QuoteExport extends BaseExport
|
|||
|
||||
$query = $this->addQuoteStatusFilter($query, $this->input['status'] ?? '');
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ class QuoteItemExport extends BaseExport
|
|||
if ($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query = $this->addQuoteStatusFilter($query, $this->input['status'] ?? '');
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ class RecurringInvoiceExport extends BaseExport
|
|||
if ($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query = $this->addRecurringInvoiceStatusFilter($query, $this->input['status'] ?? '');
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ class RecurringInvoiceItemExport extends BaseExport
|
|||
if ($this->input['status'] ?? false) {
|
||||
$query = $this->addRecurringInvoiceStatusFilter($query, $this->input['status']);
|
||||
}
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query = $this->applyProductFilters($query);
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,12 @@ class TaskExport extends BaseExport
|
|||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
|
||||
if($this->input['status'] ?? false){
|
||||
$query = $this->addTaskStatusFilter($query, $this->input['status']);
|
||||
}
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$document_attachments = &$this->input['document_email_attachment'];
|
||||
|
||||
if ($document_attachments) {
|
||||
|
|
@ -261,6 +267,7 @@ class TaskExport extends BaseExport
|
|||
*/
|
||||
protected function addTaskStatusFilter(Builder $query, string $status): Builder
|
||||
{
|
||||
nlog(['addTaskStatusFilter', $status]);
|
||||
/** @var array $status_parameters */
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
|
|
@ -276,6 +283,16 @@ class TaskExport extends BaseExport
|
|||
$query->whereNull('invoice_id');
|
||||
}
|
||||
|
||||
$keys = $this->transformKeys($status_parameters);
|
||||
|
||||
$keys = collect($keys)->filter(function ($key){
|
||||
return is_int($key);
|
||||
})->toArray();
|
||||
|
||||
if(count($keys) > 0){
|
||||
$query->whereIn('status_id', $keys);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class VendorExport extends BaseExport
|
|||
}
|
||||
|
||||
$query = $this->addDateRange($query, 'vendors');
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
if ($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
|
|
|
|||
|
|
@ -1089,7 +1089,7 @@ class BaseController extends Controller
|
|||
$data = $this->first_load;
|
||||
}
|
||||
} else {
|
||||
$included = request()->input('include', '');
|
||||
$included = request()->input('include') ?? '';
|
||||
$included = explode(',', $included);
|
||||
|
||||
foreach ($included as $include) {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ class ReportPreviewController extends BaseController
|
|||
{
|
||||
|
||||
$report = Cache::get($hash);
|
||||
|
||||
nlog($report);
|
||||
|
||||
if (!$report) {
|
||||
return response()->json(['message' => 'Still working.....'], 409);
|
||||
|
|
|
|||
|
|
@ -70,9 +70,11 @@ class ProductSalesReportRequest extends Request
|
|||
$input['end_date'] = null;
|
||||
}
|
||||
|
||||
if (array_key_exists('client_id', $input) && strlen($input['client_id']) >= 1) {
|
||||
if (array_key_exists('client_id', $input) && strlen($input['client_id'] ?? '') > 1) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
$input['user_id'] = auth()->user()->id;
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
|
@ -89,7 +91,7 @@ class ProductSalesReportRequest extends Request
|
|||
return false;
|
||||
}
|
||||
|
||||
return $user->isAdmin() || $user->hasPermission('view_reports');
|
||||
return $user->isAdmin() || ($user->hasPermission('view_all') && $user->hasPermission('view_reports'));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ class ProfitLossRequest extends Request
|
|||
$input['date_range'] = 'all';
|
||||
}
|
||||
|
||||
$input['user_id'] = auth()->user()->id;
|
||||
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +69,7 @@ class ProfitLossRequest extends Request
|
|||
return false;
|
||||
}
|
||||
|
||||
return $user->isAdmin() || $user->hasPermission('view_reports');
|
||||
return $user->isAdmin() || ($user->hasPermission('view_all') && $user->hasPermission('view_reports'));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ class ProjectReportRequest extends Request
|
|||
$input['end_date'] = null;
|
||||
}
|
||||
|
||||
$input['user_id'] = auth()->user()->id;
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class PreviewReport implements ShouldQueue
|
|||
/**
|
||||
* Handle a job failure.
|
||||
*/
|
||||
public function failed(\Throwable $exception = null)
|
||||
public function failed(?\Throwable $exception)
|
||||
{
|
||||
if($exception) {
|
||||
nlog("EXCEPTION:: PreviewReport:: could not preview report for " . $exception->getMessage());
|
||||
|
|
|
|||
|
|
@ -37,25 +37,13 @@ class SendToAdmin implements ShouldQueue
|
|||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
protected Company $company;
|
||||
|
||||
protected array $request;
|
||||
|
||||
protected string $report_class;
|
||||
|
||||
protected string $file_name;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*/
|
||||
public function __construct(Company $company, array $request, $report_class, $file_name)
|
||||
public function __construct(protected Company $company, protected array $request, protected string $report_class, protected string $file_name)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->request = $request;
|
||||
$this->report_class = $report_class;
|
||||
$this->file_name = $file_name;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
|
|
@ -69,8 +57,7 @@ class SendToAdmin implements ShouldQueue
|
|||
$file_name = $this->file_name;
|
||||
|
||||
$size_mb = round(strlen($csv) / (1024 * 1024), 2); // Size in MB
|
||||
nlog("Report Size: MB " . $size_mb);
|
||||
|
||||
|
||||
// If the file is greater than 5MB, we need to zip it to ensure it does not break attachment size limits
|
||||
if($size_mb > 5){
|
||||
|
||||
|
|
@ -116,12 +103,7 @@ class SendToAdmin implements ShouldQueue
|
|||
|
||||
}
|
||||
|
||||
// public function middleware()
|
||||
// {
|
||||
// return [(new WithoutOverlapping("report-{$this->company->company_key}-{$this->report_class}"))->expireAfter(60)];
|
||||
// }
|
||||
|
||||
public function failed(\Throwable $exception = null)
|
||||
public function failed(?\Throwable $exception = null)
|
||||
{
|
||||
if($exception) {
|
||||
nlog("EXCEPTION:: SendToAdmin:: could not email report for" . $exception->getMessage());
|
||||
|
|
|
|||
|
|
@ -471,10 +471,10 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
}
|
||||
|
||||
return $this->isSuperUser() ||
|
||||
(stripos($this->token()->cu->permissions, $permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $all_permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $edit_all) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $edit_entity) !== false);
|
||||
(stripos($this->token()->cu->permissions ?? '', $permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions ?? '', $all_permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions ?? '', $edit_all) !== false) ||
|
||||
(stripos($this->token()->cu->permissions ?? '', $edit_entity) !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ class ARDetailReport extends BaseExport
|
|||
$query = $this->addDateRange($query, 'invoices');
|
||||
|
||||
$query = $this->filterByClients($query);
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($invoice) {
|
||||
|
|
|
|||
|
|
@ -92,10 +92,13 @@ class ARSummaryReport extends BaseExport
|
|||
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
Client::query()
|
||||
$query = Client::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0)
|
||||
->orderBy('balance', 'desc')
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query->orderBy('balance', 'desc')
|
||||
->cursor()
|
||||
->each(function ($client) {
|
||||
|
||||
|
|
|
|||
|
|
@ -88,13 +88,16 @@ class ClientBalanceReport extends BaseExport
|
|||
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
Client::query()
|
||||
$query = Client::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0)
|
||||
->orderBy('balance', 'desc')
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query->orderBy('balance', 'desc')
|
||||
->cursor()
|
||||
->each(function ($client) {
|
||||
|
||||
/** @var \App\Models\Client $client */
|
||||
$this->csv->insertOne($this->buildRow($client));
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -90,13 +90,16 @@ class ClientSalesReport extends BaseExport
|
|||
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
Client::query()
|
||||
$query = Client::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0)
|
||||
->orderBy('balance', 'desc')
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$query->orderBy('balance', 'desc')
|
||||
->cursor()
|
||||
->each(function ($client) {
|
||||
|
||||
/** @var \App\Models\Client $client */
|
||||
$this->csv->insertOne($this->buildRow($client));
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ class ProjectReport extends BaseExport
|
|||
$query = \App\Models\Project::with(['invoices','expenses','tasks'])
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$projects = &$this->input['projects'];
|
||||
|
||||
if ($projects) {
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ class TaxSummaryReport extends BaseExport
|
|||
->orderBy('balance', 'desc');
|
||||
|
||||
$query = $this->addDateRange($query, 'invoices');
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$this->csv->insertOne([ctrans('texts.tax_summary')]);
|
||||
$this->csv->insertOne([ctrans('texts.created_on'),' ',$this->translateDate(now()->format('Y-m-d'), $this->company->date_format(), $this->company->locale())]);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ class UserSalesReport extends BaseExport
|
|||
|
||||
$query = $this->filterByClients($query);
|
||||
|
||||
$query = $this->filterByUserPermissions($query);
|
||||
|
||||
$this->csv->insertOne([ctrans('texts.user_sales_report_header', ['client' => $this->client_description, 'start_date' => $this->start_date, 'end_date' => $this->end_date])]);
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue