deadline feature
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Auth check for AJAX endpoints.
|
||||
* Include this at the top of every ajax handler.
|
||||
* Sets $currentUserId from session or returns 401 JSON.
|
||||
*/
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
if (empty($_SESSION['iduserlogin'])) {
|
||||
header('Content-Type: application/json');
|
||||
http_response_code(401);
|
||||
echo json_encode(['success' => false, 'message' => 'Non autorizzato. Effettua il login.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$currentUserId = (int)$_SESSION['iduserlogin'];
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT * FROM scad_deadlines WHERE id = ? AND status = 'active'");
|
||||
$stmt->execute([$id]);
|
||||
$deadline = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$deadline) {
|
||||
echo json_encode(['success' => false, 'message' => 'Scadenza non trovata o già completata.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// Mark as completed
|
||||
$pdo->prepare("UPDATE scad_deadlines SET status = 'completed', completed_at = NOW(), completed_by = ? WHERE id = ?")
|
||||
->execute([$currentUserId, $id]);
|
||||
|
||||
// History
|
||||
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action) VALUES (?, ?, 'completed')")
|
||||
->execute([$id, $currentUserId]);
|
||||
|
||||
$newId = null;
|
||||
|
||||
// If recurring, create next deadline
|
||||
if ($deadline['recurrence_type'] !== 'once') {
|
||||
$dueDate = new DateTime($deadline['due_date']);
|
||||
$checkDate = $deadline['check_date'] ? new DateTime($deadline['check_date']) : null;
|
||||
|
||||
switch ($deadline['recurrence_type']) {
|
||||
case 'monthly': $interval = new DateInterval('P1M'); break;
|
||||
case 'quarterly': $interval = new DateInterval('P3M'); break;
|
||||
case 'semiannual': $interval = new DateInterval('P6M'); break;
|
||||
case 'annual': $interval = new DateInterval('P1Y'); break;
|
||||
case 'biennial': $interval = new DateInterval('P2Y'); break;
|
||||
case 'triennial': $interval = new DateInterval('P3Y'); break;
|
||||
case 'quinquennial': $interval = new DateInterval('P5Y'); break;
|
||||
default: $interval = null;
|
||||
}
|
||||
|
||||
if ($interval) {
|
||||
$dueDate->add($interval);
|
||||
if ($checkDate) $checkDate->add($interval);
|
||||
|
||||
$ins = $pdo->prepare("
|
||||
INSERT INTO scad_deadlines
|
||||
(category, topic, law_regulation, recurrence_type, due_date, check_date,
|
||||
document_date, notification_days, storage_location, notes, created_by, departments)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
$ins->execute([
|
||||
$deadline['category'], $deadline['topic'], $deadline['law_regulation'],
|
||||
$deadline['recurrence_type'], $dueDate->format('Y-m-d'),
|
||||
$checkDate ? $checkDate->format('Y-m-d') : null,
|
||||
$deadline['document_date'],
|
||||
$deadline['notification_days'], $deadline['storage_location'],
|
||||
$deadline['notes'], $deadline['created_by'], $deadline['departments']
|
||||
]);
|
||||
|
||||
$newId = $pdo->lastInsertId();
|
||||
|
||||
// Copy employee assignments
|
||||
$empStmt = $pdo->prepare("SELECT employee_id FROM scad_deadline_employee WHERE deadline_id = ?");
|
||||
$empStmt->execute([$id]);
|
||||
$empIds = $empStmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
if (!empty($empIds)) {
|
||||
$insertEmp = $pdo->prepare("INSERT INTO scad_deadline_employee (deadline_id, employee_id) VALUES (?, ?)");
|
||||
foreach ($empIds as $empId) {
|
||||
$insertEmp->execute([$newId, $empId]);
|
||||
}
|
||||
}
|
||||
|
||||
// History for new
|
||||
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, 'created', ?)")
|
||||
->execute([$newId, $currentUserId, 'Creata automaticamente dalla scadenza #' . $id]);
|
||||
}
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
|
||||
$msg = 'Scadenza completata con successo.';
|
||||
if ($newId) {
|
||||
$msg .= ' Nuova scadenza creata con data ' . $dueDate->format('d/m/Y') . '.';
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'message' => $msg, 'new_id' => $newId]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
if (isset($pdo) && $pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT * FROM scad_deadline_attachments WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$att = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$att) {
|
||||
echo json_encode(['success' => false, 'message' => 'Allegato non trovato.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Delete file
|
||||
$filePath = __DIR__ . '/../attachments/' . $att['stored_name'];
|
||||
if (file_exists($filePath)) {
|
||||
unlink($filePath);
|
||||
}
|
||||
|
||||
// Delete DB record
|
||||
$pdo->prepare("DELETE FROM scad_deadline_attachments WHERE id = ?")->execute([$id]);
|
||||
|
||||
// History
|
||||
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, 'attachment_removed', ?)")
|
||||
->execute([$att['deadline_id'], $currentUserId, $att['original_name']]);
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Allegato eliminato.']);
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$stmt = $pdo->prepare("DELETE FROM scad_deadlines WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
echo json_encode(['success' => true, 'message' => 'Scadenza eliminata con successo.']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Scadenza non trovata.']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
http_response_code(400);
|
||||
echo 'ID non valido.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT * FROM scad_deadline_attachments WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$att = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$att) {
|
||||
http_response_code(404);
|
||||
echo 'Allegato non trovato.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$filePath = __DIR__ . '/../attachments/' . $att['stored_name'];
|
||||
if (!file_exists($filePath)) {
|
||||
http_response_code(404);
|
||||
echo 'File non trovato sul server.';
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: ' . ($att['mime_type'] ?: 'application/octet-stream'));
|
||||
header('Content-Disposition: attachment; filename="' . addslashes($att['original_name']) . '"');
|
||||
header('Content-Length: ' . filesize($filePath));
|
||||
readfile($filePath);
|
||||
exit;
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$start = $_GET['start'] ?? null;
|
||||
$end = $_GET['end'] ?? null;
|
||||
$filterStatus = $_GET['status'] ?? '';
|
||||
$filterDept = $_GET['department'] ?? '';
|
||||
$filterEmployee = $_GET['employee'] ?? '';
|
||||
|
||||
$sql = "SELECT DISTINCT d.id, d.topic, d.category, d.due_date, d.status, d.notification_days, d.departments
|
||||
FROM scad_deadlines d
|
||||
LEFT JOIN scad_deadline_employee de ON de.deadline_id = d.id
|
||||
LEFT JOIN employees e ON e.id = de.employee_id";
|
||||
|
||||
$where = [];
|
||||
$params = [];
|
||||
|
||||
if ($start && $end) {
|
||||
$where[] = "d.due_date >= ? AND d.due_date <= ?";
|
||||
$params[] = $start;
|
||||
$params[] = $end;
|
||||
}
|
||||
|
||||
if ($filterStatus === 'non-completata') {
|
||||
$where[] = "d.status != 'completed'";
|
||||
} elseif ($filterStatus === 'completata') {
|
||||
$where[] = "d.status = 'completed'";
|
||||
} elseif ($filterStatus === 'scaduta') {
|
||||
$where[] = "d.status = 'active' AND d.due_date < CURDATE()";
|
||||
} elseif ($filterStatus === 'in-scadenza') {
|
||||
$where[] = "d.status = 'active' AND d.due_date >= CURDATE() AND d.due_date <= DATE_ADD(CURDATE(), INTERVAL d.notification_days DAY)";
|
||||
} elseif ($filterStatus === 'attiva') {
|
||||
$where[] = "d.status = 'active' AND d.due_date > DATE_ADD(CURDATE(), INTERVAL d.notification_days DAY)";
|
||||
}
|
||||
|
||||
if ($filterDept) {
|
||||
$where[] = "(e.department = ? OR FIND_IN_SET(?, d.departments))";
|
||||
$params[] = $filterDept;
|
||||
$params[] = $filterDept;
|
||||
}
|
||||
|
||||
if ($filterEmployee) {
|
||||
$where[] = "CONCAT(e.first_name, ' ', e.last_name) = ?";
|
||||
$params[] = $filterEmployee;
|
||||
}
|
||||
|
||||
if (!empty($where)) {
|
||||
$sql .= " WHERE " . implode(' AND ', $where);
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$deadlines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$today = date('Y-m-d');
|
||||
$events = [];
|
||||
|
||||
foreach ($deadlines as $d) {
|
||||
$isCompleted = $d['status'] === 'completed';
|
||||
$isOverdue = !$isCompleted && $d['due_date'] < $today;
|
||||
$approachDate = date('Y-m-d', strtotime($today . ' + ' . (int)$d['notification_days'] . ' days'));
|
||||
$isApproaching = !$isCompleted && !$isOverdue && $d['due_date'] <= $approachDate;
|
||||
|
||||
if ($isCompleted) { $color = '#198754'; }
|
||||
elseif ($isOverdue) { $color = '#dc3545'; }
|
||||
elseif ($isApproaching) { $color = '#e8930c'; }
|
||||
else { $color = '#5a8fd8'; }
|
||||
|
||||
$title = $d['topic'];
|
||||
if ($d['category']) $title = $d['category'] . ': ' . $title;
|
||||
|
||||
$events[] = [
|
||||
'id' => $d['id'],
|
||||
'title' => $title,
|
||||
'start' => $d['due_date'],
|
||||
'backgroundColor' => $color,
|
||||
'borderColor' => $color,
|
||||
'url' => 'scadenzario/detail.php?id=' . $d['id'],
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($events);
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode([]);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT * FROM scad_deadlines WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$deadline = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$deadline) {
|
||||
echo json_encode(['success' => false, 'message' => 'Scadenza non trovata.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get assigned employee IDs
|
||||
$empStmt = $pdo->prepare("SELECT employee_id FROM scad_deadline_employee WHERE deadline_id = ?");
|
||||
$empStmt->execute([$id]);
|
||||
$deadline['employee_ids'] = $empStmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
// Parse departments into array
|
||||
$deadline['department_names'] = [];
|
||||
if (!empty($deadline['departments'])) {
|
||||
$deadline['department_names'] = array_map('trim', explode(',', $deadline['departments']));
|
||||
}
|
||||
|
||||
// Get attachments
|
||||
$attStmt = $pdo->prepare("SELECT id, original_name, mime_type, size, created_at FROM scad_deadline_attachments WHERE deadline_id = ? ORDER BY created_at DESC");
|
||||
$attStmt->execute([$id]);
|
||||
$deadline['attachments'] = $attStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo json_encode(['success' => true, 'data' => $deadline]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT h.*,
|
||||
au.first_name as user_first_name,
|
||||
au.last_name as user_last_name
|
||||
FROM scad_deadline_histories h
|
||||
LEFT JOIN auth_users au ON au.id = h.user_id
|
||||
WHERE h.deadline_id = ?
|
||||
ORDER BY h.created_at DESC
|
||||
");
|
||||
$stmt->execute([$id]);
|
||||
$history = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Format for display
|
||||
$actionLabels = [
|
||||
'created' => 'Creata',
|
||||
'updated' => 'Modificata',
|
||||
'completed' => 'Completata',
|
||||
'attachment_added' => 'Allegato aggiunto',
|
||||
'attachment_removed' => 'Allegato rimosso',
|
||||
'notification_sent' => 'Notifica inviata'
|
||||
];
|
||||
|
||||
foreach ($history as &$h) {
|
||||
$h['action_label'] = $actionLabels[$h['action']] ?? $h['action'];
|
||||
$h['user_name'] = trim(($h['user_first_name'] ?? '') . ' ' . ($h['user_last_name'] ?? '')) ?: 'Sistema';
|
||||
$h['changes'] = $h['changes'] ? json_decode($h['changes'], true) : null;
|
||||
unset($h['user_first_name'], $h['user_last_name']);
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'data' => $history]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$id = isset($_POST['id']) && is_numeric($_POST['id']) ? (int)$_POST['id'] : null;
|
||||
$category = trim($_POST['category'] ?? '') ?: null;
|
||||
$topic = trim($_POST['topic'] ?? '');
|
||||
$law_regulation = trim($_POST['law_regulation'] ?? '') ?: null;
|
||||
$recurrence_type = $_POST['recurrence_type'] ?? 'once';
|
||||
$due_date = $_POST['due_date'] ?? '';
|
||||
$check_date = trim($_POST['check_date'] ?? '') ?: null;
|
||||
$document_date = trim($_POST['document_date'] ?? '') ?: null;
|
||||
$notification_days = isset($_POST['notification_days']) && is_numeric($_POST['notification_days']) ? (int)$_POST['notification_days'] : 7;
|
||||
$storage_location = trim($_POST['storage_location'] ?? '') ?: null;
|
||||
$notes = trim($_POST['notes'] ?? '') ?: null;
|
||||
$employee_ids = $_POST['employee_ids'] ?? [];
|
||||
$department_names = $_POST['department_names'] ?? [];
|
||||
|
||||
// Validation
|
||||
if ($topic === '') {
|
||||
echo json_encode(['success' => false, 'message' => 'Il campo Tema è obbligatorio.']);
|
||||
exit;
|
||||
}
|
||||
if ($due_date === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $due_date)) {
|
||||
echo json_encode(['success' => false, 'message' => 'La data di scadenza è obbligatoria.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$validRecurrences = ['once', 'monthly', 'quarterly', 'semiannual', 'annual', 'biennial', 'triennial', 'quinquennial'];
|
||||
if (!in_array($recurrence_type, $validRecurrences)) {
|
||||
$recurrence_type = 'once';
|
||||
}
|
||||
|
||||
if (!is_array($employee_ids)) {
|
||||
$employee_ids = [];
|
||||
}
|
||||
$employee_ids = array_filter(array_map('intval', $employee_ids));
|
||||
|
||||
if (!is_array($department_names)) {
|
||||
$department_names = [];
|
||||
}
|
||||
$department_names = array_filter(array_map('trim', $department_names));
|
||||
$departmentsStr = !empty($department_names) ? implode(', ', $department_names) : null;
|
||||
|
||||
$pdo->beginTransaction();
|
||||
|
||||
if ($id) {
|
||||
$stmt = $pdo->prepare("
|
||||
UPDATE scad_deadlines SET
|
||||
category = ?, topic = ?, law_regulation = ?, recurrence_type = ?,
|
||||
due_date = ?, check_date = ?, document_date = ?, notification_days = ?,
|
||||
storage_location = ?, notes = ?, departments = ?
|
||||
WHERE id = ?
|
||||
");
|
||||
$stmt->execute([
|
||||
$category, $topic, $law_regulation, $recurrence_type,
|
||||
$due_date, $check_date, $document_date, $notification_days,
|
||||
$storage_location, $notes, $departmentsStr, $id
|
||||
]);
|
||||
|
||||
// Re-link employees
|
||||
$pdo->prepare("DELETE FROM scad_deadline_employee WHERE deadline_id = ?")->execute([$id]);
|
||||
|
||||
// History
|
||||
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action) VALUES (?, ?, 'updated')")
|
||||
->execute([$id, $currentUserId ?: null]);
|
||||
|
||||
$deadlineId = $id;
|
||||
} else {
|
||||
// INSERT
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO scad_deadlines
|
||||
(category, topic, law_regulation, recurrence_type, due_date, check_date,
|
||||
document_date, notification_days, storage_location, notes, created_by, departments)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
$stmt->execute([
|
||||
$category, $topic, $law_regulation, $recurrence_type,
|
||||
$due_date, $check_date, $document_date, $notification_days,
|
||||
$storage_location, $notes, $currentUserId, $departmentsStr
|
||||
]);
|
||||
|
||||
$deadlineId = $pdo->lastInsertId();
|
||||
|
||||
// History
|
||||
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action) VALUES (?, ?, 'created')")
|
||||
->execute([$deadlineId, $currentUserId ?: null]);
|
||||
}
|
||||
|
||||
// Link employees
|
||||
if (!empty($employee_ids)) {
|
||||
$insertEmployee = $pdo->prepare("INSERT INTO scad_deadline_employee (deadline_id, employee_id) VALUES (?, ?)");
|
||||
foreach ($employee_ids as $empId) {
|
||||
$insertEmployee->execute([$deadlineId, $empId]);
|
||||
}
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => $id ? 'Scadenza aggiornata con successo.' : 'Scadenza creata con successo.',
|
||||
'id' => $deadlineId
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
if (isset($pdo) && $pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/auth_check.php');
|
||||
header('Content-Type: application/json');
|
||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||
|
||||
try {
|
||||
if (!isset($_POST['deadline_id']) || !is_numeric($_POST['deadline_id'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID scadenza non valido.']);
|
||||
exit;
|
||||
}
|
||||
if (empty($_FILES['files']['name'][0])) {
|
||||
echo json_encode(['success' => false, 'message' => 'Nessun file selezionato.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$deadlineId = (int)$_POST['deadline_id'];
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// Verify deadline exists
|
||||
$check = $pdo->prepare("SELECT id FROM scad_deadlines WHERE id = ?");
|
||||
$check->execute([$deadlineId]);
|
||||
if (!$check->fetch()) {
|
||||
echo json_encode(['success' => false, 'message' => 'Scadenza non trovata.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$uploadDir = __DIR__ . '/../attachments/';
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
$inserted = [];
|
||||
$pdo->beginTransaction();
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO scad_deadline_attachments (deadline_id, original_name, stored_name, mime_type, size, uploaded_by)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
$histStmt = $pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, 'attachment_added', ?)");
|
||||
|
||||
$fileCount = count($_FILES['files']['name']);
|
||||
for ($i = 0; $i < $fileCount; $i++) {
|
||||
if ($_FILES['files']['error'][$i] !== UPLOAD_ERR_OK) continue;
|
||||
|
||||
$originalName = $_FILES['files']['name'][$i];
|
||||
$mimeType = $_FILES['files']['type'][$i];
|
||||
$size = $_FILES['files']['size'][$i];
|
||||
$storedName = uniqid('att_') . '_' . preg_replace('/[^a-zA-Z0-9._-]/', '_', $originalName);
|
||||
|
||||
if (!move_uploaded_file($_FILES['files']['tmp_name'][$i], $uploadDir . $storedName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$stmt->execute([$deadlineId, $originalName, $storedName, $mimeType, $size, $currentUserId]);
|
||||
$histStmt->execute([$deadlineId, $currentUserId, $originalName]);
|
||||
$inserted[] = ['id' => $pdo->lastInsertId(), 'original_name' => $originalName, 'stored_name' => $storedName];
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => count($inserted) . ' file caricato/i con successo.',
|
||||
'files' => $inserted
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
Reference in New Issue
Block a user