const Product = require('../models/Product'); const { validationResult } = require('express-validator'); // @desc Get all products // @route GET /api/products // @access Private (all roles, but filtered by company) exports.getProducts = async (req, res, next) => { try { let query = {}; // Filter products by company if (req.user.role !== 'superadmin') { query.companyId = req.user.companyId; } else if (req.query.companyId) { // Superadmin can filter by company query.companyId = req.query.companyId; } const products = await Product.find(query) .populate('companyId', 'name') .populate('createdBy', 'email'); res.status(200).json({ success: true, count: products.length, data: products }); } catch (error) { next(error); } }; // @desc Get single product // @route GET /api/products/:id // @access Private (all roles, but filtered by company) exports.getProduct = async (req, res, next) => { try { const product = await Product.findById(req.params.id) .populate('companyId', 'name') .populate('createdBy', 'email'); if (!product) { return res.status(404).json({ success: false, message: 'Product not found' }); } // Check if user has access to this product if (req.user.role !== 'superadmin' && product.companyId._id.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to access this product' }); } res.status(200).json({ success: true, data: product }); } catch (error) { next(error); } }; // @desc Create product // @route POST /api/products // @access Private (all roles, but company is restricted) exports.createProduct = async (req, res, next) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, errors: errors.array() }); } // Set company ID based on user role let companyId; if (req.user.role === 'superadmin' && req.body.companyId) { // Superadmin can specify company companyId = req.body.companyId; } else { // Other roles can only add products to their own company companyId = req.user.companyId; } const product = await Product.create({ ...req.body, companyId, createdBy: req.user._id }); res.status(201).json({ success: true, data: product }); } catch (error) { next(error); } }; // @desc Update product // @route PUT /api/products/:id // @access Private (all roles, but company is restricted) exports.updateProduct = async (req, res, next) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, errors: errors.array() }); } let product = await Product.findById(req.params.id); if (!product) { return res.status(404).json({ success: false, message: 'Product not found' }); } // Check if user has access to this product if (req.user.role !== 'superadmin' && product.companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to update this product' }); } // Prevent changing companyId for non-superadmin users if (req.user.role !== 'superadmin' && req.body.companyId && req.body.companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to change company for this product' }); } product = await Product.findByIdAndUpdate( req.params.id, req.body, { new: true, runValidators: true } ) .populate('companyId', 'name') .populate('createdBy', 'email'); res.status(200).json({ success: true, data: product }); } catch (error) { next(error); } }; // @desc Delete product // @route DELETE /api/products/:id // @access Private (all roles, but company is restricted) exports.deleteProduct = async (req, res, next) => { try { const product = await Product.findById(req.params.id); if (!product) { return res.status(404).json({ success: false, message: 'Product not found' }); } // Check if user has access to this product if (req.user.role !== 'superadmin' && product.companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to delete this product' }); } await product.deleteOne(); res.status(200).json({ success: true, data: {} }); } catch (error) { next(error); } };