diff --git a/admin.php b/admin.php index 0f07c06..5041a67 100644 --- a/admin.php +++ b/admin.php @@ -544,7 +544,7 @@ require_once __DIR__ . '/includes/header.php'; Systeembeheer & Integraties
- Beheer hier de centrale organisatiekoppelingen zoals Microsoft 365 Azure App Registratie en Jira, inspecteer de teamstatus en configureer toekomstige modules. + Centrale organisatiekoppelingen (Microsoft 365 & Jira), beveiligingsinstellingen en teamstatus.
diff --git a/api/board.php b/api/board.php index f8b0581..e9b4879 100644 --- a/api/board.php +++ b/api/board.php @@ -391,7 +391,7 @@ try { $resCreate = microsoft_create_event($assigneeId, $eventPayload); if (!empty($resCreate['success'])) { - $outlookEventId = $resCreate['id'] ?? null; + $outlookEventId = $resCreate['event_id'] ?? ($resCreate['id'] ?? null); $outlookSyncedAt = date('Y-m-d H:i:s'); $outlookSyncMsg = 'Taak succesvol ingepland in de Outlook agenda van de collega!'; } else { diff --git a/api/integrations.php b/api/integrations.php index de216b8..2592571 100644 --- a/api/integrations.php +++ b/api/integrations.php @@ -112,10 +112,50 @@ try { $planId = (int)$db->lastInsertId(); } + // Bereken eindtijd indien starttijd bekend is + if (!empty($timeBlockStart) && empty($timeBlockEnd)) { + try { + $dtEnd = new DateTime("{$planDate} {$timeBlockStart}:00", new DateTimeZone('Europe/Amsterdam')); + $dtEnd->modify("+{$durationMinutes} minutes"); + $timeBlockEnd = $dtEnd->format('H:i'); + } catch (Throwable $e) {} + } + + $source = 'JIRA'; + $externalId = $key; + $externalUrl = $url; + $outlookSyncMsg = null; + + // Automatisch synchroniseren naar Microsoft Outlook indien gekoppeld + if (function_exists('microsoft_create_event')) { + try { + $syncStartTime = !empty($timeBlockStart) ? $timeBlockStart : '09:00'; + $msResult = microsoft_create_event($user['id'], [ + 'subject' => $title, + 'description' => "Jira ticket {$key} gepland via Fociz ({$priority})\n\n{$url}", + 'date' => $planDate, + 'start_time' => $syncStartTime, + 'end_time' => $timeBlockEnd, + 'duration_minutes' => $durationMinutes, + ]); + + if (!empty($msResult['success']) && !empty($msResult['event_id'])) { + $source = 'OUTLOOK'; + $externalId = $msResult['event_id']; + $externalUrl = $msResult['web_link'] ?? ($url ?: 'https://outlook.office.com'); + $timeBlockStart = $msResult['start_time'] ?? $syncStartTime; + $timeBlockEnd = $msResult['end_time'] ?? $timeBlockEnd; + $outlookSyncMsg = 'Gesynchroniseerd naar Microsoft Outlook.'; + } + } catch (Throwable $t) { + error_log("Fout bij auto-sync Jira naar Outlook: " . $t->getMessage()); + } + } + // Voeg taak toe $stmt = $db->prepare(" INSERT INTO tasks (user_id, daily_plan_id, title, priority, time_block_start, time_block_end, duration_minutes, status, source, external_id, external_url) - VALUES (?, ?, ?, ?, ?, ?, ?, 'TODO', 'JIRA', ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, 'TODO', ?, ?, ?) "); $stmt->execute([ $user['id'], @@ -125,15 +165,17 @@ try { $timeBlockStart, $timeBlockEnd, $durationMinutes, - $key, - $url + $source, + $externalId, + $externalUrl ]); $taskId = (int)$db->lastInsertId(); echo json_encode([ 'success' => true, 'task_id' => $taskId, - 'message' => "Ticket {$key} is succesvol ingepland voor " . date('d-m-Y', strtotime($planDate)) . "!", + 'outlook_synced' => ($source === 'OUTLOOK'), + 'message' => "Ticket {$key} is succesvol ingepland voor " . date('d-m-Y', strtotime($planDate)) . "!" . ($outlookSyncMsg ? " ({$outlookSyncMsg})" : ""), ]); exit; } diff --git a/api/mail.php b/api/mail.php index ada9fc6..c116478 100644 --- a/api/mail.php +++ b/api/mail.php @@ -164,9 +164,40 @@ try { } } + $source = 'OUTLOOK_MAIL'; + $externalId = $messageId; + $externalUrl = $webLink; + $outlookSyncMsg = null; + + // Automatisch synchroniseren naar Microsoft Outlook agenda + if (function_exists('microsoft_create_event')) { + try { + $syncStartTime = !empty($timeBlockStart) ? $timeBlockStart : '09:00'; + $msResult = microsoft_create_event($userId, [ + 'subject' => $taskTitle, + 'description' => "E-mail actiepunt gepland via Fociz ({$priority})\n\nAfzender: {$sender}\nWeblink: {$webLink}", + 'date' => $planDate, + 'start_time' => $syncStartTime, + 'end_time' => $timeBlockEnd, + 'duration_minutes' => $durationMinutes, + ]); + + if (!empty($msResult['success']) && !empty($msResult['event_id'])) { + $source = 'OUTLOOK'; + $externalId = $msResult['event_id']; + $externalUrl = $msResult['web_link'] ?? ($webLink ?: 'https://outlook.office.com'); + $timeBlockStart = $msResult['start_time'] ?? $syncStartTime; + $timeBlockEnd = $msResult['end_time'] ?? $timeBlockEnd; + $outlookSyncMsg = 'Gesynchroniseerd naar Microsoft Outlook.'; + } + } catch (Throwable $t) { + error_log("Fout bij auto-sync Mail naar Outlook: " . $t->getMessage()); + } + } + $stmtTask = $db->prepare(" INSERT INTO tasks (user_id, daily_plan_id, title, priority, time_block_start, time_block_end, duration_minutes, source, external_id, external_url) - VALUES (?, ?, ?, ?, ?, ?, ?, 'OUTLOOK_MAIL', ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "); $stmtTask->execute([ $userId, @@ -176,16 +207,18 @@ try { $timeBlockStart, $timeBlockEnd, $durationMinutes, - $messageId, - $webLink + $source, + $externalId, + $externalUrl ]); $taskId = (int)$db->lastInsertId(); echo json_encode([ - 'success' => true, - 'task_id' => $taskId, - 'plan_date' => $planDate, - 'message' => "E-mail succesvol ingepland voor {$planDate}." + 'success' => true, + 'task_id' => $taskId, + 'plan_date' => $planDate, + 'outlook_synced' => ($source === 'OUTLOOK'), + 'message' => "E-mail succesvol ingepland voor {$planDate}." . ($outlookSyncMsg ? " ({$outlookSyncMsg})" : "") ]); exit; } diff --git a/api/planner.php b/api/planner.php index d5988fe..8fe2ee4 100644 --- a/api/planner.php +++ b/api/planner.php @@ -139,18 +139,28 @@ try { $externalUrl = !empty($data['external_url']) ? trim($data['external_url']) : null; $outlookSyncError = null; - // Als synchronisatie naar Outlook gewenst is (of source is OUTLOOK) en nog geen extern ID heeft - if (($syncOutlook || $source === 'OUTLOOK') && empty($externalId)) { - // Als er geen starttijd is ingevuld maar wel sync gewenst is, gebruik 09:00 als veilige standaard - if (empty($timeBlockStart)) { - $timeBlockStart = '09:00'; + // Controleer of de gebruiker Outlook 365 heeft gekoppeld + $userHasOutlook = false; + if (function_exists('microsoft_create_event')) { + $stmtChk = $db->prepare("SELECT id FROM integrations WHERE user_id = ? AND provider = 'OUTLOOK' AND is_enabled = 1 AND access_token IS NOT NULL LIMIT 1"); + $stmtChk->execute([$user['id']]); + $userHasOutlook = (bool)$stmtChk->fetchColumn(); + } + + // Automatisch synchroniseren naar Outlook indien gevraagd OF indien gebruiker Outlook heeft gekoppeld + if (($syncOutlook || $source === 'OUTLOOK' || $userHasOutlook) && empty($externalId)) { + $syncStartTime = !empty($timeBlockStart) ? $timeBlockStart : '09:00'; + + $itemDesc = !empty($data['description']) ? trim((string)$data['description']) : "Gepland via Fociz Dagplanning ({$priority})"; + if ($source === 'JIRA' && !empty($data['external_url'])) { + $itemDesc .= "\n\nJira: " . $data['external_url']; } $msResult = microsoft_create_event($user['id'], [ 'subject' => $title, - 'description' => "Gepland via Fociz Dagplanning ({$priority})", + 'description' => $itemDesc, 'date' => $date, - 'start_time' => $timeBlockStart, + 'start_time' => $syncStartTime, 'end_time' => $timeBlockEnd, 'duration_minutes' => $durationMinutes, ]); @@ -158,8 +168,8 @@ try { if (!empty($msResult['success']) && !empty($msResult['event_id'])) { $source = 'OUTLOOK'; $externalId = $msResult['event_id']; - $externalUrl = $msResult['web_link'] ?? 'https://outlook.office.com'; - $timeBlockStart = $msResult['start_time'] ?? $timeBlockStart; + $externalUrl = $msResult['web_link'] ?? ($externalUrl ?: 'https://outlook.office.com'); + $timeBlockStart = $msResult['start_time'] ?? $syncStartTime; $timeBlockEnd = $msResult['end_time'] ?? $timeBlockEnd; } else { $outlookSyncError = $msResult['error'] ?? 'Kon afspraak niet aanmaken in Microsoft Outlook'; @@ -257,10 +267,22 @@ try { $planDate = $stmtPlan->fetchColumn() ?: date('Y-m-d'); } + // Controleer of de gebruiker Outlook 365 heeft gekoppeld + $userHasOutlook = false; + if (function_exists('microsoft_create_event')) { + $stmtChk = $db->prepare("SELECT id FROM integrations WHERE user_id = ? AND provider = 'OUTLOOK' AND is_enabled = 1 AND access_token IS NOT NULL LIMIT 1"); + $stmtChk->execute([$user['id']]); + $userHasOutlook = (bool)$stmtChk->fetchColumn(); + } + + $source = $existingTask['source'] ?? 'FOCIZ'; + $externalId = $existingTask['external_id'] ?? null; + $externalUrl = $existingTask['external_url'] ?? null; + // Indien gekoppeld aan Outlook, werk afspraak bij via Graph API - if (!empty($existingTask['external_id']) && $existingTask['source'] === 'OUTLOOK') { + if (!empty($externalId) && $source === 'OUTLOOK') { try { - microsoft_update_event($user['id'], $existingTask['external_id'], [ + microsoft_update_event($user['id'], $externalId, [ 'subject' => $title, 'date' => $planDate, 'start_time' => $timeBlockStart ?: '09:00', @@ -269,6 +291,32 @@ try { } catch (Throwable $t) { error_log("Fout bij bijwerken Outlook event: " . $t->getMessage()); } + } elseif ($userHasOutlook && empty($externalId) && function_exists('microsoft_create_event')) { + // Nog niet in Outlook gesynchroniseerd, maar gebruiker heeft Outlook: maak afspraak aan + try { + $syncStartTime = !empty($timeBlockStart) ? $timeBlockStart : '09:00'; + $itemDesc = !empty($existingTask['description']) ? trim((string)$existingTask['description']) : "Gepland via Fociz Dagplanning ({$priority})"; + if ($source === 'JIRA' && !empty($externalUrl)) { + $itemDesc .= "\n\nJira: " . $externalUrl; + } + + $msResult = microsoft_create_event($user['id'], [ + 'subject' => $title, + 'description' => $itemDesc, + 'date' => $planDate, + 'start_time' => $syncStartTime, + 'end_time' => $timeBlockEnd, + 'duration_minutes' => $durationMinutes, + ]); + + if (!empty($msResult['success']) && !empty($msResult['event_id'])) { + $source = 'OUTLOOK'; + $externalId = $msResult['event_id']; + $externalUrl = $msResult['web_link'] ?? ($externalUrl ?: 'https://outlook.office.com'); + } + } catch (Throwable $t) { + error_log("Fout bij auto-create Outlook event in update_task: " . $t->getMessage()); + } } $description = isset($data['description']) ? trim((string)$data['description']) : ($existingTask['description'] ?? null); @@ -276,17 +324,17 @@ try { if ($newPlanId) { $stmtUpdate = $db->prepare(" UPDATE tasks - SET title = ?, description = ?, priority = ?, time_block_start = ?, time_block_end = ?, duration_minutes = ?, daily_plan_id = ? + SET title = ?, description = ?, priority = ?, time_block_start = ?, time_block_end = ?, duration_minutes = ?, source = ?, external_id = ?, external_url = ?, daily_plan_id = ? WHERE id = ? AND user_id = ? "); - $stmtUpdate->execute([$title, $description, $priority, $timeBlockStart, $timeBlockEnd, $durationMinutes, $newPlanId, $taskId, $user['id']]); + $stmtUpdate->execute([$title, $description, $priority, $timeBlockStart, $timeBlockEnd, $durationMinutes, $source, $externalId, $externalUrl, $newPlanId, $taskId, $user['id']]); } else { $stmtUpdate = $db->prepare(" UPDATE tasks - SET title = ?, description = ?, priority = ?, time_block_start = ?, time_block_end = ?, duration_minutes = ? + SET title = ?, description = ?, priority = ?, time_block_start = ?, time_block_end = ?, duration_minutes = ?, source = ?, external_id = ?, external_url = ? WHERE id = ? AND user_id = ? "); - $stmtUpdate->execute([$title, $description, $priority, $timeBlockStart, $timeBlockEnd, $durationMinutes, $taskId, $user['id']]); + $stmtUpdate->execute([$title, $description, $priority, $timeBlockStart, $timeBlockEnd, $durationMinutes, $source, $externalId, $externalUrl, $taskId, $user['id']]); } echo json_encode([ diff --git a/board.php b/board.php index 33787fa..e39578e 100644 --- a/board.php +++ b/board.php @@ -101,9 +101,7 @@ $isAdmin = ($userRole === 'ADMIN'); Beheerder -- Teamtaken, opdrachten & Outlook agendablokkering -
+ @@ -134,10 +132,10 @@ $isAdmin = ($userRole === 'ADMIN');- Beheer tickets toegewezen aan jou en je projectteams. Plan ze direct in je dagplanning of zet ze op een Kanban bord. -
diff --git a/planner.php b/planner.php index 9ac107d..695e052 100644 --- a/planner.php +++ b/planner.php @@ -527,50 +527,29 @@ for ($h = $startHour; $h <= $endHour; $h++) {- Jouw centrale werkstation • Taken, Agenda, Mail & Jira -
- -