REDROOM
PHP 8.2.30
Path:
Logout
Edit File
Size: 12.15 KB
Close
//home/byroehnu/easepay.easetack.com/controllers/inventoryController.js
Text
Base64
const { prisma } = require('../config/prisma'); const inventoryController = { // Get all inventory items getAllItems: async (req, res) => { try { const userId = req.user.id; const businessId = req.user.businessId; const { page = 1, limit = 20, category, search, includeInactive = false } = req.query; const whereClause = { userId, ...(businessId && { businessId }), ...(category && { category }), ...(search && { OR: [ { name: { contains: search, mode: 'insensitive' } }, { description: { contains: search, mode: 'insensitive' } } ] }), ...(includeInactive === 'false' && { isActive: true }) }; const items = await prisma.inventoryItem.findMany({ where: whereClause, orderBy: { name: 'asc' }, skip: (parseInt(page) - 1) * parseInt(limit), take: parseInt(limit) }); const totalItems = await prisma.inventoryItem.count({ where: whereClause }); res.json({ success: true, data: { items, pagination: { currentPage: parseInt(page), totalPages: Math.ceil(totalItems / parseInt(limit)), totalItems, limit: parseInt(limit) } } }); } catch (error) { console.error('Error getting inventory items:', error); res.status(500).json({ success: false, message: 'Error getting inventory items', error: error.message }); } }, // Get single inventory item getItem: async (req, res) => { try { const { id } = req.params; const userId = req.user.id; const item = await prisma.inventoryItem.findFirst({ where: { id, userId }, include: { invoiceItems: { include: { invoice: { select: { id: true, invoiceNumber: true, customerName: true, invoiceDate: true, total: true } } }, orderBy: { createdAt: 'desc' }, take: 10 } } }); if (!item) { return res.status(404).json({ success: false, message: 'Item not found' }); } res.json({ success: true, data: item }); } catch (error) { console.error('Error getting inventory item:', error); res.status(500).json({ success: false, message: 'Error getting inventory item', error: error.message }); } }, // Create new inventory item createItem: async (req, res) => { try { const userId = req.user.id; const businessId = req.user.businessId; const { name, description, category, unitPrice, costPrice, stock = 0, unit, minStock } = req.body; // Validate required fields if (!name || !unitPrice) { return res.status(400).json({ success: false, message: 'Name and unit price are required' }); } const item = await prisma.inventoryItem.create({ data: { name, description, category, unitPrice: parseFloat(unitPrice), costPrice: costPrice ? parseFloat(costPrice) : null, stock: parseFloat(stock), unit, minStock: minStock ? parseFloat(minStock) : null, userId, businessId } }); res.status(201).json({ success: true, message: 'Item created successfully', data: item }); } catch (error) { console.error('Error creating inventory item:', error); res.status(500).json({ success: false, message: 'Error creating inventory item', error: error.message }); } }, // Update inventory item updateItem: async (req, res) => { try { const { id } = req.params; const userId = req.user.id; const updateData = req.body; // Check if item exists and belongs to user const existingItem = await prisma.inventoryItem.findFirst({ where: { id, userId } }); if (!existingItem) { return res.status(404).json({ success: false, message: 'Item not found' }); } // Convert numeric fields if (updateData.unitPrice) updateData.unitPrice = parseFloat(updateData.unitPrice); if (updateData.costPrice) updateData.costPrice = parseFloat(updateData.costPrice); if (updateData.stock !== undefined) updateData.stock = parseFloat(updateData.stock); if (updateData.minStock) updateData.minStock = parseFloat(updateData.minStock); const updatedItem = await prisma.inventoryItem.update({ where: { id }, data: updateData }); res.json({ success: true, message: 'Item updated successfully', data: updatedItem }); } catch (error) { console.error('Error updating inventory item:', error); res.status(500).json({ success: false, message: 'Error updating inventory item', error: error.message }); } }, // Delete inventory item deleteItem: async (req, res) => { try { const { id } = req.params; const userId = req.user.id; const item = await prisma.inventoryItem.findFirst({ where: { id, userId } }); if (!item) { return res.status(404).json({ success: false, message: 'Item not found' }); } await prisma.inventoryItem.delete({ where: { id } }); res.json({ success: true, message: 'Item deleted successfully' }); } catch (error) { console.error('Error deleting inventory item:', error); res.status(500).json({ success: false, message: 'Error deleting inventory item', error: error.message }); } }, // Update stock for multiple items updateStock: async (req, res) => { try { const userId = req.user.id; const { updates } = req.body; // Array of { id, quantity, operation: 'add' | 'subtract' | 'set' } if (!Array.isArray(updates) || updates.length === 0) { return res.status(400).json({ success: false, message: 'Updates array is required' }); } const results = []; for (const update of updates) { const { id, quantity, operation = 'set' } = update; const item = await prisma.inventoryItem.findFirst({ where: { id, userId } }); if (!item) { results.push({ id, success: false, message: 'Item not found' }); continue; } let newStock; switch (operation) { case 'add': newStock = parseFloat(item.stock) + parseFloat(quantity); break; case 'subtract': newStock = parseFloat(item.stock) - parseFloat(quantity); break; case 'set': default: newStock = parseFloat(quantity); break; } if (newStock < 0) { results.push({ id, success: false, message: 'Stock cannot be negative' }); continue; } const updatedItem = await prisma.inventoryItem.update({ where: { id }, data: { stock: newStock } }); results.push({ id, success: true, newStock: updatedItem.stock }); } res.json({ success: true, message: 'Stock update completed', data: results }); } catch (error) { console.error('Error updating stock:', error); res.status(500).json({ success: false, message: 'Error updating stock', error: error.message }); } }, // Get low stock items getLowStockItems: async (req, res) => { try { const userId = req.user.id; const businessId = req.user.businessId; const lowStockItems = await prisma.inventoryItem.findMany({ where: { userId, ...(businessId && { businessId }), isActive: true, minStock: { not: null }, OR: [ { stock: { lte: { minStock: true } } } ] }, orderBy: { stock: 'asc' } }); res.json({ success: true, data: { lowStockItems, count: lowStockItems.length } }); } catch (error) { console.error('Error getting low stock items:', error); res.status(500).json({ success: false, message: 'Error getting low stock items', error: error.message }); } }, // Get inventory categories getCategories: async (req, res) => { try { const userId = req.user.id; const businessId = req.user.businessId; const categories = await prisma.inventoryItem.findMany({ where: { userId, ...(businessId && { businessId }), category: { not: null }, isActive: true }, select: { category: true }, distinct: ['category'] }); const categoryList = categories .map(item => item.category) .filter(category => category && category.trim() !== '') .sort(); res.json({ success: true, data: { categories: categoryList } }); } catch (error) { console.error('Error getting categories:', error); res.status(500).json({ success: false, message: 'Error getting categories', error: error.message }); } }, // Get inventory analytics getInventoryAnalytics: async (req, res) => { try { const userId = req.user.id; const businessId = req.user.businessId; const whereClause = { userId, ...(businessId && { businessId }), isActive: true }; const analytics = await prisma.inventoryItem.aggregate({ where: whereClause, _count: { id: true }, _sum: { stock: true, unitPrice: true, costPrice: true }, _avg: { unitPrice: true, stock: true } }); const categoryBreakdown = await prisma.inventoryItem.groupBy({ by: ['category'], where: whereClause, _count: { category: true }, _sum: { stock: true, unitPrice: true } }); // Calculate total inventory value const inventoryValue = await prisma.inventoryItem.findMany({ where: whereClause, select: { stock: true, unitPrice: true, costPrice: true } }); const totalValue = inventoryValue.reduce((sum, item) => { return sum + (parseFloat(item.stock) * parseFloat(item.unitPrice)); }, 0); const totalCost = inventoryValue.reduce((sum, item) => { return sum + (parseFloat(item.stock) * parseFloat(item.costPrice || 0)); }, 0); res.json({ success: true, data: { totalItems: analytics._count.id, totalStock: analytics._sum.stock || 0, averagePrice: analytics._avg.unitPrice || 0, averageStock: analytics._avg.stock || 0, totalInventoryValue: totalValue, totalInventoryCost: totalCost, potentialProfit: totalValue - totalCost, categoryBreakdown } }); } catch (error) { console.error('Error getting inventory analytics:', error); res.status(500).json({ success: false, message: 'Error getting inventory analytics', error: error.message }); } } }; module.exports = inventoryController;
Save
Close
Exit & Reset
Text mode: syntax highlighting auto-detects file type.
Directory Contents
Dirs: 1 × Files: 17
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
controllers
DIR
-
drwxr-xr-x
2026-03-20 23:25:48
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
.htaccess
127 B
lr--r--r--
2026-03-14 01:49:22
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
advancedAuthController.js
15.34 KB
lrw-r--r--
2026-02-19 22:06:47
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
authController.js
30.77 KB
lrw-r--r--
2026-03-04 06:33:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
authController_copy.js
62.98 KB
lrw-r--r--
2026-03-01 23:46:52
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
businessController.js
10.79 KB
lrw-r--r--
2026-02-07 16:28:16
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
businessProfileController.js
14.17 KB
lrw-r--r--
2026-02-27 04:02:38
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
creditScoreController.js
6.32 KB
lrw-r--r--
2026-02-06 17:10:19
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
dashboardController.js
15.13 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
expenseController.js
8.50 KB
lrw-r--r--
2026-03-01 05:05:52
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
inventoryController.js
12.15 KB
lrw-r--r--
2026-02-27 04:02:38
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
invoiceController.js
25.39 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
reportController.js
17.61 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
saleController.js
6.45 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
settingsController.js
2.33 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
subscriptionController.js
12.78 KB
lrw-r--r--
2026-02-21 08:13:30
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
taxController.js
9.96 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
webhookController.js
8.51 KB
lrw-r--r--
2026-02-20 19:31:28
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).