feat: already_done checkbox in schedule modal; fix: capacity check skips ended slots; feat: ha_poll_interval configurable
Deploy via Portainer / deploy (push) Successful in 0s
Deploy via Portainer / deploy (push) Successful in 0s
This commit is contained in:
@@ -1799,6 +1799,14 @@ def api_new_slot():
|
||||
if over:
|
||||
conn.close()
|
||||
return jsonify({'error': f"Capacité maximale atteinte : {peak} impression(s) déjà en cours sur ce créneau (limite : {max_printers} simultanées). Décalez l'horaire ou attendez qu'une imprimante se libère."}), 409
|
||||
already_done = bool(d.get('already_done', False))
|
||||
if already_done:
|
||||
# Retroactive — skip capacity/overlap checks, insert as done
|
||||
conn.execute(
|
||||
'INSERT INTO print_slots(job_id,printer_id,planned_start,planned_end,status) VALUES(?,?,?,?,?)',
|
||||
(job_id, printer_id, start_dt.isoformat(), end_dt.isoformat(), 'done'))
|
||||
conn.commit(); conn.close()
|
||||
return jsonify({'ok': True})
|
||||
conn.execute('INSERT INTO print_slots(job_id,printer_id,planned_start,planned_end,status) VALUES(?,?,?,?,?)',
|
||||
(job_id, printer_id, start_dt.isoformat(), end_dt.isoformat(), 'planned'))
|
||||
conn.commit(); conn.close()
|
||||
|
||||
+38
-5
@@ -148,6 +148,15 @@
|
||||
<label class="form-label fw-semibold">Date et heure de lancement</label>
|
||||
<input type="datetime-local" id="modalStart" class="form-control">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="modalAlreadyDone" onchange="onAlreadyDoneChange()">
|
||||
<label class="form-check-label fw-semibold text-success" for="modalAlreadyDone">
|
||||
<i class="bi bi-check-circle-fill me-1"></i>Déjà imprimé
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-text ms-4">Enregistre le plateau comme terminé sans passer par le planning actif.</div>
|
||||
</div>
|
||||
<div id="modalSuggestion" class="alert alert-success py-2 small d-none">
|
||||
<i class="bi bi-magic me-1"></i><span id="modalSuggestionText"></span>
|
||||
</div>
|
||||
@@ -157,7 +166,7 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Annuler</button>
|
||||
<button type="button" class="btn fw-bold" style="background:#ff6b35;color:#fff" onclick="saveSlot()">
|
||||
<button type="button" id="modalSaveBtn" class="btn fw-bold" style="background:#ff6b35;color:#fff" onclick="saveSlot()">
|
||||
<i class="bi bi-save me-1"></i>Planifier
|
||||
</button>
|
||||
</div>
|
||||
@@ -525,11 +534,33 @@ function formatDt(iso) {
|
||||
d.toLocaleTimeString('fr-FR',{hour:'2-digit',minute:'2-digit'});
|
||||
}
|
||||
|
||||
function onAlreadyDoneChange() {
|
||||
const done = document.getElementById('modalAlreadyDone').checked;
|
||||
const btn = document.getElementById('modalSaveBtn');
|
||||
if (done) {
|
||||
btn.innerHTML = '<i class="bi bi-check-circle me-1"></i>Enregistrer comme terminé';
|
||||
btn.style.background = '#22c55e';
|
||||
// Reset to "now" so user picks when it was done
|
||||
const now = new Date();
|
||||
now.setMinutes(0, 0, 0);
|
||||
document.getElementById('modalStart').value = now.toISOString().slice(0,16);
|
||||
document.getElementById('modalSuggestion').classList.add('d-none');
|
||||
document.getElementById('modalError').classList.add('d-none');
|
||||
} else {
|
||||
btn.innerHTML = '<i class="bi bi-save me-1"></i>Planifier';
|
||||
btn.style.background = '#ff6b35';
|
||||
}
|
||||
}
|
||||
|
||||
function openScheduleModal(jobId, printTime, jobName) {
|
||||
document.getElementById('modalJobId').value = jobId;
|
||||
document.getElementById('modalPrintTime').value = printTime;
|
||||
document.getElementById('modalJobName').textContent = jobName;
|
||||
document.getElementById('modalSuggestion').classList.add('d-none');
|
||||
document.getElementById('modalError').classList.add('d-none');
|
||||
// Reset already-done checkbox
|
||||
document.getElementById('modalAlreadyDone').checked = false;
|
||||
onAlreadyDoneChange();
|
||||
// Default: now rounded to next hour
|
||||
const now = new Date();
|
||||
now.setMinutes(0, 0, 0);
|
||||
@@ -559,15 +590,17 @@ async function suggestSlot(jobId, printTime, jobName) {
|
||||
}
|
||||
|
||||
async function saveSlot() {
|
||||
const jobId = parseInt(document.getElementById('modalJobId').value);
|
||||
const printer = parseInt(document.getElementById('modalPrinter').value);
|
||||
const start = document.getElementById('modalStart').value;
|
||||
const jobId = parseInt(document.getElementById('modalJobId').value);
|
||||
const printer = parseInt(document.getElementById('modalPrinter').value);
|
||||
const start = document.getElementById('modalStart').value;
|
||||
const alreadyDone = document.getElementById('modalAlreadyDone').checked;
|
||||
// Clear previous error
|
||||
document.getElementById('modalError').classList.add('d-none');
|
||||
const r = await fetch('/api/slots/new', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({job_id: jobId, printer_id: printer, planned_start: start})
|
||||
body: JSON.stringify({job_id: jobId, printer_id: printer, planned_start: start,
|
||||
already_done: alreadyDone})
|
||||
});
|
||||
const res = await r.json();
|
||||
if (res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user