211 lines
6.5 KiB
PHP
211 lines
6.5 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* RecurringTicketModel - Manages recurring ticket schedules
|
||
|
|
*/
|
||
|
|
|
||
|
|
class RecurringTicketModel {
|
||
|
|
private $conn;
|
||
|
|
|
||
|
|
public function __construct($conn) {
|
||
|
|
$this->conn = $conn;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all recurring tickets
|
||
|
|
*/
|
||
|
|
public function getAll($includeInactive = false) {
|
||
|
|
$sql = "SELECT rt.*, u1.display_name as assigned_name, u1.username as assigned_username,
|
||
|
|
u2.display_name as creator_name, u2.username as creator_username
|
||
|
|
FROM recurring_tickets rt
|
||
|
|
LEFT JOIN users u1 ON rt.assigned_to = u1.user_id
|
||
|
|
LEFT JOIN users u2 ON rt.created_by = u2.user_id";
|
||
|
|
|
||
|
|
if (!$includeInactive) {
|
||
|
|
$sql .= " WHERE rt.is_active = 1";
|
||
|
|
}
|
||
|
|
|
||
|
|
$sql .= " ORDER BY rt.next_run_at ASC";
|
||
|
|
|
||
|
|
$result = $this->conn->query($sql);
|
||
|
|
$items = [];
|
||
|
|
while ($row = $result->fetch_assoc()) {
|
||
|
|
$items[] = $row;
|
||
|
|
}
|
||
|
|
return $items;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get a single recurring ticket by ID
|
||
|
|
*/
|
||
|
|
public function getById($recurringId) {
|
||
|
|
$sql = "SELECT * FROM recurring_tickets WHERE recurring_id = ?";
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param('i', $recurringId);
|
||
|
|
$stmt->execute();
|
||
|
|
$result = $stmt->get_result();
|
||
|
|
$row = $result->fetch_assoc();
|
||
|
|
$stmt->close();
|
||
|
|
return $row;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new recurring ticket
|
||
|
|
*/
|
||
|
|
public function create($data) {
|
||
|
|
$sql = "INSERT INTO recurring_tickets
|
||
|
|
(title_template, description_template, category, type, priority, assigned_to,
|
||
|
|
schedule_type, schedule_day, schedule_time, next_run_at, is_active, created_by)
|
||
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||
|
|
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param('ssssiiisssis',
|
||
|
|
$data['title_template'],
|
||
|
|
$data['description_template'],
|
||
|
|
$data['category'],
|
||
|
|
$data['type'],
|
||
|
|
$data['priority'],
|
||
|
|
$data['assigned_to'],
|
||
|
|
$data['schedule_type'],
|
||
|
|
$data['schedule_day'],
|
||
|
|
$data['schedule_time'],
|
||
|
|
$data['next_run_at'],
|
||
|
|
$data['is_active'],
|
||
|
|
$data['created_by']
|
||
|
|
);
|
||
|
|
|
||
|
|
if ($stmt->execute()) {
|
||
|
|
$id = $this->conn->insert_id;
|
||
|
|
$stmt->close();
|
||
|
|
return ['success' => true, 'recurring_id' => $id];
|
||
|
|
}
|
||
|
|
|
||
|
|
$error = $stmt->error;
|
||
|
|
$stmt->close();
|
||
|
|
return ['success' => false, 'error' => $error];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Update a recurring ticket
|
||
|
|
*/
|
||
|
|
public function update($recurringId, $data) {
|
||
|
|
$sql = "UPDATE recurring_tickets SET
|
||
|
|
title_template = ?, description_template = ?, category = ?, type = ?,
|
||
|
|
priority = ?, assigned_to = ?, schedule_type = ?, schedule_day = ?,
|
||
|
|
schedule_time = ?, next_run_at = ?, is_active = ?
|
||
|
|
WHERE recurring_id = ?";
|
||
|
|
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param('ssssiissssii',
|
||
|
|
$data['title_template'],
|
||
|
|
$data['description_template'],
|
||
|
|
$data['category'],
|
||
|
|
$data['type'],
|
||
|
|
$data['priority'],
|
||
|
|
$data['assigned_to'],
|
||
|
|
$data['schedule_type'],
|
||
|
|
$data['schedule_day'],
|
||
|
|
$data['schedule_time'],
|
||
|
|
$data['next_run_at'],
|
||
|
|
$data['is_active'],
|
||
|
|
$recurringId
|
||
|
|
);
|
||
|
|
|
||
|
|
$success = $stmt->execute();
|
||
|
|
$stmt->close();
|
||
|
|
return ['success' => $success];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Delete a recurring ticket
|
||
|
|
*/
|
||
|
|
public function delete($recurringId) {
|
||
|
|
$sql = "DELETE FROM recurring_tickets WHERE recurring_id = ?";
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param('i', $recurringId);
|
||
|
|
$success = $stmt->execute();
|
||
|
|
$stmt->close();
|
||
|
|
return ['success' => $success];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get recurring tickets due for execution
|
||
|
|
*/
|
||
|
|
public function getDueRecurringTickets() {
|
||
|
|
$sql = "SELECT * FROM recurring_tickets WHERE is_active = 1 AND next_run_at <= NOW()";
|
||
|
|
$result = $this->conn->query($sql);
|
||
|
|
$items = [];
|
||
|
|
while ($row = $result->fetch_assoc()) {
|
||
|
|
$items[] = $row;
|
||
|
|
}
|
||
|
|
return $items;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Update last run and calculate next run time
|
||
|
|
*/
|
||
|
|
public function updateAfterRun($recurringId) {
|
||
|
|
$recurring = $this->getById($recurringId);
|
||
|
|
if (!$recurring) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$nextRun = $this->calculateNextRunTime(
|
||
|
|
$recurring['schedule_type'],
|
||
|
|
$recurring['schedule_day'],
|
||
|
|
$recurring['schedule_time']
|
||
|
|
);
|
||
|
|
|
||
|
|
$sql = "UPDATE recurring_tickets SET last_run_at = NOW(), next_run_at = ? WHERE recurring_id = ?";
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param('si', $nextRun, $recurringId);
|
||
|
|
$success = $stmt->execute();
|
||
|
|
$stmt->close();
|
||
|
|
return $success;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Calculate the next run time based on schedule
|
||
|
|
*/
|
||
|
|
private function calculateNextRunTime($scheduleType, $scheduleDay, $scheduleTime) {
|
||
|
|
$now = new DateTime();
|
||
|
|
$time = new DateTime($scheduleTime);
|
||
|
|
|
||
|
|
switch ($scheduleType) {
|
||
|
|
case 'daily':
|
||
|
|
$next = new DateTime('tomorrow ' . $scheduleTime);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'weekly':
|
||
|
|
$dayName = ['', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'][$scheduleDay] ?? 'Monday';
|
||
|
|
$next = new DateTime("next {$dayName} " . $scheduleTime);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'monthly':
|
||
|
|
$day = max(1, min(28, $scheduleDay)); // Limit to 28 for safety
|
||
|
|
$next = new DateTime();
|
||
|
|
$next->modify('first day of next month');
|
||
|
|
$next->setDate($next->format('Y'), $next->format('m'), $day);
|
||
|
|
$next->setTime($time->format('H'), $time->format('i'), 0);
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
$next = new DateTime('tomorrow ' . $scheduleTime);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $next->format('Y-m-d H:i:s');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Toggle active status
|
||
|
|
*/
|
||
|
|
public function toggleActive($recurringId) {
|
||
|
|
$sql = "UPDATE recurring_tickets SET is_active = NOT is_active WHERE recurring_id = ?";
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param('i', $recurringId);
|
||
|
|
$success = $stmt->execute();
|
||
|
|
$stmt->close();
|
||
|
|
return ['success' => $success];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
?>
|