var router = require('express').Router(), mongoose = require('mongoose'), Product = mongoose.model('Product'), User = mongoose.model('User'), Metal = mongoose.model('Metal'); const auth = require('../auth'); // Preload product objects on routes with ':product' router.param('product', function (req, res, next, slug) { Product.findOne({ slug: slug }) .populate('author') .populate('metal') .then(function (product) { if (!product) { return res.sendStatus(404); } req.product = product; return next(); }).catch(next); }); router.get('/', auth.required, function (req, res, next) { var query = {}; var limit = 20; var offset = 0; if (typeof req.query.limit !== 'undefined') { limit = req.query.limit; } if (typeof req.query.offset !== 'undefined') { offset = req.query.offset; } if (typeof req.query.title !== 'undefined') { const rgx = new RegExp(`.*${req.query.title}.*`); query = { $or: [ { title: { $regex: rgx, $options: "i" } }, { slug: { $regex: rgx, $options: "i" } }, ], } } Promise.all([ req.query.author ? User.findOne({ username: req.query.author }) : null, req.query.favorited ? User.findOne({ username: req.query.favorited }) : null ]).then(function (users) { var author = users[0]; var favoriter = users[1]; if (author) { query.author = author._id; } if (favoriter) { query._id = { $in: favoriter.favorites }; } else if (req.query.favorited) { query._id = { $in: [] }; } return Promise.all([ Product.find(query) .limit(Number(limit)) .skip(Number(offset)) .sort({ ordering: 'asc' }) .populate('author') .populate('metal') .exec(), Product.count(query).exec(), req.payload ? User.findById(req.payload.id) : null ]).then(function (results) { var products = results[0]; var productsCount = results[1]; var user = results[2]; return res.json({ products: products.map(function (product) { return product.toJSONFor(user); }), productsCount: productsCount }); }); }).catch(next); }); router.get('/feed', auth.required, function (req, res, next) { var limit = 20; var offset = 0; if (typeof req.query.limit !== 'undefined') { limit = req.query.limit; } if (typeof req.query.offset !== 'undefined') { offset = req.query.offset; } User.findById(req.payload.id).then(function (user) { if (!user) { return res.sendStatus(401); } var query = { author: { $in: user.following } }; Promise.all([ Product.find(query) .limit(Number(limit)) .skip(Number(offset)) .populate('author') .populate('metal') .exec(), Product.count(query) ]).then(function (results) { var products = results[0]; var productsCount = results[1]; return res.json({ products: products.map(function (product) { return product.toJSONFor(user); }), productsCount: productsCount }); }).catch(next); }); }); router.post('/', auth.required, function (req, res, next) { Promise.all([ req.payload ? User.findById(req.payload.id) : null, Metal.findOne({ code: req.body.product.metal.code }).exec(), Product .find({}).select('ordering') .sort({"ordering" : -1}).limit(1) .exec() ]).then(function (results) { var user = results[0]; var metal = results[1]; var ordering = (results[2][0].ordering + 1); if (!user) { return res.sendStatus(401); } var product = new Product(req.body.product); product.author = user; product.metal = metal; product.ordering = ordering; return product.save().then(function () { return res.json({ product: product.toJSONFor(user) }); }); }).catch(next); }); // return a product router.get('/:product', auth.optional, function (req, res, next) { Promise.all([ req.payload ? User.findById(req.payload.id) : null, req.product.populate('author'), req.product.populate('metal') ]).then(function (results) { var user = results[0]; return res.json({ product: req.product.toJSONFor(user) }); }).catch(next); }); router.put('/:product', auth.required, function (req, res, next) { Promise.all([ req.payload ? User.findById(req.payload.id) : null, Metal.findOne({ code: req.body.product.metal.code }).exec() ]).then(function (results) { var user = results[0]; var metal = results[1]; if (!user) { return res.sendStatus(401); } if (req.product.author._id.toString() !== req.payload.id.toString()) { return res.sendStatus(403); } if (typeof req.body.product.title !== 'undefined') { req.product.title = req.body.product.title; } if (typeof req.body.product.prime_achat !== 'undefined') { req.product.prime_achat = req.body.product.prime_achat; } if (typeof req.body.product.prime_vente !== 'undefined') { req.product.prime_vente = req.body.product.prime_vente; } if (typeof req.body.product.poids !== 'undefined') { req.product.poids = req.body.product.poids; } req.product.metal = metal; return req.product.save().then(function (product) { return res.json({ product: product.toJSONFor(user) }); }); }).catch(next); }); // delete product router.delete('/:product', auth.required, function (req, res, next) { User.findById(req.payload.id).then(function (user) { if (!user) { return res.sendStatus(401); } if (req.product.author._id.toString() === req.payload.id.toString()) { return req.product.remove().then(function () { return res.sendStatus(204); }); } else { return res.sendStatus(403); } }).catch(next); }); // Favorite an product router.post('/:product/favorite', auth.required, function (req, res, next) { var productId = req.product._id; User.findById(req.payload.id).then(function (user) { if (!user) { return res.sendStatus(401); } return user.favorite(productId).then(function () { return req.product.updateFavoriteCount().then(function (product) { return res.json({ product: product.toJSONFor(user) }); }); }); }).catch(next); }); // Unfavorite an product router.delete('/:product/favorite', auth.required, function (req, res, next) { var productId = req.product._id; User.findById(req.payload.id).then(function (user) { if (!user) { return res.sendStatus(401); } return user.unfavorite(productId).then(function () { return req.product.updateFavoriteCount().then(function (product) { return res.json({ product: product.toJSONFor(user) }); }); }); }).catch(next); }); module.exports = router;