Procesy obsługi spotkań
This commit is contained in:
parent
2cc2c42b57
commit
eb3e723258
@ -763,15 +763,15 @@ class WorkflowEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOrCreateMeeting(int $groupId, string $meetingDatetime): int {
|
public function getOrCreateMeeting(int $bniGroupId, string $meetingDatetime): int {
|
||||||
$meetingKey = $groupId . '_' . $meetingDatetime;
|
$meetingKey = $bniGroupId . '_' . $meetingDatetime;
|
||||||
$stmt = $this->pdo->prepare("SELECT id FROM meetings WHERE meeting_key = ?");
|
$stmt = $this->pdo->prepare("SELECT id FROM meetings WHERE meeting_key = ?");
|
||||||
$stmt->execute([$meetingKey]);
|
$stmt->execute([$meetingKey]);
|
||||||
$meetingId = $stmt->fetchColumn();
|
$meetingId = $stmt->fetchColumn();
|
||||||
|
|
||||||
if (!$meetingId) {
|
if (!$meetingId) {
|
||||||
$stmt = $this->pdo->prepare("INSERT INTO meetings (bni_group_id, meeting_datetime, meeting_key) VALUES (?, ?, ?)");
|
$stmt = $this->pdo->prepare("INSERT INTO meetings (bni_group_id, meeting_date, meeting_datetime, meeting_key) VALUES (?, DATE(?), ?, ?)");
|
||||||
$stmt->execute([$groupId, $meetingDatetime, $meetingKey]);
|
$stmt->execute([$bniGroupId, $meetingDatetime, $meetingDatetime, $meetingKey]);
|
||||||
$meetingId = $this->pdo->lastInsertId();
|
$meetingId = $this->pdo->lastInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,8 +793,14 @@ class WorkflowEngine {
|
|||||||
|
|
||||||
public function updateMeetingAttendance(int $meetingId, int $personId, int $bniGroupId, string $status, int $userId, ?string $guestSurvey = null): void {
|
public function updateMeetingAttendance(int $meetingId, int $personId, int $bniGroupId, string $status, int $userId, ?string $guestSurvey = null): void {
|
||||||
$sql = "INSERT INTO meeting_attendance (meeting_id, person_id, bni_group_id, attendance_status, guest_survey, updated_by) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE attendance_status = VALUES(attendance_status), guest_survey = VALUES(guest_survey), updated_by = VALUES(updated_by), bni_group_id = VALUES(bni_group_id)";
|
$sql = "INSERT INTO meeting_attendance (meeting_id, person_id, bni_group_id, attendance_status, guest_survey, updated_by) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE attendance_status = VALUES(attendance_status), guest_survey = VALUES(guest_survey), updated_by = VALUES(updated_by), bni_group_id = VALUES(bni_group_id)";
|
||||||
|
|
||||||
|
// Log query and params
|
||||||
|
$params = [$meetingId, $personId, $bniGroupId, $status, $guestSurvey, $userId];
|
||||||
|
error_log("SQL: $sql");
|
||||||
|
error_log("Params: " . json_encode($params));
|
||||||
|
|
||||||
$stmt = $this->pdo->prepare($sql);
|
$stmt = $this->pdo->prepare($sql);
|
||||||
$stmt->execute([$meetingId, $personId, $bniGroupId, $status, $guestSurvey, $userId]);
|
$stmt->execute($params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMeetingAttendanceByGroupAndDate(int $groupId, string $meetingDatetime): array {
|
public function getMeetingAttendanceByGroupAndDate(int $groupId, string $meetingDatetime): array {
|
||||||
|
|||||||
@ -1,47 +1,47 @@
|
|||||||
<?php
|
<?php
|
||||||
|
require_once 'lib/ErrorHandler.php';
|
||||||
|
register_error_handler();
|
||||||
|
|
||||||
|
require_once 'db/config.php';
|
||||||
require_once 'WorkflowEngine.php';
|
require_once 'WorkflowEngine.php';
|
||||||
|
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
$response = ['success' => false, 'message' => 'An error occurred.'];
|
|
||||||
|
|
||||||
if (!isset($_SESSION['user_id'])) {
|
if (!isset($_SESSION['user_id'])) {
|
||||||
$response['message'] = 'You must be logged in to perform this action.';
|
throw new WorkflowException('You must be logged in to perform this action.', 401);
|
||||||
echo json_encode($response);
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
$response['message'] = 'Invalid request method.';
|
throw new WorkflowException('Invalid request method.', 405);
|
||||||
echo json_encode($response);
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$personId = $_POST['person_id'] ?? null;
|
$personId = $_POST['person_id'] ?? null;
|
||||||
$groupId = $_POST['group_id'] ?? null;
|
$bniGroupId = $_POST['bni_group_id'] ?? $_POST['group_id'] ?? null;
|
||||||
$meetingDate = $_POST['meeting_date'] ?? null;
|
$meetingDate = $_POST['meeting_date'] ?? null;
|
||||||
$status = $_POST['attendance_status'] ?? null;
|
$status = $_POST['attendance_status'] ?? null;
|
||||||
$guestSurvey = $_POST['guest_survey'] ?? null;
|
$guestSurvey = $_POST['guest_survey'] ?? null;
|
||||||
$userId = $_SESSION['user_id'];
|
$userId = $_SESSION['user_id'];
|
||||||
|
|
||||||
if (!$personId || !$groupId || !$meetingDate || !$status) {
|
if (!$personId || !$bniGroupId || !$meetingDate || !$status) {
|
||||||
$response['message'] = 'Missing required parameters.';
|
$missing_params = [];
|
||||||
echo json_encode($response);
|
if (!$personId) $missing_params[] = 'person_id';
|
||||||
exit;
|
if (!$bniGroupId) $missing_params[] = 'bni_group_id';
|
||||||
|
if (!$meetingDate) $missing_params[] = 'meeting_date';
|
||||||
|
if (!$status) $missing_params[] = 'status';
|
||||||
|
throw new WorkflowException('Missing required parameters: ' . implode(', ', $missing_params), 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
$workflowEngine = new WorkflowEngine();
|
$workflowEngine = new WorkflowEngine();
|
||||||
$meetingId = $workflowEngine->getOrCreateMeeting((int)$groupId, $meetingDate);
|
|
||||||
$workflowEngine->updateMeetingAttendance($meetingId, (int)$personId, (int)$groupId, $status, (int)$userId, $guestSurvey);
|
|
||||||
|
|
||||||
$response['success'] = true;
|
$meetingId = $workflowEngine->getOrCreateMeeting((int)$bniGroupId, $meetingDate);
|
||||||
$response['message'] = 'Attendance updated successfully.';
|
$workflowEngine->updateMeetingAttendance($meetingId, (int)$personId, (int)$bniGroupId, $status, (int)$userId, $guestSurvey);
|
||||||
} catch (Exception $e) {
|
|
||||||
error_log($e->getMessage());
|
$response = [
|
||||||
$response['message'] = 'Error updating attendance: ' . $e->getMessage();
|
'success' => true,
|
||||||
}
|
'message' => 'Attendance updated successfully.'
|
||||||
|
];
|
||||||
|
|
||||||
echo json_encode($response);
|
echo json_encode($response);
|
||||||
|
|
||||||
|
|||||||
18
db/migrations/035_cleanup_meetings_table.php
Normal file
18
db/migrations/035_cleanup_meetings_table.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../../db/config.php';
|
||||||
|
|
||||||
|
$db = db();
|
||||||
|
|
||||||
|
// Step 1: Back-fill bni_group_id from group_id where bni_group_id is NULL
|
||||||
|
$db->exec("UPDATE meetings SET bni_group_id = group_id WHERE bni_group_id IS NULL");
|
||||||
|
|
||||||
|
// Step 2: Modify bni_group_id to be NOT NULL
|
||||||
|
$db->exec("ALTER TABLE meetings MODIFY COLUMN bni_group_id INT(11) NOT NULL");
|
||||||
|
|
||||||
|
// Step 3: Find and drop the foreign key constraint on group_id
|
||||||
|
$db->exec("ALTER TABLE meetings DROP FOREIGN KEY `meetings_ibfk_1`");
|
||||||
|
|
||||||
|
// Step 4: Drop the old group_id column
|
||||||
|
$db->exec("ALTER TABLE meetings DROP COLUMN group_id");
|
||||||
|
|
||||||
|
echo "Migration 035 cleanup meetings table applied successfully.";
|
||||||
40
index.php
40
index.php
@ -510,7 +510,7 @@ $status_colors = [
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input type="hidden" name="person_id" id="meetingPersonId">
|
<input type="hidden" name="person_id" id="meetingPersonId">
|
||||||
<input type="hidden" name="group_id" id="meetingGroupId">
|
<input type="hidden" name="bni_group_id" id="meetingGroupId">
|
||||||
<input type="hidden" name="meeting_date" id="meetingDate">
|
<input type="hidden" name="meeting_date" id="meetingDate">
|
||||||
<p><strong>Person:</strong> <span id="meetingPersonName"></span></p>
|
<p><strong>Person:</strong> <span id="meetingPersonName"></span></p>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@ -645,13 +645,38 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const personId = formData.get('person_id');
|
const personId = formData.get('person_id');
|
||||||
const bniGroupId = formData.get('group_id');
|
const bniGroupId = formData.get('bni_group_id');
|
||||||
|
|
||||||
fetch('_update_meeting_attendance.php', {
|
fetch('_update_meeting_attendance.php', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => {
|
||||||
|
// We need to handle the body carefully to avoid "body already consumed" errors.
|
||||||
|
// We'll get the text first, then try to parse it.
|
||||||
|
return response.text().then(text => {
|
||||||
|
// If the response wasn't OK, we always treat it as an error.
|
||||||
|
if (!response.ok) {
|
||||||
|
try {
|
||||||
|
// See if the error response is JSON
|
||||||
|
const data = JSON.parse(text);
|
||||||
|
const errorMessage = data.error || 'Unknown server error.';
|
||||||
|
const correlationId = data.correlation_id || 'N/A';
|
||||||
|
throw new Error(`Server Error: ${errorMessage} (Correlation ID: ${correlationId})`);
|
||||||
|
} catch (e) {
|
||||||
|
// If it's not JSON, throw the raw text.
|
||||||
|
throw new Error('Server error: ' + response.status + ' ' + response.statusText + '. Response: ' + text.substring(0, 200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the response was OK, parse the text as JSON.
|
||||||
|
// It might still fail if the OK response is not valid JSON.
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('Failed to parse successful response as JSON. Raw response: ' + text.substring(0, 200));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
meetingModal.hide();
|
meetingModal.hide();
|
||||||
@ -661,8 +686,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
updateDot(dot, formData.get('attendance_status'));
|
updateDot(dot, formData.get('attendance_status'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert(data.message || 'An error occurred.');
|
// Handle structured errors from a successful (e.g. 200) response
|
||||||
|
const errorMessage = data.error || 'An unknown error occurred.';
|
||||||
|
const correlationId = data.correlation_id || 'N/A';
|
||||||
|
alert(`Error: ${errorMessage}\nCorrelation ID: ${correlationId}`);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Fetch Error:', error);
|
||||||
|
alert('An error occurred while submitting the form. ' + error.message);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user