155 lines
5.6 KiB
PHP
155 lines
5.6 KiB
PHP
<?php
|
|
|
|
require_once __DIR__ . '/auth_check.php';
|
|
|
|
mnt_require_permission('maintenance.manage');
|
|
|
|
/**
|
|
* Registers (or updates) one intervention against a maintenance and
|
|
* recomputes the maintenance schedule.
|
|
*
|
|
* The operator signature arrives as a data URL from the tablet canvas and
|
|
* is stored as a PNG in attachments/.
|
|
*/
|
|
try {
|
|
$pdo = mnt_pdo();
|
|
|
|
$id = (int)($_POST['id'] ?? 0);
|
|
$maintenanceId = (int)($_POST['maintenance_id'] ?? 0);
|
|
$performedAt = trim((string)($_POST['performed_at'] ?? ''));
|
|
$status = (string)($_POST['status'] ?? 'completed');
|
|
$result = trim((string)($_POST['result'] ?? ''));
|
|
$notes = trim((string)($_POST['notes'] ?? ''));
|
|
$materials = trim((string)($_POST['materials'] ?? ''));
|
|
$operatorId = (int)($_POST['operator_employee_id'] ?? 0);
|
|
$operatorName = trim((string)($_POST['operator_name'] ?? ''));
|
|
$supplierId = (int)($_POST['supplier_id'] ?? 0);
|
|
$signatureData = (string)($_POST['signature'] ?? '');
|
|
$clearSignature = !empty($_POST['clear_signature']);
|
|
|
|
if ($performedAt === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $performedAt)) {
|
|
mnt_json_fail('La data dell\'intervento è obbligatoria.');
|
|
}
|
|
|
|
$validStatuses = mnt_lookup($pdo, 'maint_status', ['planned' => '', 'in_progress' => '', 'completed' => '']);
|
|
if (!array_key_exists($status, $validStatuses)) {
|
|
mnt_json_fail('Stato intervento non valido.');
|
|
}
|
|
|
|
$validResults = mnt_lookup($pdo, 'maint_result', []);
|
|
if ($result !== '' && $validResults && !array_key_exists($result, $validResults)) {
|
|
mnt_json_fail('Esito intervento non valido.');
|
|
}
|
|
|
|
// Existing row: maintenance is taken from the record, not from the client
|
|
if ($id > 0) {
|
|
$stmt = $pdo->prepare("SELECT * FROM maint_interventions WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$existing) {
|
|
mnt_json_fail('Intervento non trovato.');
|
|
}
|
|
|
|
$maintenanceId = (int)$existing['maintenance_id'];
|
|
$equipmentId = (int)$existing['equipment_id'];
|
|
$signaturePath = $existing['signature_path'];
|
|
} else {
|
|
$stmt = $pdo->prepare("SELECT equipment_id FROM maint_maintenances WHERE id = ?");
|
|
$stmt->execute([$maintenanceId]);
|
|
$equipmentId = (int)$stmt->fetchColumn();
|
|
|
|
if (!$equipmentId) {
|
|
mnt_json_fail('Manutenzione non trovata.');
|
|
}
|
|
|
|
$signaturePath = null;
|
|
}
|
|
|
|
// Signature handling
|
|
if ($clearSignature && $signaturePath) {
|
|
mnt_delete_stored_file((string)$signaturePath);
|
|
$signaturePath = null;
|
|
}
|
|
|
|
if ($signatureData !== '' && preg_match('#^data:image/png;base64,#', $signatureData)) {
|
|
$binary = base64_decode(substr($signatureData, strlen('data:image/png;base64,')), true);
|
|
|
|
if ($binary === false || strlen($binary) > 2 * 1024 * 1024) {
|
|
mnt_json_fail('Firma non valida.');
|
|
}
|
|
|
|
$uploadDir = __DIR__ . '/../attachments/';
|
|
if (!is_dir($uploadDir) && !mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) {
|
|
mnt_json_fail('Cartella allegati non scrivibile.');
|
|
}
|
|
|
|
$newSignature = uniqid('sig_', true) . '.png';
|
|
$newSignature = preg_replace('/[^A-Za-z0-9._-]/', '_', $newSignature);
|
|
|
|
if (file_put_contents($uploadDir . $newSignature, $binary) === false) {
|
|
mnt_json_fail('Impossibile salvare la firma.');
|
|
}
|
|
|
|
if ($signaturePath) {
|
|
mnt_delete_stored_file((string)$signaturePath);
|
|
}
|
|
|
|
$signaturePath = $newSignature;
|
|
}
|
|
|
|
$values = [
|
|
'performed_at' => $performedAt,
|
|
'status' => $status,
|
|
'result' => $result ?: null,
|
|
'notes' => $notes ?: null,
|
|
'materials' => $materials ?: null,
|
|
'operator_employee_id' => $operatorId ?: null,
|
|
'operator_name' => $operatorName ?: null,
|
|
'supplier_id' => $supplierId ?: null,
|
|
'signature_path' => $signaturePath,
|
|
];
|
|
|
|
if ($id > 0) {
|
|
$assignments = [];
|
|
foreach (array_keys($values) as $column) {
|
|
$assignments[] = "$column = :$column";
|
|
}
|
|
|
|
$stmt = $pdo->prepare("UPDATE maint_interventions SET " . implode(', ', $assignments) . " WHERE id = :id");
|
|
$stmt->execute($values + ['id' => $id]);
|
|
|
|
$interventionId = $id;
|
|
$action = 'intervention_updated';
|
|
} else {
|
|
$values['maintenance_id'] = $maintenanceId;
|
|
$values['equipment_id'] = $equipmentId;
|
|
$values['created_by'] = $currentUserId;
|
|
|
|
$columns = array_keys($values);
|
|
$placeholders = array_map(fn($column) => ':' . $column, $columns);
|
|
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO maint_interventions (" . implode(', ', $columns) . ")
|
|
VALUES (" . implode(', ', $placeholders) . ")"
|
|
);
|
|
$stmt->execute($values);
|
|
|
|
$interventionId = (int)$pdo->lastInsertId();
|
|
$action = 'intervention_created';
|
|
}
|
|
|
|
// Only completed interventions move the next due date; this call handles it
|
|
mnt_recalc_maintenance($pdo, $maintenanceId);
|
|
|
|
mnt_log($pdo, $action, $equipmentId, $maintenanceId, $interventionId, $currentUserId, $values);
|
|
|
|
$stmt = $pdo->prepare("SELECT last_done_date, next_due_date FROM maint_maintenances WHERE id = ?");
|
|
$stmt->execute([$maintenanceId]);
|
|
$schedule = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
|
|
|
|
mnt_json_ok(['id' => $interventionId, 'schedule' => $schedule]);
|
|
} catch (Throwable $e) {
|
|
mnt_json_fail('Errore: ' . $e->getMessage());
|
|
}
|