Enhance department report handling with date support

Added date parameter support for department daily reports, including validation, new functions, and route updates. Improved functionality allows fetching or creating reports for specific dates and prevents duplicate entries for the same date. Introduced a standardized date format within the API.
This commit is contained in:
Jepp9350
2025-03-06 14:37:32 +01:00
parent 9e7984b93a
commit 2038547d1c
3 changed files with 120 additions and 8 deletions
@@ -298,19 +298,23 @@ class department_daily_reports_o extends db
/**
* Check if a department daily report exists for today
* @param int $department_id The id of the department
* @param string $date The date to check for (YYYY-MM-DD)
* @return bool True if the report exists, false otherwise
*/
public function doesDepartmentDailyReportExist(int $department_id): bool
public function doesDepartmentDailyReportExist(int $department_id, string $date = 'today'): bool
{
global $db;
if ($date === 'today') {
$date = date('Y-m-d');
}
$conn = $db->conn();
$stmt = $conn->prepare(
'SELECT COUNT(*) as amount FROM department_daily_reports o
WHERE o.department_id = ? AND DATE(o.created_at) = CURDATE()'
WHERE o.department_id = ? AND DATE(o.created_at) = ?'
);
if ($stmt) {
$stmt->bind_param('i', $department_id); // Bind parameters (i = integer, s = string)
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
$stmt->execute();
$result = $stmt->get_result(); // Get the result set from the statement
$data = $result->fetch_assoc(); // Fetch the result as an associative array
@@ -393,4 +397,60 @@ class department_daily_reports_o extends db
}
return (int)$amount;
}
/**
* Check if a department daily report exists for today
* @param int $department_id The id of the department
* @return bool True if the report exists, false otherwise
*/
public function hasReportForToday(int $department_id): bool
{
return $this->doesDepartmentDailyReportExist($department_id);
}
/**
* Select the department daily report for a given date
* @param int $department_id The id of the department
* @param string $date The date to get the report for (YYYY-MM-DD)
* @return department_daily_reports_o The department daily report
* @throws Exception If a department daily report does not exist for today
* @throws Exception If the object was not selected
*/
public function selectDepartmentReportByDate(int $department_id, string $date): department_daily_reports_o
{
global $db;
if (!$this->doesDepartmentDailyReportExist($department_id, $date)) {
throw new Exception('Department daily report does not exist');
}
$conn = $db->conn();
$stmt = $conn->prepare(
'SELECT id FROM department_daily_reports o
WHERE o.department_id = ? AND DATE(o.created_at) = ?'
);
// Check if the statement was prepared successfully
if ($stmt) {
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
$stmt->execute();
$result = $stmt->get_result(); // Get the result set from the statement
$data = $result->fetch_assoc(); // Fetch the result as an associative array
// Access the "amount" field
if (!$data) {
throw new Exception('Department daily report does not exist');
}
$id = $data['id'];
$stmt->close(); // Close the statement
} else {
// Handle query preparation error
die('Query preparation failed: ' . $conn->error);
}
$this->select($id);
return $this;
}
public function hasReport(int $department_id, string $date): bool
{
return $this->doesDepartmentDailyReportExist($department_id, $date);
}
}
@@ -31,9 +31,11 @@ class departmentDailyReportsRoute
// 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',
'water_usage_morning',
'notes',
'filled_by',
'created_at'
'created_at',
'department_id',
])
->listObjectsWithPaginationIfSet(
function ($department_report) use ($user) {
@@ -41,6 +43,7 @@ class departmentDailyReportsRoute
'id' => (int)$department_report['id'],
'department_id' => (int)$department_report['department_id'],
'water_usage' => (int)$department_report['water_usage'],
'water_usage_morning' => (int)$department_report['water_usage_morning'],
'notes' => (string)$department_report['notes'],
'filled_by' => (int)$department_report['filled_by'],
'created_at' => (string)$department_report['created_at'],
@@ -68,7 +71,7 @@ class departmentDailyReportsRoute
]
);
$this->get('/departments/daily-reports/latest', function () {
$this->get('/departments/daily-reports/get', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('list_department_daily_reports');
@@ -79,7 +82,8 @@ class departmentDailyReportsRoute
// Check if the required fields are set
self::requireParameters(
[
'id'
'id',
'date'
]
);
// Validate the department_id
@@ -92,6 +96,16 @@ class departmentDailyReportsRoute
(int)self::getParameter('id'),
1
);
// Require the date to be at least 0 characters long
self::requireMinLength(
'date',
0
);
// Validate the date
self::requireDateFormat(
(string)self::getParameter('date'),
self::FORMAT_DATE()
);
// Determine if the user has access to the department
self::requireDepartmentAccess((int)self::getParameter('id'));
// Log the incident
@@ -99,7 +113,10 @@ class departmentDailyReportsRoute
// Return the list of departments
$department_daily_reports_o = new department_daily_reports_o();
try {
$department_daily_report_latest = $department_daily_reports_o->selectLastDepartmentDailyReport((int)self::getParameter('id'));
$department_daily_report_latest = $department_daily_reports_o->selectDepartmentReportByDate(
(int)self::getParameter('id'),
(string)self::getParameter('date')
);
} catch (\Exception $e) {
$response->error('No department daily report found', 404);
}
@@ -141,7 +158,8 @@ class departmentDailyReportsRoute
'department_id',
'water_usage',
'water_usage_morning',
'notes'
'notes',
'date'
]
);
// Validate the department_id
@@ -189,8 +207,32 @@ class departmentDailyReportsRoute
'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
+10
View File
@@ -39,6 +39,16 @@ trait route_t
return true;
}
/**
* The default date format (Y-m-d) Example: 2023-01-01
* @note This is used to format dates in the API
* @return string
*/
public function FORMAT_DATE(): string
{
return 'Y-m-d';
}
public function requireDateFormat(string $date, string $format): void
{
global $response;