fix: bilancia ricette attende ≥5g di variazione; sale spurio in Bring!
- Recipe use modal: reset _scaleLastConfirmedGrams al peso attuale prima di aprire il modale, così la tara ha tempo; soglia ridotta 10→5g - PHP useFromInventory: prima di auto-aggiungere a Bring! un prodotto esaurito, controlla se la famiglia shopping_name ha scorte da altri prodotti (es. 'Sale marino iodato' esaurito ma 3kg di altri sali in dispensa → non aggiunge) JS, così il cron bringCleanupObsolete può auto-rimuovere - Rimosso manualmente 'Sale' da Bring! (aggiunto senza marker dalla vecchia logica)
This commit is contained in:
+24
-2
@@ -1374,6 +1374,26 @@ function useFromInventory(PDO $db): void {
|
||||
$product = $stmt->fetch();
|
||||
|
||||
if ($product) {
|
||||
// Before adding to Bring!, check if the shopping_name family already
|
||||
// has adequate stock from OTHER products (e.g. "Sale marino iodato" depleted
|
||||
// but "Sale alimentare" has 1kg → no need to add to shopping list).
|
||||
$sNameKey = strtolower(trim($product['shopping_name'] ?? ''));
|
||||
$familyCoverage = 0;
|
||||
if ($sNameKey !== '') {
|
||||
$covStmt = $db->prepare("
|
||||
SELECT SUM(i.quantity)
|
||||
FROM inventory i
|
||||
JOIN products p ON i.product_id = p.id
|
||||
WHERE LOWER(TRIM(p.shopping_name)) = ? AND i.product_id != ? AND i.quantity > 0
|
||||
");
|
||||
$covStmt->execute([$sNameKey, $productId]);
|
||||
$familyCoverage = (float)($covStmt->fetchColumn() ?: 0);
|
||||
}
|
||||
if ($familyCoverage > 0) {
|
||||
// Family has stock — no need to restock, suppress Bring! add.
|
||||
// Set addedToBring=true so the JS fallback is also suppressed.
|
||||
$addedToBring = true;
|
||||
} else {
|
||||
try {
|
||||
$auth = bringAuth();
|
||||
if ($auth) {
|
||||
@@ -1399,9 +1419,10 @@ function useFromInventory(PDO $db): void {
|
||||
$addedToBring = false;
|
||||
} else {
|
||||
// Specification: specific product name (and brand) so the user knows which variant
|
||||
// Add 🛒 marker so the cron cleanup can auto-remove if no longer needed.
|
||||
$spec = $genericName !== $product['name']
|
||||
? $product['name'] . ($product['brand'] ? ' · ' . $product['brand'] : '')
|
||||
: ($product['brand'] ?: $product['name']);
|
||||
? $product['name'] . ($product['brand'] ? ' · ' . $product['brand'] : '') . ' · 🛒 Esaurito'
|
||||
: ($product['brand'] ?: $product['name']) . ' · 🛒 Esaurito';
|
||||
$body = http_build_query([
|
||||
'uuid' => $listUUID,
|
||||
'purchase' => $bringName,
|
||||
@@ -1420,6 +1441,7 @@ function useFromInventory(PDO $db): void {
|
||||
} catch (Exception $e) {
|
||||
// Silently fail — don't block inventory operation
|
||||
}
|
||||
} // end else (family not covered)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-5
@@ -624,8 +624,9 @@ function _scaleAutoFillRecipeUse(msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reject if weight hasn't changed enough from last confirmed reading
|
||||
if (_scaleLastConfirmedGrams !== null && Math.abs(grams - _scaleLastConfirmedGrams) < 10) {
|
||||
// Reject if weight hasn't changed enough from last confirmed reading.
|
||||
// Threshold: 5g — gives enough time to tare after opening the modal.
|
||||
if (_scaleLastConfirmedGrams !== null && Math.abs(grams - _scaleLastConfirmedGrams) < 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7651,8 +7652,8 @@ function showLowStockBringPrompt(result, afterCallback) {
|
||||
// configured, or product already on list), silently attempt it from JS.
|
||||
if (!result.added_to_bring && shoppingName) {
|
||||
// Fire-and-forget — don't block the callback
|
||||
// Use generic shopping name; specific name goes into specification.
|
||||
const spec = shoppingName !== name ? name + (result.product_brand ? ` · ${result.product_brand}` : '') : '';
|
||||
// Use generic shopping name; specific name + 🛒 marker in spec so cron cleanup can auto-remove.
|
||||
const spec = (shoppingName !== name ? name + (result.product_brand ? ` · ${result.product_brand}` : '') : name) + ' · 🛒 Esaurito';
|
||||
(async () => {
|
||||
try {
|
||||
const payload = { items: [{ name: shoppingName, specification: spec }] };
|
||||
@@ -11150,7 +11151,16 @@ async function useRecipeIngredient(idx, productId, location, qtyNumber, btn, rec
|
||||
|
||||
_recipeUseContext = { idx, productId, btn, qtyNumber, recipeQty };
|
||||
_recipeUseConfMode = null;
|
||||
|
||||
|
||||
// Reset scale state: set the current weight as baseline so only a *change*
|
||||
// of ≥5g after the modal opens triggers auto-fill (allows time to tare).
|
||||
_cancelScaleAutoConfirm(false);
|
||||
_scaleRecipeAutoFillPaused = false;
|
||||
if (_scaleLatestWeight) {
|
||||
const _baseline = _scaleToGrams(parseFloat(_scaleLatestWeight.value), _scaleLatestWeight.unit);
|
||||
if (_baseline !== null && _baseline >= 5) _scaleLastConfirmedGrams = _baseline;
|
||||
}
|
||||
|
||||
// Fetch inventory to build the modal
|
||||
try {
|
||||
const data = await api('inventory_list');
|
||||
|
||||
+1
-1
@@ -1462,6 +1462,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="assets/js/app.js?v=20260510j"></script>
|
||||
<script src="assets/js/app.js?v=20260510k"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user