Files
api/services/nginx/app/routes/departmentDailyReportsRoute.php
T
Jeppe Bundgaard 3dca3c8a24 Add support for date range in department daily reports
- Introduced optional `date_to` parameter across relevant routes and methods for handling date ranges in department daily reports.
- Added `getDate_to` method and refactored date validation logic into `validateDateLocally` for reuse and reduced redundancy.
- Updated SQL queries in `department_daily_reports_o` to support date range queries using `BETWEEN`.
- Enhanced error handling and parameter validation for date-related inputs.
- Cleaned up comments and redundant code for improved readability.
2025-09-03 12:52:03 +02:00

662 lines
29 KiB
PHP

<?php
namespace routes;
use classes\authentication;
use Exception;
use objects\department_daily_reports_o;
use objects\departments_o;
use objects\logs_o;
use traits\route_t;
class departmentDailyReportsRoute
{
use route_t;
public function run(): void
{
$this->get('/departments/daily-reports', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('list_department_daily_reports');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Log the incident
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENT_DAILY_REPORTS', 'Successfully listed departments daily reports');
$department_daily_reports_o = new department_daily_reports_o();
// Return the list of departments
$response->success(
$department_daily_reports_o
->setSearchableFields([
// The fields that can be searched. This would otherwise make it possible to get secret information from the database, simply by searching for it and getting the result count back
'id',
'water_usage',
'notes',
'filled_by',
'created_at',
'department_id',
])
->listObjectsWithPaginationIfSet(
function ($department_report) use ($user) {
return [
'id' => (int)$department_report['id'],
'department_id' => (int)$department_report['department_id'],
'water_usage' => (int)$department_report['water_usage'],
'notes' => (string)$department_report['notes'],
'filled_by' => (int)$department_report['filled_by'],
'created_at' => (string)$department_report['created_at'],
];
},
// This makes sure that the user can only see reports from the departments they explicitly have access to
$department_daily_reports_o->forceRestrictFilters(
[
// This makes sure that the user can only see orders from the departments they explicitly have access to
'department_id' => $user->getGroup()->getDepartments(),
]
)
)
);
} else {
// Log the incident
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENT_DAILY_REPORTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'list_department_daily_reports' => 'List the department daily reports, provided the user has access to the department',
'department_access_:id' => 'Access the department'
]
);
$this->get('/departments/daily-reports/get', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('list_department_daily_reports');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the required fields are set
self::requireParameters(
[
'id',
'date',
]
);
// Validate the department_id
self::requireType(
(int)self::getParameter('id'),
self::type_int()
);
// Require the department_id to be above 0
self::requireMinValue(
(int)self::getParameter('id'),
1
);
/** Date parameter */
// Validate the date
self::validateDateLocally();
// Determine if the user has access to the department
self::requireDepartmentAccess((int)self::getParameter('id'));
// Log the incident
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENT_DAILY_REPORTS', 'Successfully listed departments daily reports');
// Return the list of departments
$department_daily_reports_o = new department_daily_reports_o();
try {
$department_daily_report_latest = $department_daily_reports_o->selectDepartmentReportByDate(
(int)self::getParameter('id'),
(string)self::getParameter('date')
);
} catch (Exception $e) {
// Create a new department daily report if it does not exist
$department_daily_report_latest = $department_daily_reports_o->add(
(int)self::getParameter('id'),
0,
0,
'',
$user->id,
(string)self::getParameter('date')
);
}
$response->success(
[
'id' => (int)$department_daily_report_latest->id,
'department_id' => (int)$department_daily_report_latest->department_id->value(),
'water_usage' => (int)$department_daily_report_latest->water_usage->value(),
'notes' => (string)$department_daily_report_latest->notes->value(),
'filled_by' => (int)$department_daily_report_latest->filled_by->value(),
'created_at' => (string)$department_daily_report_latest->created_at->value(),
]
);
} else {
// Log the incident
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENT_DAILY_REPORTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'list_department_daily_reports' => 'List the department daily reports, provided the user has access to the department',
'department_access_:id' => 'Access the department'
]
);
$this->post('/departments/daily-reports', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('create_department_daily_reports');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the required fields are set
self::requireParameters(
[
'department_id',
'water_usage',
'notes',
'date'
]
);
// Validate the department_id
self::requireType(
(int)self::getParameter('department_id'),
self::type_int()
);
// Require the department_id to be above 0
self::requireMinValue(
(int)self::getParameter('department_id'),
1
);
// Validate the water_usage
self::requireType(
(int)self::getParameter('water_usage'),
self::type_int()
);
// Require the water_usage to be at least 0
self::requireMinValue(
(int)self::getParameter('water_usage'),
0
);
// Validate the notes
self::requireType(
(string)self::getParameter('notes'),
self::type_string()
);
// Require the notes to be at least 0 characters long
self::requireMinLength(
'notes',
0
);
// Require the notes to be at most 4000 characters long
self::requireMaxLength(
'notes',
4000
);
// Validate the date
self::requireType(
(string)self::getParameter('date'),
self::type_string()
);
// Require the date to be at least 0 characters long
self::requireMinLength(
'date',
0
);
// Require the date to be at most 10 characters long
self::requireMaxLength(
'date',
10
);
// Validate the date format (YYYY-MM-DD)
self::requireDateFormat(
(string)self::getParameter('date'),
self::FORMAT_DATE()
);
// Determine if the user has access to the department
self::requireDepartmentAccess((int)self::getParameter('department_id'));
// Check if there is already a report for today
if ((new department_daily_reports_o())->hasReport((int)self::getParameter('department_id'), (string)self::getParameter('date'))) {
$response->error('There is already a report for today', 400);
}
// Log the incident
(new logs_o())->add('departments', 'global', 1, $user->id, 'CREATE_DEPARTMENT_DAILY_REPORTS', 'Successfully created department daily report');
// Return the list of departments
$response->success(
(new department_daily_reports_o())
->add(
(int)self::getParameter('department_id'),
(int)self::getParameter('water_usage'),
(int)0,
(string)self::getParameter('notes'),
$user->id
)->asArray()
);
} else {
// Log the incident
(new logs_o())->add('departments', 'global', 1, 0, 'CREATE_DEPARTMENT_DAILY_REPORTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'create_department_daily_reports' => 'Create a new department daily report',
'department_access_:id' => 'Access the department'
]
);
$this->put('/departments/daily-reports', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('update_department_daily_reports');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the required fields are set
self::requireParameters(
[
'id',
]
);
// Validate the id
self::requireType(
(int)self::getParameter('id'),
self::type_int()
);
// Require the department_id to be above 0
self::requireMinValue(
(int)self::getParameter('id'),
1
);
// Check which fields are set
if (self::isParametersSet(['water_usage'])) {
// Validate the water_usage
self::requireType(
(int)self::getParameter('water_usage'),
self::type_int()
);
// Require the water_usage to be at least 0
self::requireMinValue(
(int)self::getParameter('water_usage'),
0
);
}
if (self::isParametersSet(['notes'])) {
// Validate the notes
self::requireType(
(string)self::getParameter('notes'),
self::type_string()
);
// Require the notes to be at least 0 characters long
self::requireMinLength(
(string)self::getParameter('notes'),
0
);
// Require the notes to be at most 4000 characters long
self::requireMaxLength(
(string)self::getParameter('notes'),
4000
);
}
// Get the department from the daily report
$department_daily_report = new department_daily_reports_o();
$department_daily_report->select((int)self::getParameter('id'));
if (!$department_daily_report->exists()) {
$response->error('Department daily report not found', 404);
}
// Get the department
$department = (new departments_o())->select((int)$department_daily_report->department_id->value());
if (!$department->exists()) {
$response->error('Department not found', 404);
}
// Require the user to have access to the department
self::requireDepartmentAccess((int)$department->id);
// Check the parameters that are set
if (self::isParametersSet(['water_usage'])) {
$department_daily_report->water_usage->set((int)self::getParameter('water_usage'));
}
if (self::isParametersSet(['notes'])) {
$department_daily_report->notes->set((string)self::getParameter('notes'));
}
// Log the incident
(new logs_o())->add('departments', 'global', 1, $user->id, 'UPDATE_DEPARTMENT_DAILY_REPORTS', 'Successfully updated department daily report');
// Return the department daily report
$response->success($department_daily_report->asArray());
} else {
// Log the incident
(new logs_o())->add('departments', 'global', 1, 0, 'UPDATE_DEPARTMENT_DAILY_REPORTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'update_department_daily_reports' => 'Update a department daily report',
'department_access_:id' => 'Access the department'
]
);
$this->get('/departments/daily-reports/product-count', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('list_department_daily_reports');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the required fields are set
self::requireParameters(
[
'date',
'department_id',
'product_id',
// 'date-to' (Optional)
]
);
/** date parameter */
// Validate the date
self::requireType(
(string)self::getParameter('date'),
self::type_string()
);
// Require the date to be at least 0 characters long
self::requireMinLength(
'date',
0
);
// Require the date to be at most 10 characters long
self::requireMaxLength(
'date',
10
);
// Validate the date format (YYYY-MM-DD)
self::requireDateFormat(
(string)self::getParameter('date'),
'Y-m-d'
);
/** date-to parameter (Optional, defaults to date parameter if not set) */
$date_to = $this->getDate_to();
// Validate the department_id
self::requireType(
(int)self::getParameter('department_id'),
self::type_int()
);
// Require the department_id to be above 0
self::requireMinValue(
(int)self::getParameter('department_id'),
1
);
// Validate the product_id
self::requireType(
(int)self::getParameter('product_id'),
self::type_int()
);
// Require the product_id to be above 0
self::requireMinValue(
(int)self::getParameter('product_id'),
1
);
// Determine if the user has access to the department
self::requireDepartmentAccess((int)self::getParameter('department_id'));
// Log the incident
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENT_DAILY_REPORTS_PRODUCTS', 'Successfully listed departments daily reports products');
// Return the list of products sold on the selected date
$response->success(
[
'quantity' =>
(new department_daily_reports_o())
->getProductsSoldOnDate(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
(int)self::getParameter('product_id'),
$date_to
),
'date' => (string)self::getParameter('date'),
'date_to' => $date_to,
'department_id' => (int)self::getParameter('department_id'),
'product_id' => (int)self::getParameter('product_id'),
// This is the amount of products sold on the selected date, that this product could have been sold as a part of. (Addons)
'out_of' => (int)(new department_daily_reports_o())->getProductsSoldWithAddonApplicable(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
(int)self::getParameter('product_id'),
$date_to
)
]
);
} else {
// Log the incident
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENT_DAILY_REPORTS_PRODUCTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'list_department_daily_reports' => 'List the department daily reports, provided the user has access to the department',
'department_access_:id' => 'Access the department'
]
);
$this->get('/departments/daily-reports/transaction-count', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('list_department_daily_reports');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the required fields are set
self::requireParameters(
[
'date',
'department_id'
]
);
// Validate the date
self::validateDateLocally();
// Get the date to parameter, or return the date parameter if not set
$date_to = $this->getDate_to();
// Validate the department_id
self::requireType(
(int)self::getParameter('department_id'),
self::type_int()
);
// Require the department_id to be above 0
self::requireMinValue(
(int)self::getParameter('department_id'),
1
);
// Determine if the user has access to the department
self::requireDepartmentAccess((int)self::getParameter('department_id'));
// Log the incident
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENT_DAILY_REPORTS_PRODUCTS', 'Successfully listed departments daily reports products');
// Return the list of products sold on the selected date
$response->success(
[
'quantity' =>
(new department_daily_reports_o())
->getTransactionsOnDateCount(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
$date_to
),
'products' =>
(new department_daily_reports_o())
->getTransactionProductsOnDateCount(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
$date_to
),
'earnings' =>
(new department_daily_reports_o())
->getTransactionsOnDateEarnings(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
$date_to
),
'date' => (string)self::getParameter('date'),
'department_id' => (int)self::getParameter('department_id'),
'date_to' => $date_to,
]
);
} else {
// Log the incident
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENT_DAILY_REPORTS_PRODUCTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'list_department_daily_reports' => 'List the department daily reports, provided the user has access to the department',
'department_access_:id' => 'Access the department'
]
);
$this->get('/departments/daily-reports/bookings-count', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('list_bookings');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the required fields are set
self::requireParameters(
[
'date',
'department_id'
]
);
// Validate the date
self::requireType(
(string)self::getParameter('date'),
self::type_string()
);
// Require the date to be at least 0 characters long
self::requireMinLength(
'date',
0
);
// Require the date to be at most 10 characters long
self::requireMaxLength(
'date',
10
);
// Validate the date format (YYYY-MM-DD)
self::requireDateFormat(
(string)self::getParameter('date'),
'Y-m-d'
);
// Validate the department_id
self::requireType(
(int)self::getParameter('department_id'),
self::type_int()
);
// Require the department_id to be above 0
self::requireMinValue(
(int)self::getParameter('department_id'),
1
);
// Determine if the user has access to the department
self::requireDepartmentAccess((int)self::getParameter('department_id'));
// Log the incident
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENT_DAILY_REPORTS_PRODUCTS', 'Successfully listed departments daily reports products');
// Return the list of products sold on the selected date
$response->success(
[
'pending' =>
(new department_daily_reports_o())
->getBookingsOnDateCount(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
'pending'
),
'completed' =>
(new department_daily_reports_o())
->getBookingsOnDateCount(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
'completed'
),
'cancelled' =>
(new department_daily_reports_o())
->getBookingsOnDateCount(
(string)self::getParameter('date'),
(int)self::getParameter('department_id'),
'cancelled'
),
]
);
} else {
// Log the incident
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENT_DAILY_REPORTS_PRODUCTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'list_department_daily_reports' => 'List the department daily reports, provided the user has access to the department',
'department_access_:id' => 'Access the department'
]
);
}
/**
* Get the date_to parameter, or return the date parameter if not set
* @return string
* @throws Exception if the date is set, but invalid
* @see validateDateLocally
* @see requireType
* @see requireMinLength
* @see requireMaxLength
* @see requireDateFormat
*/
function getDate_to(): string
{
$date_to = (string)self::getParameter('date');
if (self::isParametersSet(['date_to'])) {
// Validate the date
self::validateDateLocally('date_to');
$date_to = (string)self::getParameter('date_to');
}
return $date_to;
}
/**
* Validate a date locally without using requireType and other functions that would throw an error
* This is to avoid repeating the same code multiple times
* @param string $parameterName The name of the parameter to validate
* @throws Exception if the date is invalid
* @see requireType
* @see requireMinLength
* @see requireMaxLength
* @see requireDateFormat
* @see getDate_to
*/
private function validateDateLocally(string $parameterName = 'date'): void
{
// Require the date to be at least 0 characters long
self::requireMinLength(
$parameterName,
0
);
// Require the date to be at most 10 characters long
self::requireMaxLength(
$parameterName,
10
);
// Validate the date
self::requireDateFormat(
(string)self::getParameter($parameterName),
self::FORMAT_DATE()
);
}
}