Prodotti aperti: mostra solo conf con capacità nota (latte, panna ecc.)

This commit is contained in:
dadaloop82
2026-03-13 15:15:46 +00:00
parent cb3d3a56bb
commit bd1e5d950f
3 changed files with 14 additions and 39 deletions
+3 -10
View File
@@ -753,19 +753,12 @@ function getStats(PDO $db): void {
ORDER BY i.expiry_date ASC
")->fetchAll();
// Opened (partially used) products
// 1) conf items with fractional quantity
// 2) non-conf items where quantity is not a clean multiple of default_quantity
// Opened (partially used conf items with known package capacity)
$opened = $db->query("
SELECT i.*, p.name, p.brand, p.category, p.unit, p.default_quantity, p.package_unit, p.image_url
FROM inventory i JOIN products p ON i.product_id = p.id
WHERE i.quantity > 0 AND p.default_quantity > 0 AND (
(p.unit = 'conf' AND p.package_unit IS NOT NULL
AND CAST(i.quantity AS REAL) != CAST(CAST(i.quantity AS INTEGER) AS REAL))
OR
(p.unit != 'conf' AND p.default_quantity > 1
AND ABS((CAST(i.quantity AS REAL) / p.default_quantity) - ROUND(CAST(i.quantity AS REAL) / p.default_quantity)) > 0.03)
)
WHERE p.unit = 'conf' AND p.default_quantity > 0 AND p.package_unit IS NOT NULL
AND i.quantity > 0 AND CAST(i.quantity AS REAL) != CAST(CAST(i.quantity AS INTEGER) AS REAL)
ORDER BY i.updated_at DESC
")->fetchAll();
+10 -28
View File
@@ -814,7 +814,7 @@ async function loadDashboard() {
// Review suspicious quantities
loadReviewItems();
// Opened (partially used) products
// Opened (partially used conf products with known package capacity)
const openedSection = document.getElementById('alert-opened');
const openedList = document.getElementById('opened-list');
if (statsData.opened && statsData.opened.length > 0) {
@@ -823,37 +823,19 @@ async function loadDashboard() {
const locInfo = LOCATIONS[item.location] || { icon: '📦', label: item.location };
const qty = parseFloat(item.quantity);
const pkgSize = parseFloat(item.default_quantity);
const unit = item.unit;
const pkgUnit = item.package_unit;
const unitLabels = { 'ml': 'ml', 'l': 'L', 'g': 'g', 'kg': 'kg', 'pz': 'pz' };
const unitLabels = { 'ml': 'ml', 'l': 'L', 'g': 'g', 'kg': 'kg' };
const pkgLabel = unitLabels[pkgUnit] || pkgUnit;
const wholeConf = Math.floor(qty + 0.001);
const frac = Math.round((qty - wholeConf) * 1000) / 1000;
const remainderAmt = frac * pkgSize;
const remainderText = formatSubRemainder(remainderAmt, pkgUnit);
let qtyText = '';
if (unit === 'conf' && pkgUnit && pkgSize > 0) {
// Conf product: show whole conf + remainder in sub-unit
const wholeConf = Math.floor(qty + 0.001);
const frac = Math.round((qty - wholeConf) * 1000) / 1000;
const remainderAmt = frac * pkgSize;
const remainderText = formatSubRemainder(remainderAmt, pkgUnit);
const pkgLabel = unitLabels[pkgUnit] || pkgUnit;
if (wholeConf > 0) {
qtyText = `${wholeConf} conf (da ${pkgSize}${pkgLabel}) + ${remainderText}`;
} else {
qtyText = remainderText;
}
if (wholeConf > 0) {
qtyText = `${wholeConf} conf (da ${pkgSize}${pkgLabel}) + ${remainderText}`;
} else {
// Non-conf product: show qty / package size
const wholePacks = Math.floor(qty / pkgSize + 0.001);
const remainder = Math.round((qty - wholePacks * pkgSize) * 100) / 100;
const uLabel = unitLabels[unit] || unit;
if (wholePacks > 0 && remainder > 0) {
qtyText = `${wholePacks} × ${pkgSize}${uLabel} + ${Math.round(remainder)}${uLabel}`;
} else if (remainder > 0) {
qtyText = `${Math.round(qty)}${uLabel} / ${pkgSize}${uLabel}`;
} else {
qtyText = `${qty} ${uLabel}`;
}
qtyText = remainderText;
}
return `
<div class="alert-item alert-item-clickable" onclick="showAlertItemDetail(${item.id}, ${item.product_id})">
<div class="alert-item-info">
+1 -1
View File
@@ -884,6 +884,6 @@
</div>
</div>
<script src="assets/js/app.js?v=20260313.2"></script>
<script src="assets/js/app.js?v=20260313.3"></script>
</body>
</html>