const Category = require('../models/Category'); const Content = require('../models/Content'); const {body, validationResult} = require('express-validator'); const {_sr} = require('../plugins/serverResponses'); const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions'); const News = require('../models/News'); const sharp = require('sharp') const fs = require('fs') // variables const titleFilterRegex = new RegExp('/', 'g') const noCover = '/img/no-cover.jpg' const coverNewsWidth = 400; const coverNewsHeight = 400; const coverQuality = 100; ////////////////// functions const _customTitle = async (categories) => { try { const newCatArr = []; for (const item of categories) { const title = []; const treeCat = item.treeCat; for (let i = treeCat.length - 1; i >= 0; i--) { title.push(treeCat[i].title); } title.push(item.title); item.title = title.join(" >> "); newCatArr.push(item); } return newCatArr; } catch (error) { console.log(error) return [] } } /** یک آرایه داریم که خونه اول رو میگیریم و میریزیم داخل آرایه جدید بعد داخل فور دوم کل آرایه رو طی میکنیم * و اونایی که قسمتی از تایتل دیتای پوش شده داخل آرایه جدید رو دارن داخل این آرایه جدید پوش میکنیم */ // todo this is peace of shit please change it in future const _sortedCategory = async (categories) => { try { let sortedArr = []; // let clone = JSON.parse(JSON.stringify(categories)); // // for (const cat of clone) { // if (cat.parent){ // let getParent = categories.find(item => item._id === cat.parent._id) // } // } for (let i = 0; i < categories.length; i++) { if (!sortedArr.includes(categories[i]) && !categories[i].parent) { sortedArr.push(categories[i]); } for (let j = 0; j < categories.length; j++) { if (categories[i].childs.includes(categories[j]._id) && !sortedArr.includes(categories[j])) { sortedArr.push(categories[j]); } } } if (sortedArr.length !== categories.length) { for (const cat of categories) { if (!sortedArr.includes(cat)) { sortedArr.push(cat); } } } return sortedArr; } catch (error) { console.log(error) return [] } } const _checkSpecPermission = async (req, category) => { return !req.user.specialPermissions.includes(category._id) && //check parent id exist in special permissions or not !req.user.specialPermissions.some(item => category?.treeCat?.join().includes(item)); } /////////////////////////////////////////////////////////////////////// admin module.exports.addCategory = [ [ body('title') .notEmpty().withMessage(_sr['fa'].required.title) .custom((value, { req }) => { return Category.findOne({ title: value }) .then(category => { if (category) return Promise.reject(_sr['fa'].duplicated.title); else return true }) }), body('parent') .optional().isString().withMessage(`parent ${_sr['fa'].optional.string}`), // body('showInMenu') // .isBoolean().withMessage(_sr['fa'].format.boolean), body('navIndex') .optional().isNumeric().withMessage(_sr['fa'].format.number), body('priority') .isNumeric().withMessage(_sr['fa'].format.number), // body('showInSectionOne') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // // body('showInSectionTwo') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // // body('showInSectionThree') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('siteMap') .isBoolean().withMessage(_sr['fa'].format.boolean), body('special') .isBoolean().withMessage(_sr['fa'].format.boolean), body('url') .optional().isString().withMessage(`url ${_sr['fa'].optional.string}`), body('pageContent') .optional().isString().withMessage(`pageContent ${_sr['fa'].optional.string}`), body('news') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('child') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNewsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasContentTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasMediaTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasSubMenusTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasTermsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNotificationsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasSpecNewsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNazarTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNewsFileTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('modelType') .custom((value, { req }) => { if (req.user.portals.join() === portal.join()) { if (!portal.includes(value)) { return Promise.reject(_sr['fa'].required.field); } else { return true } } else { return true } }) ], checkValidations(validationResult), async (req, res) => { try { let { title, parent, // showInMenu, navIndex, priority, // showInSectionOne, // showInSectionTwo, // showInSectionThree, siteMap, special, modelType, showInFooter, url, pageContent, news, child, hasNewsTab, hasContentTab, hasMediaTab, hasSubMenusTab, hasTermsTab, hasNotificationsTab, hasSpecNewsTab, hasNazarTab, hasNewsFileTab, defaultPageType, hasManagerInfo, managerName, managerDescription } = req.body; ///////////// permissions if (req.user.specialPermissions.length && _.isEmpty(parent)) { return res.status(403).json({ message: `شما مجاز به اضافه کردن دسته بندی اصلی نیستید` }); } // if (req.user.specialPermissions.length && !_.isEmpty(parent) && !req.user.permissions.includes('categories-add')){ // return res.status(403).json(`شما اجازه اضافه کردن یک دسته بندی جدید را ندارید`); // } /** set portals */ modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0]; /** only one category can be in to the section one and two */ // if (showInSectionOne === true) { // await _checkOtherSection('one'); // } // // if (showInSectionTwo === true) { // await _checkOtherSection('two'); // } const catData = { title: title.trim().replace(titleFilterRegex, '-'), priority: priority, parent: parent || null, // showInMenu: showInMenu, navIndex: navIndex, siteMap: siteMap, special: special, showInFooter, url, // showInSectionOne, // showInSectionTwo, // showInSectionThree, pageContent, modelType, news, child, hasNewsTab, hasContentTab, hasMediaTab, hasSubMenusTab, hasTermsTab, hasNotificationsTab, hasSpecNewsTab, hasNazarTab, hasNewsFileTab, defaultPageType, hasManagerInfo, managerName, managerDescription, _creator: req.user._id, _updatedBy: req.user._id } let getParent; if (parent) { /** * check parent exist or not */ getParent = await Category.findById(parent) // .populate({ // path: 'parent', // populate: { // path: 'parent', // model: 'Category' // } // }); /** * if not found show error */ if (!getParent) return res404(res, `دسته بندی پدر پیدا نشد`); ////// start permissions /** check special permission */ if (req.user.specialPermissions.length && await _checkSpecPermission(req, getParent)) { return res.status(403).json({ message: `شما اجازه اضافه کردن فرزند جدید برای این دسته بندی را ندارید` }); } /** check can add child */ if (!getParent.child) return res.status(403).json({message: `این دسته بندی نمی تواند زیرمجموعه داشته باشد`}); /** check access portal */ if (!req.user.portals.includes(getParent.modelType)) return res.status(403).json({ message: `شما اجازه انتخاب این دسته بندی را ندارید` }); /** check type */ if (getParent.modelType !== modelType) return res500(res, `شما اجازه استفاده این دسته بندی به عنوان سردسته را ندارید`); ////// end permissions /** * add level of new category */ catData.level = Number(getParent.level) + 1; /** add tree cat */ // catData.treeCat = await _makeTreeCat(getParent); const treeCatClone = JSON.parse(JSON.stringify(getParent.treeCat)) treeCatClone.push(getParent._id) catData.treeCat = treeCatClone catData.rootParent = getParent.rootParent || getParent._id } /** * add new category */ const create = await Category.create(catData); /** * check added or not */ if (!create) return res500(res, `مشکلی در ثبت اطلاعات پیش آمده لطفا دوباره تلاش کنید`); /** * if have parent should added new category in child of parent category * and set level for new category */ if (getParent) { /** * add new category for parent */ getParent.childs.push(create._id); await getParent.save(); } if (req.files?.managerCover) { const image = req.files.managerCover; if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) { return res.status(422).json({ validation: { cover: { msg: _sr['fa'].format.image } } }); } const imageName = `manager_${Date.now()}_${create._id}.${image.mimetype.split('/')[1]}`; try { const target = sharp(image.data) await target .resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'}) .jpeg({quality: coverQuality}) .toFile(`./static/uploads/images/category/${imageName}`); /** * if exist old pic delete it from file */ // if (targetNews.cover !== noCover && !targetNews.imported) { // let oldPic = `./static${targetNews.cover}`; // // if (await fs.existsSync(oldPic)) { // fs.unlink(oldPic, (err) => { // if (err) return res500(res, err?.message); // }); // } // } // if (targetNews.thumbCover !== noCover && !targetNews.imported) { // let oldPic = `./static${targetNews.thumbCover}`; // // if (await fs.existsSync(oldPic)) { // fs.unlink(oldPic, (err) => { // if (err) return res500(res, err?.message); // }); // } // } create.managerCover = imageName; await create.save() } catch (e) { return res500(res, e?.message); } } /** * show result */ return res.json(create); } catch (error) { console.log(error); /** * if we got unkown error show to client */ res500(res, error.message); } } ] module.exports.updateCategory = [ [ body('title') .notEmpty().withMessage(_sr['fa'].required.title), // body('parent') // .optional().isString().withMessage(`parent ${_sr['fa'].optional.string}`), // body('showInMenu') // .isBoolean().withMessage(_sr['fa'].format.boolean), body('navIndex') .isNumeric().withMessage(_sr['fa'].format.number), body('priority') .isNumeric().withMessage(_sr['fa'].format.number), // body('showInSectionOne') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // body('showInSectionTwo') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // body('showInSectionThree') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('siteMap') .isBoolean().withMessage(_sr['fa'].format.boolean), body('special') .isBoolean().withMessage(_sr['fa'].format.boolean), body('showInFooter') .isNumeric().withMessage(_sr['fa'].format.number) .bail() .isIn([0, 1, 2, 3]).withMessage(`از بین اعداد 1و2و3 یک عدد ارسال کنید`), body('url') .optional().isString().withMessage(`url ${_sr['fa'].optional.string}`), body('pageContent') .optional().isString().withMessage(`pageContent ${_sr['fa'].optional.string}`), body('news') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('child') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNewsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasContentTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasMediaTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasSubMenusTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasTermsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNotificationsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasSpecNewsTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNazarTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body('hasNewsFileTab') .optional().isBoolean().withMessage(_sr['fa'].format.boolean), ], checkValidations(validationResult), async (req, res) => { try { /** * get data from input */ let { title, parent, // showInMenu, navIndex, priority, // showInSectionOne, // showInSectionTwo, // showInSectionThree, siteMap, special, showInFooter, url, pageContent, news, child, hasNewsTab, hasContentTab, hasMediaTab, hasSubMenusTab, hasTermsTab, hasNotificationsTab, hasSpecNewsTab, hasNazarTab, hasNewsFileTab, defaultPageType, hasManagerInfo, managerName, managerDescription } = req.body; /** * get id */ const catId = req.params.id; ////////// permissions // if (req.user.specialPermissions.length && !req.user.permissions.includes('categories-update')){ // return res.status(403).json(`شما اجازه بروزرسانی این دسته بندی را ندارید`); // } /** * check category exist or not */ const targetCategory = await Category.findOne({ _id: catId }); if (!targetCategory) return res404(res, `دسته بندی مورد نظر پیدا نشد`); /** check special permission */ if (req.user.specialPermissions.length && await _checkSpecPermission(req, targetCategory)) { return res.status(403).json({ message: `شما اجازه بروزرسانی این دسته بندی را ندارید` }); } /** check access portal */ if (!req.user.portals.includes(targetCategory.modelType)) { return res.status(403).json({ message: `شما اجازه آپدیت این دسته بندی را ندارید` }); } /** only one category can be in to the section one and two */ // if (showInSectionOne === 'true') { // targetCategory.showInSectionOne = await _checkOtherSection('one'); // } // if (showInSectionTwo === 'true') { // targetCategory.showInSectionTwo = await _checkOtherSection('two'); // } if (targetCategory.title !== title) { const checkDuppTitle = await Category.findOne({ title: title }); if (checkDuppTitle) { return res.status(422).json({validation: {title: {msg: _sr['fa'].duplicated.title}}}); } } // if(parent != null && targetCategory.parent != null && parent != targetCategory.parent) { // /** check have news or not */ // var checkHaveNews = await News.find({allCat : [targetCategory._id]}); // if(checkHaveNews.length){ // return res.status(403).json({message :`این دسته بندی دارای اخبار می باشد و شما نمیتوانید دسته بندی والد آن را تغییر دهید لطفا ابتدا اخبار را حذف کرده سپس این کار را انجام دهید`}); // } // /** // * check new parent // */ // var newParentCategory = await Category.findOne({_id : parent}); // if(!newParentCategory){ // return res404(res,`دسته بندی انتخاب شده پیدا نشد`); // }; // if(newParentCategory.treeCat.includes(targetCategory._id)){ // return res.status(422).json({validation : {parent : {msg : ``}}}) // } // /** // * get category parent // */ // if(targetCategory.parent){ // var parentCategory = await Category.findOne({_id : targetCategory.parent}); // if(parentCategory){ // /** // * delete catId from old category // */ // const index = parentCategory.childs.indexOf(targetCategory._id); // if (index > -1) { // parentCategory.childs.splice(index, 1); // await parentCategory.save(); // } // } // } // if(!newParentCategory.child){ // return res.status(403).json({message :`این دسته بندی اجازه داشتن زیرمجموعه ندارد`}); // } // /** check access portal */ // if(!req.user.portals.includes(newParentCategory.modelType)){ // return res.status(403).json({message :`شما اجازه انتخاب این دسته بندی را ندارید`}); // } // /** check type */ // if(newParentCategory.modelType != modelType){ // return res.status(403).json({message :`شما اجازه استفاده این دسته بندی به عنوان سردسته را ندارید`}); // } // /** // * add catId for new parnet // */ // newParentCategory.childs.push(targetCategory._id); // await newParentCategory.save(); // /** // * update level // */ // targetCategory.level = newParentCategory.level + 1; // } /** * make update object */ targetCategory.title = title.trim().replace(titleFilterRegex, '-'); // targetCategory.showInMenu = showInMenu; targetCategory.navIndex = navIndex; targetCategory.priority = priority; // targetCategory.showInSectionOne = showInSectionOne; // targetCategory.showInSectionTwo = showInSectionTwo; // targetCategory.showInSectionThree = showInSectionThree; targetCategory.siteMap = siteMap; targetCategory.special = special; targetCategory._creator = req.user._id; targetCategory._updatedBy = req.user._id; targetCategory.showInFooter = showInFooter; targetCategory.pageContent = pageContent; targetCategory.child = child; targetCategory.url = url; targetCategory.news = news; targetCategory.hasNewsTab = hasNewsTab; targetCategory.hasContentTab = hasContentTab; targetCategory.hasMediaTab = hasMediaTab; targetCategory.hasSubMenusTab = hasSubMenusTab; targetCategory.hasTermsTab = hasTermsTab; targetCategory.hasNotificationsTab = hasNotificationsTab; targetCategory.hasSpecNewsTab = hasSpecNewsTab; targetCategory.hasNazarTab = hasNazarTab; targetCategory.hasNewsFileTab = hasNewsFileTab; targetCategory.defaultPageType = defaultPageType; targetCategory.hasManagerInfo = hasManagerInfo; targetCategory.managerName = managerName; targetCategory.managerDescription = managerDescription; if (req.files?.managerCover) { const image = req.files.managerCover; if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) { return res.status(422).json({ validation: { cover: { msg: _sr['fa'].format.image } } }); } const imageName = `manager_${Date.now()}_${targetCategory._id}.${image.mimetype.split('/')[1]}`; try { const target = sharp(image.data) await target .resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'}) .jpeg({quality: coverQuality}) .toFile(`./static/uploads/images/category/${imageName}`); /** * if exist old pic delete it from file */ if (targetCategory.managerCover !== noCover) { let oldPic = `./static${targetCategory.managerCover}`; if (await fs.existsSync(oldPic)) { fs.unlink(oldPic, (err) => { if (err) return res500(res, err?.message); }); } } targetCategory.managerCover = imageName; } catch (e) { return res500(res, e?.message); } } await targetCategory.save(); /** * show result */ return res.json(targetCategory); } catch (error) { return res500(res, error.message); } } ] module.exports.deletOneCategory = [ async (req, res) => { try { const catId = req.params.id; /** * check category */ const targetCategory = await Category.findOne({ _id: catId }); if (!targetCategory) { return res404(res, `دسته بندی مورد نظر پیدا نشد`); } /** check special permission */ if (req.user.specialPermissions.length && await _checkSpecPermission(req, targetCategory)) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید` }); } /** check access portal */ if (!req.user.portals.includes(targetCategory.modelType)) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید` }); } /** check special permissions */ if (req.user.specialPermissions.includes(targetCategory._id) && !targetCategory.parent) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید` }); } /** check owner ship */ if (req.user.specialPermissions.includes(targetCategory._id) && targetCategory.parent !== req.user._id) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید` }); } const checkHaveNews = await News.find({ allCat: [targetCategory._id] }); if (checkHaveNews.length) { return res.status(403).json({ message: `دسته بندی شما دارای خبر می باشد و قبل از حذف آن باید اخبار مربوط به این دسته بندی را حذف کنید` }); } if (targetCategory.childs.length) { return res.status(403).json({ message: `دسته بندی مورد نظر دارای زیرمجموعه می باشد ابتدا زیرمجوعه ها را حذف کنید` }); } /** * get category parent */ if (targetCategory.parent) { const categoryParent = await Category.findOne({ _id: targetCategory.parent }); if (categoryParent) { /** * delete catId from category parent */ const index = categoryParent.childs.indexOf(targetCategory._id); if (index > -1) { categoryParent.childs.splice(index, 1); await categoryParent.save(); } } } /** * delete category */ targetCategory.delete(); /** * show result */ return res.json(targetCategory); } catch (error) { /** * if we got unkown error show to client */ res500(res, error); } } ] module.exports.deleteAllCategory = [ async (req, res) => { try { } catch (error) { /** * if we got unkown error show to client */ res500(res, error); } } ] module.exports.getOneCategory = [ async (req, res) => { try { const catId = req.params.id; /** * get category */ const targetCategory = await Category.findOne({ _id: catId }); /** * if not exist */ if (!targetCategory) { return res404(res, `دسته بندی مورد نظر پیدا نشد`); } /** check access portal */ if (!req.user.portals.includes(targetCategory.modelType)) { return res.status(403).json({ message: `شما اجازه دسترسی به اطلاعات این دسته بندی را ندارید` }); } /** * show result */ return res.json(targetCategory); } catch (error) { /** * if we got unkown error show to client */ res500(res, error); } } ] module.exports.getAll = [ async (req, res) => { try { const findQuery = {}; let populate = {}; if (req.user.specialPermissions.length) { findQuery._id = {$in: req.user.specialPermissions}; } else { findQuery.parent = null; // populate = { // path: 'childs', // populate: { // path: 'childs' // } // }; } if (req.user.portals.join() !== portal.join()) { findQuery.modelType = req.user.portals[0]; } /** * get all category */ const getAll = await Category.find(findQuery).populate('').sort({ navIndex: 1 }); /** * این قسمت ابجکت های تکراری را از بین میبره */ // if (req.user.specialPermissions.length) { // /** جدا کردن دسته بندی های اصلی */ // const parents = getAll.filter((item) => !item.parent); // /** جدا کردن دسته بندی های غیر اصلی */ // const nonParents = getAll.filter((item) => item.parent); // // /** با یک لوپ تو در تو اگر دسته بندی غیر اصلی در فرزندان دسته بندی اصلی وجود داشت حذف میشه */ // for (let i = 0; i < nonParents.length; i++) { // for (let j = 0; j < parents.length; j++) { // if (nonParents[i].treeCat.includes(parents[j]._id)) { // getAll.splice(getAll.findIndex(item => item._id === nonParents[i]._id), 1); // } // } // } // } /** * show result */ return res.json(getAll); } catch (error) { return res500(res, error.message); } } ] module.exports.search = [ async (req, res) => { try { const term = req.body?.term?.toString().trim() || ''; /** * search */ const search = await Category.find({ title: { $regex: '.*' + term + '.*', $options: 'i' }, modelType: 'normal', type: 'category' }); /** * show result */ return res.json(search); } catch (error) { return res500(res, error.message); } } ] module.exports.permissions = [ async (req, res) => { try { const type = req.query.type; const findQuery = type ? { modelType: type } : {}; const categories = await Category.find(findQuery).populate('treeCat').sort({navIndex: 1}).lean(); let changeTitles = await _customTitle(categories); let sortedCats = await _sortedCategory(changeTitles); return res.json(sortedCats); } catch (error) { res500(res, error?.message); } } ] module.exports.getParent = [ async (req, res) => { try { const findQuery = {}; const type = req.query.type; // findQuery.parent = null; if (req.user.specialPermissions.length) { findQuery.$or = [ { _id: { $in: req.user.specialPermissions } } ] } if (req.user.portals.length) { findQuery.modelType = { $in: req.user.portals }; } if (type && type === 'news') { findQuery.news = true; } if (type && type === 'child') { findQuery.child = true; } /** * get all category */ const getAll = await Category.find(findQuery).populate('parent').populate('treeCat').sort({navIndex: 1}); let changeTitles = await _customTitle(getAll); let sortedCats = await _sortedCategory(changeTitles); /** * show result */ return res.json(sortedCats); } catch (error) { return res500(res, error?.message); } } ] //////////// add attachment file to category module.exports.addTermsFileToCategory = [ [ body('termsTitle') .notEmpty().withMessage(_sr['fa'].required.title) ], checkValidations(validationResult), (req, res) => { if (!req.files?.file) return res.status(422).json({validation: {file: {msg: _sr['fa'].required.file}}}) if (req.files?.file.mimetype.split('/')[1] !== 'pdf') return res.status(422).json({validation: {file: {msg: 'فقط فرمت PDF قابل قبول است'}}}) const data = {title: req.body.termsTitle} const file = req.files.file const fileName = req.body.termsTitle.replace(titleFilterRegex, '-') + '_' + Date.now() + '.pdf' file.mv(`./static/uploads/files/terms/${fileName}`) data.file = fileName Category.findById(req.params.categoryId, (err, category) => { if (err || !category) return res404(res, err) category.terms.push(data) category.save(err => { if (err) return res500(res, err) else return res.json({message: _sr['fa'].response.success_save}) }) }) } ] module.exports.removeTermsFileFromCategory = [ (req, res) => { Category.findOne({'terms._id': req.params.fileId}, (err, category) => { if (err || !category) return res404(res, err) const file = category.terms.id(req.params.fileId) if (!file) return res404(res, 'not found') file.remove() fs.unlink(`./static/${file.file}`, err => { if (err) console.log(err) }) category.save(err => { if (err) return res500(res, err) else return res.json({message: _sr['fa'].response.success_remove}) }) }) } ] /////////////////////////////////////////////////////////////////////// public module.exports.getMenu = [ async (req, res) => { try { const portal = req.query?.portal || 'ostandari'; const findQuery = { parent: null, // showInMenu: true, modelType: portal }; let result = {}; /** * get all category */ const getAll = await Category.find(findQuery).populate('treeCat').sort({ navIndex: 1, // created_at: 1 }).select('title childs navIndex url modelType treeCat defaultPageType'); /// get all page content const getContent = await Content.find({showInMenu : true}) result.categories = getAll; result.staticContents = !!getContent.length; /** * show result */ return res.json(result) } catch (error) { return res500(res, error.message); } } ]