diff --git a/app/Export/CSV/ActivityExport.php b/app/Export/CSV/ActivityExport.php index bd44c60c2b..a78c90e8a3 100644 --- a/app/Export/CSV/ActivityExport.php +++ b/app/Export/CSV/ActivityExport.php @@ -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); }); diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php index 809246bb5d..634dd3902c 100644 --- a/app/Export/CSV/BaseExport.php +++ b/app/Export/CSV/BaseExport.php @@ -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); + } + + }); + } } diff --git a/app/Export/CSV/ClientExport.php b/app/Export/CSV/ClientExport.php index b553e4286a..7622fd8eeb 100644 --- a/app/Export/CSV/ClientExport.php +++ b/app/Export/CSV/ClientExport.php @@ -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); } diff --git a/app/Export/CSV/ContactExport.php b/app/Export/CSV/ContactExport.php index 0c7789e188..6ea46473b0 100644 --- a/app/Export/CSV/ContactExport.php +++ b/app/Export/CSV/ContactExport.php @@ -65,6 +65,7 @@ class ContactExport extends BaseExport }); $query = $this->addDateRange($query, 'client_contacts'); + $query = $this->filterByUserPermissions($query); return $query; diff --git a/app/Export/CSV/CreditExport.php b/app/Export/CSV/CreditExport.php index ea9c4fb418..96e4cd2333 100644 --- a/app/Export/CSV/CreditExport.php +++ b/app/Export/CSV/CreditExport.php @@ -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); } diff --git a/app/Export/CSV/DocumentExport.php b/app/Export/CSV/DocumentExport.php index 8701d0d6cf..d4ddeb53f3 100644 --- a/app/Export/CSV/DocumentExport.php +++ b/app/Export/CSV/DocumentExport.php @@ -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); } diff --git a/app/Export/CSV/ExpenseExport.php b/app/Export/CSV/ExpenseExport.php index 73ba2c0172..50ff2f6ac2 100644 --- a/app/Export/CSV/ExpenseExport.php +++ b/app/Export/CSV/ExpenseExport.php @@ -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); } diff --git a/app/Export/CSV/InvoiceExport.php b/app/Export/CSV/InvoiceExport.php index c9ffcd2b9b..595ec0a67f 100644 --- a/app/Export/CSV/InvoiceExport.php +++ b/app/Export/CSV/InvoiceExport.php @@ -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); } diff --git a/app/Export/CSV/InvoiceItemExport.php b/app/Export/CSV/InvoiceItemExport.php index 2a4f8e9e50..d870fde8ad 100644 --- a/app/Export/CSV/InvoiceItemExport.php +++ b/app/Export/CSV/InvoiceItemExport.php @@ -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) { diff --git a/app/Export/CSV/PaymentExport.php b/app/Export/CSV/PaymentExport.php index 1c6fab3aa0..8735db0b16 100644 --- a/app/Export/CSV/PaymentExport.php +++ b/app/Export/CSV/PaymentExport.php @@ -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); diff --git a/app/Export/CSV/ProductExport.php b/app/Export/CSV/ProductExport.php index 1c2f08fdb1..bac14f4f3e 100644 --- a/app/Export/CSV/ProductExport.php +++ b/app/Export/CSV/ProductExport.php @@ -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); diff --git a/app/Export/CSV/ProductSalesExport.php b/app/Export/CSV/ProductSalesExport.php index 85794732ed..3009728b0e 100644 --- a/app/Export/CSV/ProductSalesExport.php +++ b/app/Export/CSV/ProductSalesExport.php @@ -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()); diff --git a/app/Export/CSV/PurchaseOrderExport.php b/app/Export/CSV/PurchaseOrderExport.php index cf2977718f..05f735c345 100644 --- a/app/Export/CSV/PurchaseOrderExport.php +++ b/app/Export/CSV/PurchaseOrderExport.php @@ -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'] ?? ''); diff --git a/app/Export/CSV/PurchaseOrderItemExport.php b/app/Export/CSV/PurchaseOrderItemExport.php index ba3ec76181..894dcf9bb2 100644 --- a/app/Export/CSV/PurchaseOrderItemExport.php +++ b/app/Export/CSV/PurchaseOrderItemExport.php @@ -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'] ?? ''); diff --git a/app/Export/CSV/QuoteExport.php b/app/Export/CSV/QuoteExport.php index 940ae45b3a..6ee9778f35 100644 --- a/app/Export/CSV/QuoteExport.php +++ b/app/Export/CSV/QuoteExport.php @@ -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); } diff --git a/app/Export/CSV/QuoteItemExport.php b/app/Export/CSV/QuoteItemExport.php index 4cab802e74..880d02b068 100644 --- a/app/Export/CSV/QuoteItemExport.php +++ b/app/Export/CSV/QuoteItemExport.php @@ -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'] ?? ''); diff --git a/app/Export/CSV/RecurringInvoiceExport.php b/app/Export/CSV/RecurringInvoiceExport.php index 5468338c35..9bddd0c915 100644 --- a/app/Export/CSV/RecurringInvoiceExport.php +++ b/app/Export/CSV/RecurringInvoiceExport.php @@ -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'] ?? ''); diff --git a/app/Export/CSV/RecurringInvoiceItemExport.php b/app/Export/CSV/RecurringInvoiceItemExport.php index fabf441283..8498dd93ec 100644 --- a/app/Export/CSV/RecurringInvoiceItemExport.php +++ b/app/Export/CSV/RecurringInvoiceItemExport.php @@ -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); diff --git a/app/Export/CSV/TaskExport.php b/app/Export/CSV/TaskExport.php index b47ac07c48..4235bde1bb 100644 --- a/app/Export/CSV/TaskExport.php +++ b/app/Export/CSV/TaskExport.php @@ -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; } diff --git a/app/Export/CSV/VendorExport.php b/app/Export/CSV/VendorExport.php index 099ed696b3..a279d0323b 100644 --- a/app/Export/CSV/VendorExport.php +++ b/app/Export/CSV/VendorExport.php @@ -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); diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index ca6b38de7a..2e16386d3b 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -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) { diff --git a/app/Http/Controllers/Reports/ReportPreviewController.php b/app/Http/Controllers/Reports/ReportPreviewController.php index 17c495bee7..793e36554f 100644 --- a/app/Http/Controllers/Reports/ReportPreviewController.php +++ b/app/Http/Controllers/Reports/ReportPreviewController.php @@ -30,8 +30,6 @@ class ReportPreviewController extends BaseController { $report = Cache::get($hash); - - nlog($report); if (!$report) { return response()->json(['message' => 'Still working.....'], 409); diff --git a/app/Http/Requests/Report/ProductSalesReportRequest.php b/app/Http/Requests/Report/ProductSalesReportRequest.php index aaa29e0e9b..915bc5de8c 100644 --- a/app/Http/Requests/Report/ProductSalesReportRequest.php +++ b/app/Http/Requests/Report/ProductSalesReportRequest.php @@ -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')); } diff --git a/app/Http/Requests/Report/ProfitLossRequest.php b/app/Http/Requests/Report/ProfitLossRequest.php index 9a4c9ef1a6..7f26083735 100644 --- a/app/Http/Requests/Report/ProfitLossRequest.php +++ b/app/Http/Requests/Report/ProfitLossRequest.php @@ -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')); } diff --git a/app/Http/Requests/Report/ProjectReportRequest.php b/app/Http/Requests/Report/ProjectReportRequest.php index 03b44b3da5..6860427cc1 100644 --- a/app/Http/Requests/Report/ProjectReportRequest.php +++ b/app/Http/Requests/Report/ProjectReportRequest.php @@ -69,6 +69,8 @@ class ProjectReportRequest extends Request $input['end_date'] = null; } + $input['user_id'] = auth()->user()->id; + $this->replace($input); } diff --git a/app/Jobs/Report/PreviewReport.php b/app/Jobs/Report/PreviewReport.php index b515964992..7be9f9fb7e 100644 --- a/app/Jobs/Report/PreviewReport.php +++ b/app/Jobs/Report/PreviewReport.php @@ -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()); diff --git a/app/Jobs/Report/SendToAdmin.php b/app/Jobs/Report/SendToAdmin.php index 08b4ec9ce2..46087342f6 100644 --- a/app/Jobs/Report/SendToAdmin.php +++ b/app/Jobs/Report/SendToAdmin.php @@ -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()); diff --git a/app/Models/User.php b/app/Models/User.php index 9e3a7eb356..29ac538e3b 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -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); } /** diff --git a/app/Services/Report/ARDetailReport.php b/app/Services/Report/ARDetailReport.php index b6be50cac7..d6e33c4e02 100644 --- a/app/Services/Report/ARDetailReport.php +++ b/app/Services/Report/ARDetailReport.php @@ -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) { diff --git a/app/Services/Report/ARSummaryReport.php b/app/Services/Report/ARSummaryReport.php index f59a49f6f3..6e07ae1fb5 100644 --- a/app/Services/Report/ARSummaryReport.php +++ b/app/Services/Report/ARSummaryReport.php @@ -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) { diff --git a/app/Services/Report/ClientBalanceReport.php b/app/Services/Report/ClientBalanceReport.php index afb9bbee14..99f9fecda4 100644 --- a/app/Services/Report/ClientBalanceReport.php +++ b/app/Services/Report/ClientBalanceReport.php @@ -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)); }); diff --git a/app/Services/Report/ClientSalesReport.php b/app/Services/Report/ClientSalesReport.php index 46f9fa5b2c..d64cfae5d8 100644 --- a/app/Services/Report/ClientSalesReport.php +++ b/app/Services/Report/ClientSalesReport.php @@ -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)); }); diff --git a/app/Services/Report/ProjectReport.php b/app/Services/Report/ProjectReport.php index 063cd694f5..2d23512aad 100644 --- a/app/Services/Report/ProjectReport.php +++ b/app/Services/Report/ProjectReport.php @@ -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) { diff --git a/app/Services/Report/TaxSummaryReport.php b/app/Services/Report/TaxSummaryReport.php index 99c896a720..a4ec929476 100644 --- a/app/Services/Report/TaxSummaryReport.php +++ b/app/Services/Report/TaxSummaryReport.php @@ -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())]); diff --git a/app/Services/Report/UserSalesReport.php b/app/Services/Report/UserSalesReport.php index b362f34884..4ab612ca5e 100644 --- a/app/Services/Report/UserSalesReport.php +++ b/app/Services/Report/UserSalesReport.php @@ -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) {