inventario/backend/src/routes/items.ts
2025-07-02 22:29:39 +02:00

142 lines
4.1 KiB
TypeScript

import { Router } from 'express';
import Item from '../models/Item.js';
import Tag from '../models/Tag.js';
import auth from '../middleware/auth.js';
const router = Router();
/* ──────────── GET: lista completa ──────────── */
router.get('/', async (_req, res) => {
const items = await Item.find().populate('tags');
res.json(items);
});
/* ──────────── GET: ricerca ──────────── */
router.get('/search', async (req, res) => {
const { query = '', tagIds = '' } = req.query as {
query?: string;
tagIds?: string;
};
const regex = new RegExp(query, 'i');
const filter: any = {
$and: [
{ $or: [{ name: regex }, { description: regex }] },
tagIds ? { tags: { $in: tagIds.split(',') } } : {},
],
};
res.json(await Item.find(filter).populate('tags'));
});
/* ──────────── POST: crea item ──────────── */
router.post('/', auth, async (req, res) => {
const { name, description, tagIds, quantity = 0, used = false } = req.body as {
name: string;
description: string;
tagIds: string[];
quantity?: number;
used?: number;
};
const tags = await Tag.find({ _id: { $in: tagIds } });
const item = await Item.create({
name,
description,
tags,
quantity,
used,
addedBy: req.user!.email,
});
res.status(201).json(await item.populate('tags'));
});
/* ──────────── PUT: aggiorna intero item ──────────── */
router.put('/:id', auth, async (req, res) => {
const { id } = req.params;
const { name, description, tagIds, quantity } = req.body as {
name?: string;
description?: string;
tagIds?: string[];
quantity?: number;
};
const update: any = {};
if (name !== undefined) update.name = name;
if (description !== undefined) update.description = description;
if (quantity !== undefined) update.quantity = quantity;
if (tagIds) update.tags = await Tag.find({ _id: { $in: tagIds } });
const item = await Item.findByIdAndUpdate(id, update, { new: true }).populate('tags');
if (!item) {
res.status(404).json({ message: 'Item non trovato' });
return;
}
res.json(item);
});
/* ──────────── PATCH: modifica solo la quantità ──────────── */
router.patch('/:id/quantity', auth, async (req, res) => {
const { id } = req.params;
const { quantity } = req.body as { quantity: number };
if (quantity < 0) {
res.status(400).json({ message: 'La quantità non può essere negativa' });
return;
}
const item = await Item.findById(id);
if (!item) {
res.status(404).json({ message: 'Item non trovato' });
return;
}
if (item.used > quantity) {
res.status(400).json({ message: 'La quantità non può essere inferiore alla quantità utilizzata' });
return;
}
item.quantity = quantity;
await item.save();
res.json(await item.populate('tags'));
});
/* ──────────── PATCH: modifica solo la quantità utilizzata ──────────── */
router.patch('/:id/usedquantity', auth, async (req, res) => {
const { id } = req.params;
const { quantity } = req.body as { quantity: number };
if (quantity < 0) {
res.status(400).json({ message: 'La quantità utilizzata non può essere negativa' });
return;
}
const item = await Item.findById(id);
if (!item) {
res.status(404).json({ message: 'Item non trovato' });
return;
}
if (quantity > item.quantity) {
res.status(400).json({ message: 'La quantità utilizzata non può essere maggiore della quantità totale' });
return;
}
item.used = quantity;
await item.save();
res.json(await item.populate('tags'));
});
/* ──────────── DELETE: elimina item ──────────── */
router.delete('/:id', auth, async (req, res) => {
const { id } = req.params;
const deleted = await Item.findByIdAndDelete(id);
if (!deleted) {
res.status(404).json({ message: 'Item non trovato' });
return;
}
res.status(204).end();
});
export default router;