Files
zibo-dashboard/public/userarea/manutenzioni/include/maintenance_modal.php
T
2026-08-12 21:29:55 +03:00

260 lines
14 KiB
PHP

<?php
/**
* Create/edit modal for a maintenance.
* Expects $formData in scope. Defines mntOpenMaintenanceModal(data, equipmentId).
*/
?>
<div class="modal fade" id="maintenanceModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered modal-fullscreen-sm-down">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="maintenanceModalTitle">Nuova manutenzione</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Chiudi"></button>
</div>
<form id="maintenanceForm">
<div class="modal-body">
<input type="hidden" name="id" id="mtId" value="">
<input type="hidden" name="equipment_id" id="mtEquipmentId" value="">
<div class="row g-3">
<div class="col-4 col-md-2">
<label class="form-label fw-semibold">Codice</label>
<input type="text" class="form-control" name="code" id="mtCode" maxlength="10" placeholder="A">
</div>
<div class="col-8 col-md-10">
<label class="form-label fw-semibold">Titolo <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="title" id="mtTitle" maxlength="500" required>
</div>
<div class="col-12">
<label class="form-label fw-semibold">Descrizione dell'intervento</label>
<textarea class="form-control" name="description" id="mtDescription" rows="3"></textarea>
</div>
<div class="col-12 col-md-6">
<label class="form-label fw-semibold">Tipo</label>
<select class="form-select" name="intervention_type" id="mtType">
<?php foreach (mnt_intervention_types() as $value => $label): ?>
<option value="<?= mnt_h($value) ?>"><?= mnt_h($label) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12 col-md-6">
<label class="form-label fw-semibold">Esecuzione</label>
<select class="form-select" name="execution_type" id="mtExecution">
<?php foreach (mnt_execution_types() as $value => $label): ?>
<option value="<?= mnt_h($value) ?>"><?= mnt_h($label) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12" id="mtSupplierWrap" style="display:none">
<label class="form-label fw-semibold">Fornitore esterno <span class="text-danger">*</span></label>
<select class="form-select" name="supplier_id" id="mtSupplier">
<option value="">— seleziona —</option>
<?php foreach ($formData['suppliers'] as $supplier): ?>
<option value="<?= (int)$supplier['id'] ?>"><?= mnt_h($supplier['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12">
<div class="mnt-section-title mb-0 mt-2">Frequenza</div>
</div>
<div class="col-6 col-md-3">
<label class="form-label fw-semibold">Ogni</label>
<input type="number" class="form-control" name="frequency_value" id="mtFrequencyValue" min="1" max="999" value="1">
</div>
<div class="col-6 col-md-5">
<label class="form-label fw-semibold">Unità</label>
<select class="form-select" name="frequency_unit" id="mtFrequencyUnit">
<?php foreach (mnt_frequency_units() as $value => $label): ?>
<option value="<?= mnt_h($value) ?>" <?= $value === 'month' ? 'selected' : '' ?>><?= mnt_h($label) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12 col-md-4">
<label class="form-label fw-semibold">Preavviso (giorni)</label>
<input type="number" class="form-control" name="alert_days" id="mtAlertDays" min="0" max="365" value="7">
</div>
<div class="col-12">
<label class="form-label fw-semibold">Nota sulla frequenza</label>
<input type="text" class="form-control" name="frequency_note" id="mtFrequencyNote" maxlength="500"
placeholder="Es. prima dell'accensione, d'estate settimanale, dopo lo spegnimento">
<div class="form-text">Per i casi che non rientrano in un intervallo fisso.</div>
</div>
<div class="col-12 col-md-6">
<label class="form-label fw-semibold">Incaricato</label>
<select class="form-select" name="assignee_employee_id" id="mtAssignee">
<option value="">—</option>
<?php foreach ($formData['employees'] as $employee): ?>
<option value="<?= (int)$employee['id'] ?>"><?= mnt_h($employee['full_name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12 col-md-6">
<label class="form-label fw-semibold">Responsabile</label>
<select class="form-select" name="supervisor_employee_id" id="mtSupervisor">
<option value="">—</option>
<?php foreach ($formData['employees'] as $employee): ?>
<option value="<?= (int)$employee['id'] ?>"><?= mnt_h($employee['full_name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12">
<label class="form-label fw-semibold">Note</label>
<textarea class="form-control" name="notes" id="mtNotes" rows="2"></textarea>
</div>
<div class="col-12 d-flex flex-wrap gap-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="is_critical" id="mtCritical" value="1">
<label class="form-check-label fw-semibold" for="mtCritical">Manutenzione critica</label>
</div>
<div class="form-check">
<!-- Una checkbox non spuntata non viene inviata: senza questo campo
nascosto (che deve precederla) l'endpoint riceverebbe sempre
"attiva" e la manutenzione non si potrebbe mai disattivare. -->
<input type="hidden" name="is_active" value="0">
<input class="form-check-input" type="checkbox" name="is_active" id="mtActive" value="1" checked>
<label class="form-check-label fw-semibold" for="mtActive">Attiva</label>
</div>
</div>
<div class="col-12" id="mtFilesWrap">
<div class="mnt-section-title mt-2">Istruzioni allegate</div>
<div id="mtFilesList" class="mb-2"></div>
<input type="file" class="form-control" id="mtFilesInput" multiple>
<div class="form-text">I file vengono caricati dopo il salvataggio.</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Annulla</button>
<button type="submit" class="btn btn-mnt-primary">Salva</button>
</div>
</form>
</div>
</div>
</div>
<script>
function mntSyncMaintenanceForm() {
const isExternal = $('#mtExecution').val() === 'external';
$('#mtSupplierWrap').toggle(isExternal);
const onDemand = $('#mtFrequencyUnit').val() === 'on_demand';
$('#mtFrequencyValue').prop('disabled', onDemand).closest('.col-6').toggle(!onDemand);
$('#mtAlertDays').prop('disabled', onDemand);
}
function mntRenderMaintenanceFiles(files) {
const $list = $('#mtFilesList').empty();
if (!files || !files.length) { return; }
files.forEach(f => {
$list.append(
$('<div class="mnt-file-row"></div>').append(
$('<i class="fa-solid fa-paperclip text-muted"></i>'),
$('<a class="file-name" target="_blank"></a>')
.attr('href', 'manutenzioni/ajax/download_file.php?scope=maintenance&id=' + f.id)
.text(f.original_name),
$('<button type="button" class="btn-action btn-action-delete btn-del-file"><i class="fa-solid fa-trash"></i></button>')
.attr('data-id', f.id)
)
);
});
}
function mntOpenMaintenanceModal(data, equipmentId) {
const isEdit = !!data;
$('#maintenanceModalTitle').text(isEdit ? 'Modifica manutenzione' : 'Nuova manutenzione');
$('#mtId').val(isEdit ? data.id : '');
$('#mtEquipmentId').val(isEdit ? data.equipment_id : (equipmentId || ''));
$('#mtCode').val(isEdit ? (data.code || '') : '');
$('#mtTitle').val(isEdit ? (data.title || '') : '');
$('#mtDescription').val(isEdit ? (data.description || '') : '');
$('#mtType').val(isEdit ? data.intervention_type : 'scheduled');
$('#mtExecution').val(isEdit ? data.execution_type : 'internal');
$('#mtSupplier').val(isEdit && data.supplier_id ? String(data.supplier_id) : '');
$('#mtFrequencyValue').val(isEdit && data.frequency_value ? data.frequency_value : 1);
$('#mtFrequencyUnit').val(isEdit ? data.frequency_unit : 'month');
$('#mtFrequencyNote').val(isEdit ? (data.frequency_note || '') : '');
$('#mtAlertDays').val(isEdit ? data.alert_days : 7);
$('#mtAssignee').val(isEdit && data.assignee_employee_id ? String(data.assignee_employee_id) : '');
$('#mtSupervisor').val(isEdit && data.supervisor_employee_id ? String(data.supervisor_employee_id) : '');
$('#mtNotes').val(isEdit ? (data.notes || '') : '');
$('#mtCritical').prop('checked', isEdit ? Number(data.is_critical) === 1 : false);
$('#mtActive').prop('checked', isEdit ? Number(data.is_active) === 1 : true);
mntRenderMaintenanceFiles(isEdit ? (data.files || []) : []);
$('#mtFilesInput').val('');
mntSyncMaintenanceForm();
new bootstrap.Modal('#maintenanceModal').show();
}
$(function () {
$('#mtExecution, #mtFrequencyUnit').on('change', mntSyncMaintenanceForm);
$('#mtFilesList').on('click', '.btn-del-file', function () {
const $row = $(this).closest('.mnt-file-row');
$.post('manutenzioni/ajax/delete_file.php', { scope: 'maintenance', id: $(this).data('id') })
.done(res => {
if (res.success) { $row.remove(); }
else { Swal.fire({ icon: 'error', title: 'Errore', text: res.message }); }
});
});
$('#maintenanceForm').on('submit', function (e) {
e.preventDefault();
if (!$('#mtTitle').val().trim()) {
Swal.fire({ icon: 'warning', title: 'Il titolo è obbligatorio' });
return;
}
if ($('#mtExecution').val() === 'external' && !$('#mtSupplier').val()) {
Swal.fire({ icon: 'warning', title: 'Seleziona il fornitore esterno' });
return;
}
// Disabled inputs are not serialised — send the unit explicitly
const payload = $(this).serializeArray();
payload.push({ name: 'frequency_unit', value: $('#mtFrequencyUnit').val() });
$.post('manutenzioni/ajax/save_maintenance.php', $.param(payload))
.done(res => {
if (!res.success) {
Swal.fire({ icon: 'error', title: 'Errore', text: res.message });
return;
}
const input = document.getElementById('mtFilesInput');
if (!input.files.length) { location.reload(); return; }
const form = new FormData();
form.append('scope', 'maintenance');
form.append('owner_id', res.id);
Array.from(input.files).forEach(f => form.append('files[]', f));
$.ajax({
url: 'manutenzioni/ajax/upload_file.php',
method: 'POST', data: form, processData: false, contentType: false, dataType: 'json'
}).always(() => location.reload());
})
.fail(() => Swal.fire({ icon: 'error', title: 'Errore di rete' }));
});
});
</script>