fixed lookup options
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class WidenLubricationTypeOnWorkSheetMescole extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$this->table('work_sheet_mescole')
|
||||||
|
->changeColumn('lubrication_type', 'string', [
|
||||||
|
'limit' => 60,
|
||||||
|
'null' => true,
|
||||||
|
'default' => null,
|
||||||
|
'comment' => 'Valore da ws_lookup_options (category lubrication_type)',
|
||||||
|
])
|
||||||
|
->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// i valori non previsti dal vecchio ENUM vengono azzerati, altrimenti il ripristino fallisce
|
||||||
|
$this->execute("UPDATE work_sheet_mescole SET lubrication_type = NULL WHERE lubrication_type NOT IN ('S','G','N')");
|
||||||
|
|
||||||
|
$this->table('work_sheet_mescole')
|
||||||
|
->changeColumn('lubrication_type', 'enum', [
|
||||||
|
'values' => ['S', 'G', 'N'],
|
||||||
|
'null' => true,
|
||||||
|
'default' => null,
|
||||||
|
])
|
||||||
|
->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
use Phinx\Db\Adapter\MysqlAdapter;
|
||||||
|
|
||||||
|
final class AddDifficoltaToMatrice extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$this->table('matrice')
|
||||||
|
->addColumn('difficolta', 'integer', [
|
||||||
|
'limit' => MysqlAdapter::INT_TINY,
|
||||||
|
'signed' => false,
|
||||||
|
'null' => true,
|
||||||
|
'default' => null,
|
||||||
|
'after' => 'cliente',
|
||||||
|
'comment' => 'Difficoltà 1 (facile) - 10 (difficile), NULL = non indicata',
|
||||||
|
])
|
||||||
|
->addIndex(['difficolta'], ['name' => 'idx_matrice_difficolta'])
|
||||||
|
->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
+115
-2
@@ -46,6 +46,48 @@ function revisionLabel($rev)
|
|||||||
return $rev !== '' ? $rev : '0';
|
return $rev !== '' ? $rev : '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DIFFICOLTÀ MATRICE (1 = più facile, 10 = più difficile)
|
||||||
|
* Per aggiungere un'etichetta basta una riga qui (es. 8 => 'Molto difficile').
|
||||||
|
*/
|
||||||
|
const DIFF_LABELS = [1 => 'Facile', 5 => 'Media', 10 => 'Difficile'];
|
||||||
|
// fasce usate dal filtro in tabella
|
||||||
|
const DIFF_BANDS = [
|
||||||
|
'facile' => ['label' => 'Facile (1–3)', 'min' => 1, 'max' => 3],
|
||||||
|
'media' => ['label' => 'Media (4–7)', 'min' => 4, 'max' => 7],
|
||||||
|
'difficile' => ['label' => 'Difficile (8–10)', 'min' => 8, 'max' => 10],
|
||||||
|
];
|
||||||
|
|
||||||
|
function diffValue($v)
|
||||||
|
{
|
||||||
|
$n = (int)$v;
|
||||||
|
return ($n >= 1 && $n <= 10) ? $n : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** testo: "5 · Media", "3", "" */
|
||||||
|
function diffText($v)
|
||||||
|
{
|
||||||
|
$n = diffValue($v);
|
||||||
|
if ($n === null) return '';
|
||||||
|
return isset(DIFF_LABELS[$n]) ? $n . ' · ' . DIFF_LABELS[$n] : (string)$n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** colore dal verde (1) al rosso (10) */
|
||||||
|
function diffStyle($v)
|
||||||
|
{
|
||||||
|
$n = diffValue($v);
|
||||||
|
if ($n === null) return '';
|
||||||
|
$hue = (int)round(120 * (10 - $n) / 9);
|
||||||
|
return "background:hsl($hue,75%,90%);color:hsl($hue,70%,26%);border-color:hsl($hue,55%,68%);";
|
||||||
|
}
|
||||||
|
|
||||||
|
function diffBadge($v)
|
||||||
|
{
|
||||||
|
$n = diffValue($v);
|
||||||
|
if ($n === null) return "<span class='diff-badge diff-none'>—</span>";
|
||||||
|
return "<span class='diff-badge' style='" . diffStyle($n) . "'>" . h(diffText($n)) . "</span>";
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="it">
|
<html lang="it">
|
||||||
@@ -489,6 +531,29 @@ function revisionLabel($rev)
|
|||||||
font-size: .82rem;
|
font-size: .82rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.diff-badge {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 34px;
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: .85rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-badge.diff-none {
|
||||||
|
color: #adb5bd;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
#diffFilter {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.worksheet-counter-badge {
|
.worksheet-counter-badge {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -714,6 +779,7 @@ function revisionLabel($rev)
|
|||||||
<th>Foto</th>
|
<th>Foto</th>
|
||||||
<th>Nome</th>
|
<th>Nome</th>
|
||||||
<th>Cliente</th>
|
<th>Cliente</th>
|
||||||
|
<th>Difficoltà</th>
|
||||||
<th>Linee</th>
|
<th>Linee</th>
|
||||||
<th>Fogli</th>
|
<th>Fogli</th>
|
||||||
<th>Azioni</th>
|
<th>Azioni</th>
|
||||||
@@ -760,7 +826,7 @@ function revisionLabel($rev)
|
|||||||
");
|
");
|
||||||
|
|
||||||
if ($stmt->rowCount() === 0) {
|
if ($stmt->rowCount() === 0) {
|
||||||
echo "<tr><td colspan='6' class='text-muted'>Nessuna matrice presente</td></tr>";
|
echo "<tr><td colspan='7' class='text-muted'>Nessuna matrice presente</td></tr>";
|
||||||
} else {
|
} else {
|
||||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
$dataIT = formatDateIT($row['data_produzione']);
|
$dataIT = formatDateIT($row['data_produzione']);
|
||||||
@@ -802,6 +868,11 @@ function revisionLabel($rev)
|
|||||||
. htmlspecialchars($row['cliente'])
|
. htmlspecialchars($row['cliente'])
|
||||||
. "</td>";
|
. "</td>";
|
||||||
|
|
||||||
|
$diff = diffValue($row['difficolta'] ?? null);
|
||||||
|
echo "<td class='diff-cell' data-diff='" . ($diff ?? '') . "' data-order='" . ($diff ?? 0) . "'>"
|
||||||
|
. diffBadge($diff)
|
||||||
|
. "</td>";
|
||||||
|
|
||||||
$lineeTxt = $row['linee_associate'] ?? '—';
|
$lineeTxt = $row['linee_associate'] ?? '—';
|
||||||
$mescoleTxt = $row['mescole_associate'] ?? '';
|
$mescoleTxt = $row['mescole_associate'] ?? '';
|
||||||
$mescoleCount = (int)($row['mescole_count'] ?? 0);
|
$mescoleCount = (int)($row['mescole_count'] ?? 0);
|
||||||
@@ -849,6 +920,7 @@ function revisionLabel($rev)
|
|||||||
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
|
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
|
||||||
data-cliente='" . htmlspecialchars($row['cliente'], ENT_QUOTES) . "'
|
data-cliente='" . htmlspecialchars($row['cliente'], ENT_QUOTES) . "'
|
||||||
data-data='{$dataIT}'
|
data-data='{$dataIT}'
|
||||||
|
data-difficolta='" . (diffValue($row['difficolta'] ?? null) ?? '') . "'
|
||||||
data-photo='" . htmlspecialchars($hasPhoto ? $thumb : '', ENT_QUOTES) . "'
|
data-photo='" . htmlspecialchars($hasPhoto ? $thumb : '', ENT_QUOTES) . "'
|
||||||
data-bs-toggle='tooltip' data-bs-title='Modifica'>
|
data-bs-toggle='tooltip' data-bs-title='Modifica'>
|
||||||
<i class='fa-solid fa-pen-to-square'></i>
|
<i class='fa-solid fa-pen-to-square'></i>
|
||||||
@@ -929,6 +1001,17 @@ function revisionLabel($rev)
|
|||||||
<input type="text" class="form-control" id="clienteMatrice">
|
<input type="text" class="form-control" id="clienteMatrice">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="fw-semibold">Difficoltà</label>
|
||||||
|
<select class="form-select" id="difficoltaMatrice">
|
||||||
|
<option value="">— Non indicata —</option>
|
||||||
|
<?php for ($i = 1; $i <= 10; $i++): ?>
|
||||||
|
<option value="<?= $i ?>" style="<?= h(diffStyle($i)) ?>"><?= h(diffText($i)) ?></option>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</select>
|
||||||
|
<div class="form-text">1 = più facile, 10 = più difficile</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="fw-semibold">Data</label>
|
<label class="fw-semibold">Data</label>
|
||||||
<input type="text" class="form-control" id="dataMatrice" placeholder="dd/mm/yyyy">
|
<input type="text" class="form-control" id="dataMatrice" placeholder="dd/mm/yyyy">
|
||||||
@@ -1551,6 +1634,9 @@ function revisionLabel($rev)
|
|||||||
if (!old) return;
|
if (!old) return;
|
||||||
old.innerHTML = td.innerHTML;
|
old.innerHTML = td.innerHTML;
|
||||||
if (td.hasAttribute('title')) old.setAttribute('title', td.getAttribute('title'));
|
if (td.hasAttribute('title')) old.setAttribute('title', td.getAttribute('title'));
|
||||||
|
['data-diff', 'data-order'].forEach(a => {
|
||||||
|
if (td.hasAttribute(a)) old.setAttribute(a, td.getAttribute(a));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
this.invalidate('dom');
|
this.invalidate('dom');
|
||||||
flashRow(tr);
|
flashRow(tr);
|
||||||
@@ -1592,7 +1678,10 @@ function revisionLabel($rev)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
targets: 5,
|
targets: 3,
|
||||||
|
searchable: false
|
||||||
|
}, {
|
||||||
|
targets: 6,
|
||||||
orderable: false,
|
orderable: false,
|
||||||
searchable: false
|
searchable: false
|
||||||
}],
|
}],
|
||||||
@@ -1610,6 +1699,28 @@ function revisionLabel($rev)
|
|||||||
.attr('placeholder', 'Nome matrice, cliente…')
|
.attr('placeholder', 'Nome matrice, cliente…')
|
||||||
.addClass('form-control');
|
.addClass('form-control');
|
||||||
|
|
||||||
|
// ---- filtro difficoltà ----
|
||||||
|
const DIFF_BANDS = <?= json_encode(DIFF_BANDS, JSON_UNESCAPED_UNICODE) ?>;
|
||||||
|
const $diffFilter = $('<select id="diffFilter" class="form-select form-select-sm"></select>')
|
||||||
|
.append('<option value="">Difficoltà: tutte</option>');
|
||||||
|
Object.keys(DIFF_BANDS).forEach(k => $diffFilter.append($('<option>').val(k).text(DIFF_BANDS[k].label)));
|
||||||
|
$diffFilter.append('<option value="none">Non indicata</option>');
|
||||||
|
$('#tabellaMatrici_filter').append($diffFilter);
|
||||||
|
|
||||||
|
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
|
||||||
|
if (settings.nTable.id !== 'tabellaMatrici') return true;
|
||||||
|
const f = $diffFilter.val();
|
||||||
|
if (!f) return true;
|
||||||
|
const tr = settings.aoData[dataIndex].nTr;
|
||||||
|
const td = tr && tr.querySelector('td.diff-cell');
|
||||||
|
if (!td) return false;
|
||||||
|
const n = parseInt(td.getAttribute('data-diff') || '0', 10);
|
||||||
|
if (f === 'none') return !n;
|
||||||
|
const b = DIFF_BANDS[f];
|
||||||
|
return n >= b.min && n <= b.max;
|
||||||
|
});
|
||||||
|
$diffFilter.on('change', () => $('#tabellaMatrici').DataTable().draw());
|
||||||
|
|
||||||
function resetFotoMatrice(photoUrl) {
|
function resetFotoMatrice(photoUrl) {
|
||||||
$("#fotoMatrice").val('');
|
$("#fotoMatrice").val('');
|
||||||
$("#removeFotoMatrice").val('0');
|
$("#removeFotoMatrice").val('0');
|
||||||
@@ -1627,6 +1738,7 @@ function revisionLabel($rev)
|
|||||||
$("#nomeMatrice").val($(this).data("nome"));
|
$("#nomeMatrice").val($(this).data("nome"));
|
||||||
$("#clienteMatrice").val($(this).data("cliente"));
|
$("#clienteMatrice").val($(this).data("cliente"));
|
||||||
$("#dataMatrice").val($(this).data("data"));
|
$("#dataMatrice").val($(this).data("data"));
|
||||||
|
$("#difficoltaMatrice").val(String($(this).attr("data-difficolta") || ''));
|
||||||
resetFotoMatrice($(this).data("photo") || "");
|
resetFotoMatrice($(this).data("photo") || "");
|
||||||
bootstrap.Modal.getOrCreateInstance(document.getElementById('addMatriceModal')).show();
|
bootstrap.Modal.getOrCreateInstance(document.getElementById('addMatriceModal')).show();
|
||||||
});
|
});
|
||||||
@@ -1669,6 +1781,7 @@ function revisionLabel($rev)
|
|||||||
formData.append("nome", nome);
|
formData.append("nome", nome);
|
||||||
formData.append("cliente", cliente);
|
formData.append("cliente", cliente);
|
||||||
formData.append("data", dataSQL);
|
formData.append("data", dataSQL);
|
||||||
|
formData.append("difficolta", $("#difficoltaMatrice").val());
|
||||||
formData.append("remove_photo", $("#removeFotoMatrice").val());
|
formData.append("remove_photo", $("#removeFotoMatrice").val());
|
||||||
|
|
||||||
const fotoFile = $("#fotoMatrice")[0].files[0];
|
const fotoFile = $("#fotoMatrice")[0].files[0];
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ $id = (int)($_POST['id'] ?? 0);
|
|||||||
$nome = trim($_POST['nome'] ?? '');
|
$nome = trim($_POST['nome'] ?? '');
|
||||||
$cliente = trim($_POST['cliente'] ?? '');
|
$cliente = trim($_POST['cliente'] ?? '');
|
||||||
$data = trim($_POST['data'] ?? '');
|
$data = trim($_POST['data'] ?? '');
|
||||||
|
$difficolta = trim($_POST['difficolta'] ?? '');
|
||||||
$removePhoto = ($_POST['remove_photo'] ?? '0') === '1';
|
$removePhoto = ($_POST['remove_photo'] ?? '0') === '1';
|
||||||
|
|
||||||
if ($nome === '') {
|
if ($nome === '') {
|
||||||
@@ -26,6 +27,15 @@ if ($nome === '') {
|
|||||||
$data = ($data !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $data)) ? $data : null;
|
$data = ($data !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $data)) ? $data : null;
|
||||||
$cliente = $cliente !== '' ? $cliente : null;
|
$cliente = $cliente !== '' ? $cliente : null;
|
||||||
|
|
||||||
|
// difficoltà: vuota = non indicata, altrimenti intero 1..10
|
||||||
|
if ($difficolta === '') {
|
||||||
|
$difficolta = null;
|
||||||
|
} elseif (ctype_digit($difficolta) && (int)$difficolta >= 1 && (int)$difficolta <= 10) {
|
||||||
|
$difficolta = (int)$difficolta;
|
||||||
|
} else {
|
||||||
|
jsonOut(false, 'Difficoltà non valida (valori ammessi: 1–10)');
|
||||||
|
}
|
||||||
|
|
||||||
$photoDir = __DIR__ . '/photos/matrici/';
|
$photoDir = __DIR__ . '/photos/matrici/';
|
||||||
if (!is_dir($photoDir)) {
|
if (!is_dir($photoDir)) {
|
||||||
mkdir($photoDir, 0775, true);
|
mkdir($photoDir, 0775, true);
|
||||||
@@ -65,11 +75,11 @@ try {
|
|||||||
}
|
}
|
||||||
$oldPhoto = $row['photo'];
|
$oldPhoto = $row['photo'];
|
||||||
|
|
||||||
$st = $pdo->prepare("UPDATE matrice SET nome = ?, cliente = ?, data_produzione = ? WHERE id = ?");
|
$st = $pdo->prepare("UPDATE matrice SET nome = ?, cliente = ?, data_produzione = ?, difficolta = ? WHERE id = ?");
|
||||||
$st->execute([$nome, $cliente, $data, $id]);
|
$st->execute([$nome, $cliente, $data, $difficolta, $id]);
|
||||||
} else {
|
} else {
|
||||||
$st = $pdo->prepare("INSERT INTO matrice (nome, cliente, data_produzione) VALUES (?, ?, ?)");
|
$st = $pdo->prepare("INSERT INTO matrice (nome, cliente, data_produzione, difficolta) VALUES (?, ?, ?, ?)");
|
||||||
$st->execute([$nome, $cliente, $data]);
|
$st->execute([$nome, $cliente, $data, $difficolta]);
|
||||||
$id = (int)$pdo->lastInsertId();
|
$id = (int)$pdo->lastInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user