Compare commits

..

2 Commits

Author SHA1 Message Date
Luigi Negri e52fb1d7d1 Update server.js 2026-01-30 11:08:58 +00:00
Luigi Negri 0baa651b43 Merge pull request 'Update db.js' (#1) from lnegri-db-inventario-1 into main
Reviewed-on: #1
2026-01-30 11:04:56 +00:00
1 changed files with 169 additions and 0 deletions

169
server.js
View File

@ -81,5 +81,174 @@ app.delete('/api/cocktails/:id', (req, res) => {
});
});
// =========================
// INVENTARIO BOTTIGLIE
// =========================
// Get all inventory items
app.get('/api/inventory', (req, res) => {
const sql = `
SELECT ii.*, ing.name AS ingredient_name
FROM inventory_items ii
JOIN ingredients ing ON ing.id = ii.ingredient_id
WHERE ii.is_active = 1
ORDER BY ing.name, ii.brand
`;
db.all(sql, [], (err, rows) => {
if (err) return res.status(500).json({ error: err.message });
res.json(rows);
});
});
// Get single inventory item
app.get('/api/inventory/:id', (req, res) => {
const { id } = req.params;
const sql = `
SELECT ii.*, ing.name AS ingredient_name
FROM inventory_items ii
JOIN ingredients ing ON ing.id = ii.ingredient_id
WHERE ii.id = ?
`;
db.get(sql, [id], (err, row) => {
if (err) return res.status(500).json({ error: err.message });
if (!row) return res.status(404).json({ error: 'Not found' });
res.json(row);
});
});
// Create inventory item
app.post('/api/inventory', (req, res) => {
const {
ingredient_id,
brand,
label_name,
barcode,
bottle_size_ml,
bottle_type,
origin_country,
region,
style,
abv,
current_level_fraction,
current_level_ml,
condition,
location,
storage_notes,
opened_at,
purchase_price,
purchase_currency,
purchase_date,
supplier,
par_level_bottles,
reorder_point_bottles,
reorder_qty_bottles,
status,
is_collectible,
personal_rating,
tasting_notes
} = req.body;
const sql = `
INSERT INTO inventory_items (
ingredient_id, brand, label_name, barcode,
bottle_size_ml, bottle_type, origin_country, region, style, abv,
current_level_fraction, current_level_ml, condition, location, storage_notes, opened_at,
purchase_price, purchase_currency, purchase_date, supplier,
par_level_bottles, reorder_point_bottles, reorder_qty_bottles, status,
is_collectible, personal_rating, tasting_notes, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
`;
const params = [
ingredient_id, brand, label_name, barcode,
bottle_size_ml, bottle_type, origin_country, region, style, abv,
current_level_fraction, current_level_ml, condition, location, storage_notes, opened_at,
purchase_price, purchase_currency, purchase_date, supplier,
par_level_bottles, reorder_point_bottles, reorder_qty_bottles, status,
is_collectible, personal_rating, tasting_notes
];
db.run(sql, params, function (err) {
if (err) return res.status(500).json({ error: err.message });
res.status(201).json({ id: this.lastID });
});
});
// Update inventory item
app.put('/api/inventory/:id', (req, res) => {
const { id } = req.params;
const body = req.body;
const fields = [
'ingredient_id','brand','label_name','barcode',
'bottle_size_ml','bottle_type','origin_country','region','style','abv',
'current_level_fraction','current_level_ml','condition','location','storage_notes','opened_at',
'purchase_price','purchase_currency','purchase_date','supplier',
'par_level_bottles','reorder_point_bottles','reorder_qty_bottles','status',
'is_collectible','personal_rating','tasting_notes'
];
const setClauses = [];
const params = [];
fields.forEach(f => {
if (Object.prototype.hasOwnProperty.call(body, f)) {
setClauses.push(`${f} = ?`);
params.push(body[f]);
}
});
if (setClauses.length === 0) {
return res.status(400).json({ error: 'No fields to update' });
}
const sql = `
UPDATE inventory_items
SET ${setClauses.join(', ')}, updated_at = datetime('now')
WHERE id = ?
`;
params.push(id);
db.run(sql, params, function (err) {
if (err) return res.status(500).json({ error: err.message });
if (this.changes === 0) return res.status(404).json({ error: 'Not found' });
res.json({ success: true });
});
});
// Soft delete inventory item
app.delete('/api/inventory/:id', (req, res) => {
const { id } = req.params;
const sql = `
UPDATE inventory_items
SET is_active = 0, updated_at = datetime('now')
WHERE id = ?
`;
db.run(sql, [id], function (err) {
if (err) return res.status(500).json({ error: err.message });
if (this.changes === 0) return res.status(404).json({ error: 'Not found' });
res.json({ success: true });
});
});
// Cocktail completamente fattibili con l'inventario attuale
app.get('/api/cocktails/available', (req, res) => {
const sql = `
SELECT c.*
FROM cocktails c
JOIN cocktail_ingredients ci ON ci.cocktail_id = c.id
LEFT JOIN inventory_items ii
ON ii.ingredient_id = ci.ingredient_id
AND ii.status IN ('in_stock', 'low')
AND ii.is_active = 1
GROUP BY c.id
HAVING COUNT(DISTINCT ci.ingredient_id) = COUNT(DISTINCT ii.ingredient_id)
`;
db.all(sql, [], (err, rows) => {
if (err) return res.status(500).json({ error: err.message });
res.json(rows);
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server su http://localhost:${PORT}`));