file repo, cc, auto-open
This commit is contained in:
@@ -31,6 +31,8 @@ MAIL_USERNAME=null
|
|||||||
MAIL_PASSWORD=null
|
MAIL_PASSWORD=null
|
||||||
MAIL_ENCRYPTION=null
|
MAIL_ENCRYPTION=null
|
||||||
|
|
||||||
|
MANAGER_USER_ID=
|
||||||
|
|
||||||
PUSHER_APP_ID=
|
PUSHER_APP_ID=
|
||||||
PUSHER_APP_KEY=
|
PUSHER_APP_KEY=
|
||||||
PUSHER_APP_SECRET=
|
PUSHER_APP_SECRET=
|
||||||
|
|||||||
@@ -4,12 +4,19 @@ header('Content-Type: application/json');
|
|||||||
require_once(__DIR__ . '/../../class/db-functions.php');
|
require_once(__DIR__ . '/../../class/db-functions.php');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
$rawId = $_POST['id'] ?? $_GET['id'] ?? null;
|
||||||
|
if ($rawId === null || !is_numeric($rawId)) {
|
||||||
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = (int)$_GET['id'];
|
$id = (int)$rawId;
|
||||||
|
|
||||||
|
// Whether to create the next (recurring) deadline. Absent or '1' => create; '0' => complete only.
|
||||||
|
$createNext = ($_POST['create_next'] ?? '1') !== '0';
|
||||||
|
|
||||||
|
// Whether to carry the attachment links over to the new deadline. Default ON ("default all activate").
|
||||||
|
$copyAttachments = ($_POST['copy_attachments'] ?? '1') !== '0';
|
||||||
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
$db = DBHandlerSelect::getInstance();
|
||||||
$pdo = $db->getConnection();
|
$pdo = $db->getConnection();
|
||||||
@@ -34,11 +41,13 @@ try {
|
|||||||
->execute([$id, $currentUserId]);
|
->execute([$id, $currentUserId]);
|
||||||
|
|
||||||
$newId = null;
|
$newId = null;
|
||||||
|
$newDueDate = null;
|
||||||
|
|
||||||
// If recurring, create next deadline
|
// If recurring AND the user asked for it, create the next deadline
|
||||||
if ($deadline['recurrence_type'] !== 'once') {
|
if ($deadline['recurrence_type'] !== 'once' && $createNext) {
|
||||||
$dueDate = new DateTime($deadline['due_date']);
|
$dueDate = new DateTime($deadline['due_date']);
|
||||||
$checkDate = $deadline['check_date'] ? new DateTime($deadline['check_date']) : null;
|
$checkDate = $deadline['check_date'] ? new DateTime($deadline['check_date']) : null;
|
||||||
|
$documentDate = $deadline['document_date'] ? new DateTime($deadline['document_date']) : null;
|
||||||
|
|
||||||
switch ($deadline['recurrence_type']) {
|
switch ($deadline['recurrence_type']) {
|
||||||
case 'monthly': $interval = new DateInterval('P1M'); break;
|
case 'monthly': $interval = new DateInterval('P1M'); break;
|
||||||
@@ -57,6 +66,7 @@ try {
|
|||||||
if ($interval) {
|
if ($interval) {
|
||||||
$dueDate->add($interval);
|
$dueDate->add($interval);
|
||||||
if ($checkDate) $checkDate->add($interval);
|
if ($checkDate) $checkDate->add($interval);
|
||||||
|
if ($documentDate) $documentDate->add($interval);
|
||||||
|
|
||||||
$ins = $pdo->prepare("
|
$ins = $pdo->prepare("
|
||||||
INSERT INTO scad_deadlines
|
INSERT INTO scad_deadlines
|
||||||
@@ -68,12 +78,13 @@ try {
|
|||||||
$deadline['subject_id'], $deadline['topic'], $deadline['law_regulation'],
|
$deadline['subject_id'], $deadline['topic'], $deadline['law_regulation'],
|
||||||
$deadline['recurrence_type'], $dueDate->format('Y-m-d'),
|
$deadline['recurrence_type'], $dueDate->format('Y-m-d'),
|
||||||
$checkDate ? $checkDate->format('Y-m-d') : null,
|
$checkDate ? $checkDate->format('Y-m-d') : null,
|
||||||
$deadline['document_date'],
|
$documentDate ? $documentDate->format('Y-m-d') : null,
|
||||||
$deadline['notification_days'], $deadline['storage_location'],
|
$deadline['notification_days'], $deadline['storage_location'],
|
||||||
$deadline['notes'], $deadline['created_by'], $deadline['departments']
|
$deadline['notes'], $deadline['created_by'], $deadline['departments']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$newId = $pdo->lastInsertId();
|
$newId = $pdo->lastInsertId();
|
||||||
|
$newDueDate = $dueDate;
|
||||||
|
|
||||||
// Copy employee assignments
|
// Copy employee assignments
|
||||||
$empStmt = $pdo->prepare("SELECT employee_id FROM scad_deadline_employee WHERE deadline_id = ?");
|
$empStmt = $pdo->prepare("SELECT employee_id FROM scad_deadline_employee WHERE deadline_id = ?");
|
||||||
@@ -87,6 +98,31 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Carry forward ALL attachment links from the source deadline (shared physical file, same stored_name).
|
||||||
|
// Individual links can later be removed on the new deadline without deleting the file.
|
||||||
|
if ($copyAttachments) {
|
||||||
|
$attSel = $pdo->prepare("
|
||||||
|
SELECT original_name, stored_name, mime_type, size
|
||||||
|
FROM scad_deadline_attachments
|
||||||
|
WHERE deadline_id = ?
|
||||||
|
");
|
||||||
|
$attSel->execute([$id]);
|
||||||
|
$attRows = $attSel->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($attRows) {
|
||||||
|
$attIns = $pdo->prepare("
|
||||||
|
INSERT INTO scad_deadline_attachments
|
||||||
|
(deadline_id, original_name, stored_name, mime_type, size, uploaded_by)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
|
");
|
||||||
|
$attHist = $pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, 'attachment_linked', ?)");
|
||||||
|
foreach ($attRows as $a) {
|
||||||
|
$attIns->execute([$newId, $a['original_name'], $a['stored_name'], $a['mime_type'], $a['size'], $currentUserId]);
|
||||||
|
$attHist->execute([$newId, $currentUserId, $a['original_name']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// History for new
|
// History for new
|
||||||
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, 'created', ?)")
|
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, 'created', ?)")
|
||||||
->execute([$newId, $currentUserId, 'Creata automaticamente dalla scadenza #' . $id]);
|
->execute([$newId, $currentUserId, 'Creata automaticamente dalla scadenza #' . $id]);
|
||||||
@@ -97,7 +133,7 @@ try {
|
|||||||
|
|
||||||
$msg = 'Scadenza completata con successo.';
|
$msg = 'Scadenza completata con successo.';
|
||||||
if ($newId) {
|
if ($newId) {
|
||||||
$msg .= ' Nuova scadenza creata con data ' . $dueDate->format('d/m/Y') . '.';
|
$msg .= ' Nuova scadenza creata con data ' . $newDueDate->format('d/m/Y') . '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
echo json_encode(['success' => true, 'message' => $msg, 'new_id' => $newId]);
|
echo json_encode(['success' => true, 'message' => $msg, 'new_id' => $newId]);
|
||||||
|
|||||||
@@ -23,20 +23,32 @@ try {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete file
|
// Remove this link (DB record) first
|
||||||
|
$pdo->prepare("DELETE FROM scad_deadline_attachments WHERE id = ?")->execute([$id]);
|
||||||
|
|
||||||
|
// The same physical file may be shared with other deadlines (carried forward on completion).
|
||||||
|
// Only unlink it when no other link references the same stored file.
|
||||||
|
$refStmt = $pdo->prepare("SELECT COUNT(*) FROM scad_deadline_attachments WHERE stored_name = ?");
|
||||||
|
$refStmt->execute([$att['stored_name']]);
|
||||||
|
$stillReferenced = (int)$refStmt->fetchColumn() > 0;
|
||||||
|
|
||||||
|
if ($stillReferenced) {
|
||||||
|
$action = 'attachment_unlinked';
|
||||||
|
$message = 'Collegamento rimosso. Il file è conservato (usato da un\'altra scadenza).';
|
||||||
|
} else {
|
||||||
$filePath = __DIR__ . '/../attachments/' . $att['stored_name'];
|
$filePath = __DIR__ . '/../attachments/' . $att['stored_name'];
|
||||||
if (file_exists($filePath)) {
|
if (file_exists($filePath)) {
|
||||||
unlink($filePath);
|
unlink($filePath);
|
||||||
}
|
}
|
||||||
|
$action = 'attachment_removed';
|
||||||
// Delete DB record
|
$message = 'Allegato eliminato.';
|
||||||
$pdo->prepare("DELETE FROM scad_deadline_attachments WHERE id = ?")->execute([$id]);
|
}
|
||||||
|
|
||||||
// History
|
// History
|
||||||
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, 'attachment_removed', ?)")
|
$pdo->prepare("INSERT INTO scad_deadline_histories (deadline_id, user_id, action, notes) VALUES (?, ?, ?, ?)")
|
||||||
->execute([$att['deadline_id'], $currentUserId, $att['original_name']]);
|
->execute([$att['deadline_id'], $currentUserId, $action, $att['original_name']]);
|
||||||
|
|
||||||
echo json_encode(['success' => true, 'message' => 'Allegato eliminato.']);
|
echo json_encode(['success' => true, 'message' => $message]);
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||||
|
|||||||
@@ -13,10 +13,29 @@ try {
|
|||||||
$db = DBHandlerSelect::getInstance();
|
$db = DBHandlerSelect::getInstance();
|
||||||
$pdo = $db->getConnection();
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// Collect the physical files referenced by this deadline before the FK cascade removes its links
|
||||||
|
$attStmt = $pdo->prepare("SELECT DISTINCT stored_name FROM scad_deadline_attachments WHERE deadline_id = ?");
|
||||||
|
$attStmt->execute([$id]);
|
||||||
|
$storedNames = $attStmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
// Deleting the deadline cascades to its attachment/employee/history rows (FK ON DELETE CASCADE)
|
||||||
$stmt = $pdo->prepare("DELETE FROM scad_deadlines WHERE id = ?");
|
$stmt = $pdo->prepare("DELETE FROM scad_deadlines WHERE id = ?");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
|
|
||||||
if ($stmt->rowCount() > 0) {
|
if ($stmt->rowCount() > 0) {
|
||||||
|
// Unlink physical files no longer referenced by any other deadline (shared-file safe)
|
||||||
|
if (!empty($storedNames)) {
|
||||||
|
$refStmt = $pdo->prepare("SELECT COUNT(*) FROM scad_deadline_attachments WHERE stored_name = ?");
|
||||||
|
foreach ($storedNames as $storedName) {
|
||||||
|
$refStmt->execute([$storedName]);
|
||||||
|
if ((int)$refStmt->fetchColumn() === 0) {
|
||||||
|
$filePath = __DIR__ . '/../attachments/' . $storedName;
|
||||||
|
if (file_exists($filePath)) {
|
||||||
|
unlink($filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
echo json_encode(['success' => true, 'message' => 'Scadenza eliminata con successo.']);
|
echo json_encode(['success' => true, 'message' => 'Scadenza eliminata con successo.']);
|
||||||
} else {
|
} else {
|
||||||
echo json_encode(['success' => false, 'message' => 'Scadenza non trovata.']);
|
echo json_encode(['success' => false, 'message' => 'Scadenza non trovata.']);
|
||||||
|
|||||||
@@ -25,6 +25,17 @@ $pdo = $db->getConnection();
|
|||||||
$today = date('Y-m-d');
|
$today = date('Y-m-d');
|
||||||
$appUrl = rtrim($_ENV['APP_URL'] ?? 'http://localhost:8001', '/');
|
$appUrl = rtrim($_ENV['APP_URL'] ?? 'http://localhost:8001', '/');
|
||||||
|
|
||||||
|
// Manager email for Cc — taken from MANAGER_USER_ID → auth_users.email
|
||||||
|
$managerCcEmail = null;
|
||||||
|
if (!empty($_ENV['MANAGER_USER_ID']) && is_numeric($_ENV['MANAGER_USER_ID'])) {
|
||||||
|
$mgrStmt = $pdo->prepare("SELECT email FROM auth_users WHERE id = ?");
|
||||||
|
$mgrStmt->execute([(int)$_ENV['MANAGER_USER_ID']]);
|
||||||
|
$mgrEmail = $mgrStmt->fetchColumn();
|
||||||
|
if (!empty($mgrEmail)) {
|
||||||
|
$managerCcEmail = $mgrEmail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$sent = 0;
|
$sent = 0;
|
||||||
$skipped = 0;
|
$skipped = 0;
|
||||||
$errors = 0;
|
$errors = 0;
|
||||||
@@ -143,6 +154,11 @@ foreach ($deadlines as $dl) {
|
|||||||
);
|
);
|
||||||
$mail->addAddress($emp['email'], trim($emp['first_name'] . ' ' . $emp['last_name']));
|
$mail->addAddress($emp['email'], trim($emp['first_name'] . ' ' . $emp['last_name']));
|
||||||
|
|
||||||
|
// Cc the manager (unless they are the direct recipient)
|
||||||
|
if ($managerCcEmail && strcasecmp($managerCcEmail, $emp['email']) !== 0) {
|
||||||
|
$mail->addCC($managerCcEmail);
|
||||||
|
}
|
||||||
|
|
||||||
$detailUrl = $appUrl . '/userarea/scadenzario/detail.php?id=' . $dl['id'];
|
$detailUrl = $appUrl . '/userarea/scadenzario/detail.php?id=' . $dl['id'];
|
||||||
$topicText = (!empty($dl['subject_name']) ? $dl['subject_name'] . ' — ' : '') . $dl['topic'];
|
$topicText = (!empty($dl['subject_name']) ? $dl['subject_name'] . ' — ' : '') . $dl['topic'];
|
||||||
|
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$recurrenceLabels = ['once' => 'Una tantum', 'monthly' => 'Mensile', 'quarterly' => 'Trimestrale', 'semiannual' => 'Semestrale', 'annual' => 'Annuale', 'biennial' => 'Biennale', 'triennial' => 'Triennale', 'quadriennial' => 'Quadriennale', 'quinquennial' => 'Quinquennale', 'decennial' => 'Decennale', 'quindecennial' => 'Quindicennale'];
|
$recurrenceLabels = ['once' => 'Una tantum', 'monthly' => 'Mensile', 'quarterly' => 'Trimestrale', 'semiannual' => 'Semestrale', 'annual' => 'Annuale', 'biennial' => 'Biennale', 'triennial' => 'Triennale', 'quadriennial' => 'Quadriennale', 'quinquennial' => 'Quinquennale', 'decennial' => 'Decennale', 'quindecennial' => 'Quindicennale'];
|
||||||
$actionLabels = ['created' => 'Creata', 'updated' => 'Modificata', 'completed' => 'Completata', 'attachment_added' => 'Allegato aggiunto', 'attachment_removed' => 'Allegato rimosso', 'notification_sent' => 'Notifica inviata'];
|
$actionLabels = ['created' => 'Creata', 'updated' => 'Modificata', 'completed' => 'Completata', 'attachment_added' => 'Allegato aggiunto', 'attachment_removed' => 'Allegato rimosso', 'attachment_linked' => 'Allegato collegato', 'attachment_unlinked' => 'Collegamento rimosso', 'notification_sent' => 'Notifica inviata'];
|
||||||
$actionColors = ['created' => '#198754', 'updated' => '#5a8fd8', 'completed' => '#6f42c1', 'attachment_added' => '#e8930c', 'attachment_removed' => '#e8930c', 'notification_sent' => '#adb5bd'];
|
$actionColors = ['created' => '#198754', 'updated' => '#5a8fd8', 'completed' => '#6f42c1', 'attachment_added' => '#e8930c', 'attachment_removed' => '#e8930c', 'attachment_linked' => '#0dcaf0', 'attachment_unlinked' => '#adb5bd', 'notification_sent' => '#adb5bd'];
|
||||||
$actionIcons = ['created' => 'fa-plus', 'updated' => 'fa-pen', 'completed' => 'fa-check', 'attachment_added' => 'fa-paperclip', 'attachment_removed' => 'fa-trash', 'notification_sent' => 'fa-bell'];
|
$actionIcons = ['created' => 'fa-plus', 'updated' => 'fa-pen', 'completed' => 'fa-check', 'attachment_added' => 'fa-paperclip', 'attachment_removed' => 'fa-trash', 'attachment_linked' => 'fa-link', 'attachment_unlinked' => 'fa-link-slash', 'notification_sent' => 'fa-bell'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -763,17 +763,16 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
window.location.href = 'scadenzario/index.php?edit=<?= (int)$deadline['id'] ?>';
|
window.location.href = 'scadenzario/index.php?edit=<?= (int)$deadline['id'] ?>';
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#btnCompleta').on('click', function() {
|
function detailSubmitComplete(createNext, copyAttachments) {
|
||||||
Swal.fire({
|
var fd = new FormData();
|
||||||
title: 'Completare la scadenza?',
|
fd.append('id', '<?= (int)$deadline['id'] ?>');
|
||||||
icon: 'question',
|
fd.append('create_next', createNext ? '1' : '0');
|
||||||
showCancelButton: true,
|
fd.append('copy_attachments', copyAttachments ? '1' : '0');
|
||||||
confirmButtonColor: '#198754',
|
|
||||||
cancelButtonText: 'Annulla',
|
fetch('scadenzario/ajax/complete_deadline.php', {
|
||||||
confirmButtonText: 'Completa'
|
method: 'POST',
|
||||||
}).then(function(result) {
|
body: fd
|
||||||
if (result.isConfirmed) {
|
})
|
||||||
fetch('scadenzario/ajax/complete_deadline.php?id=<?= (int)$deadline['id'] ?>')
|
|
||||||
.then(function(r) {
|
.then(function(r) {
|
||||||
return r.json();
|
return r.json();
|
||||||
})
|
})
|
||||||
@@ -783,11 +782,15 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
icon: 'success',
|
icon: 'success',
|
||||||
title: 'Completata',
|
title: 'Completata',
|
||||||
text: data.message,
|
text: data.message,
|
||||||
timer: 2500,
|
timer: 1800,
|
||||||
showConfirmButton: false
|
showConfirmButton: false
|
||||||
})
|
})
|
||||||
.then(function() {
|
.then(function() {
|
||||||
|
if (data.new_id) {
|
||||||
|
window.location.href = 'scadenzario/index.php?edit=' + data.new_id;
|
||||||
|
} else {
|
||||||
window.location.href = 'scadenzario/index.php';
|
window.location.href = 'scadenzario/index.php';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Swal.fire('Errore', data.message, 'error');
|
Swal.fire('Errore', data.message, 'error');
|
||||||
@@ -797,6 +800,55 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('#btnCompleta').on('click', function() {
|
||||||
|
var recurrence = <?= json_encode($deadline['recurrence_type'] ?? 'once') ?>;
|
||||||
|
var attCount = <?= count($attachments) ?>;
|
||||||
|
|
||||||
|
if (recurrence === 'once') {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Completare la scadenza?',
|
||||||
|
text: 'La scadenza verrà contrassegnata come completata.',
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#198754',
|
||||||
|
cancelButtonText: 'Annulla',
|
||||||
|
confirmButtonText: 'Completa',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then(function(result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
detailSubmitComplete(false, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var attCheckbox = attCount > 0 ?
|
||||||
|
'<div class="form-check d-flex align-items-center justify-content-center gap-2 mt-3">' +
|
||||||
|
'<input class="form-check-input" type="checkbox" id="swCopyAtt" checked>' +
|
||||||
|
'<label class="form-check-label" for="swCopyAtt">Copia gli allegati (' + attCount + ') sulla nuova scadenza</label>' +
|
||||||
|
'</div>' :
|
||||||
|
'';
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Completare la scadenza?',
|
||||||
|
html: 'Vuoi creare automaticamente la prossima scadenza ricorrente?' + attCheckbox,
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
showDenyButton: true,
|
||||||
|
confirmButtonColor: '#198754',
|
||||||
|
denyButtonColor: '#6c757d',
|
||||||
|
confirmButtonText: 'Completa e crea la prossima',
|
||||||
|
denyButtonText: 'Completa senza nuova',
|
||||||
|
cancelButtonText: 'Annulla',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then(function(result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
var copy = attCount > 0 ? document.getElementById('swCopyAtt').checked : false;
|
||||||
|
detailSubmitComplete(true, copy);
|
||||||
|
} else if (result.isDenied) {
|
||||||
|
detailSubmitComplete(false, false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -923,7 +923,9 @@ function getContrastTextColor($hexColor)
|
|||||||
data-department="<?= htmlspecialchars($row['reparti'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-department="<?= htmlspecialchars($row['reparti'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-employees="<?= htmlspecialchars($row['responsabili'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-employees="<?= htmlspecialchars($row['responsabili'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
|
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
|
data-recurrence="<?= htmlspecialchars($row['recurrence_type'] ?? 'once', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
|
data-att-count="<?= (int)$row['attachment_count'] ?>">
|
||||||
<?php if (!empty($row['subject_name'])): ?>
|
<?php if (!empty($row['subject_name'])): ?>
|
||||||
<div class="mb-1"><?php
|
<div class="mb-1"><?php
|
||||||
$subjectBadgeBg = $row['subject_color'] ?: '#6c757d';
|
$subjectBadgeBg = $row['subject_color'] ?: '#6c757d';
|
||||||
@@ -1000,7 +1002,9 @@ function getContrastTextColor($hexColor)
|
|||||||
data-department="<?= htmlspecialchars($row['reparti'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-department="<?= htmlspecialchars($row['reparti'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-employees="<?= htmlspecialchars($row['responsabili'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-employees="<?= htmlspecialchars($row['responsabili'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
|
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
|
data-recurrence="<?= htmlspecialchars($row['recurrence_type'] ?? 'once', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
|
data-att-count="<?= (int)$row['attachment_count'] ?>">
|
||||||
<td>
|
<td>
|
||||||
<?php if (!empty($row['subject_name'])): ?>
|
<?php if (!empty($row['subject_name'])): ?>
|
||||||
<?php
|
<?php
|
||||||
@@ -1613,12 +1617,14 @@ function getContrastTextColor($hexColor)
|
|||||||
var btn = $(this);
|
var btn = $(this);
|
||||||
var attId = btn.data('att-id');
|
var attId = btn.data('att-id');
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Eliminare allegato?',
|
title: 'Rimuovere l\'allegato?',
|
||||||
|
text: 'Il collegamento verrà rimosso da questa scadenza. Il file resta disponibile se è usato da altre scadenze.',
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: '#dc3545',
|
confirmButtonColor: '#dc3545',
|
||||||
cancelButtonText: 'Annulla',
|
cancelButtonText: 'Annulla',
|
||||||
confirmButtonText: 'Elimina'
|
confirmButtonText: 'Rimuovi',
|
||||||
|
reverseButtons: true
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
fetch('scadenzario/ajax/delete_attachment.php?id=' + attId)
|
fetch('scadenzario/ajax/delete_attachment.php?id=' + attId)
|
||||||
@@ -1631,6 +1637,13 @@ function getContrastTextColor($hexColor)
|
|||||||
if ($('#attachmentsList .att-item').length === 0) {
|
if ($('#attachmentsList .att-item').length === 0) {
|
||||||
renderAttachments([]);
|
renderAttachments([]);
|
||||||
}
|
}
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'success',
|
||||||
|
title: 'Fatto',
|
||||||
|
text: data.message,
|
||||||
|
timer: 1800,
|
||||||
|
showConfirmButton: false
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Swal.fire('Errore', data.message, 'error');
|
Swal.fire('Errore', data.message, 'error');
|
||||||
}
|
}
|
||||||
@@ -1703,19 +1716,16 @@ function getContrastTextColor($hexColor)
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Complete
|
// Complete
|
||||||
$(document).on('click', '.btn-complete', function() {
|
function submitComplete(id, createNext, copyAttachments) {
|
||||||
var el = $(this).closest('[data-id]');
|
var fd = new FormData();
|
||||||
var id = el.data('id');
|
fd.append('id', id);
|
||||||
Swal.fire({
|
fd.append('create_next', createNext ? '1' : '0');
|
||||||
title: 'Completare la scadenza?',
|
fd.append('copy_attachments', copyAttachments ? '1' : '0');
|
||||||
icon: 'question',
|
|
||||||
showCancelButton: true,
|
fetch('scadenzario/ajax/complete_deadline.php', {
|
||||||
confirmButtonColor: '#198754',
|
method: 'POST',
|
||||||
cancelButtonText: 'Annulla',
|
body: fd
|
||||||
confirmButtonText: 'Completa'
|
})
|
||||||
}).then(function(result) {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
fetch('scadenzario/ajax/complete_deadline.php?id=' + id)
|
|
||||||
.then(function(r) {
|
.then(function(r) {
|
||||||
return r.json();
|
return r.json();
|
||||||
})
|
})
|
||||||
@@ -1725,11 +1735,16 @@ function getContrastTextColor($hexColor)
|
|||||||
icon: 'success',
|
icon: 'success',
|
||||||
title: 'Completata',
|
title: 'Completata',
|
||||||
text: data.message,
|
text: data.message,
|
||||||
timer: 2500,
|
timer: 1800,
|
||||||
showConfirmButton: false
|
showConfirmButton: false
|
||||||
})
|
})
|
||||||
.then(function() {
|
.then(function() {
|
||||||
|
// Auto-open the newly created deadline; otherwise just refresh the list
|
||||||
|
if (data.new_id) {
|
||||||
|
window.location = 'scadenzario/index.php?edit=' + data.new_id;
|
||||||
|
} else {
|
||||||
location.reload();
|
location.reload();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Swal.fire('Errore', data.message, 'error');
|
Swal.fire('Errore', data.message, 'error');
|
||||||
@@ -1739,6 +1754,59 @@ function getContrastTextColor($hexColor)
|
|||||||
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(document).on('click', '.btn-complete', function() {
|
||||||
|
var el = $(this).closest('[data-id]');
|
||||||
|
var id = el.data('id');
|
||||||
|
var recurrence = el.data('recurrence') || 'once';
|
||||||
|
var attCount = parseInt(el.data('att-count'), 10) || 0;
|
||||||
|
|
||||||
|
// Non-recurring: simple confirm, no new deadline is created
|
||||||
|
if (recurrence === 'once') {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Completare la scadenza?',
|
||||||
|
text: 'La scadenza verrà contrassegnata come completata.',
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#198754',
|
||||||
|
cancelButtonText: 'Annulla',
|
||||||
|
confirmButtonText: 'Completa',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then(function(result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
submitComplete(id, false, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recurring: ask whether to create the next deadline; optionally carry attachments over
|
||||||
|
var attCheckbox = attCount > 0 ?
|
||||||
|
'<div class="form-check d-flex align-items-center justify-content-center gap-2 mt-3">' +
|
||||||
|
'<input class="form-check-input" type="checkbox" id="swCopyAtt" checked>' +
|
||||||
|
'<label class="form-check-label" for="swCopyAtt">Copia gli allegati (' + attCount + ') sulla nuova scadenza</label>' +
|
||||||
|
'</div>' :
|
||||||
|
'';
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Completare la scadenza?',
|
||||||
|
html: 'Vuoi creare automaticamente la prossima scadenza ricorrente?' + attCheckbox,
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
showDenyButton: true,
|
||||||
|
confirmButtonColor: '#198754',
|
||||||
|
denyButtonColor: '#6c757d',
|
||||||
|
confirmButtonText: 'Completa e crea la prossima',
|
||||||
|
denyButtonText: 'Completa senza nuova',
|
||||||
|
cancelButtonText: 'Annulla',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then(function(result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
var copy = attCount > 0 ? document.getElementById('swCopyAtt').checked : false;
|
||||||
|
submitComplete(id, true, copy);
|
||||||
|
} else if (result.isDenied) {
|
||||||
|
submitComplete(id, false, false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user