1520 lines
51 KiB
JavaScript
1520 lines
51 KiB
JavaScript
import moment from "moment-jalaali";
|
|
import * as path from "path";
|
|
|
|
const xlsx = require('xlsx');
|
|
const User = require('../models/User')
|
|
const Job = require('../models/Job')
|
|
const StoreInfo = require('../models/StoreInfo')
|
|
const Food = require('../models/Food')
|
|
const DiscountCode = require('../models/DiscountCode')
|
|
const GetTokenLimit = require('../models/GetTokenLimit')
|
|
const {body, validationResult} = require('express-validator')
|
|
const bcrypt = require('bcryptjs')
|
|
const jwt = require('jsonwebtoken')
|
|
const sharp = require('sharp')
|
|
const {secretKey, getID} = require('./../authentication')
|
|
const {sms} = require('../SMSModule')
|
|
const {_sr} = require('../plugins/serverResponses')
|
|
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits, removeWhiteSpaces, checkValidations} = require('../plugins/controllersHelperFunctions')
|
|
const permissions = require('../plugins/permissions')
|
|
const fs = require('fs')
|
|
// const path = require('path')
|
|
const axios = require('axios')
|
|
const {sendSingle, sendMulti} = require('./../plugins/pushNotif').notification
|
|
|
|
////// variables
|
|
const profileWidth = 500
|
|
const profileHeight = 500
|
|
const profileQuality = 100
|
|
const apiKey = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIn0.eyJhdWQiOiIxNDk3OSIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIiwiaWF0IjoxNjI3MzI2Mzc0LCJuYmYiOjE2MjczMjYzNzQsImV4cCI6MTYyOTkxODM3NCwic3ViIjoiIiwic2NvcGVzIjpbImJhc2ljIl19.hyKNSy4fmPps6yIdm33Wof-mES9ujh5lmI3VFWyecbkNCm9ATPwsZ9s53A3a1wPJmHfLBXpCcob5NGL-GjZlVfqfRBiReRMr_iniCjUOnqENfFwVEJutxI-xrzVe7PZzOgx1Vr6WwSUHvQ36eJSS1lBlHlqCgwRbkG0hs4YdZsKhzhfYdlAluNw9djjUAMbRWZVL0EluP9CYko4w8tB0KHUZMZYGQcevCfb_3OU9ygHo7B--Z5aTPfm7IK4eP0gHsZ_t857B3tu3ZJB1mkgxc2R9gZUflKqj1ZqkYiR0uMGP-571enXh6pYQLXL2k-gOxLIedCaE6XytxVXhENnotA';
|
|
|
|
// user scores
|
|
// const userRegistrationScore = 100
|
|
// const userEmailVerifyScore = 50
|
|
// const invitePoint = 5
|
|
const limit = 20
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////// admin
|
|
module.exports.register_admin = [
|
|
[
|
|
body('first_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.first_name),
|
|
|
|
body('last_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.last_name),
|
|
|
|
body('username')
|
|
.isLength({min: 2}).withMessage(_sr['fa'].min_char.min2)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (hasWhiteSpaces(value)) return Promise.reject(_sr['fa'].response.whiteSpace)
|
|
else return true
|
|
})
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (!isLatinCharactersWithSymbol(value)) return Promise.reject(_sr['fa'].response.latinChar)
|
|
else return true
|
|
})
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
return User.findOne({username: value})
|
|
.then(user => {
|
|
if (user) return Promise.reject(_sr['fa'].duplicated.username)
|
|
else return true
|
|
})
|
|
}),
|
|
|
|
body('password')
|
|
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4)
|
|
.custom((value, {req}) => {
|
|
if (value === req.body.password_confirmation) return Promise.resolve()
|
|
else return Promise.reject(_sr['fa'].response.passwords_not_match)
|
|
})
|
|
],
|
|
async (req, res) => {
|
|
const errors = validationResult(req)
|
|
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
|
|
|
|
const creatorID = await getID(req)
|
|
const {username, first_name, last_name, email, mobile_number , permissions , branches} = req.body
|
|
const data = {username, first_name, last_name, email, mobile_number}
|
|
data.permissions = JSON.parse(permissions)
|
|
data.branches = JSON.parse(branches)
|
|
|
|
if (req.files && req.files.profile_pic) {
|
|
const image = req.files.profile_pic
|
|
const imageName = 'user_' + Date.now() + '_' + req.body.username + '.' + image.mimetype.split('/')[1]
|
|
data.profile_pic = imageName
|
|
try {
|
|
const target = sharp(image.data)
|
|
await target
|
|
.resize(profileWidth, profileHeight, {fit: 'cover'})
|
|
.jpeg({quality: profileQuality})
|
|
.toFile(`./static/uploads/images/users/${imageName}`)
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
}
|
|
|
|
bcrypt.genSalt(10, (err, salt) => {
|
|
bcrypt.hash(req.body.password, salt, (err, hash) => {
|
|
if (err) console.log(err)
|
|
data.password = hash
|
|
data.scope = ['admin']
|
|
data._creator = creatorID
|
|
const newAdmin = new User(data)
|
|
newAdmin.save(err => {
|
|
if (err) return res500(res, err)
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.get_all_admins = [
|
|
(req, res) => {
|
|
const branchId = req?.params?.branchId
|
|
// const filter = req?.user?.permissions.includes('super-admin') ? {scope: ['admin'], private: false} : {scope: ['admin'], private: false , branches : branchId}
|
|
const filter = {scope: ['admin'], private: false, branches: branchId}
|
|
User.paginate(filter, {
|
|
page: req?.query?.page,
|
|
limit,
|
|
select: '-password -token'
|
|
}, (err, users) => {
|
|
if (err) return res500(res, err.message)
|
|
else return res.json(users)
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.get_all_users = [
|
|
(req, res) => {
|
|
const branchId = req?.params?.branchId
|
|
const filter = {registration_done: true, scope: ['user'], branches : branchId}
|
|
User.paginate(filter, {
|
|
page: req.query.page,
|
|
limit,
|
|
select: '-password -token'
|
|
}, (err, users) => {
|
|
if (err) return res500(res, err)
|
|
else return res.json(users)
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.get_all_users_for_reports = [
|
|
async (req, res) => {
|
|
try {
|
|
const branchId = req?.params?.branchId
|
|
const filter = {registration_done: true, scope: ['user'] , branches : branchId}
|
|
const users = await User.find(filter).select('-password -token')
|
|
return res.json(users)
|
|
} catch (error) {
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.get_all_users_without_paginate = [
|
|
(req, res) => {
|
|
const branchId = req?.params?.branchId
|
|
const filter = {registration_done: true, scope: ['user'] , branches : branchId}
|
|
User.find(filter).select('-password -token').exec((err, users) => {
|
|
if (err) return res500(res, err)
|
|
else return res.json(users)
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.get_one_admin = [
|
|
(req, res) => {
|
|
User.findById(req.params.id).select('-password -token ').exec(async (err, user) => {
|
|
if (err || !user) return res404(res, err)
|
|
const clone = JSON.parse(JSON.stringify(user))
|
|
try {
|
|
clone.discount_codes = await DiscountCode.find({discount_user_id: user._id})
|
|
return res.json(clone)
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.permissions = [
|
|
(req, res) => {
|
|
return res.json(permissions)
|
|
}
|
|
]
|
|
|
|
module.exports.update_admin = [
|
|
[
|
|
body('first_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.first_name),
|
|
|
|
body('last_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.last_name),
|
|
|
|
body('username')
|
|
.isLength({min: 2}).withMessage(_sr['fa'].min_char.min2)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (hasWhiteSpaces(value)) return Promise.reject(_sr['fa'].response.whiteSpace)
|
|
else return true
|
|
})
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (!isLatinCharactersWithSymbol(value)) return Promise.reject(_sr['fa'].response.latinChar)
|
|
else return true
|
|
})
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
return User.findOne({username: value})
|
|
.then(user => {
|
|
if (user && user._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.username)
|
|
else return true
|
|
})
|
|
}),
|
|
|
|
body('password')
|
|
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4)
|
|
.custom((value, {req}) => {
|
|
if (value === req.body.password_confirmation) return Promise.resolve()
|
|
else return Promise.reject(_sr['fa'].response.passwords_not_match)
|
|
})
|
|
],
|
|
async (req, res) => {
|
|
const errors = validationResult(req)
|
|
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
|
|
|
|
const creatorID = await getID(req)
|
|
const {username, first_name, last_name, email, mobile_number, permissions, branches} = req.body
|
|
const data = {username, first_name, last_name, email, mobile_number}
|
|
data._creator = creatorID
|
|
data.permissions = JSON.parse(permissions)
|
|
data.branches = JSON.parse(branches)
|
|
|
|
if (req.files && req.files.profile_pic) {
|
|
const image = req.files.profile_pic
|
|
const imageName = 'user_' + Date.now() + '_' + req.body.username + '.' + image.mimetype.split('/')[1]
|
|
data.profile_pic = imageName
|
|
try {
|
|
const target = sharp(image.data)
|
|
await target
|
|
.resize(profileWidth, profileHeight, {fit: 'cover'})
|
|
.jpeg({quality: profileQuality})
|
|
.toFile(`./static/uploads/images/users/${imageName}`)
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
}
|
|
|
|
User.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
|
|
if (err || !oldData) return res404(res, err)
|
|
if (req.files && req.files.profile_pic && oldData.profile_pic) {
|
|
fs.unlink(`./static/${oldData.profile_pic}`, err => {
|
|
if (err) console.log(err)
|
|
})
|
|
}
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.remove_admin = [
|
|
(req, res) => {
|
|
User.findByIdAndDelete(req.params.id, (err, data) => {
|
|
if (err || !data) return res404(res, err)
|
|
if (data.profile_pic) {
|
|
fs.unlink(`./static/${data.profile_pic}`, err => {
|
|
if (err) console.log(err)
|
|
})
|
|
}
|
|
return res.json({message: _sr['fa'].response.success_remove})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.change_admin_password_by_another = [
|
|
[
|
|
body('password')
|
|
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4)
|
|
.custom((value, {req}) => {
|
|
if (value === req.body.password_confirmation) return Promise.resolve()
|
|
else return Promise.reject(_sr['fa'].response.passwords_not_match)
|
|
})
|
|
],
|
|
(req, res) => {
|
|
const errors = validationResult(req)
|
|
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
|
|
|
|
User.findById(req.params.id, (err, user) => {
|
|
if (err || !user) return res404(res, err)
|
|
bcrypt.genSalt(10, (err, salt) => {
|
|
bcrypt.hash(req.body.password, salt, (err, hash) => {
|
|
if (err) console.log(err)
|
|
user.password = hash
|
|
user.save(err => {
|
|
if (err) return res500(res, err)
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
////////////////////////////////////////////////////////////////////// user discount code
|
|
module.exports.generate_discount_code_for_users = [
|
|
[
|
|
body('discount_amount')
|
|
.notEmpty().withMessage(_sr['fa'].required.discount_amount)
|
|
.bail()
|
|
.isNumeric().withMessage(_sr['fa'].format.number),
|
|
|
|
body('discount_expire_date')
|
|
.notEmpty().withMessage(_sr['fa'].required.discount_expire_date),
|
|
|
|
body('discount_user_id')
|
|
.if((value, {req}) => !req.body.newDiscountIsPublic)
|
|
.notEmpty().withMessage(_sr['fa'].required.user_id),
|
|
|
|
body('newDiscountIsPublic')
|
|
.notEmpty().withMessage('Discount public status must be specified'),
|
|
|
|
body('publicDiscountIsAuto')
|
|
.notEmpty().withMessage('Discount public code method must be specified'),
|
|
|
|
body('customDiscountCode')
|
|
.if((value, {req}) => req.body.newDiscountIsPublic && !req.body.publicDiscountIsAuto)
|
|
.notEmpty().withMessage(_sr['fa'].required.discount_code),
|
|
|
|
body('branchId')
|
|
.notEmpty().withMessage(_sr['fa'].required.field)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
return StoreInfo.findOne({_id: value})
|
|
.then(store => {
|
|
if (!store) return Promise.reject(_sr['fa'].not_found.item_id)
|
|
else return true
|
|
})
|
|
})
|
|
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
const {branchId , discount_amount, discount_expire_date, discount_user_id, newDiscountIsPublic, publicDiscountIsAuto, customDiscountCode, menuTypeId} = req.body
|
|
|
|
async function generateDiscountCode() {
|
|
try {
|
|
let code = generateRandomDigits(6)
|
|
const checkDiscountCodes = await DiscountCode.findOne({discount_code: code, discount_user_id: discount_user_id, isPublic: false})
|
|
if (checkDiscountCodes) generateDiscountCode()
|
|
else return code
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
}
|
|
|
|
async function generatePublicDiscountCode() {
|
|
try {
|
|
let code = generateRandomDigits(6)
|
|
const checkDiscountCodes = await DiscountCode.findOne({discount_code: code, isPublic: true})
|
|
if (checkDiscountCodes) generatePublicDiscountCode()
|
|
else return code
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
}
|
|
|
|
const data = {
|
|
branchId,
|
|
discount_amount,
|
|
menuTypeId,
|
|
discount_expire_date: discount_expire_date
|
|
}
|
|
|
|
if (newDiscountIsPublic) {
|
|
data.isPublic = true
|
|
if (publicDiscountIsAuto) data.discount_code = await generatePublicDiscountCode()
|
|
else {
|
|
try {
|
|
const checkDiscountCodes = await DiscountCode.findOne({discount_code: customDiscountCode, isPublic: true})
|
|
if (checkDiscountCodes) return res.status(422).json({validation: {discount_code: {msg: 'کد تخفیف تکراری است'}}})
|
|
else data.discount_code = customDiscountCode
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
}
|
|
|
|
const users = await User.find({registration_done : true , test : true}) //, test : true
|
|
|
|
const tokens = []
|
|
let mobiles = []
|
|
|
|
for (const user of users) {
|
|
if (user.fcmToken) tokens.push(user.fcmToken)
|
|
if (user.mobile_number) mobiles.push(user.mobile_number)
|
|
}
|
|
|
|
|
|
const smsTemplate = `با سلام یک عدد کد تخفیف ${data.discount_amount} درصدی تا تاریخ ${moment(data.discount_expire_date, 'X').format('jYYYY/jMM/jDD')} به شما اختصاص داده شد کد: ${data.discount_code} رستوران برگ لغو11`
|
|
|
|
//--------------------- send notif to user --------------------------
|
|
const messageUser = {
|
|
title: 'کد تخفیف',
|
|
body: smsTemplate
|
|
}
|
|
const payloadUser = {
|
|
notification: messageUser,
|
|
};
|
|
const inputUser = {
|
|
registrationTokens: tokens,
|
|
payload: payloadUser
|
|
}
|
|
await sendMulti(inputUser)
|
|
//-------------------------------------------------------------------
|
|
|
|
const smsResult = await sms(mobiles, smsTemplate)
|
|
|
|
if (!smsResult || !smsResult.data.IsSuccessful) {
|
|
console.log(smsResult)
|
|
// return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
|
|
}
|
|
|
|
} else {
|
|
data.discount_code = await generateDiscountCode()
|
|
data.discount_user_id = discount_user_id
|
|
|
|
const user = await User.findById(discount_user_id)
|
|
|
|
if (user) {
|
|
let smsTemplate = ''
|
|
if (user?.fromWhere === 'app') smsTemplate = `با سلام یک عدد کد تخفیف ${data.discount_amount} درصدی تا تاریخ ${moment(data.discount_expire_date, 'X').format('jYYYY/jMM/jDD')} به شما اختصاص داده شد کد: ${data.discount_code}
|
|
رستوران برگ
|
|
لینک : https://app.bargrestaurant.com/discountCode`
|
|
else smsTemplate = `با سلام یک عدد کد تخفیف ${data.discount_amount} درصدی تا تاریخ ${moment(data.discount_expire_date, 'X').format('jYYYY/jMM/jDD')} به شما اختصاص داده شد کد: ${data.discount_code} رستوران برگ
|
|
لینک : https://app.bargrestaurant.com/discountCodes
|
|
`
|
|
|
|
|
|
//--------------------- send notif to user --------------------------
|
|
const messageUser = {
|
|
title: 'کد تخفیف',
|
|
body: smsTemplate
|
|
}
|
|
const payloadUser = {
|
|
notification: messageUser,
|
|
};
|
|
const inputUser = {
|
|
registrationTokens: user.fcmToken,
|
|
payload: payloadUser
|
|
}
|
|
await sendSingle(inputUser)
|
|
//-------------------------------------------------------------------
|
|
|
|
const smsResult = await sms(user.mobile_number, smsTemplate)
|
|
|
|
if (!smsResult || !smsResult.data.IsSuccessful) {
|
|
console.log(smsResult)
|
|
// return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
|
|
}
|
|
}
|
|
}
|
|
|
|
const newDiscount = DiscountCode(data)
|
|
newDiscount.save((err, data) => {
|
|
if (err) return res500(res, err)
|
|
else return res.json(data)
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.get_all_discounts_for_admin = [
|
|
(req, res) => {
|
|
const filter = {branchId: req?.params?.branchId}
|
|
DiscountCode.paginate(filter, {
|
|
page: req.query.page,
|
|
limit,
|
|
populate: {
|
|
path: 'discount_user_id',
|
|
select: 'first_name last_name business_code mobile_number score'
|
|
}
|
|
}, (err, data) => {
|
|
if (err) return res500(res, err)
|
|
else return res.json(data)
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.delete_discount_code = [
|
|
(req, res) => {
|
|
DiscountCode.findByIdAndRemove(req.params.id, (err, oldData) => {
|
|
if (err || !oldData) return res404(res, err)
|
|
else return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.getAllDiscountCodeOfUser = [
|
|
async (req, res) => {
|
|
try {
|
|
const discounts = await DiscountCode.find({
|
|
branchId: req?.params?.branchId,
|
|
$or : [
|
|
{isPublic : true},
|
|
{
|
|
discount_user_id: req.user._id,
|
|
used_by: {'$nin': req.user._id},
|
|
discount_expire_date: {'$gte': +new Date().setHours(0, 0, 0, 0)}
|
|
}
|
|
]
|
|
})
|
|
const user = await User.findById(req.user._id).select('first_name last_name')
|
|
|
|
if (!user) return res404(res, 'اطلاعات کاربر یافت نشد')
|
|
|
|
const clone = JSON.parse(JSON.stringify(discounts))
|
|
|
|
clone.map(item => {
|
|
item.user = user
|
|
item.used = item.used_by.includes(req.user._id)
|
|
})
|
|
|
|
return res.json(clone)
|
|
} catch (error) {
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
/////////////////////////////////////////////////////////////////////// user
|
|
|
|
/////////////// user registration
|
|
module.exports.get_phone_number = [
|
|
[
|
|
body('mobile_number')
|
|
.notEmpty().withMessage(_sr['fa'].required.phone_number)
|
|
.bail()
|
|
.isMobilePhone().withMessage(_sr['fa'].format.phone_number)
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
try {
|
|
let getTokenLimit = await GetTokenLimit.find({phone: req.body.mobile_number})
|
|
|
|
if (getTokenLimit.length) return res.status(429).json({message: 'شما هر دو دقیقه یکبار مجاز به گرفتن کد تایید می باشید'})
|
|
|
|
const user = await User.findOne({mobile_number: req.body.mobile_number})
|
|
if (user) {
|
|
if (user.registration_done) {
|
|
return res.json({
|
|
// hasAccount: true,
|
|
registration_done: user.registration_done
|
|
})
|
|
} else {
|
|
user.token = await generateRandomDigits(6)
|
|
user.save(err => {
|
|
if (err) return res500(res, err)
|
|
})
|
|
|
|
const smsTemplate = `
|
|
با تشکر از ثبت نام شما در برگ من
|
|
کد فعال سازی شما: ${user.token}
|
|
لغو11
|
|
`
|
|
|
|
const smsResult = await sms(req.body.mobile_number, smsTemplate)
|
|
|
|
if (!smsResult || !smsResult.data.IsSuccessful) {
|
|
console.log(smsResult)
|
|
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
|
|
}
|
|
|
|
await GetTokenLimit.create({
|
|
phone: req.body.mobile_number
|
|
});
|
|
|
|
return res.json({
|
|
// hasAccount: true,
|
|
registration_done: user.registration_done
|
|
})
|
|
}
|
|
} else {
|
|
const data = {
|
|
mobile_number: req.body.mobile_number,
|
|
registration_done: false
|
|
}
|
|
let token = await generateRandomDigits(6)
|
|
data.token = token
|
|
|
|
const smsTemplate = `
|
|
با تشکر از ثبت نام شما در برگ من
|
|
کد فعال سازی شما: ${token}
|
|
لغو11
|
|
`
|
|
|
|
const smsResult = await sms(req.body.mobile_number, smsTemplate)
|
|
|
|
if (!smsResult || !smsResult.data.IsSuccessful) {
|
|
console.log(smsResult)
|
|
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
|
|
}
|
|
|
|
await GetTokenLimit.create({
|
|
phone: req.body.mobile_number
|
|
});
|
|
|
|
const newUser = new User(data)
|
|
newUser.save((err, data) => {
|
|
if (err) return res500(res, err)
|
|
return res.json({registration_done: false})
|
|
})
|
|
}
|
|
} catch (e) {
|
|
console.log(e.message)
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.resend_user_resgistration_token = [
|
|
async (req, res) => {
|
|
try {
|
|
const getTokenLimit = await GetTokenLimit.find({phone: req.params.mobile_number});
|
|
|
|
if (getTokenLimit.length) return res.status(429).json({message: 'شما هر دو دقیقه یکبار مجاز به گرفتن کد تایید می باشید'})
|
|
|
|
const user = await User.findOne({mobile_number: req.params.mobile_number})
|
|
if (user) {
|
|
const smsTemplate = `
|
|
با تشکر از ثبت نام شما در برگ من
|
|
کد فعال سازی شما: ${user.token}
|
|
لغو11
|
|
`
|
|
const smsResult = await sms(req.params.mobile_number, smsTemplate)
|
|
|
|
if (!smsResult || !smsResult.data.IsSuccessful) {
|
|
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
|
|
}
|
|
|
|
await GetTokenLimit.create({
|
|
phone: req.params.mobile_number
|
|
});
|
|
|
|
return res.json({message: 'کد فعال سازی دوباره برای شما ارسال شد.'})
|
|
} else return res404(res, 'برای این شماره هیچ کد تایید ای یافت نشد.')
|
|
|
|
} catch (e) {
|
|
console.log('resend_user_resgistration_token', error.message)
|
|
return res404(res, 'برای این شماره هیچ کد تایید ای یافت نشد.')
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.generate_temp_token_for_user = [
|
|
async (req, res) => {
|
|
try {
|
|
const getTokenLimit = await GetTokenLimit.find({phone: req.params.mobile_number});
|
|
|
|
if (getTokenLimit.length) return res.status(429).json({message: 'شما هر دو دقیقه یکبار مجاز به گرفتن کد تایید می باشید'})
|
|
|
|
const user = await User.findOne({mobile_number: req.params.mobile_number})
|
|
if (user) {
|
|
|
|
const token = await generateRandomDigits(6)
|
|
const smsTemplate = `
|
|
با تشکر از ثبت نام شما در برگ من
|
|
کد فعال سازی شما: ${token}
|
|
لغو11
|
|
`
|
|
|
|
user.token = token
|
|
|
|
await user.save()
|
|
|
|
const smsResult = await sms(req.params.mobile_number, smsTemplate)
|
|
|
|
if (!smsResult || !smsResult.data.IsSuccessful) {
|
|
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
|
|
}
|
|
|
|
await GetTokenLimit.create({
|
|
phone: req.params.mobile_number
|
|
});
|
|
|
|
return res.json({message: 'کد فعال سازی برای شما ارسال شد.'})
|
|
} else return res404(res, 'کاربر مورد نظر وجود ندارد')
|
|
} catch (error) {
|
|
console.log('generate_temp_token_for_user', error.message)
|
|
return res500(res, _sr['fa'].response.unknownError);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.validate_user_temp_token = [
|
|
[
|
|
body('mobile_number')
|
|
.notEmpty().withMessage(_sr['fa'].required.phone_number),
|
|
|
|
body('token')
|
|
.notEmpty().withMessage(_sr['fa'].required.token)
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
try {
|
|
const user = await User.findOne({mobile_number: req.body.mobile_number, token: req.body.token})
|
|
if (user) {
|
|
user.token = null
|
|
const response = {registration_done: user.registration_done}
|
|
if (user.registration_done) {
|
|
response.token = await jwt.sign({_id: user._id}, secretKey, {expiresIn: '1000d'})
|
|
user.token = response.token;
|
|
user.fromWhere = req.body?.fromWhere;
|
|
user.save((err, newUserData) => {
|
|
if (err) return res500(res, _sr['fa'].response.unknownError)
|
|
return res.json(response)
|
|
})
|
|
} else {
|
|
return res.json(response)
|
|
}
|
|
} else return res404(res, 'کد تایید معتبر نمیباشد.')
|
|
} catch (e) {
|
|
return res404(res, 'برای این شماره هیچ کد تایید ای یافت نشد.')
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.add_name_to_user_registration = [
|
|
[
|
|
body('first_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.first_name)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 3) return Promise.reject(_sr['fa'].min_char.min2)
|
|
else return true
|
|
}),
|
|
body('last_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.last_name)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 3) return Promise.reject(_sr['fa'].min_char.min2)
|
|
else return true
|
|
}),
|
|
|
|
body('job')
|
|
.notEmpty().withMessage(_sr['fa'].required.field),
|
|
|
|
body('invitation')
|
|
.custom((value, {req}) => {
|
|
if (value) {
|
|
return User.findOne({business_code: value, registration_done: true})
|
|
.then(user => {
|
|
if (!user) return Promise.reject('کد دعوت وارد شده صحیح نمی باشد')
|
|
else return true
|
|
})
|
|
} else {
|
|
return true
|
|
}
|
|
}),
|
|
],
|
|
checkValidations(validationResult),
|
|
(req, res) => {
|
|
User.findOne({mobile_number: req.body.mobile_number}, (err, user) => {
|
|
if (err || !user) return res404(res, _sr['fa'].not_found.user_id)
|
|
user.first_name = req.body.first_name
|
|
user.last_name = req.body.last_name
|
|
user.job = req.body.job
|
|
user.invitation = req.body.invitation
|
|
user.save((err, newUserData) => {
|
|
if (err) return res500(res, err)
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.add_password_to_user_registration = [
|
|
[
|
|
body('password')
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 4) return Promise.reject(_sr['fa'].min_char.min4)
|
|
else return true
|
|
}),
|
|
|
|
body('password_confirmation')
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 4) return Promise.reject(_sr['fa'].min_char.min4)
|
|
else return true
|
|
})
|
|
.custom((value, {req}) => {
|
|
if (value === req.body.password) return true
|
|
else return Promise.reject(_sr['fa'].response.passwords_not_match)
|
|
}),
|
|
|
|
body('branchId')
|
|
.notEmpty().withMessage(_sr['fa'].required.field)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
return StoreInfo.findOne({_id: value})
|
|
.then(store => {
|
|
if (!store) return Promise.reject(_sr['fa'].not_found.item_id)
|
|
else return true
|
|
})
|
|
})
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
try {
|
|
const {branchId, mobile_number, password, deviceId, platform ,fromWhere} = req.body
|
|
const user = await User.findOne({mobile_number: mobile_number})
|
|
if (!user) return res404(res, _sr['fa'].not_found.user_id)
|
|
|
|
const storeInfo = await StoreInfo.findOne({_id : branchId})
|
|
|
|
const userInvite = await User.findOne({business_code: user.invitation, registration_done: true})
|
|
|
|
// generate user password hash
|
|
const salt = await bcrypt.genSalt(10)
|
|
const hash = await bcrypt.hash(password, salt)
|
|
|
|
// generate user business code
|
|
const users = await User.find({registration_done: true, scope: ['user']})
|
|
const businessCode = new Date().getFullYear().toString() + (users.length + 1).toString()
|
|
|
|
// add new fields to user
|
|
const token = jwt.sign({_id: user._id}, secretKey, {expiresIn: '1000d'})
|
|
user.token = token
|
|
user.password = hash
|
|
user.business_code = businessCode
|
|
user.registration_done = true
|
|
user.score = storeInfo?.userRegistrationScore
|
|
user.scoreLogs = [
|
|
{
|
|
score: storeInfo?.userRegistrationScore,
|
|
forWhat: 'register',
|
|
action: 'increase'
|
|
}
|
|
]
|
|
user.deviceId = deviceId
|
|
user.platform = platform
|
|
user.fromWhere = fromWhere
|
|
user.branches = [branchId]
|
|
|
|
if (userInvite) {
|
|
userInvite.score = userInvite.score + storeInfo?.invitePoint
|
|
userInvite.scoreLogs = [
|
|
{
|
|
score: storeInfo?.invitePoint,
|
|
forWhat: 'invite',
|
|
action: 'increase'
|
|
}
|
|
]
|
|
|
|
await userInvite.save()
|
|
}
|
|
|
|
// save user
|
|
user.save((err, newUserData) => {
|
|
if (err) return res500(res, err)
|
|
return res.json({token: token})
|
|
})
|
|
} catch (e) {
|
|
return res500(res, e.message)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.change_user_password = [
|
|
[
|
|
body('password')
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 4) return Promise.reject(_sr['fa'].min_char.min4)
|
|
else return true
|
|
}),
|
|
|
|
body('password_confirmation')
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 4) return Promise.reject(_sr['fa'].min_char.min4)
|
|
else return true
|
|
})
|
|
.custom((value, {req}) => {
|
|
if (value === req.body.password) return true
|
|
else return Promise.reject(_sr['fa'].response.passwords_not_match)
|
|
})
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
try {
|
|
const userID = await getID(req)
|
|
const user = await User.findById(userID)
|
|
if (!user) return res404(res, _sr['fa'].not_found.user_id)
|
|
// generate user password hash
|
|
const salt = await bcrypt.genSalt(10)
|
|
user.password = await bcrypt.hash(req.body.password, salt)
|
|
user.token = null
|
|
user.save((err, newUserData) => {
|
|
if (err) return res500(res, err)
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.update_user = [
|
|
[
|
|
body('first_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.first_name)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 3) return Promise.reject(_sr['fa'].min_char.min2)
|
|
else return true
|
|
}),
|
|
body('last_name')
|
|
.notEmpty().withMessage(_sr['fa'].required.last_name)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (removeWhiteSpaces(value).length < 3) return Promise.reject(_sr['fa'].min_char.min2)
|
|
else return true
|
|
}),
|
|
|
|
body('birth_date')
|
|
.optional()
|
|
.isString().withMessage(_sr['fa'].required.birthdate),
|
|
|
|
body('marriage_date')
|
|
.optional()
|
|
.isString().withMessage(_sr['fa'].required.field),
|
|
|
|
body('job')
|
|
.optional()
|
|
.isString().withMessage(_sr['fa'].required.field),
|
|
|
|
body('national_code')
|
|
.optional()
|
|
.isString().withMessage(_sr['fa'].required.national_code)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
if (value && removeWhiteSpaces(value).length !== 10) return Promise.reject(_sr['fa'].min_char.min10)
|
|
else return true
|
|
}),
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
try {
|
|
const {first_name, last_name, email, birth_date, marriage_date, job, national_code, showBirthDate} = req.body
|
|
const userID = await getID(req)
|
|
User.findById(userID, (err, user) => {
|
|
if (err || !user) return res404(res, err)
|
|
user.first_name = first_name
|
|
user.last_name = last_name
|
|
user.email = email
|
|
user.birth_date = birth_date
|
|
// user.showBirthDate = showBirthDate
|
|
user.marriage_date = marriage_date
|
|
user.job = job
|
|
user.national_code = national_code
|
|
// if (email?.length){
|
|
// user.score += userEmailVerifyScore
|
|
// user.scoreLogs = [
|
|
// {
|
|
// score : userEmailVerifyScore,
|
|
// forWhat : 'emailVerify',
|
|
// action : 'increase'
|
|
// }
|
|
// ]
|
|
// }
|
|
user.save(err => {
|
|
if (err) return res500(res, err)
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
})
|
|
} catch (e) {
|
|
return res500(res, e)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.exportExel = [
|
|
async (req, res) => {
|
|
try {
|
|
const admin = await User.findOne({_id : req?.params?.id , scope : 'admin'})
|
|
|
|
if (!admin) return res.status(403).json({message : 'شما اجازه گرفتن خروجی اکسل را ندارید'})
|
|
|
|
const users = await User.find({scope: 'user', registration_done: true}).select('first_name last_name business_code birth_date marriage_date national_code bagAmount score mobile_number')
|
|
|
|
const data = users.map(user => {
|
|
return [
|
|
user.mobile_number,
|
|
user.first_name,
|
|
user.last_name,
|
|
user.business_code,
|
|
moment(user.birth_date).format('jYYYY/jMM/jDD') === 'Invalid date' ? '' : moment(user.birth_date).format('jYYYY/jMM/jDD'),
|
|
moment(user.marriage_date).format('jYYYY/jMM/jDD') === 'Invalid date' ? '' : moment(user.marriage_date).format('jYYYY/jMM/jDD'),
|
|
user.national_code,
|
|
user.bagAmount.toLocaleString() + ' ریال',
|
|
user.score
|
|
];
|
|
});
|
|
|
|
const workSheetColumn = [
|
|
'شماره موبایل','نام','نام خانوادگی', 'کد مشتری', 'تاریخ تولد', 'سالگرد ازدواج', 'کد ملی', 'کیف پول', 'امتیاز'
|
|
];
|
|
|
|
const workbook = xlsx.utils.book_new()
|
|
const workSheetData = [
|
|
workSheetColumn,
|
|
...data
|
|
];
|
|
|
|
|
|
const workSheet = xlsx.utils.aoa_to_sheet(workSheetData)
|
|
xlsx.utils.book_append_sheet(workbook, workSheet, "لیست کاربران")
|
|
xlsx.writeFile(workbook, path.resolve('./static/export/usersList.xlsx'))
|
|
|
|
return res.download(`./static/export/usersList.xlsx`)
|
|
} catch (e) {
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
/////////////// user addresses
|
|
module.exports.add_address_to_user = [
|
|
[
|
|
body('title')
|
|
.optional().isString().withMessage(`فرمت عنوان از نوع رشته می باشد`),
|
|
|
|
body('province')
|
|
.notEmpty().withMessage(_sr['fa'].required.province),
|
|
|
|
body('city')
|
|
.notEmpty().withMessage(_sr['fa'].required.city),
|
|
// .bail()
|
|
// .custom((value, {req}) => {
|
|
// if (req.body.city.localeCompare('اراک') !== 0) return Promise.reject('آدرس خارج از محدوده مد نظر می باشد')
|
|
// else return true
|
|
// }),
|
|
|
|
body('address')
|
|
.notEmpty().withMessage(_sr['fa'].required.address),
|
|
|
|
body('location')
|
|
.isObject().withMessage(`لوکیشن از نوع آبجکت می باشد`),
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
const errors = validationResult(req)
|
|
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
|
|
|
|
try {
|
|
const {title, province, city, address, location} = req.body
|
|
const newAddress = {title, province, city, address, location, useRate: 1};
|
|
|
|
const targetUser = await User.findById(req?.user?._id);
|
|
|
|
if (!targetUser) return res404(res, `کاربر مورد نظر یافت نشد`)
|
|
|
|
for (const item of targetUser.addresses) {
|
|
item.used = false;
|
|
}
|
|
|
|
targetUser.addresses.push(newAddress)
|
|
|
|
await targetUser.save();
|
|
|
|
return res.json({message: _sr['fa'].response.success_save});
|
|
} catch (error) {
|
|
return res500(res, _sr['fa'].response.unknownError);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.update_user_address = [
|
|
[
|
|
body('title')
|
|
.optional().isString().withMessage(`فرمت عنوان از نوع رشته می باشد`),
|
|
|
|
body('province')
|
|
.notEmpty().withMessage(_sr['fa'].required.province),
|
|
|
|
body('city')
|
|
.notEmpty().withMessage(_sr['fa'].required.city),
|
|
// .bail()
|
|
// .custom((value, {req}) => {
|
|
// if (req.body.city.localeCompare('اراک') !== 0) return Promise.reject('آدرس خارج از محدوده مد نظر می باشد')
|
|
// else return true
|
|
// }),
|
|
|
|
body('address')
|
|
.notEmpty().withMessage(_sr['fa'].required.address),
|
|
|
|
body('location')
|
|
.isObject().withMessage(`لوکیشن از نوع آبجکت می باشد`),
|
|
],
|
|
checkValidations(validationResult),
|
|
(req, res) => {
|
|
User.findOne({'addresses._id': req?.params?.id}, (err, user) => {
|
|
if (err || !user) return res404(req, res)
|
|
const oldAddress = user.addresses.id(req?.params?.id)
|
|
oldAddress.remove()
|
|
|
|
const {title, province, city, address, location} = req.body
|
|
const newAddress = {title, province, city, address, location}
|
|
|
|
user.addresses.push(newAddress)
|
|
user.save(err => {
|
|
if (err) return res500(res, err)
|
|
else return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.update_user_address_by_admin = [
|
|
[
|
|
body('title')
|
|
.optional().isString().withMessage(`فرمت عنوان از نوع رشته می باشد`),
|
|
|
|
body('province')
|
|
.notEmpty().withMessage(_sr['fa'].required.province),
|
|
|
|
body('city')
|
|
.notEmpty().withMessage(_sr['fa'].required.city),
|
|
// .bail()
|
|
// .custom((value, {req}) => {
|
|
// if (req.body.city.localeCompare('اراک') !== 0) return Promise.reject('آدرس خارج از محدوده مد نظر می باشد')
|
|
// else return true
|
|
// }),
|
|
|
|
body('address')
|
|
.notEmpty().withMessage(_sr['fa'].required.address)
|
|
],
|
|
checkValidations(validationResult),
|
|
(req, res) => {
|
|
User.findOne({'addresses._id': req?.params?.id}, (err, user) => {
|
|
if (err || !user) return res404(req, res)
|
|
const targetAddress = user.addresses.id(req?.params?.id)
|
|
|
|
const {title, province, city, address} = req.body
|
|
targetAddress.title = title
|
|
targetAddress.province = province
|
|
targetAddress.city = city
|
|
targetAddress.address = address
|
|
|
|
user.save(err => {
|
|
if (err) return res500(res, err)
|
|
else return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.remove_user_address = [
|
|
(req, res) => {
|
|
User.findOne({'addresses._id': req?.params?.id}, (err, user) => {
|
|
if (err || !user) return res404(res, `کاربر مورد نظر یافت نشد`)
|
|
const oldAddress = user.addresses.id(req?.params?.id)
|
|
oldAddress.remove()
|
|
if (user.addresses.length && user.addresses.find(item => item.used !== true)) {
|
|
user.addresses[0].used = true;
|
|
user.addresses[0].useRate = user.addresses[0].useRate + 1;
|
|
}
|
|
user.save(err => {
|
|
if (err) return res500(res, _sr['fa'].response.unknownError)
|
|
else return res.json({message: _sr['fa'].response.success_remove})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.getAlladdress = [
|
|
async (req, res) => {
|
|
try {
|
|
const storeId = req.params.storeId
|
|
const user = await User.findById(req?.user?._id)
|
|
const addresses = [];
|
|
const getStoreInfo = await StoreInfo.findOne({_id : storeId})
|
|
const storeLocation = getStoreInfo?.location
|
|
|
|
if (!user) return res404(res, `کاربر مورد نظر پیدا نشد`);
|
|
|
|
for (const address of user.addresses) {
|
|
const newAddress = JSON.parse(JSON.stringify(address));
|
|
if (getStoreInfo) {
|
|
if (getStoreInfo?.shippingType) {
|
|
newAddress.cost = getStoreInfo?.shippingCost || 0
|
|
addresses.push(newAddress);
|
|
} else {
|
|
if (storeLocation) {
|
|
const lng = newAddress.location.coordinates[0]
|
|
const lat = newAddress.location.coordinates[1]
|
|
|
|
const storeLng = storeLocation.coordinates[0]
|
|
const storeLat = storeLocation.coordinates[1]
|
|
|
|
const getDistance = await axios.get(`https://map.ir/routes/route/v1/driving/${lng},${lat};${storeLng},${storeLat}`, {
|
|
headers: {
|
|
'x-api-key': apiKey
|
|
}
|
|
});
|
|
|
|
if (getDistance.data.code !== 'Ok') return res500(_sr['fa'].response.unknownError);
|
|
|
|
const distance =getDistance.data.routes[0].distance<=1000 ? 0 : Math.round(getDistance.data.routes[0].distance / 1000) || 0
|
|
|
|
newAddress.cost = distance * (getStoreInfo?.shippingCost || 0) || 0
|
|
addresses.push(newAddress)
|
|
} else {
|
|
newAddress.cost = 0
|
|
addresses.push(newAddress);
|
|
}
|
|
}
|
|
} else {
|
|
newAddress.cost = 0;
|
|
addresses.push(newAddress);
|
|
}
|
|
}
|
|
|
|
return res.json(addresses);
|
|
} catch (error) {
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.setDefaultAddress = [
|
|
async (req, res) => {
|
|
try {
|
|
const checkAddress = await User.findOne({'addresses._id': req?.params?.id})
|
|
|
|
if (!checkAddress) return res404(res, `آدرس انتخاب شده وجود ندارد`)
|
|
|
|
for (const item of checkAddress.addresses) {
|
|
item.used = false;
|
|
}
|
|
|
|
let address = checkAddress.addresses.id(req?.params?.id)
|
|
|
|
address.used = true
|
|
address.useRate = address.useRate++
|
|
|
|
await checkAddress.save()
|
|
|
|
return res.json({message: _sr['fa'].response.success_save});
|
|
} catch (error) {
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
////////////// user comments
|
|
module.exports.getAllComments = [
|
|
async (req, res) => {
|
|
try {
|
|
const branchId = req?.params?.branchId
|
|
const comments = [];
|
|
const allComments = await Food.find({branchId , 'ratings.user_id': req.user._id})
|
|
.populate({path: 'ratings.user_id', select: 'first_name last_name'});
|
|
|
|
for (const comment of allComments) {
|
|
for (const item of comment.ratings) {
|
|
if (item?.user_id?._id.toString() === req?.user?._id.toString() && item.comment) {
|
|
comments.push(item)
|
|
}
|
|
}
|
|
}
|
|
|
|
return res.json(comments)
|
|
} catch (error) {
|
|
console.log(error.message)
|
|
return res500(res, _sr['fa'].response.unknownError);
|
|
}
|
|
}
|
|
]
|
|
|
|
/////////////////////////////////////////////////////////////////////// login (Admin)
|
|
module.exports.login = [
|
|
[
|
|
body('username')
|
|
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4)
|
|
.bail()
|
|
.if((value, {req}) => {
|
|
return req.body.password && req.body.password.length >= 4
|
|
})
|
|
.custom((value, {req}) => {
|
|
return User.findOne({$or: [{email: value.toLowerCase()}, {username: value}]})
|
|
.then(user => {
|
|
if (!user) return Promise.reject(_sr['fa'].not_found.password)
|
|
else return true
|
|
})
|
|
}),
|
|
|
|
body('password')
|
|
.notEmpty().withMessage(_sr['fa'].required.password)
|
|
.bail()
|
|
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4),
|
|
|
|
body('remember_me')
|
|
.exists().withMessage(_sr['fa'].required.remember_me)
|
|
.bail()
|
|
.isBoolean().withMessage(_sr['fa'].format.boolean)
|
|
],
|
|
(req, res) => {
|
|
const errors = validationResult(req)
|
|
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
|
|
const {deviceId, platform , fromWhere} = req.body
|
|
User.findOne({$or: [{email: req.body.username.toLowerCase()}, {username: req.body.username}]}, (err, user) => {
|
|
if (err || !user) return res404(res, err)
|
|
bcrypt.compare(req.body.password, user.password, async (err, isMatch) => {
|
|
if (err || !isMatch) return res.status(422).json({validation: {username: {msg: _sr['fa'].not_found.password}}})
|
|
if (user.token) {
|
|
jwt.verify(user.token.replace(/^Bearer\s/, ''), secretKey, async (err, decoded) => {
|
|
if (err) {
|
|
let token = await jwt.sign({_id: user._id}, secretKey, {expiresIn: req.body.remember_me ? '7d' : '1h'})
|
|
user.token = token
|
|
user.deviceId = deviceId
|
|
user.fromWhere = fromWhere
|
|
user.save(err => {
|
|
if (err) console.log(err)
|
|
return res.json({token: token})
|
|
})
|
|
} else {
|
|
user.deviceId = deviceId
|
|
user.platform = platform
|
|
user.fromWhere = fromWhere
|
|
user.save(err => {
|
|
if (err) console.log(err)
|
|
return res.json({token: user.token})
|
|
})
|
|
}
|
|
})
|
|
} else {
|
|
let token = await jwt.sign({_id: user._id}, secretKey, {expiresIn: req.body.remember_me ? '7d' : '1h'})
|
|
user.token = token
|
|
user.deviceId = deviceId
|
|
user.fromWhere = fromWhere
|
|
user.save(err => {
|
|
if (err) console.log(err)
|
|
return res.json({token: token})
|
|
})
|
|
}
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
/////////////////////////////////////////////////////////////////////// login (User)
|
|
module.exports.login_user = [
|
|
[
|
|
body('mobile_number')
|
|
.notEmpty().withMessage(_sr['fa'].required.phone_number)
|
|
.bail()
|
|
.isMobilePhone().withMessage(_sr['fa'].format.phone_number)
|
|
.bail()
|
|
.if((value, {req}) => {
|
|
return req.body.password && req.body.password.length >= 4
|
|
})
|
|
.custom((value, {req}) => {
|
|
return User.findOne({mobile_number: value})
|
|
.then(user => {
|
|
if (!user) return Promise.reject('کلمه عبور اشتباه است')
|
|
else return true
|
|
})
|
|
}),
|
|
|
|
body('password')
|
|
.notEmpty().withMessage(_sr['fa'].required.password)
|
|
.bail()
|
|
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4),
|
|
|
|
body('branchId')
|
|
.notEmpty().withMessage(_sr['fa'].required.field)
|
|
.bail()
|
|
.custom((value, {req}) => {
|
|
return StoreInfo.findOne({_id: value})
|
|
.then(store => {
|
|
if (!store) return Promise.reject(_sr['fa'].not_found.item_id)
|
|
else return true
|
|
})
|
|
})
|
|
],
|
|
checkValidations(validationResult),
|
|
(req, res) => {
|
|
const {branchId, deviceId, platform , fromWhere} = req.body
|
|
User.findOne({mobile_number: req.body.mobile_number}, (err, user) => {
|
|
if (err || !user) return res404(res, 'کلمه عبور اشتباه است')
|
|
bcrypt.compare(req.body.password, user.password, async (err, isMatch) => {
|
|
if (err || !isMatch) return res.status(422).json({validation: {password: {msg: 'کلمه عبور اشتباه است'}}})
|
|
let token = await jwt.sign({_id: user._id}, secretKey, {expiresIn: '1000d'})
|
|
user.token = token
|
|
user.deviceId = deviceId
|
|
user.platform = platform
|
|
user.fromWhere = fromWhere
|
|
if(!user.branches.includes(branchId)) user.branches.push(branchId)
|
|
user.save(err => {
|
|
if (err) console.log(err.message)
|
|
return res.json({token: token})
|
|
})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
/////////////////////////////////////////////////////////////////////// logout (Admin)
|
|
module.exports.logout = [
|
|
(req, res) => {
|
|
const token = req.headers.authorization
|
|
if (token) {
|
|
User.findOneAndUpdate({token: token}, {token: null}, (err, oldData) => {
|
|
if (err || !oldData) res.status(401).json({message: 'Your not logged in'})
|
|
else return res.json({message: 'You are logged out.'})
|
|
})
|
|
} else {
|
|
return res.status(401).json({message: 'Your not logged in'})
|
|
}
|
|
}
|
|
]
|
|
|
|
/////////////////////////////////////////////////////////////////////// get user (Admin)
|
|
// module.exports.getUser = [
|
|
// (req, res) => {
|
|
// const token = req?.headers?.authorization?.replace(/^Bearer\s/, '')
|
|
// if (token) {
|
|
// jwt.verify(token, secretKey, (err, decoded) => {
|
|
// if (err) return res.status(401).json({message: 'unauthenticated'})
|
|
// User.findById(decoded._id).select('-token -password').exec(async (err, user) => {
|
|
// if (err || !user) return res404(res, err)
|
|
// const clone = JSON.parse(JSON.stringify(user))
|
|
// try {
|
|
// clone.discount_codes = await DiscountCode.find({discount_user_id: user._id})
|
|
// return res.json({user: clone})
|
|
// } catch (e) {
|
|
// return res500(res, e)
|
|
// }
|
|
// })
|
|
// })
|
|
// } else {
|
|
// return res.status(401).json({message: 'unauthenticated'})
|
|
// }
|
|
// }
|
|
// ]
|
|
|
|
module.exports.getUser = [
|
|
async (req, res) => {
|
|
try {
|
|
const result = {}
|
|
const token = req?.headers?.authorization?.replace(/^Bearer\s/, '')
|
|
if (token) {
|
|
const decoded = await jwt.verify(token, secretKey)
|
|
if (decoded) {
|
|
const getUser = await User.findById(decoded._id).select('-token -password')
|
|
if (!getUser) return res404(res, `کاربر مورد نظر پیدا نشد`)
|
|
|
|
const clone = JSON.parse(JSON.stringify(getUser))
|
|
clone.discount_codes = await DiscountCode.find({discount_user_id: getUser._id})
|
|
|
|
result.user = clone
|
|
result.jobs = await Job.find()
|
|
|
|
return res.json(result)
|
|
} else {
|
|
res.status(401).json({message: 'unauthenticated'})
|
|
}
|
|
} else {
|
|
return res.status(401).json({message: 'unauthenticated'})
|
|
}
|
|
} catch (error) {
|
|
console.log(error.message)
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.addFcmToken = [
|
|
async (req, res) => {
|
|
try {
|
|
const fcmToken = req.body.fcmToken
|
|
const admin = await User.findOne({_id: req.user._id, scope: 'admin'})
|
|
|
|
if (!admin) return res404(res, 'اطلاعات ادمین پیدا نشد با پشتیبانی تماس بگیرید')
|
|
|
|
admin.fcmToken = fcmToken
|
|
|
|
await admin.save()
|
|
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
} catch (error) {
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.addFcmTokenUser = [
|
|
async (req, res) => {
|
|
try {
|
|
const {token, deviceId, platform, deviceName ,fromWhere} = req.body
|
|
const user = await User.findOne({_id: req.user._id, scope: 'user'})
|
|
|
|
if (!user) return res404(res, 'اطلاعات کاربر پیدا نشد با پشتیبانی تماس بگیرید')
|
|
|
|
user.fcmToken = token
|
|
user.deviceId = deviceId
|
|
user.platform = platform
|
|
user.fromWhere = fromWhere
|
|
user.deviceName = deviceName
|
|
|
|
await user.save()
|
|
|
|
return res.json({message: _sr['fa'].response.success_save})
|
|
} catch (error) {
|
|
return res500(res, _sr['fa'].response.unknownError)
|
|
}
|
|
}
|
|
]
|