feat(measure): il fuori tolleranza si autorizza, non si chiude

Il punto 5 c'era a meta': la schermata apriva il modale del capoturno e bloccava
l'avanzamento automatico, ma il modale si chiudeva con Annulla o con un click
sullo sfondo, la misura era gia' salvata, e `pendingAdvance` veniva impostato e
non letto da nessuno. Era una conferma, non uno sbarramento.

Ora l'autorizzazione finisce sulla misura: due colonne, chi ha autorizzato e
quando. Finche' una quota e' fuori tolleranza e nessuno l'ha autorizzata, il
server rifiuta la misura della quota successiva e la chiusura del ciclo. Non e'
la schermata a impedirlo: la schermata risparmia solo il viaggio.

Rimisurare la stessa quota resta possibile — il calibro scivola, il pezzo si
riposiziona — e una seconda lettura in tolleranza libera il blocco, perche' conta
l'ultima lettura di ogni quota. Quante volte si possa riprovare e' il punto 4, e
tutte le letture restano comunque a registro. Un warning non blocca: fuori dai
limiti di attenzione ma dentro la tolleranza e' dentro la tolleranza.

Ricaricare la pagina era il modo piu' semplice per scavalcare il vecchio gate.
Non lo e' piu': la schermata chiede al server, all'apertura, se una quota sta
aspettando, e si ritrova davanti lo stesso blocco.

Sparisce /validate-supervisor, che verificava le credenziali e buttava via la
risposta. Al suo posto un endpoint che le credenziali le usa per scrivere
l'approvazione dove serve. Il controllo del capoturno si sposta in auth_service,
accanto al resto delle credenziali: fermo linea, chiusura e fuori tolleranza
fanno la stessa domanda, e solo una delle tre riguarda la produzione.

Il file di statistica guadagna authorised_by e authorised_at: mostrava il
fallimento e non la decisione, che e' la meta' che un auditor chiede.

Migrazione 010: due colonne nullable sulle misure. Le righe esistenti restano
nulle — retrodatare un'autorizzazione mai avvenuta sarebbe inventarsi un record
di audit, e quelle produzioni sono chiuse da un pezzo.

