From 0f4d06af613c8349b09294f12afee4451f0b4f8e Mon Sep 17 00:00:00 2001 From: jekkos Date: Thu, 19 Sep 2024 00:55:49 +0200 Subject: [PATCH] Blind SQL injection fix (#3284) --- app/Controllers/Attributes.php | 2 +- app/Controllers/Cashups.php | 2 +- app/Controllers/Customers.php | 2 +- app/Controllers/Employees.php | 2 +- app/Controllers/Expenses.php | 2 +- app/Controllers/Expenses_categories.php | 2 +- app/Controllers/Giftcards.php | 2 +- app/Controllers/Item_kits.php | 2 +- app/Controllers/Items.php | 2 +- app/Controllers/Sales.php | 2 +- app/Controllers/Secure_Controller.php | 5 + app/Controllers/Suppliers.php | 2 +- app/Helpers/tabular_helper.php | 226 +++++++++++++----------- 13 files changed, 135 insertions(+), 118 deletions(-) diff --git a/app/Controllers/Attributes.php b/app/Controllers/Attributes.php index 93b52d673..29c955fbb 100644 --- a/app/Controllers/Attributes.php +++ b/app/Controllers/Attributes.php @@ -41,7 +41,7 @@ class Attributes extends Secure_Controller $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(ATTRIBUTE_DEFINITION_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'definition_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $attributes = $this->attribute->search($search, $limit, $offset, $sort, $order); diff --git a/app/Controllers/Cashups.php b/app/Controllers/Cashups.php index d17a1b6e5..b7e9e2363 100644 --- a/app/Controllers/Cashups.php +++ b/app/Controllers/Cashups.php @@ -46,7 +46,7 @@ class Cashups extends Secure_Controller $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(CASHUPS_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'cashup_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $filters = [ 'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS), //TODO: Is this the best way to filter dates diff --git a/app/Controllers/Customers.php b/app/Controllers/Customers.php index 9778a605a..2bd62add1 100644 --- a/app/Controllers/Customers.php +++ b/app/Controllers/Customers.php @@ -90,7 +90,7 @@ class Customers extends Persons $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(CUSTOMER_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'person_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $customers = $this->customer->search($search, $limit, $offset, $sort, $order); diff --git a/app/Controllers/Employees.php b/app/Controllers/Employees.php index 2e9b26cf8..b3de87dd7 100644 --- a/app/Controllers/Employees.php +++ b/app/Controllers/Employees.php @@ -30,7 +30,7 @@ class Employees extends Persons $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(PERSON_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'person_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $employees = $this->employee->search($search, $limit, $offset, $sort, $order); diff --git a/app/Controllers/Expenses.php b/app/Controllers/Expenses.php index f24fe5ce5..91b364f44 100644 --- a/app/Controllers/Expenses.php +++ b/app/Controllers/Expenses.php @@ -48,7 +48,7 @@ class Expenses extends Secure_Controller $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(EXPENSE_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $filters = [ 'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS), diff --git a/app/Controllers/Expenses_categories.php b/app/Controllers/Expenses_categories.php index e12d801ef..dd7352cae 100644 --- a/app/Controllers/Expenses_categories.php +++ b/app/Controllers/Expenses_categories.php @@ -34,7 +34,7 @@ class Expenses_categories extends Secure_Controller //TODO: Is this class ever u $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(EXPENSE_CATEGORY_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_category_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $expense_categories = $this->expense_category->search($search, $limit, $offset, $sort, $order); diff --git a/app/Controllers/Giftcards.php b/app/Controllers/Giftcards.php index a1f20d9ee..d41089ebe 100644 --- a/app/Controllers/Giftcards.php +++ b/app/Controllers/Giftcards.php @@ -35,7 +35,7 @@ class Giftcards extends Secure_Controller $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(GIFTCARD_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'giftcard_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $giftcards = $this->giftcard->search($search, $limit, $offset, $sort, $order); diff --git a/app/Controllers/Item_kits.php b/app/Controllers/Item_kits.php index f64e5bd2c..3b3bef591 100644 --- a/app/Controllers/Item_kits.php +++ b/app/Controllers/Item_kits.php @@ -79,7 +79,7 @@ class Item_kits extends Secure_Controller $search = $this->request->getGet('search') ?? ''; $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(ITEM_KIT_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'item_kit_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $item_kits = $this->item_kit->search($search, $limit, $offset, $sort, $order); diff --git a/app/Controllers/Items.php b/app/Controllers/Items.php index 2fdd0fd43..6b61ae50c 100644 --- a/app/Controllers/Items.php +++ b/app/Controllers/Items.php @@ -97,7 +97,7 @@ class Items extends Secure_Controller $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(ITEM_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'item_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $this->item_lib->set_item_location($this->request->getGet('stock_location')); diff --git a/app/Controllers/Sales.php b/app/Controllers/Sales.php index 03fb37541..b87c203ea 100644 --- a/app/Controllers/Sales.php +++ b/app/Controllers/Sales.php @@ -136,7 +136,7 @@ class Sales extends Secure_Controller $search = $this->request->getGet('search', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(SALES_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'sale_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $filters = [ diff --git a/app/Controllers/Secure_Controller.php b/app/Controllers/Secure_Controller.php index cbb8bfb02..27b656330 100644 --- a/app/Controllers/Secure_Controller.php +++ b/app/Controllers/Secure_Controller.php @@ -82,6 +82,11 @@ class Secure_Controller extends BaseController view('viewData', $this->global_view_data); } + public function sanitizeSortColumn($headers, $field, $default): string + { + return $field != null && in_array($field, array_keys(array_merge(...$headers))) ? $field : $default; + } + /** * AJAX function used to confirm whether values sent in the request are numeric * @return void diff --git a/app/Controllers/Suppliers.php b/app/Controllers/Suppliers.php index 02c4c3592..caee78081 100644 --- a/app/Controllers/Suppliers.php +++ b/app/Controllers/Suppliers.php @@ -48,7 +48,7 @@ class Suppliers extends Persons $search = $this->request->getGet('search'); $limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT); $offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT); - $sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $sort = $this->sanitizeSortColumn(SUPPLIER_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'person_id'); $order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $suppliers = $this->supplier->search($search, $limit, $offset, $sort, $order); diff --git a/app/Helpers/tabular_helper.php b/app/Helpers/tabular_helper.php index 722e963e6..971a542e7 100644 --- a/app/Helpers/tabular_helper.php +++ b/app/Helpers/tabular_helper.php @@ -16,11 +16,11 @@ use Config\Services; /** * Basic tabular headers function */ -function transform_headers_readonly(array $array): string //TODO: $array needs to be refactored to a new name. Perhaps $headers? +function transform_headers_readonly(array $headers): string { $result = []; - foreach($array as $key => $value) + foreach($headers as $key => $value) { $result[] = ['field' => $key, 'title' => $value, 'sortable' => $value != '', 'switchable' => !preg_match('(^$| )', $value)]; } @@ -31,21 +31,21 @@ function transform_headers_readonly(array $array): string //TODO: $array needs t /** * Basic tabular headers function */ -function transform_headers(array $array, bool $readonly = false, bool $editable = true): string //TODO: $array needs to be refactored to a new name. Perhaps $headers? +function transform_headers(array $headers, bool $readonly = false, bool $editable = true): string //TODO: $array needs to be refactored to a new name. Perhaps $headers? { $result = []; if(!$readonly) { - $array = array_merge ([['checkbox' => 'select', 'sortable' => false]], $array); + $headers = array_merge ([['checkbox' => 'select', 'sortable' => false]], $headers); } if($editable) { - $array[] = ['edit' => '']; + $headers[] = ['edit' => '']; } - foreach($array as $element) //TODO: This might be clearer to refactor this to `foreach($headers as $header)` + foreach($headers as $element) //TODO: This might be clearer to refactor this to `foreach($headers as $header)` { reset($element); $result[] = [ @@ -63,20 +63,22 @@ function transform_headers(array $array, bool $readonly = false, bool $editable return json_encode($result); } +define("SALES_HEADERS", [ + ['sale_id' => lang('Common.id')], + ['sale_time' => lang('Sales.sale_time')], + ['customer_name' => lang('Customers.customer')], + ['amount_due' => lang('Sales.amount_due')], + ['amount_tendered' => lang('Sales.amount_tendered')], + ['change_due' => lang('Sales.change_due')], + ['payment_type' => lang('Sales.payment_type')] +]); + /** * Get the header for the sales tabular view */ function get_sales_manage_table_headers(): string { - $headers = [ - ['sale_id' => lang('Common.id')], - ['sale_time' => lang('Sales.sale_time')], - ['customer_name' => lang('Customers.customer')], - ['amount_due' => lang('Sales.amount_due')], - ['amount_tendered' => lang('Sales.amount_tendered')], - ['change_due' => lang('Sales.change_due')], - ['payment_type' => lang('Sales.payment_type')] - ]; + $headers = SALES_HEADERS; $config = config(OSPOS::class)->settings; if($config['invoice_enable']) @@ -187,18 +189,20 @@ function get_sales_manage_payments_summary(array $payments): string return $table; } +define('PERSON_HEADERS', [ + ['people.person_id' => lang('Common.id')], + ['last_name' => lang('Common.last_name')], + ['first_name' => lang('Common.first_name')], + ['email' => lang('Common.email')], + ['phone_number' => lang('Common.phone_number')] +]); + /** * Get the header for the people tabular view */ function get_people_manage_table_headers(): string { - $headers = [ - ['people.person_id' => lang('Common.id')], - ['last_name' => lang('Common.last_name')], - ['first_name' => lang('Common.first_name')], - ['email' => lang('Common.email')], - ['phone_number' => lang('Common.phone_number')] - ]; + $headers = PERSON_HEADERS; $employee = model(Employee::class); $session = session(); @@ -247,19 +251,21 @@ function get_person_data_row(object $person): array ]; } +define('CUSTOMER_HEADERS', [ + ['people.person_id' => lang('Common.id')], + ['last_name' => lang('Common.last_name')], + ['first_name' => lang('Common.first_name')], + ['email' => lang('Common.email')], + ['phone_number' => lang('Common.phone_number')], + ['total' => lang('Common.total_spent'), 'sortable' => false] +]); + /** * Get the header for the customer tabular view */ function get_customer_manage_table_headers(): string { - $headers = [ - ['people.person_id' => lang('Common.id')], - ['last_name' => lang('Common.last_name')], - ['first_name' => lang('Common.first_name')], - ['email' => lang('Common.email')], - ['phone_number' => lang('Common.phone_number')], - ['total' => lang('Common.total_spent'), 'sortable' => false] - ]; + $headers = CUSTOMER_HEADERS; $employee = model(Employee::class); $session = session(); @@ -309,21 +315,23 @@ function get_customer_data_row(object $person, object $stats): array ]; } +define('SUPPLIER_HEADERS', [ + ['people.person_id' => lang('Common.id')], + ['company_name' => lang('Suppliers.company_name')], + ['agency_name' => lang('Suppliers.agency_name')], + ['category' => lang('Suppliers.category')], + ['last_name' => lang('Common.last_name')], + ['first_name' => lang('Common.first_name')], + ['email' => lang('Common.email')], + ['phone_number' => lang('Common.phone_number')] +]); + /** * Get the header for the suppliers tabular view */ function get_suppliers_manage_table_headers(): string { - $headers = [ - ['people.person_id' => lang('Common.id')], - ['company_name' => lang('Suppliers.company_name')], - ['agency_name' => lang('Suppliers.agency_name')], - ['category' => lang('Suppliers.category')], - ['last_name' => lang('Common.last_name')], - ['first_name' => lang('Common.first_name')], - ['email' => lang('Common.email')], - ['phone_number' => lang('Common.phone_number')] - ]; + $headers = SUPPLIER_HEADERS; $employee = model(Employee::class); $session = session(); @@ -375,6 +383,17 @@ function get_supplier_data_row(object $supplier): array ]; } +define('ITEM_HEADERS', [ + ['items.item_id' => lang('Common.id')], + ['item_number' => lang('Items.item_number')], + ['name' => lang('Items.name')], + ['category' => lang('Items.category')], + ['company_name' => lang('Suppliers.company_name')], + ['cost_price' => lang('Items.cost_price')], + ['unit_price' => lang('Items.unit_price')], + ['quantity' => lang('Items.quantity')] +]); + /** * Get the header for the items tabular view */ @@ -384,16 +403,7 @@ function get_items_manage_table_headers(): string $config = config(OSPOS::class)->settings; $definition_names = $attribute->get_definitions_by_flags($attribute::SHOW_IN_ITEMS); //TODO: this should be made into a constant in constants.php - $headers = [ - ['items.item_id' => lang('Common.id')], - ['item_number' => lang('Items.item_number')], - ['name' => lang('Items.name')], - ['category' => lang('Items.category')], - ['company_name' => lang('Suppliers.company_name')], - ['cost_price' => lang('Items.cost_price')], - ['unit_price' => lang('Items.unit_price')], - ['quantity' => lang('Items.quantity')] - ]; + $headers = ITEM_HEADERS; if($config['use_destination_based_tax']) { @@ -523,20 +533,20 @@ function get_item_data_row(object $item): array return $columns + expand_attribute_values($definition_names, (array) $item) + $icons; } +define('GIFTCARD_HEADERS', [ + ['giftcard_id' => lang('Common.id')], + ['last_name' => lang('Common.last_name')], + ['first_name' => lang('Common.first_name')], + ['giftcard_number' => lang('Giftcards.giftcard_number')], + ['value' => lang('Giftcards.card_value')] +]); + /** * Get the header for the giftcard tabular view */ function get_giftcards_manage_table_headers(): string { - $headers = [ - ['giftcard_id' => lang('Common.id')], - ['last_name' => lang('Common.last_name')], - ['first_name' => lang('Common.first_name')], - ['giftcard_number' => lang('Giftcards.giftcard_number')], - ['value' => lang('Giftcards.card_value')] - ]; - - return transform_headers($headers); + return transform_headers(GIFTCARD_HEADERS); } /** @@ -564,21 +574,21 @@ function get_giftcard_data_row(object $giftcard): array ]; } +define('ITEM_KIT_HEADERS', [ + ['item_kit_id' => lang('Item_kits.kit')], + ['item_kit_number' => lang('Item_kits.item_kit_number')], + ['name' => lang('Item_kits.name')], + ['description' => lang('Item_kits.description')], + ['total_cost_price' => lang('Items.cost_price'), 'sortable' => false], + ['total_unit_price' => lang('Items.unit_price'), 'sortable' => false] +]); + /** * Get the header for the item kits tabular view */ function get_item_kits_manage_table_headers(): string { - $headers = [ - ['item_kit_id' => lang('Item_kits.kit')], - ['item_kit_number' => lang('Item_kits.item_kit_number')], - ['name' => lang('Item_kits.name')], - ['description' => lang('Item_kits.description')], - ['total_cost_price' => lang('Items.cost_price'), 'sortable' => false], - ['total_unit_price' => lang('Items.unit_price'), 'sortable' => false] - ]; - - return transform_headers($headers); + return transform_headers(ITEM_KIT_HEADERS); } /** @@ -662,20 +672,20 @@ function expand_attribute_values(array $definition_names, array $row): array return $attribute_values; } +define('ATTRIBUTE_DEFINITION_HEADERS', [ + ['definition_id' => lang('Attributes.definition_id')], + ['definition_name' => lang('Attributes.definition_name')], + ['definition_type' => lang('Attributes.definition_type')], + ['definition_flags' => lang('Attributes.definition_flags')], + ['definition_group' => lang('Attributes.definition_group')], +]); + /** * @return string */ function get_attribute_definition_manage_table_headers(): string { - $headers = [ - ['definition_id' => lang('Attributes.definition_id')], - ['definition_name' => lang('Attributes.definition_name')], - ['definition_type' => lang('Attributes.definition_type')], - ['definition_flags' => lang('Attributes.definition_flags')], - ['definition_group' => lang('Attributes.definition_group')], - ]; - - return transform_headers($headers); + return transform_headers(ATTRIBUTE_DEFINITION_HEADERS); } /** @@ -719,18 +729,18 @@ function get_attribute_definition_data_row(object $attribute_row): array ]; } +define('EXPENSE_CATEGORY_HEADERS', [ + ['expense_category_id' => lang('Expenses_categories.category_id')], + ['category_name' => lang('Expenses_categories.name')], + ['category_description' => lang('Expenses_categories.description')] +]); + /** * Get the header for the expense categories tabular view */ function get_expense_category_manage_table_headers(): string { - $headers = [ - ['expense_category_id' => lang('Expenses_categories.category_id')], - ['category_name' => lang('Expenses_categories.name')], - ['category_description' => lang('Expenses_categories.description')] - ]; - - return transform_headers($headers); + return transform_headers(EXPENSE_CATEGORY_HEADERS); } /** @@ -756,26 +766,25 @@ function get_expense_category_data_row(object $expense_category): array ]; } +define('EXPENSE_HEADERS', [ + ['expense_id' => lang('Expenses.expense_id')], + ['date' => lang('Expenses.date')], + ['supplier_name' => lang('Expenses.supplier_name')], + ['supplier_tax_code' => lang('Expenses.supplier_tax_code')], + ['amount' => lang('Expenses.amount')], + ['tax_amount' => lang('Expenses.tax_amount')], + ['payment_type' => lang('Expenses.payment')], + ['category_name' => lang('Expenses_categories.name')], + ['description' => lang('Expenses.description')], + ['created_by' => lang('Expenses.employee')] +]); /** * Get the header for the expenses tabular view */ function get_expenses_manage_table_headers(): string { - $headers = [ - ['expense_id' => lang('Expenses.expense_id')], - ['date' => lang('Expenses.date')], - ['supplier_name' => lang('Expenses.supplier_name')], - ['supplier_tax_code' => lang('Expenses.supplier_tax_code')], - ['amount' => lang('Expenses.amount')], - ['tax_amount' => lang('Expenses.tax_amount')], - ['payment_type' => lang('Expenses.payment')], - ['category_name' => lang('Expenses_categories.name')], - ['description' => lang('Expenses.description')], - ['created_by' => lang('Expenses.employee')] - ]; - - return transform_headers($headers); + return transform_headers(EXPENSE_HEADERS); } /** @@ -849,13 +858,7 @@ function get_expenses_manage_payments_summary(array $payments, ResultInterface $ return $table; } - -/** - * Get the header for the cashup tabular view - */ -function get_cashups_manage_table_headers(): string -{ - $headers = [ +define('CASHUPS_HEADERS', [ ['cashup_id' => lang('Cashups.id')], ['open_date' => lang('Cashups.opened_date')], ['open_employee_id' => lang('Cashups.open_employee')], @@ -869,7 +872,16 @@ function get_cashups_manage_table_headers(): string ['closed_amount_card' => lang('Cashups.closed_amount_card')], ['closed_amount_check' => lang('Cashups.closed_amount_check')], ['closed_amount_total' => lang('Cashups.closed_amount_total')] - ]; + ] +); + + +/** + * Get the header for the cashup tabular view + */ +function get_cashups_manage_table_headers(): string +{ + $headers = CASHUPS_HEADERS; return transform_headers($headers); }