197 lines
6.5 KiB
PHP
197 lines
6.5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Manutenzioni — email notifications
|
|
* Run daily, e.g.: 0 7 * * * php /var/www/html/public/userarea/manutenzioni/cron/send_notifications.php
|
|
*
|
|
* Sends:
|
|
* - "advance" when next_due_date <= today + alert_days
|
|
* - "overdue" when next_due_date < today
|
|
*
|
|
* Recipients are the assignee and the supervisor of the maintenance
|
|
* (employees.auth_user_id -> auth_users.email). Deduplicated per
|
|
* maintenance + email + type + day by maint_notifications.
|
|
*/
|
|
|
|
require_once __DIR__ . '/../../class/db-functions.php';
|
|
require_once __DIR__ . '/../include/functions.php';
|
|
require_once __DIR__ . '/../../../../vendor/autoload.php';
|
|
|
|
use Dotenv\Dotenv;
|
|
use PHPMailer\PHPMailer\PHPMailer;
|
|
|
|
$dotenv = Dotenv::createImmutable(__DIR__ . '/../../../../');
|
|
$dotenv->safeLoad();
|
|
|
|
$pdo = mnt_pdo();
|
|
|
|
$today = date('Y-m-d');
|
|
$appUrl = rtrim($_ENV['APP_URL'] ?? 'http://localhost:8001', '/');
|
|
|
|
/**
|
|
* --dry-run (or MNT_MAIL_DRYRUN=1) works out the queue and prints it without
|
|
* sending anything and without writing to maint_notifications, so a run leaves
|
|
* no trace and can be repeated. Useful before a change to see what tonight
|
|
* would deliver, and it is what the test suite drives.
|
|
*
|
|
* One line per queued message, tab separated:
|
|
* QUEUE <type> <email> <maintenance_id> <label>
|
|
*/
|
|
$dryRun = in_array('--dry-run', $argv ?? [], true) || !empty($_ENV['MNT_MAIL_DRYRUN']);
|
|
if ($dryRun) {
|
|
echo "DRY-RUN — nothing is sent, nothing is recorded\n";
|
|
}
|
|
|
|
$sent = 0;
|
|
$skipped = 0;
|
|
$errors = 0;
|
|
|
|
// Only active maintenances of active equipment, with a real due date
|
|
$stmt = $pdo->prepare("
|
|
SELECT m.id, m.code, m.title, m.next_due_date, m.alert_days, m.is_critical,
|
|
e.id AS equipment_id, e.name AS equipment_name,
|
|
m.assignee_employee_id, m.supervisor_employee_id
|
|
FROM maint_maintenances m
|
|
INNER JOIN inv_equipment e ON e.id = m.equipment_id
|
|
WHERE m.is_active = 1
|
|
AND e.status = 'active'
|
|
AND m.next_due_date IS NOT NULL
|
|
AND m.next_due_date <= DATE_ADD(?, INTERVAL m.alert_days DAY)
|
|
");
|
|
$stmt->execute([$today]);
|
|
$maintenances = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
if (!$maintenances) {
|
|
echo date('Y-m-d H:i:s') . " — Nessuna manutenzione da notificare.\n";
|
|
exit(0);
|
|
}
|
|
|
|
$getRecipient = $pdo->prepare("
|
|
SELECT e.id AS employee_id, e.first_name, e.last_name, u.email
|
|
FROM employees e
|
|
INNER JOIN auth_users u ON u.id = e.auth_user_id
|
|
WHERE e.id = ?
|
|
AND e.auth_user_id IS NOT NULL
|
|
AND u.email IS NOT NULL
|
|
AND u.email <> ''
|
|
");
|
|
|
|
$checkSent = $pdo->prepare("
|
|
SELECT COUNT(*) FROM maint_notifications
|
|
WHERE maintenance_id = ? AND email = ? AND type = ? AND sent_date = ?
|
|
");
|
|
|
|
$insertNotification = $pdo->prepare("
|
|
INSERT INTO maint_notifications (maintenance_id, employee_id, email, type, sent_date)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
");
|
|
|
|
// mnt_mail_body() and mnt_notification_mail() live in include/functions.php,
|
|
// so that the preview renders the very same markup this cron sends.
|
|
|
|
foreach ($maintenances as $maintenance) {
|
|
$isOverdue = $maintenance['next_due_date'] < $today;
|
|
$type = $isOverdue ? 'overdue' : 'advance';
|
|
$daysLeft = (int)((strtotime($maintenance['next_due_date']) - strtotime($today)) / 86400);
|
|
|
|
// Assignee + supervisor, de-duplicated by employee id
|
|
$recipients = [];
|
|
foreach ([$maintenance['assignee_employee_id'], $maintenance['supervisor_employee_id']] as $employeeId) {
|
|
if (!$employeeId) {
|
|
continue;
|
|
}
|
|
|
|
$getRecipient->execute([(int)$employeeId]);
|
|
$recipient = $getRecipient->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($recipient) {
|
|
$recipients[(int)$recipient['employee_id']] = $recipient;
|
|
}
|
|
}
|
|
|
|
if (!$recipients) {
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
|
|
$label = ($maintenance['code'] ? $maintenance['code'] . ' — ' : '') . $maintenance['title'];
|
|
$detailUrl = $appUrl . '/userarea/manutenzioni/equipment.php?id=' . (int)$maintenance['equipment_id'];
|
|
|
|
foreach ($recipients as $recipient) {
|
|
$checkSent->execute([$maintenance['id'], $recipient['email'], $type, $today]);
|
|
if ((int)$checkSent->fetchColumn() > 0) {
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
|
|
if ($dryRun) {
|
|
printf("QUEUE\t%s\t%s\t%d\t%s\n", $type, $recipient['email'], (int)$maintenance['id'], $label);
|
|
$sent++;
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$mail = new PHPMailer(true);
|
|
|
|
if (($_ENV['MAIL_MAILER'] ?? 'mail') === 'smtp') {
|
|
$mail->isSMTP();
|
|
$mail->Host = $_ENV['MAIL_HOST'] ?? 'localhost';
|
|
$mail->Port = (int)($_ENV['MAIL_PORT'] ?? 587);
|
|
|
|
if (!empty($_ENV['MAIL_USERNAME']) && $_ENV['MAIL_USERNAME'] !== 'null') {
|
|
$mail->SMTPAuth = true;
|
|
$mail->Username = $_ENV['MAIL_USERNAME'];
|
|
$mail->Password = $_ENV['MAIL_PASSWORD'] ?? '';
|
|
}
|
|
|
|
$encryption = $_ENV['MAIL_ENCRYPTION'] ?? '';
|
|
if ($encryption && $encryption !== 'null') {
|
|
$mail->SMTPSecure = $encryption;
|
|
}
|
|
}
|
|
|
|
$mail->CharSet = 'UTF-8';
|
|
$mail->isHTML(true);
|
|
$mail->setFrom(
|
|
$_ENV['MAIL_FROM_ADDRESS'] ?? 'noreply@zibogomma.it',
|
|
$_ENV['MAIL_FROM_NAME'] ?? 'Manutenzioni ZIBOGOMMA'
|
|
);
|
|
$mail->addAddress($recipient['email'], trim($recipient['first_name'] . ' ' . $recipient['last_name']));
|
|
|
|
$composed = mnt_notification_mail($maintenance, $label, $daysLeft, $detailUrl, $today);
|
|
$mail->Subject = $composed['subject'];
|
|
$mail->Body = $composed['body'];
|
|
|
|
$mail->send();
|
|
|
|
$insertNotification->execute([
|
|
$maintenance['id'],
|
|
(int)$recipient['employee_id'],
|
|
$recipient['email'],
|
|
$type,
|
|
$today,
|
|
]);
|
|
|
|
mnt_log(
|
|
$pdo,
|
|
'notification_sent',
|
|
(int)$maintenance['equipment_id'],
|
|
(int)$maintenance['id'],
|
|
null,
|
|
null,
|
|
null,
|
|
$type . ' → ' . $recipient['email']
|
|
);
|
|
|
|
$sent++;
|
|
} catch (Throwable $e) {
|
|
$errors++;
|
|
echo date('Y-m-d H:i:s') . ' — Errore invio a ' . $recipient['email'] . ': ' . $e->getMessage() . "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
echo date('Y-m-d H:i:s')
|
|
. ($dryRun ? " — In coda: $sent" : " — Inviate: $sent")
|
|
. ", saltate: $skipped, errori: $errors\n";
|