UX: fraction buttons for pz unit in use form + fix qty display
- _pzFractionLabel(): formats 2.5 → '2½', 2.25 → '2¼', etc. - formatQuantity/formatQuantityParts: use fraction label for pz (was rounding to int) - loadUseInventoryInfo normal mode: show ¼/½/¾/1 intero quick-select buttons for pz - setPzFraction(): sets quantity input + syncs active button highlight - adjustUseQty pz: step = 0.5 (half-piece) instead of 1; syncs frac button on ± - CSS: .pz-fraction-btns, .fraction-btn-row, .frac-btn, .frac-btn.active
This commit is contained in:
+46
-6
@@ -1354,6 +1354,15 @@ function formatSubRemainder(amt, pkgUnit) {
|
||||
return `${Math.round(amt * 10) / 10}${uL[pkgUnit] || pkgUnit}`;
|
||||
}
|
||||
|
||||
function _pzFractionLabel(n) {
|
||||
const whole = Math.floor(n);
|
||||
const frac = Math.round((n - whole) * 4) / 4; // nearest quarter
|
||||
const fracMap = { 0.25: '¼', 0.5: '½', 0.75: '¾' };
|
||||
const fracStr = fracMap[frac] || '';
|
||||
if (whole === 0) return fracStr || '0';
|
||||
return `${whole}${fracStr}`;
|
||||
}
|
||||
|
||||
function formatQuantity(qty, unit, defaultQty, packageUnit) {
|
||||
if (!qty && qty !== 0) return '';
|
||||
const n = parseFloat(qty);
|
||||
@@ -1378,7 +1387,7 @@ function formatQuantity(qty, unit, defaultQty, packageUnit) {
|
||||
|
||||
let result;
|
||||
if (n === Math.floor(n)) result = `${Math.floor(n)} ${label}`;
|
||||
else if (unit === 'pz') result = `${Math.round(n)} ${label}`;
|
||||
else if (unit === 'pz') result = `${_pzFractionLabel(n)} ${label}`;
|
||||
else result = `${n.toFixed(1)} ${label}`;
|
||||
return result;
|
||||
}
|
||||
@@ -1408,7 +1417,7 @@ function formatQuantityParts(qty, unit, defaultQty, packageUnit) {
|
||||
|
||||
let mainQty;
|
||||
if (n === Math.floor(n)) mainQty = `${Math.floor(n)}`;
|
||||
else if (unit === 'pz') mainQty = `${Math.round(n)}`;
|
||||
else if (unit === 'pz') mainQty = _pzFractionLabel(n);
|
||||
else mainQty = `${n.toFixed(1)}`;
|
||||
|
||||
let packageDetail = '';
|
||||
@@ -3957,14 +3966,33 @@ async function loadUseInventoryInfo() {
|
||||
|
||||
infoEl.innerHTML = '<strong>📦 Disponibile:</strong> ' + items.map(i => {
|
||||
const loc = LOCATIONS[i.location] || { icon: '📦', label: i.location };
|
||||
return `${loc.icon} ${loc.label}: ${i.quantity} ${i.unit}`;
|
||||
const qLabel = formatQuantity(parseFloat(i.quantity), i.unit, i.default_quantity, i.package_unit);
|
||||
return `${loc.icon} ${loc.label}: ${qLabel}`;
|
||||
}).join(' · ');
|
||||
|
||||
const qtyInput = document.getElementById('use-quantity');
|
||||
qtyInput.value = 1;
|
||||
qtyInput.step = 'any';
|
||||
qtyInput.min = (unit === 'g' || unit === 'ml') ? '1' : '1';
|
||||
qtyInput.step = unit === 'pz' ? '0.5' : 'any';
|
||||
qtyInput.min = (unit === 'g' || unit === 'ml') ? '1' : '0.25';
|
||||
document.getElementById('use-partial-hint').textContent = 'Oppure specifica la quantità usata:';
|
||||
|
||||
// Fraction buttons for pz unit
|
||||
const existingFrac = document.getElementById('pz-fraction-btns');
|
||||
if (existingFrac) existingFrac.remove();
|
||||
if (unit === 'pz') {
|
||||
const fracDiv = document.createElement('div');
|
||||
fracDiv.id = 'pz-fraction-btns';
|
||||
fracDiv.className = 'pz-fraction-btns';
|
||||
fracDiv.innerHTML = `
|
||||
<p class="form-hint">Hai usato solo una parte?</p>
|
||||
<div class="fraction-btn-row">
|
||||
<button type="button" class="frac-btn" data-frac="0.25" onclick="setPzFraction(0.25)">¼ pezzo</button>
|
||||
<button type="button" class="frac-btn" data-frac="0.5" onclick="setPzFraction(0.5)">½ pezzo</button>
|
||||
<button type="button" class="frac-btn" data-frac="0.75" onclick="setPzFraction(0.75)">¾ pezzo</button>
|
||||
<button type="button" class="frac-btn active" data-frac="1" onclick="setPzFraction(1)">1 intero</button>
|
||||
</div>`;
|
||||
document.querySelector('#page-use .use-partial').appendChild(fracDiv);
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
@@ -4019,11 +4047,16 @@ function adjustUseQty(direction) {
|
||||
if (u === 'g' || u === 'ml') {
|
||||
step = val < 50 ? 1 : (val < 500 ? 10 : 50);
|
||||
} else {
|
||||
step = 1;
|
||||
step = 0.5; // pz: allow half-piece steps
|
||||
}
|
||||
}
|
||||
val = Math.max(step, val + direction * step);
|
||||
input.value = Math.round(val * 1000) / 1000;
|
||||
// Sync fraction button highlight if visible
|
||||
const newVal = parseFloat(input.value);
|
||||
document.querySelectorAll('#pz-fraction-btns .frac-btn').forEach(b => {
|
||||
b.classList.toggle('active', parseFloat(b.dataset.frac) === newVal);
|
||||
});
|
||||
}
|
||||
|
||||
function selectUseLocation(btn, loc) {
|
||||
@@ -4032,6 +4065,13 @@ function selectUseLocation(btn, loc) {
|
||||
document.getElementById('use-location').value = loc;
|
||||
}
|
||||
|
||||
function setPzFraction(frac) {
|
||||
document.getElementById('use-quantity').value = frac;
|
||||
document.querySelectorAll('#pz-fraction-btns .frac-btn').forEach(b => {
|
||||
b.classList.toggle('active', parseFloat(b.dataset.frac) === frac);
|
||||
});
|
||||
}
|
||||
|
||||
// ===== LOW STOCK → BRING! PROMPT =====
|
||||
function isLowStock(totalRemaining, unit, defaultQty) {
|
||||
if (totalRemaining <= 0) return true; // fully depleted → definitely needs restocking
|
||||
|
||||
Reference in New Issue
Block a user