Test: +18 (309). Coprono il rifiuto della quota successiva, la rimisura ammessa,
il rilascio del blocco con una lettura buona, il ciclo che non si chiude, il
capoturno registrato sulla misura, le credenziali sbagliate e chi capoturno non
e', il file di statistica, e il fatto che una produzione chiusa non blocchi la
successiva. Aggiunto uploads/statistics/ al gitignore: i test che chiudono una
produzione scrivevano nel repository.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-07-28 20:54:24 +00:00
parent 5aa3d595ad
commit e2aae88858
17 changed files with 1341 additions and 441 deletions
+41 -19
View File
@@ -397,31 +397,53 @@ def save_measurement():
# ---------------------------------------------------------------------------
# Route: Validate supervisor credentials (AJAX)
# Routes: Out-of-tolerance authorisation (point 5)
# ---------------------------------------------------------------------------
@measure_bp.route("/validate-supervisor", methods=["POST"])
@measure_bp.route("/api/measurements/pending-authorisation", methods=["GET"])
@login_required
@role_required("MeasurementTec")
def validate_supervisor():
"""Validate supervisor (capoturno) credentials for out-of-tolerance authorization."""
def api_pending_authorisation():
"""Proxy: the out-of-tolerance measurement holding this operator up, or null.
Asked when the measurement screen loads, so reloading the page finds the same
block the server enforces rather than a clean slate.
"""
params = {"version_id": request.args.get("version_id")}
run_id = request.args.get("production_run_id")
if run_id:
params["production_run_id"] = run_id
resp = api_client.get("/api/measurements/pending-authorisation", params=params)
if isinstance(resp, dict) and resp.get("error"):
return jsonify(resp), resp.get("status_code", 500)
return jsonify(resp), 200
@measure_bp.route("/api/measurements/<int:measurement_id>/authorise", methods=["POST"])
@login_required
@role_required("MeasurementTec")
def api_authorise_measurement(measurement_id: int):
"""Proxy: the capoturno lets an out-of-tolerance value stand.
The credentials go to the endpoint that records the approval on the
measurement. Checking them separately, as this used to, left the approval
written down nowhere and nothing depending on it.
"""
data = request.get_json(silent=True) or {}
username = data.get("username", "").strip()
password = data.get("password", "")
username = (data.get("supervisor_username") or "").strip()
password = data.get("supervisor_password") or ""
if not username or not password:
return jsonify({"error": True, "detail": _("Username e password richiesti")}), 400
return jsonify({
"error": True, "detail": _("Username e password richiesti"),
}), 400
resp = api_client.post("/api/auth/login", data={"username": username, "password": password})
if resp.get("error"):
return jsonify({"error": True, "detail": _("Credenziali non valide")}), 401
user = resp.get("user", {})
is_supervisor = "Supervisor" in (user.get("roles") or [])
if not (is_supervisor or user.get("is_admin")):
return jsonify({"error": True, "detail": _("Utente non autorizzato (richiesto capoturno)")}), 403
return jsonify({"authorized": True, "supervisor": user.get("display_name", username)}), 200
resp = api_client.post(
f"/api/measurements/{measurement_id}/authorise",
data={"supervisor_username": username, "supervisor_password": password},
)
if isinstance(resp, dict) and resp.get("error"):
return jsonify(resp), resp.get("status_code", 500)
return jsonify(resp), 200
# ---------------------------------------------------------------------------
@@ -493,6 +493,32 @@
</div>
</div>
{# ================================================================
QUOTA FUORI TOLLERANZA — nothing moves from here without the capoturno or a
new reading of this same quote. Kept on screen after the modal is dismissed,
because the block outlives the modal: the server refuses the next value.
================================================================ #}
<div x-show="blockedByTolerance"
x-transition
x-cloak
class="shrink-0 bg-red-50 dark:bg-red-900/30 border-t-2 border-red-500 px-4 py-2">
<div class="flex flex-wrap items-center justify-center gap-x-3 gap-y-1">
<svg class="w-5 h-5 text-red-600 shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"/>
</svg>
<span class="text-sm font-semibold text-red-900 dark:text-red-100">
{{ _('Quota fuori tolleranza') }}
</span>
<span class="text-xs text-red-800 dark:text-red-200">
{{ _('serve il capoturno, oppure una nuova misura della stessa quota') }}
</span>
<button @click="openSupervisorModal('out_of_tolerance')"
class="btn text-xs py-1 px-2.5 bg-red-600 hover:bg-red-700 text-white">
{{ _('Autorizza') }}
</button>
</div>
</div>
{# ================================================================
LINEA FERMA — the countdown is frozen, not merely hidden. Stated plainly
because a stopped line that looks like a running one is how a measurement
@@ -826,9 +852,13 @@
</div>
<div class="flex gap-2">
{# Out of tolerance, the way out of this modal is measuring the quote
again - not cancelling. Closing it changes nothing: the quote stays
blocked, and the banner behind says so. #}
<button @click="closeSupervisorModal()"
class="btn btn-secondary flex-1 text-sm">
{{ _('Annulla') }}
<span x-show="supervisorAction !== 'out_of_tolerance'">{{ _('Annulla') }}</span>
<span x-show="supervisorAction === 'out_of_tolerance'">{{ _('Rimisura la quota') }}</span>
</button>
<button @click="submitSupervisor()"
:disabled="!supervisorUsername || !supervisorPassword || supervisorValidating"
@@ -909,7 +939,10 @@ function taskExecute() {
supervisorPassword: '',
supervisorError: '',
supervisorValidating: false,
pendingAdvance: false,
/* The out-of-tolerance measurement waiting for the capoturno:
{ id, subtask_id }, or null. While it is set the operator stays on that
quote - the server refuses the next one anyway. */
pendingFail: null,
// ---- Value from numpad / caliper ----
currentValue: null,
@@ -994,11 +1027,40 @@ function taskExecute() {
},
// ---- Init ----
init() {
async init() {
this.subtasks.sort((a, b) => (a.order_index || 0) - (b.order_index || 0));
this.inputStartedAt = Date.now();
// Rejoin whatever production is already open at this station.
this.loadProductionRun();
await this.loadProductionRun();
await this.loadPendingAuthorisation();
},
/* Is a quote already waiting for the capoturno?
Reloading the page was the simplest way past the old gate. It is not one
now - the server refuses the next measurement either way - so the screen
picks the block back up as soon as it opens, on the quote it belongs to. */
async loadPendingAuthorisation() {
if (!this.isMeasureTask || !this.subtasks.length) return;
try {
const params = new URLSearchParams({ version_id: this.task.version_id });
if (this.productionRun) {
params.set('production_run_id', this.productionRun.id);
}
const resp = await fetch(
'{{ url_for("measure.api_pending_authorisation") }}?' + params.toString(),
);
if (!resp.ok) return;
const pending = await resp.json();
if (!pending || !pending.id) return;
this.pendingFail = { id: pending.id, subtask_id: pending.subtask_id };
const idx = this.subtasks.findIndex(s => s.id === pending.subtask_id);
if (idx !== -1) this.currentIndex = idx;
this.openSupervisorModal('out_of_tolerance');
} catch (e) {
// Offline: the banner is missing, but so is the ability to save anything.
}
},
// ---- Production run: read the state back from the server ----
@@ -1124,13 +1186,21 @@ function taskExecute() {
// Pause to show result feedback
await new Promise(r => setTimeout(r, 1000));
// Out-of-tolerance: block advancement, require supervisor
// Out of tolerance: nothing moves until the capoturno says so, or until
// this same quote is measured again and comes out inside tolerance.
if (pf === 'fail') {
this.pendingAdvance = true;
this.pendingFail = { id: result.id, subtask_id: this.currentSubtask.id };
this.openSupervisorModal('out_of_tolerance');
return;
}
// A second reading of the blocked quote, this time in tolerance: the quote
// is in tolerance now, so the block goes. Both readings stay on record -
// how many attempts are allowed is point 4's business, not this one's.
if (this.pendingFail && this.pendingFail.subtask_id === this.currentSubtask.id) {
this.pendingFail = null;
}
// Check if all done
if (this.completedCount >= this.totalSubtasks) {
// START run (production not yet started): don't block with the
@@ -1173,14 +1243,38 @@ function taskExecute() {
}
},
/* Out of tolerance and nobody has authorised it: the operator stays put.
This is the whole of point 5. The screen used to open a modal that could be
dismissed, and the measurement was already saved by then, so a value outside
tolerance could be left behind by clicking the backdrop. The server refuses
the next measurement now; these checks only spare the operator the trip. */
get blockedByTolerance() {
return this.pendingFail !== null;
},
/* Say why nothing is moving, and offer the way out. */
refuseWhileBlocked() {
// |tojson, not quotes: the Italian carries an apostrophe, and an apostrophe
// inside a single-quoted literal is how every Alpine binding on the page dies.
this.errorMessage = {{ _("Quota fuori tolleranza: serve l'autorizzazione del capoturno, oppure misurare di nuovo la quota")|tojson }};
this.openSupervisorModal('out_of_tolerance');
},
// ---- Navigation ----
goToSubtask(index) {
if (index >= 0 && index < this.totalSubtasks) {
this.currentIndex = index;
this.currentValue = null;
this.errorMessage = '';
this.inputStartedAt = Date.now();
if (index < 0 || index >= this.totalSubtasks) return;
// Moving to another quote is exactly what a blocked quote forbids; going
// back to the blocked one to measure it again is not.
if (this.blockedByTolerance
&& this.subtasks[index].id !== this.pendingFail.subtask_id) {
this.refuseWhileBlocked();
return;
}
this.currentIndex = index;
this.currentValue = null;
this.errorMessage = '';
this.inputStartedAt = Date.now();
},
goToSubtaskByMarker(markerNumber) {
@@ -1195,6 +1289,12 @@ function taskExecute() {
it if it is the last. The server decides that - it knows the sequence - and
the cycle count coming back tells us which of the two happened. */
async confirmCycle() {
// Closing the cycle would be another way of walking past a quote that is out
// of tolerance. The server refuses it too.
if (this.blockedByTolerance) {
this.refuseWhileBlocked();
return;
}
this.cycleConfirmed = true;
this.showCompletionOverlay = false;
@@ -1441,6 +1541,10 @@ function taskExecute() {
documental tasks that come before the measurement, the plain sequence
applies - that is the run-up, not the loop. */
goToNextTask() {
if (this.blockedByTolerance) {
this.refuseWhileBlocked();
return;
}
if (this.productionStarted && this.isMeasurementTaskOfRun) {
const next = this.nextMeasurementTaskId || this.measurementTaskIds[0];
// A recipe with a single measurement task loops on the spot: reloading the
@@ -1511,47 +1615,57 @@ function taskExecute() {
/* Route the modal's confirm to what the action actually does. Fermo linea,
ripresa and fine produzione act on the production run; the out-of-tolerance
gate stays a pure credential check. */
one is recorded on the measurement itself. */
async submitSupervisor() {
if (this.supervisorAction === 'fermo_linea') return this.runSupervisedAction('pause');
if (this.supervisorAction === 'ripresa') return this.runSupervisedAction('resume');
if (this.supervisorAction === 'fine_produzione') return this.runSupervisedAction('close');
return this.validateSupervisor();
return this.authoriseOutOfTolerance();
},
// ---- Validate supervisor credentials ----
async validateSupervisor() {
/* The capoturno lets an out-of-tolerance value stand.
The credentials go to the endpoint that writes the approval onto that
measurement. It used to be a bare credential check whose answer was thrown
away: nothing recorded who had said yes, and nothing depended on it, so
closing the modal was enough to walk past a value out of tolerance. */
async authoriseOutOfTolerance() {
if (!this.pendingFail) {
this.closeSupervisorModal();
return;
}
this.supervisorError = '';
this.supervisorValidating = true;
try {
const csrfToken = document.querySelector('meta[name=csrf-token]')?.content || '';
const resp = await fetch('{{ url_for("measure.validate_supervisor") }}', {
const url = '{{ url_for("measure.api_authorise_measurement", measurement_id=0) }}'
.replace('/0/', '/' + this.pendingFail.id + '/');
const resp = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken },
body: JSON.stringify({ username: this.supervisorUsername, password: this.supervisorPassword })
body: JSON.stringify({
supervisor_username: this.supervisorUsername,
supervisor_password: this.supervisorPassword,
}),
});
const data = await resp.json();
const data = await resp.json().catch(() => null);
if (!resp.ok || data.error) {
this.supervisorError = data.detail || '{{ _("Credenziali non valide o utente non autorizzato") }}';
if (!resp.ok || (data && data.error)) {
this.supervisorError = (data && data.detail)
|| '{{ _("Credenziali non valide o utente non autorizzato") }}';
this.supervisorValidating = false;
return;
}
// Authorized — close modal and proceed
this.showSupervisorModal = false;
this.supervisorUsername = '';
this.supervisorPassword = '';
this.supervisorValidating = false;
this.closeSupervisorModal();
this.pendingFail = null;
if (this.supervisorAction === 'out_of_tolerance') {
this.pendingAdvance = false;
if (this.completedCount >= this.totalSubtasks) {
this.showCompletionOverlay = true;
} else {
this.advanceToNext();
}
if (this.completedCount >= this.totalSubtasks) {
this.showCompletionOverlay = true;
} else {
this.advanceToNext();
}
} catch (err) {
@@ -70,6 +70,66 @@ class TestTaskComplete:
assert b"productionClock(" in resp.data
class TestOutOfTolerance:
"""Proxies for point 5: the capoturno's answer has to reach the measurement."""
def test_authorise_forwards_the_credentials(self, logged_in_client, mock_api_client):
mock_api_client.post.return_value = {"id": 9, "supervisor_id": 4}
resp = logged_in_client.post(
"/measure/api/measurements/9/authorise",
json={"supervisor_username": "capo", "supervisor_password": "segreta"},
)
assert resp.status_code == 200
endpoint, kwargs = mock_api_client.post.call_args
assert endpoint[0] == "/api/measurements/9/authorise"
assert kwargs["data"]["supervisor_username"] == "capo"
def test_authorise_needs_credentials(self, logged_in_client, mock_api_client):
resp = logged_in_client.post(
"/measure/api/measurements/9/authorise", json={},
)
assert resp.status_code == 400
mock_api_client.post.assert_not_called()
def test_authorise_propagates_refusal(self, logged_in_client, mock_api_client):
"""A operator who is not a supervisor must not authorise their own value."""
mock_api_client.post.return_value = {
"error": True, "status_code": 403, "detail": "not a supervisor",
}
resp = logged_in_client.post(
"/measure/api/measurements/9/authorise",
json={"supervisor_username": "tec", "supervisor_password": "x"},
)
assert resp.status_code == 403
def test_pending_passes_the_scope(self, logged_in_client, mock_api_client):
mock_api_client.get.return_value = {"id": 9, "subtask_id": 21}
resp = logged_in_client.get(
"/measure/api/measurements/pending-authorisation"
"?version_id=5&production_run_id=7",
)
assert resp.status_code == 200
assert resp.get_json()["id"] == 9
endpoint, kwargs = mock_api_client.get.call_args
assert endpoint[0] == "/api/measurements/pending-authorisation"
assert kwargs["params"] == {"version_id": "5", "production_run_id": "7"}
def test_pending_without_a_run_omits_it(self, logged_in_client, mock_api_client):
mock_api_client.get.return_value = None
logged_in_client.get(
"/measure/api/measurements/pending-authorisation?version_id=5",
)
assert mock_api_client.get.call_args[1]["params"] == {"version_id": "5"}
def test_routes_require_login(self, client):
for method, url in (
("get", "/measure/api/measurements/pending-authorisation?version_id=5"),
("post", "/measure/api/measurements/9/authorise"),
):
resp = getattr(client, method)(url)
assert resp.status_code in (302, 401), f"{method} {url}"
class TestSaveMeasurement:
"""POST /measure/save-measurement tests."""
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: TieMeasureFlow 1.0\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-07-28 20:16+0000\n"
"POT-Creation-Date: 2026-07-28 20:48+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
@@ -37,7 +37,7 @@ msgstr "Please log in to continue"
msgid "Inserisci username e password"
msgstr "Enter username and password"
#: blueprints/auth.py:81 blueprints/measure.py:417
#: blueprints/auth.py:81
msgid "Credenziali non valide"
msgstr "Invalid credentials"
@@ -161,15 +161,11 @@ msgstr "Missing data: subtask_id, version_id and value are required"
msgid "Errore nel salvataggio"
msgstr "Error saving"
#: blueprints/measure.py:412 blueprints/measure.py:520
#: blueprints/measure.py:437 blueprints/measure.py:542
msgid "Username e password richiesti"
msgstr "Username and password required"
#: blueprints/measure.py:422
msgid "Utente non autorizzato (richiesto capoturno)"
msgstr "User not authorized (shift supervisor required)"
#: blueprints/measure.py:441 blueprints/measure.py:458
#: blueprints/measure.py:463 blueprints/measure.py:480
#: templates/errors/station_not_configured.html:2
#: templates/errors/station_not_configured.html:16
msgid "Stazione non configurata"
@@ -376,7 +372,7 @@ msgstr "Optional notes"
#: templates/maker/task_editor.html:782 templates/maker/task_editor.html:901
#: templates/maker/task_editor.html:966 templates/maker/task_editor.html:1071
#: templates/measure/select_recipe.html:405
#: templates/measure/task_execute.html:831
#: templates/measure/task_execute.html:860
msgid "Annulla"
msgstr "Cancel"
@@ -521,7 +517,7 @@ msgstr "New User"
#: templates/admin/users.html:48 templates/admin/users.html:173
#: templates/admin/users.html:179 templates/auth/login.html:35
#: templates/auth/login.html:49 templates/auth/profile.html:36
#: templates/measure/task_execute.html:816
#: templates/measure/task_execute.html:842
msgid "Username"
msgstr "Username"
@@ -573,7 +569,7 @@ msgstr "Username cannot be changed"
#: templates/admin/users.html:206 templates/admin/users.html:214
#: templates/auth/login.html:57 templates/auth/login.html:71
#: templates/measure/task_execute.html:821
#: templates/measure/task_execute.html:847
msgid "Password"
msgstr "Password"
@@ -835,7 +831,7 @@ msgstr "Next measurement in"
#: templates/components/production_clock.html:49
#: templates/components/production_clock.html:62
#: templates/measure/task_execute.html:463
#: templates/measure/task_execute.html:516
#: templates/measure/task_execute.html:542
msgid "Misurazione in ritardo di"
msgstr "Measurement overdue by"
@@ -844,7 +840,7 @@ msgid "Linea ferma — conto alla rovescia congelato a"
msgstr "Line stopped — countdown frozen at"
#: templates/components/production_clock.html:62
#: templates/measure/task_execute.html:510
#: templates/measure/task_execute.html:536
msgid "Linea ferma"
msgstr "Line stopped"
@@ -854,17 +850,17 @@ msgid "Ciclo"
msgstr "Cycle"
#: templates/components/production_clock.html:92
#: templates/measure/task_execute.html:678
#: templates/measure/task_execute.html:704
msgid "È ora di misurare"
msgstr "Time to measure"
#: templates/components/production_clock.html:95
#: templates/measure/task_execute.html:680
#: templates/measure/task_execute.html:706
msgid "Ritorno alla misurazione tra"
msgstr "Returning to the measurement in"
#: templates/components/production_clock.html:101
#: templates/measure/task_execute.html:685
#: templates/measure/task_execute.html:711
msgid "Vai alla misura"
msgstr "Go to the measurement"
@@ -917,8 +913,8 @@ msgstr "Preview"
#: templates/maker/recipe_editor.html:128 templates/maker/recipe_list.html:246
#: templates/maker/task_drawing.html:106 templates/maker/task_editor.html:130
#: templates/measure/task_complete.html:171
#: templates/measure/task_execute.html:589 templates/measure/task_list.html:2
#: templates/measure/task_list.html:159
#: templates/measure/task_execute.html:615 templates/measure/task_list.html:2
#: templates/measure/task_list.html:180
msgid "Task"
msgstr "Task"
@@ -1094,8 +1090,8 @@ msgstr "Error during deletion"
# Recipe Selection Additional
#: templates/maker/recipe_list.html:55 templates/measure/select_recipe.html:72
#: templates/measure/task_execute.html:1262
#: templates/measure/task_execute.html:1558
#: templates/measure/task_execute.html:1362
#: templates/measure/task_execute.html:1672
msgid "Errore di connessione"
msgstr "Connection Error"
@@ -1406,18 +1402,18 @@ msgid "Tipo"
msgstr "Type"
#: templates/maker/task_editor.html:277 templates/maker/task_editor.html:543
#: templates/measure/task_list.html:177
#: templates/measure/task_list.html:198
msgid "Nota"
msgstr "Note"
#: templates/maker/task_editor.html:278 templates/maker/task_editor.html:544
#: templates/measure/task_execute.html:309 templates/measure/task_list.html:175
#: templates/measure/task_execute.html:309 templates/measure/task_list.html:196
msgid "Misura"
msgstr "Measure"
# Maker - Task Editor
#: templates/maker/task_editor.html:279 templates/maker/task_editor.html:545
#: templates/measure/task_list.html:176
#: templates/measure/task_list.html:197
msgid "Disegno"
msgstr "Drawing"
@@ -1448,7 +1444,7 @@ msgstr "Drag to reorder"
#: templates/maker/task_editor.html:390
#: templates/maker/version_history.html:188
#: templates/measure/task_list.html:192
#: templates/measure/task_list.html:213
msgid "misurazioni"
msgstr "measurements"
@@ -1714,7 +1710,7 @@ msgid "Misurazione aggiunta"
msgstr "Measurement added"
#: templates/maker/task_editor.html:1685
#: templates/measure/task_execute.html:1108
#: templates/measure/task_execute.html:1170
msgid "Errore nel salvataggio della misurazione"
msgstr "Error saving measurement"
@@ -1782,16 +1778,16 @@ msgid "Seleziona Ricetta"
msgstr "Select Recipe"
# Measure - Task List
#: templates/measure/select_recipe.html:30
#: templates/measure/select_recipe.html:30 templates/measure/task_list.html:86
msgid "lotto"
msgstr "lot"
#: templates/measure/select_recipe.html:31
#: templates/measure/select_recipe.html:31 templates/measure/task_list.html:87
msgid "seriale"
msgstr "serial"
#: templates/measure/select_recipe.html:64
#: templates/measure/select_recipe.html:277
#: templates/measure/select_recipe.html:277 templates/measure/task_list.html:97
msgid "Compila prima:"
msgstr "Fill in first:"
@@ -1886,25 +1882,26 @@ msgstr "Search"
#: templates/measure/task_complete.html:3
#: templates/measure/task_complete.html:39
#: templates/measure/task_execute.html:113
#: templates/measure/task_execute.html:739
#: templates/measure/task_execute.html:765
#: templates/statistics/dashboard.html:139
msgid "Riepilogo"
msgstr "Summary"
#: templates/measure/task_complete.html:47
#: templates/measure/task_execute.html:716
#: templates/measure/task_execute.html:742
msgid "Misurazioni Complete"
msgstr "Measurements Complete"
# Measure - Task List
#: templates/measure/task_complete.html:64
#: templates/measure/task_complete.html:296 templates/measure/task_list.html:97
#: templates/measure/task_complete.html:296
#: templates/measure/task_list.html:118
msgid "Lotto"
msgstr "Lot"
#: templates/measure/task_complete.html:70
#: templates/measure/task_complete.html:297
#: templates/measure/task_list.html:109
#: templates/measure/task_list.html:130
msgid "Seriale"
msgstr "Serial"
@@ -1913,12 +1910,12 @@ msgid "Totale"
msgstr "Total"
#: templates/measure/task_complete.html:106
#: templates/measure/task_execute.html:724
#: templates/measure/task_execute.html:750
msgid "Conformi"
msgstr "Pass"
#: templates/measure/task_complete.html:123
#: templates/measure/task_execute.html:728
#: templates/measure/task_execute.html:754
msgid "Attenzione"
msgstr "Warning"
@@ -2114,153 +2111,172 @@ msgstr "Recorded"
msgid "Task di misura senza quote configurate: la ricetta è incompleta"
msgstr "Measurement task with no quotes configured: the recipe is incomplete"
#: templates/measure/task_execute.html:515
msgid "Il conto alla rovescia è congelato a"
msgstr "The countdown is frozen at"
#: templates/measure/task_execute.html:510
msgid "Quota fuori tolleranza"
msgstr "Measurement out of tolerance"
#: templates/measure/task_execute.html:518
msgid "serve il capoturno per riprendere"
msgstr "the supervisor must authorise the restart"
#: templates/measure/task_execute.html:513
msgid "serve il capoturno, oppure una nuova misura della stessa quota"
msgstr "the supervisor must authorise it, or the same quote must be measured again"
#: templates/measure/task_execute.html:537
msgid "Produzione non registrata sul server"
msgstr "Production not recorded on the server"
#: templates/measure/task_execute.html:558
#: templates/measure/task_execute.html:767
msgid "Avvio Produzione"
msgstr "Production Start"
#: templates/measure/task_execute.html:562
msgid "Invia segnale al gestionale per avviare il timer della linea"
msgstr "Send a signal to the ERP system to start the line timer"
#: templates/measure/task_execute.html:573
msgid "Produzione avviata"
msgstr "Production started"
#: templates/measure/task_execute.html:618
msgid "Fine ciclo misura"
msgstr "Measurement cycle complete"
#: templates/measure/task_execute.html:629
msgid "Rimisura"
msgstr "Measure again"
#: templates/measure/task_execute.html:639
#: templates/measure/task_execute.html:653
msgid "Completato"
msgstr "Completed"
#: templates/measure/task_execute.html:718
msgid "Tutte le"
msgstr "All"
#: templates/measure/task_execute.html:718
msgid "misurazioni sono state registrate."
msgstr "measurements have been recorded."
#: templates/measure/task_execute.html:732
msgid "Non Conf."
msgstr "Fail"
#: templates/measure/task_execute.html:747
msgid "Conferma ciclo"
msgstr "Confirm cycle"
#: templates/measure/task_execute.html:757
msgid "Task successivo"
msgstr "Next task"
#: templates/measure/task_execute.html:783
msgid "Girare il pezzo e rimisurare"
msgstr "Turn the piece over and measure again"
#: templates/measure/task_execute.html:809
msgid "Autorizzazione capoturno"
msgstr "Shift supervisor authorization"
#: templates/measure/task_execute.html:818
msgid "Username capoturno"
msgstr "Supervisor username"
#: templates/measure/task_execute.html:840
#: templates/measure/task_execute.html:517
#: templates/measure/task_execute.html:870
msgid "Autorizza"
msgstr "Authorize"
#: templates/measure/task_execute.html:1063
#: templates/measure/task_execute.html:541
msgid "Il conto alla rovescia è congelato a"
msgstr "The countdown is frozen at"
#: templates/measure/task_execute.html:544
msgid "serve il capoturno per riprendere"
msgstr "the supervisor must authorise the restart"
#: templates/measure/task_execute.html:563
msgid "Produzione non registrata sul server"
msgstr "Production not recorded on the server"
#: templates/measure/task_execute.html:584
#: templates/measure/task_execute.html:793
msgid "Avvio Produzione"
msgstr "Production Start"
#: templates/measure/task_execute.html:588
msgid "Invia segnale al gestionale per avviare il timer della linea"
msgstr "Send a signal to the ERP system to start the line timer"
#: templates/measure/task_execute.html:599
msgid "Produzione avviata"
msgstr "Production started"
#: templates/measure/task_execute.html:644
msgid "Fine ciclo misura"
msgstr "Measurement cycle complete"
#: templates/measure/task_execute.html:655
msgid "Rimisura"
msgstr "Measure again"
#: templates/measure/task_execute.html:665
#: templates/measure/task_execute.html:679
msgid "Completato"
msgstr "Completed"
#: templates/measure/task_execute.html:744
msgid "Tutte le"
msgstr "All"
#: templates/measure/task_execute.html:744
msgid "misurazioni sono state registrate."
msgstr "measurements have been recorded."
#: templates/measure/task_execute.html:758
msgid "Non Conf."
msgstr "Fail"
#: templates/measure/task_execute.html:773
msgid "Conferma ciclo"
msgstr "Confirm cycle"
#: templates/measure/task_execute.html:783
msgid "Task successivo"
msgstr "Next task"
#: templates/measure/task_execute.html:809
msgid "Girare il pezzo e rimisurare"
msgstr "Turn the piece over and measure again"
#: templates/measure/task_execute.html:835
msgid "Autorizzazione capoturno"
msgstr "Shift supervisor authorization"
#: templates/measure/task_execute.html:844
msgid "Username capoturno"
msgstr "Supervisor username"
#: templates/measure/task_execute.html:861
msgid "Rimisura la quota"
msgstr "Measure this quote again"
#: templates/measure/task_execute.html:1125
msgid "Questa ricetta non ammette valori digitati: usare il calibro"
msgstr "This recipe does not accept typed values: use the caliper"
#: templates/measure/task_execute.html:1152
#: templates/measure/task_execute.html:1222
msgid "Errore di rete. Riprovare."
msgstr "Network error. Please retry."
#: templates/measure/task_execute.html:1257
#: templates/measure/task_execute.html:1260
msgid ""
"Quota fuori tolleranza: serve l'autorizzazione del capoturno, oppure "
"misurare di nuovo la quota"
msgstr "Out of tolerance: the supervisor must authorise it, or the quote must be measured again"
#: templates/measure/task_execute.html:1357
msgid "Errore di comunicazione con il server"
msgstr "Error communicating with the server"
#: templates/measure/task_execute.html:1505
#: templates/measure/task_execute.html:1609
msgid "Misurazione fuori tolleranza"
msgstr "Measurement out of tolerance"
#: templates/measure/task_execute.html:1506
#: templates/measure/task_execute.html:1610
msgid "Fermo linea richiesto"
msgstr "Line stop requested"
#: templates/measure/task_execute.html:1507
#: templates/measure/task_execute.html:1611
msgid "Ripresa della produzione"
msgstr "Resuming production"
#: templates/measure/task_execute.html:1508
#: templates/measure/task_execute.html:1612
msgid "Fine produzione richiesta"
msgstr "End of production requested"
#: templates/measure/task_execute.html:1537
#: templates/measure/task_execute.html:1656
msgid "Credenziali non valide o utente non autorizzato"
msgstr "Invalid credentials or unauthorized user"
#: templates/measure/task_execute.html:1569
#: templates/measure/task_execute.html:1683
msgid "Nessuna produzione aperta su questa stazione"
msgstr "No production open at this station"
#: templates/measure/task_execute.html:1586
#: templates/measure/task_execute.html:1700
msgid "Azione non riuscita"
msgstr "Action failed"
#: templates/measure/task_list.html:87
#: templates/measure/task_list.html:107
msgid "AVVIA"
msgstr "START"
#: templates/measure/task_list.html:124
#: templates/measure/task_list.html:145
msgid "Task da eseguire"
msgstr "Tasks to execute"
#: templates/measure/task_list.html:136
#: templates/measure/task_list.html:157
msgid "misurazioni totali"
msgstr "total measurements"
#: templates/measure/task_list.html:178
#: templates/measure/task_list.html:199
msgid "Confronto profilo"
msgstr "Profile comparison"
#: templates/measure/task_list.html:179
#: templates/measure/task_list.html:200
msgid "Misura camera"
msgstr "Camera measurement"
#: templates/measure/task_list.html:201
#: templates/measure/task_list.html:222
msgid "Allegato"
msgstr "Attachment"
#: templates/measure/task_list.html:225
#: templates/measure/task_list.html:246
msgid "Visualizza Task"
msgstr "View Tasks"
#: templates/measure/task_list.html:248
#: templates/measure/task_list.html:269
msgid "Nessun task disponibile"
msgstr "No tasks available"
#: templates/measure/task_list.html:251
#: templates/measure/task_list.html:272
msgid "Questa ricetta non ha ancora task definiti."
msgstr "This recipe has no tasks defined yet."
@@ -2681,3 +2697,6 @@ msgstr "Error generating report"
#~ msgid "Inizia Misure"
#~ msgstr "Start Measurements"
#~ msgid "Utente non autorizzato (richiesto capoturno)"
#~ msgstr "User not authorized (shift supervisor required)"
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: TieMeasureFlow 1.0\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-07-28 20:16+0000\n"
"POT-Creation-Date: 2026-07-28 20:48+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: it\n"
@@ -37,7 +37,7 @@ msgstr "Effettua il login per continuare"
msgid "Inserisci username e password"
msgstr "Inserisci username e password"
#: blueprints/auth.py:81 blueprints/measure.py:417
#: blueprints/auth.py:81
msgid "Credenziali non valide"
msgstr "Credenziali non valide"
@@ -161,15 +161,11 @@ msgstr "Dati mancanti: subtask_id, version_id e value sono obbligatori"
msgid "Errore nel salvataggio"
msgstr "Errore nel salvataggio"
#: blueprints/measure.py:412 blueprints/measure.py:520
#: blueprints/measure.py:437 blueprints/measure.py:542
msgid "Username e password richiesti"
msgstr "Username e password richiesti"
#: blueprints/measure.py:422
msgid "Utente non autorizzato (richiesto capoturno)"
msgstr "Utente non autorizzato (richiesto capoturno)"
#: blueprints/measure.py:441 blueprints/measure.py:458
#: blueprints/measure.py:463 blueprints/measure.py:480
#: templates/errors/station_not_configured.html:2
#: templates/errors/station_not_configured.html:16
msgid "Stazione non configurata"
@@ -378,7 +374,7 @@ msgstr "Note opzionali"
#: templates/maker/task_editor.html:782 templates/maker/task_editor.html:901
#: templates/maker/task_editor.html:966 templates/maker/task_editor.html:1071
#: templates/measure/select_recipe.html:405
#: templates/measure/task_execute.html:831
#: templates/measure/task_execute.html:860
msgid "Annulla"
msgstr "Annulla"
@@ -523,7 +519,7 @@ msgstr "Nuovo Utente"
#: templates/admin/users.html:48 templates/admin/users.html:173
#: templates/admin/users.html:179 templates/auth/login.html:35
#: templates/auth/login.html:49 templates/auth/profile.html:36
#: templates/measure/task_execute.html:816
#: templates/measure/task_execute.html:842
msgid "Username"
msgstr "Username"
@@ -575,7 +571,7 @@ msgstr "Il nome utente non può essere modificato"
#: templates/admin/users.html:206 templates/admin/users.html:214
#: templates/auth/login.html:57 templates/auth/login.html:71
#: templates/measure/task_execute.html:821
#: templates/measure/task_execute.html:847
msgid "Password"
msgstr "Password"
@@ -837,7 +833,7 @@ msgstr "Prossima misurazione tra"
#: templates/components/production_clock.html:49
#: templates/components/production_clock.html:62
#: templates/measure/task_execute.html:463
#: templates/measure/task_execute.html:516
#: templates/measure/task_execute.html:542
msgid "Misurazione in ritardo di"
msgstr "Misurazione in ritardo di"
@@ -846,7 +842,7 @@ msgid "Linea ferma — conto alla rovescia congelato a"
msgstr "Linea ferma — conto alla rovescia congelato a"
#: templates/components/production_clock.html:62
#: templates/measure/task_execute.html:510
#: templates/measure/task_execute.html:536
msgid "Linea ferma"
msgstr "Linea ferma"
@@ -856,17 +852,17 @@ msgid "Ciclo"
msgstr "Ciclo"
#: templates/components/production_clock.html:92
#: templates/measure/task_execute.html:678
#: templates/measure/task_execute.html:704
msgid "È ora di misurare"
msgstr "È ora di misurare"
#: templates/components/production_clock.html:95
#: templates/measure/task_execute.html:680
#: templates/measure/task_execute.html:706
msgid "Ritorno alla misurazione tra"
msgstr "Ritorno alla misurazione tra"
#: templates/components/production_clock.html:101
#: templates/measure/task_execute.html:685
#: templates/measure/task_execute.html:711
msgid "Vai alla misura"
msgstr "Vai alla misura"
@@ -919,8 +915,8 @@ msgstr "Anteprima"
#: templates/maker/recipe_editor.html:128 templates/maker/recipe_list.html:246
#: templates/maker/task_drawing.html:106 templates/maker/task_editor.html:130
#: templates/measure/task_complete.html:171
#: templates/measure/task_execute.html:589 templates/measure/task_list.html:2
#: templates/measure/task_list.html:159
#: templates/measure/task_execute.html:615 templates/measure/task_list.html:2
#: templates/measure/task_list.html:180
msgid "Task"
msgstr "Task"
@@ -1096,8 +1092,8 @@ msgstr "Errore durante eliminazione"
# Recipe Selection Additional
#: templates/maker/recipe_list.html:55 templates/measure/select_recipe.html:72
#: templates/measure/task_execute.html:1262
#: templates/measure/task_execute.html:1558
#: templates/measure/task_execute.html:1362
#: templates/measure/task_execute.html:1672
msgid "Errore di connessione"
msgstr "Errore di connessione"
@@ -1408,18 +1404,18 @@ msgid "Tipo"
msgstr "Tipo"
#: templates/maker/task_editor.html:277 templates/maker/task_editor.html:543
#: templates/measure/task_list.html:177
#: templates/measure/task_list.html:198
msgid "Nota"
msgstr "Nota"
#: templates/maker/task_editor.html:278 templates/maker/task_editor.html:544
#: templates/measure/task_execute.html:309 templates/measure/task_list.html:175
#: templates/measure/task_execute.html:309 templates/measure/task_list.html:196
msgid "Misura"
msgstr "Misura"
# Maker - Task Editor
#: templates/maker/task_editor.html:279 templates/maker/task_editor.html:545
#: templates/measure/task_list.html:176
#: templates/measure/task_list.html:197
msgid "Disegno"
msgstr "Disegno"
@@ -1450,7 +1446,7 @@ msgstr "Trascina per riordinare"
#: templates/maker/task_editor.html:390
#: templates/maker/version_history.html:188
#: templates/measure/task_list.html:192
#: templates/measure/task_list.html:213
msgid "misurazioni"
msgstr "misurazioni"
@@ -1716,7 +1712,7 @@ msgid "Misurazione aggiunta"
msgstr "Misurazione aggiunta"
#: templates/maker/task_editor.html:1685
#: templates/measure/task_execute.html:1108
#: templates/measure/task_execute.html:1170
msgid "Errore nel salvataggio della misurazione"
msgstr "Errore nel salvataggio della misurazione"
@@ -1784,16 +1780,16 @@ msgid "Seleziona Ricetta"
msgstr "Seleziona Ricetta"
# Measure - Task List
#: templates/measure/select_recipe.html:30
#: templates/measure/select_recipe.html:30 templates/measure/task_list.html:86
msgid "lotto"
msgstr "lotto"
#: templates/measure/select_recipe.html:31
#: templates/measure/select_recipe.html:31 templates/measure/task_list.html:87
msgid "seriale"
msgstr "seriale"
#: templates/measure/select_recipe.html:64
#: templates/measure/select_recipe.html:277
#: templates/measure/select_recipe.html:277 templates/measure/task_list.html:97
msgid "Compila prima:"
msgstr "Compila prima:"
@@ -1890,25 +1886,26 @@ msgstr "Cerca"
#: templates/measure/task_complete.html:3
#: templates/measure/task_complete.html:39
#: templates/measure/task_execute.html:113
#: templates/measure/task_execute.html:739
#: templates/measure/task_execute.html:765
#: templates/statistics/dashboard.html:139
msgid "Riepilogo"
msgstr "Riepilogo"
#: templates/measure/task_complete.html:47
#: templates/measure/task_execute.html:716
#: templates/measure/task_execute.html:742
msgid "Misurazioni Complete"
msgstr "Misurazioni Complete"
# Measure - Task List
#: templates/measure/task_complete.html:64
#: templates/measure/task_complete.html:296 templates/measure/task_list.html:97
#: templates/measure/task_complete.html:296
#: templates/measure/task_list.html:118
msgid "Lotto"
msgstr "Lotto"
#: templates/measure/task_complete.html:70
#: templates/measure/task_complete.html:297
#: templates/measure/task_list.html:109
#: templates/measure/task_list.html:130
msgid "Seriale"
msgstr "Seriale"
@@ -1917,12 +1914,12 @@ msgid "Totale"
msgstr "Totale"
#: templates/measure/task_complete.html:106
#: templates/measure/task_execute.html:724
#: templates/measure/task_execute.html:750
msgid "Conformi"
msgstr "Conformi"
#: templates/measure/task_complete.html:123
#: templates/measure/task_execute.html:728
#: templates/measure/task_execute.html:754
msgid "Attenzione"
msgstr "Attenzione"
@@ -2118,153 +2115,172 @@ msgstr "Registrata"
msgid "Task di misura senza quote configurate: la ricetta è incompleta"
msgstr "Task di misura senza quote configurate: la ricetta è incompleta"
#: templates/measure/task_execute.html:515
msgid "Il conto alla rovescia è congelato a"
msgstr "Il conto alla rovescia è congelato a"
#: templates/measure/task_execute.html:510
msgid "Quota fuori tolleranza"
msgstr "Quota fuori tolleranza"
#: templates/measure/task_execute.html:518
msgid "serve il capoturno per riprendere"
msgstr "serve il capoturno per riprendere"
#: templates/measure/task_execute.html:513
msgid "serve il capoturno, oppure una nuova misura della stessa quota"
msgstr "serve il capoturno, oppure una nuova misura della stessa quota"
#: templates/measure/task_execute.html:537
msgid "Produzione non registrata sul server"
msgstr "Produzione non registrata sul server"
#: templates/measure/task_execute.html:558
#: templates/measure/task_execute.html:767
msgid "Avvio Produzione"
msgstr "Avvio Produzione"
#: templates/measure/task_execute.html:562
msgid "Invia segnale al gestionale per avviare il timer della linea"
msgstr "Invia segnale al gestionale per avviare il timer della linea"
#: templates/measure/task_execute.html:573
msgid "Produzione avviata"
msgstr "Produzione avviata"
#: templates/measure/task_execute.html:618
msgid "Fine ciclo misura"
msgstr "Fine ciclo misura"
#: templates/measure/task_execute.html:629
msgid "Rimisura"
msgstr "Rimisura"
#: templates/measure/task_execute.html:639
#: templates/measure/task_execute.html:653
msgid "Completato"
msgstr "Completato"
#: templates/measure/task_execute.html:718
msgid "Tutte le"
msgstr "Tutte le"
#: templates/measure/task_execute.html:718
msgid "misurazioni sono state registrate."
msgstr "misurazioni sono state registrate."
#: templates/measure/task_execute.html:732
msgid "Non Conf."
msgstr "Non Conf."
#: templates/measure/task_execute.html:747
msgid "Conferma ciclo"
msgstr "Conferma ciclo"
#: templates/measure/task_execute.html:757
msgid "Task successivo"
msgstr "Task successivo"
#: templates/measure/task_execute.html:783
msgid "Girare il pezzo e rimisurare"
msgstr "Girare il pezzo e rimisurare"
#: templates/measure/task_execute.html:809
msgid "Autorizzazione capoturno"
msgstr "Autorizzazione capoturno"
#: templates/measure/task_execute.html:818
msgid "Username capoturno"
msgstr "Username capoturno"
#: templates/measure/task_execute.html:840
#: templates/measure/task_execute.html:517
#: templates/measure/task_execute.html:870
msgid "Autorizza"
msgstr "Autorizza"
#: templates/measure/task_execute.html:1063
#: templates/measure/task_execute.html:541
msgid "Il conto alla rovescia è congelato a"
msgstr "Il conto alla rovescia è congelato a"
#: templates/measure/task_execute.html:544
msgid "serve il capoturno per riprendere"
msgstr "serve il capoturno per riprendere"
#: templates/measure/task_execute.html:563
msgid "Produzione non registrata sul server"
msgstr "Produzione non registrata sul server"
#: templates/measure/task_execute.html:584
#: templates/measure/task_execute.html:793
msgid "Avvio Produzione"
msgstr "Avvio Produzione"
#: templates/measure/task_execute.html:588
msgid "Invia segnale al gestionale per avviare il timer della linea"
msgstr "Invia segnale al gestionale per avviare il timer della linea"
#: templates/measure/task_execute.html:599
msgid "Produzione avviata"
msgstr "Produzione avviata"
#: templates/measure/task_execute.html:644
msgid "Fine ciclo misura"
msgstr "Fine ciclo misura"
#: templates/measure/task_execute.html:655
msgid "Rimisura"
msgstr "Rimisura"
#: templates/measure/task_execute.html:665
#: templates/measure/task_execute.html:679
msgid "Completato"
msgstr "Completato"
#: templates/measure/task_execute.html:744
msgid "Tutte le"
msgstr "Tutte le"
#: templates/measure/task_execute.html:744
msgid "misurazioni sono state registrate."
msgstr "misurazioni sono state registrate."
#: templates/measure/task_execute.html:758
msgid "Non Conf."
msgstr "Non Conf."
#: templates/measure/task_execute.html:773
msgid "Conferma ciclo"
msgstr "Conferma ciclo"
#: templates/measure/task_execute.html:783
msgid "Task successivo"
msgstr "Task successivo"
#: templates/measure/task_execute.html:809
msgid "Girare il pezzo e rimisurare"
msgstr "Girare il pezzo e rimisurare"
#: templates/measure/task_execute.html:835
msgid "Autorizzazione capoturno"
msgstr "Autorizzazione capoturno"
#: templates/measure/task_execute.html:844
msgid "Username capoturno"
msgstr "Username capoturno"
#: templates/measure/task_execute.html:861
msgid "Rimisura la quota"
msgstr "Rimisura la quota"
#: templates/measure/task_execute.html:1125
msgid "Questa ricetta non ammette valori digitati: usare il calibro"
msgstr "Questa ricetta non ammette valori digitati: usare il calibro"
#: templates/measure/task_execute.html:1152
#: templates/measure/task_execute.html:1222
msgid "Errore di rete. Riprovare."
msgstr "Errore di rete. Riprovare."
#: templates/measure/task_execute.html:1257
#: templates/measure/task_execute.html:1260
msgid ""
"Quota fuori tolleranza: serve l'autorizzazione del capoturno, oppure "
"misurare di nuovo la quota"
msgstr "Quota fuori tolleranza: serve l'autorizzazione del capoturno, oppure misurare di nuovo la quota"
#: templates/measure/task_execute.html:1357
msgid "Errore di comunicazione con il server"
msgstr "Errore di comunicazione con il server"
#: templates/measure/task_execute.html:1505
#: templates/measure/task_execute.html:1609
msgid "Misurazione fuori tolleranza"
msgstr "Misurazione fuori tolleranza"
#: templates/measure/task_execute.html:1506
#: templates/measure/task_execute.html:1610
msgid "Fermo linea richiesto"
msgstr "Fermo linea richiesto"
#: templates/measure/task_execute.html:1507
#: templates/measure/task_execute.html:1611
msgid "Ripresa della produzione"
msgstr "Ripresa della produzione"
#: templates/measure/task_execute.html:1508
#: templates/measure/task_execute.html:1612
msgid "Fine produzione richiesta"
msgstr "Fine produzione richiesta"
#: templates/measure/task_execute.html:1537
#: templates/measure/task_execute.html:1656
msgid "Credenziali non valide o utente non autorizzato"
msgstr "Credenziali non valide o utente non autorizzato"
#: templates/measure/task_execute.html:1569
#: templates/measure/task_execute.html:1683
msgid "Nessuna produzione aperta su questa stazione"
msgstr "Nessuna produzione aperta su questa stazione"
#: templates/measure/task_execute.html:1586
#: templates/measure/task_execute.html:1700
msgid "Azione non riuscita"
msgstr "Azione non riuscita"
#: templates/measure/task_list.html:87
#: templates/measure/task_list.html:107
msgid "AVVIA"
msgstr "AVVIA"
#: templates/measure/task_list.html:124
#: templates/measure/task_list.html:145
msgid "Task da eseguire"
msgstr "Task da eseguire"
#: templates/measure/task_list.html:136
#: templates/measure/task_list.html:157
msgid "misurazioni totali"
msgstr "misurazioni totali"
#: templates/measure/task_list.html:178
#: templates/measure/task_list.html:199
msgid "Confronto profilo"
msgstr "Confronto profilo"
#: templates/measure/task_list.html:179
#: templates/measure/task_list.html:200
msgid "Misura camera"
msgstr "Misura camera"
#: templates/measure/task_list.html:201
#: templates/measure/task_list.html:222
msgid "Allegato"
msgstr "Allegato"
#: templates/measure/task_list.html:225
#: templates/measure/task_list.html:246
msgid "Visualizza Task"
msgstr "Visualizza Task"
#: templates/measure/task_list.html:248
#: templates/measure/task_list.html:269
msgid "Nessun task disponibile"
msgstr "Nessun task disponibile"
#: templates/measure/task_list.html:251
#: templates/measure/task_list.html:272
msgid "Questa ricetta non ha ancora task definiti."
msgstr "Questa ricetta non ha ancora task definiti."
@@ -2669,3 +2685,6 @@ msgstr "Errore nella generazione del report"
#~ msgid "Inizia Misure"
#~ msgstr "Inizia Misure"
#~ msgid "Utente non autorizzato (richiesto capoturno)"
#~ msgstr "Utente non autorizzato (richiesto capoturno)"
+136 -120
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-07-28 20:16+0000\n"
"POT-Creation-Date: 2026-07-28 20:48+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -39,7 +39,7 @@ msgstr ""
msgid "Inserisci username e password"
msgstr ""
#: blueprints/auth.py:81 blueprints/measure.py:417
#: blueprints/auth.py:81
msgid "Credenziali non valide"
msgstr ""
@@ -158,15 +158,11 @@ msgstr ""
msgid "Errore nel salvataggio"
msgstr ""
#: blueprints/measure.py:412 blueprints/measure.py:520
#: blueprints/measure.py:437 blueprints/measure.py:542
msgid "Username e password richiesti"
msgstr ""
#: blueprints/measure.py:422
msgid "Utente non autorizzato (richiesto capoturno)"
msgstr ""
#: blueprints/measure.py:441 blueprints/measure.py:458
#: blueprints/measure.py:463 blueprints/measure.py:480
#: templates/errors/station_not_configured.html:2
#: templates/errors/station_not_configured.html:16
msgid "Stazione non configurata"
@@ -369,7 +365,7 @@ msgstr ""
#: templates/maker/task_editor.html:782 templates/maker/task_editor.html:901
#: templates/maker/task_editor.html:966 templates/maker/task_editor.html:1071
#: templates/measure/select_recipe.html:405
#: templates/measure/task_execute.html:831
#: templates/measure/task_execute.html:860
msgid "Annulla"
msgstr ""
@@ -513,7 +509,7 @@ msgstr ""
#: templates/admin/users.html:48 templates/admin/users.html:173
#: templates/admin/users.html:179 templates/auth/login.html:35
#: templates/auth/login.html:49 templates/auth/profile.html:36
#: templates/measure/task_execute.html:816
#: templates/measure/task_execute.html:842
msgid "Username"
msgstr ""
@@ -565,7 +561,7 @@ msgstr ""
#: templates/admin/users.html:206 templates/admin/users.html:214
#: templates/auth/login.html:57 templates/auth/login.html:71
#: templates/measure/task_execute.html:821
#: templates/measure/task_execute.html:847
msgid "Password"
msgstr ""
@@ -818,7 +814,7 @@ msgstr ""
#: templates/components/production_clock.html:49
#: templates/components/production_clock.html:62
#: templates/measure/task_execute.html:463
#: templates/measure/task_execute.html:516
#: templates/measure/task_execute.html:542
msgid "Misurazione in ritardo di"
msgstr ""
@@ -827,7 +823,7 @@ msgid "Linea ferma — conto alla rovescia congelato a"
msgstr ""
#: templates/components/production_clock.html:62
#: templates/measure/task_execute.html:510
#: templates/measure/task_execute.html:536
msgid "Linea ferma"
msgstr ""
@@ -837,17 +833,17 @@ msgid "Ciclo"
msgstr ""
#: templates/components/production_clock.html:92
#: templates/measure/task_execute.html:678
#: templates/measure/task_execute.html:704
msgid "È ora di misurare"
msgstr ""
#: templates/components/production_clock.html:95
#: templates/measure/task_execute.html:680
#: templates/measure/task_execute.html:706
msgid "Ritorno alla misurazione tra"
msgstr ""
#: templates/components/production_clock.html:101
#: templates/measure/task_execute.html:685
#: templates/measure/task_execute.html:711
msgid "Vai alla misura"
msgstr ""
@@ -896,8 +892,8 @@ msgstr ""
#: templates/maker/recipe_editor.html:128 templates/maker/recipe_list.html:246
#: templates/maker/task_drawing.html:106 templates/maker/task_editor.html:130
#: templates/measure/task_complete.html:171
#: templates/measure/task_execute.html:589 templates/measure/task_list.html:2
#: templates/measure/task_list.html:159
#: templates/measure/task_execute.html:615 templates/measure/task_list.html:2
#: templates/measure/task_list.html:180
msgid "Task"
msgstr ""
@@ -1071,8 +1067,8 @@ msgid "Errore durante eliminazione"
msgstr ""
#: templates/maker/recipe_list.html:55 templates/measure/select_recipe.html:72
#: templates/measure/task_execute.html:1262
#: templates/measure/task_execute.html:1558
#: templates/measure/task_execute.html:1362
#: templates/measure/task_execute.html:1672
msgid "Errore di connessione"
msgstr ""
@@ -1376,17 +1372,17 @@ msgid "Tipo"
msgstr ""
#: templates/maker/task_editor.html:277 templates/maker/task_editor.html:543
#: templates/measure/task_list.html:177
#: templates/measure/task_list.html:198
msgid "Nota"
msgstr ""
#: templates/maker/task_editor.html:278 templates/maker/task_editor.html:544
#: templates/measure/task_execute.html:309 templates/measure/task_list.html:175
#: templates/measure/task_execute.html:309 templates/measure/task_list.html:196
msgid "Misura"
msgstr ""
#: templates/maker/task_editor.html:279 templates/maker/task_editor.html:545
#: templates/measure/task_list.html:176
#: templates/measure/task_list.html:197
msgid "Disegno"
msgstr ""
@@ -1417,7 +1413,7 @@ msgstr ""
#: templates/maker/task_editor.html:390
#: templates/maker/version_history.html:188
#: templates/measure/task_list.html:192
#: templates/measure/task_list.html:213
msgid "misurazioni"
msgstr ""
@@ -1683,7 +1679,7 @@ msgid "Misurazione aggiunta"
msgstr ""
#: templates/maker/task_editor.html:1685
#: templates/measure/task_execute.html:1108
#: templates/measure/task_execute.html:1170
msgid "Errore nel salvataggio della misurazione"
msgstr ""
@@ -1746,16 +1742,16 @@ msgstr ""
msgid "Seleziona Ricetta"
msgstr ""
#: templates/measure/select_recipe.html:30
#: templates/measure/select_recipe.html:30 templates/measure/task_list.html:86
msgid "lotto"
msgstr ""
#: templates/measure/select_recipe.html:31
#: templates/measure/select_recipe.html:31 templates/measure/task_list.html:87
msgid "seriale"
msgstr ""
#: templates/measure/select_recipe.html:64
#: templates/measure/select_recipe.html:277
#: templates/measure/select_recipe.html:277 templates/measure/task_list.html:97
msgid "Compila prima:"
msgstr ""
@@ -1850,24 +1846,25 @@ msgstr ""
#: templates/measure/task_complete.html:3
#: templates/measure/task_complete.html:39
#: templates/measure/task_execute.html:113
#: templates/measure/task_execute.html:739
#: templates/measure/task_execute.html:765
#: templates/statistics/dashboard.html:139
msgid "Riepilogo"
msgstr ""
#: templates/measure/task_complete.html:47
#: templates/measure/task_execute.html:716
#: templates/measure/task_execute.html:742
msgid "Misurazioni Complete"
msgstr ""
#: templates/measure/task_complete.html:64
#: templates/measure/task_complete.html:296 templates/measure/task_list.html:97
#: templates/measure/task_complete.html:296
#: templates/measure/task_list.html:118
msgid "Lotto"
msgstr ""
#: templates/measure/task_complete.html:70
#: templates/measure/task_complete.html:297
#: templates/measure/task_list.html:109
#: templates/measure/task_list.html:130
msgid "Seriale"
msgstr ""
@@ -1876,12 +1873,12 @@ msgid "Totale"
msgstr ""
#: templates/measure/task_complete.html:106
#: templates/measure/task_execute.html:724
#: templates/measure/task_execute.html:750
msgid "Conformi"
msgstr ""
#: templates/measure/task_complete.html:123
#: templates/measure/task_execute.html:728
#: templates/measure/task_execute.html:754
msgid "Attenzione"
msgstr ""
@@ -2075,153 +2072,172 @@ msgstr ""
msgid "Task di misura senza quote configurate: la ricetta è incompleta"
msgstr ""
#: templates/measure/task_execute.html:515
msgid "Il conto alla rovescia è congelato a"
#: templates/measure/task_execute.html:510
msgid "Quota fuori tolleranza"
msgstr ""
#: templates/measure/task_execute.html:518
msgid "serve il capoturno per riprendere"
#: templates/measure/task_execute.html:513
msgid "serve il capoturno, oppure una nuova misura della stessa quota"
msgstr ""
#: templates/measure/task_execute.html:537
msgid "Produzione non registrata sul server"
msgstr ""
#: templates/measure/task_execute.html:558
#: templates/measure/task_execute.html:767
msgid "Avvio Produzione"
msgstr ""
#: templates/measure/task_execute.html:562
msgid "Invia segnale al gestionale per avviare il timer della linea"
msgstr ""
#: templates/measure/task_execute.html:573
msgid "Produzione avviata"
msgstr ""
#: templates/measure/task_execute.html:618
msgid "Fine ciclo misura"
msgstr ""
#: templates/measure/task_execute.html:629
msgid "Rimisura"
msgstr ""
#: templates/measure/task_execute.html:639
#: templates/measure/task_execute.html:653
msgid "Completato"
msgstr ""
#: templates/measure/task_execute.html:718
msgid "Tutte le"
msgstr ""
#: templates/measure/task_execute.html:718
msgid "misurazioni sono state registrate."
msgstr ""
#: templates/measure/task_execute.html:732
msgid "Non Conf."
msgstr ""
#: templates/measure/task_execute.html:747
msgid "Conferma ciclo"
msgstr ""
#: templates/measure/task_execute.html:757
msgid "Task successivo"
msgstr ""
#: templates/measure/task_execute.html:783
msgid "Girare il pezzo e rimisurare"
msgstr ""
#: templates/measure/task_execute.html:809
msgid "Autorizzazione capoturno"
msgstr ""
#: templates/measure/task_execute.html:818
msgid "Username capoturno"
msgstr ""
#: templates/measure/task_execute.html:840
#: templates/measure/task_execute.html:517
#: templates/measure/task_execute.html:870
msgid "Autorizza"
msgstr ""
#: templates/measure/task_execute.html:1063
#: templates/measure/task_execute.html:541
msgid "Il conto alla rovescia è congelato a"
msgstr ""
#: templates/measure/task_execute.html:544
msgid "serve il capoturno per riprendere"
msgstr ""
#: templates/measure/task_execute.html:563
msgid "Produzione non registrata sul server"
msgstr ""
#: templates/measure/task_execute.html:584
#: templates/measure/task_execute.html:793
msgid "Avvio Produzione"
msgstr ""
#: templates/measure/task_execute.html:588
msgid "Invia segnale al gestionale per avviare il timer della linea"
msgstr ""
#: templates/measure/task_execute.html:599
msgid "Produzione avviata"
msgstr ""
#: templates/measure/task_execute.html:644
msgid "Fine ciclo misura"
msgstr ""
#: templates/measure/task_execute.html:655
msgid "Rimisura"
msgstr ""
#: templates/measure/task_execute.html:665
#: templates/measure/task_execute.html:679
msgid "Completato"
msgstr ""
#: templates/measure/task_execute.html:744
msgid "Tutte le"
msgstr ""
#: templates/measure/task_execute.html:744
msgid "misurazioni sono state registrate."
msgstr ""
#: templates/measure/task_execute.html:758
msgid "Non Conf."
msgstr ""
#: templates/measure/task_execute.html:773
msgid "Conferma ciclo"
msgstr ""
#: templates/measure/task_execute.html:783
msgid "Task successivo"
msgstr ""
#: templates/measure/task_execute.html:809
msgid "Girare il pezzo e rimisurare"
msgstr ""
#: templates/measure/task_execute.html:835
msgid "Autorizzazione capoturno"
msgstr ""
#: templates/measure/task_execute.html:844
msgid "Username capoturno"
msgstr ""
#: templates/measure/task_execute.html:861
msgid "Rimisura la quota"
msgstr ""
#: templates/measure/task_execute.html:1125
msgid "Questa ricetta non ammette valori digitati: usare il calibro"
msgstr ""
#: templates/measure/task_execute.html:1152
#: templates/measure/task_execute.html:1222
msgid "Errore di rete. Riprovare."
msgstr ""
#: templates/measure/task_execute.html:1257
#: templates/measure/task_execute.html:1260
msgid ""
"Quota fuori tolleranza: serve l'autorizzazione del capoturno, oppure "
"misurare di nuovo la quota"
msgstr ""
#: templates/measure/task_execute.html:1357
msgid "Errore di comunicazione con il server"
msgstr ""
#: templates/measure/task_execute.html:1505
#: templates/measure/task_execute.html:1609
msgid "Misurazione fuori tolleranza"
msgstr ""
#: templates/measure/task_execute.html:1506
#: templates/measure/task_execute.html:1610
msgid "Fermo linea richiesto"
msgstr ""
#: templates/measure/task_execute.html:1507
#: templates/measure/task_execute.html:1611
msgid "Ripresa della produzione"
msgstr ""
#: templates/measure/task_execute.html:1508
#: templates/measure/task_execute.html:1612
msgid "Fine produzione richiesta"
msgstr ""
#: templates/measure/task_execute.html:1537
#: templates/measure/task_execute.html:1656
msgid "Credenziali non valide o utente non autorizzato"
msgstr ""
#: templates/measure/task_execute.html:1569
#: templates/measure/task_execute.html:1683
msgid "Nessuna produzione aperta su questa stazione"
msgstr ""
#: templates/measure/task_execute.html:1586
#: templates/measure/task_execute.html:1700
msgid "Azione non riuscita"
msgstr ""
#: templates/measure/task_list.html:87
#: templates/measure/task_list.html:107
msgid "AVVIA"
msgstr ""
#: templates/measure/task_list.html:124
#: templates/measure/task_list.html:145
msgid "Task da eseguire"
msgstr ""
#: templates/measure/task_list.html:136
#: templates/measure/task_list.html:157
msgid "misurazioni totali"
msgstr ""
#: templates/measure/task_list.html:178
#: templates/measure/task_list.html:199
msgid "Confronto profilo"
msgstr ""
#: templates/measure/task_list.html:179
#: templates/measure/task_list.html:200
msgid "Misura camera"
msgstr ""
#: templates/measure/task_list.html:201
#: templates/measure/task_list.html:222
msgid "Allegato"
msgstr ""
#: templates/measure/task_list.html:225
#: templates/measure/task_list.html:246
msgid "Visualizza Task"
msgstr ""
#: templates/measure/task_list.html:248
#: templates/measure/task_list.html:269
msgid "Nessun task disponibile"
msgstr ""
#: templates/measure/task_list.html:251
#: templates/measure/task_list.html:272
msgid "Questa ricetta non ha ancora task definiti."
msgstr ""