Files
Exchange/server/routes/user.ts
2025-11-07 22:24:40 +01:00

1194 lines
54 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as express from 'express';
import * as _ from 'lodash'
import { ObjectID } from 'mongodb';
import { v4 as uuidv4 } from 'uuid';
import * as mongoose from 'mongoose'
import successRes from '../middlewares/response'
import { isAuthorized } from '../middlewares/auth'
import { isEmailValid, isValidMobilePhone, userValidationRules, validate } from '../middlewares/validation'
import tryCatch from '../middlewares/tryCatch'
import { rateLimiterMiddleware } from '../middlewares/preventBruteForce'
import { User } from '../db/user'
import { Currencies } from '../db/currencies'
import myError from '../api/myError'
import { Accepted_Offers } from '../db/acceptedOffers';
import { Active_Offers } from '../db/ActiveOffers';
import { Withdraw_Offers } from '../db/withdrawOffers';
import { GetPrice } from '../db/getPrice';
import { logger } from '../api/logger'
import * as redis from '../api/redis'
import { getonlineLoginUsers } from '../api/socket'
const onlineLoginUsers = getonlineLoginUsers()
export const userRoutes = express.Router()
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////// GET ENDPOINTS /////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
userRoutes.get('/getUserWallet',
isAuthorized,
tryCatch((req, res, next) => {
const userId = req.session.userId
let rialPrice
return redis.hashget("dollarPrice")
.then((rial: number) => {
rialPrice = Number(rial/10)
User.findOne({ _id : userId })
.then((user: any) => {
if(user && user._id.toString() === userId.toString()) {
let walletArray = []
const userWallet = user.wallet
let totalAsstetsPrice =0
let totalAsstetsPriceRial =0
let status= true
const walletMap = userWallet.map((wall) => {
return redis.hashGetAll(wall.currency.toString())
.then((wallCurr: any) => {
if (wallCurr) {
let tempWalletArray = {
currencyName: wallCurr.currencyName,
persianName: wallCurr.per_name,
shortName: wallCurr.ab_name,
icon: wallCurr.icon,
_id: wall.currency.toString(),
value: wall.value,
commitment: wall.commitment,
totalPrice: 0,
totalRialPrice: 0
}
return redis.hashGetAll(wallCurr.ab_name+'-g')
.then((rate: any) => {
if(rate) {
tempWalletArray.totalPrice = wall.value * Number(rate.current)
totalAsstetsPrice += tempWalletArray.totalPrice
if(rialPrice) {
tempWalletArray.totalRialPrice = Math.ceil(Number(tempWalletArray.totalPrice ) * rialPrice)
walletArray.push(tempWalletArray)
} else {
walletArray["totalRialPrice"] = -1
walletArray.push(tempWalletArray)
}
} else {
status = false
tempWalletArray['totalPrice'] = -1
walletArray.push(tempWalletArray)
}
})
.catch((err) => {
throw (err)
})
} else {
const error = new myError(
'currency not found!',
400,
5,
'ارز پیدا نشد.!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
throw(err)
})
})
Promise.all(walletMap)
.then(() => {
successRes(res, 'user wallet data:', walletArray)
})
.catch((err) =>{
next(err)
})
} else {
const error = new myError(
'user not found!',
400,
5,
'کاربر مربوطه پیدا نشد!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err)=>{
next(err)
})
})
.catch((err) => {
next(err)
})
}))
userRoutes.get('/getUserAcceptedOffers',
isAuthorized,
userValidationRules('query', 'kind'),
validate,
tryCatch((req, res, next) => {
const kind = req.query.kind
const userId = req.session.userId
let query = {}
if(kind === "1") {
query = { creator: userId }
} else if(kind === "2") {
query = { acceptor: userId }
}
Accepted_Offers.find(query)
.then((offers) => {
if(offers && Array.isArray(offers) && offers.length > 0) {
let dataArray = []
Currencies.find()
.then((curs) => {
offers.forEach(off => {
const givenCur = _.find(curs, (i) => { return i._id.toString()=== off.curGivenId.toString()})
const takenCur = _.find(curs, (i) => { return i._id.toString()=== off.curTakenId.toString()})
if(givenCur && takenCur ){
dataArray.push({
giveCurname: givenCur.currencyName,
//giveCurValue: off.curGivenVal,
//givenCurPersianName: givenCur.per_name,
//givenCurShortName: givenCur.ab_name,
//givenCurIcon: givenCur.icon,
takenCurname: takenCur.currencyName,
//takenCurValue: off.curTakenVal,
//takenCurpersianName: takenCur.per_name,
//takenCurShortName: takenCur.ab_name,
//takenCurIcon: takenCur.icon,
//createDate: off.offeredDate,
acceptedDate: off.created_at,
})
} else {
return
}
})
const orderedDataArray = _.orderBy(dataArray,({acceptedDate}) => acceptedDate, ['asc'])
successRes(res, 'fdasdf', orderedDataArray)
})
.catch((err) =>{
next(err)
})
} else {
const error = new myError(
'there is no offer',
400,
5,
'سفارشی یافت نشد.!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
}))
userRoutes.get('/getUserActiveOffers',
isAuthorized,
tryCatch(async (req, res, next) => {
console.log(req.session)
const userId = req.session.userId
const curId = req.query.curIdOp
let query = []
let rialObj
query.push.apply(query, [{ userId : userId }, { expDate: { $gt: Date.now() } }])
if(ObjectID.isValid(curId)) {
await Currencies.findOne({ name: 'RIAL' })
.then((rial: any) => {
if (rial && rial.name === 'RIAL') {
rialObj = rial
query.push({ $or: [
{ $and: [{ curGivenId: curId }, { curTakenId: rial._id } ] },
{ $and: [{ curTakenId: curId }, { curGivenId: rial._id } ] }
] })
}
})
.catch((err) => {
console.log(err)
})
}
Active_Offers.find({ $and: query })
.then((offers) => {
if(offers && Array.isArray(offers) && offers.length > 0) {
let dataArray = []
if (ObjectID.isValid(curId)) {
redis.hashGetAll(curId.toString())
.then((curObj: any) => {
const offersMap = offers.map((offer) => {
if (offer.curTakenId.toString() === rialObj._id.toString()) {
dataArray.push({
GcurrencyName: curObj.currencyName,
GpersianName: curObj.per_name,
GshortName: curObj.ab_name,
Gvalue: offer.curGivenVal,
Gicon: curObj.icon,
TcurrencyName: rialObj.currencyName,
TpersianName: rialObj.per_name,
TshortName: rialObj.ab_name,
Tvalue: offer.curTakenVal,
Ticon: rialObj.icon,
txType: 'sell',
createDate : offer.created_at,
expireDate : offer.expDate,
offerId: offer.offerId
})
} else {
dataArray.push({
GcurrencyName: curObj.currencyName,
GpersianName: curObj.per_name,
GshortName: curObj.ab_name,
Gvalue: offer.curTakenVal,
Gicon: curObj.icon,
TcurrencyName: rialObj.currencyName,
TpersianName: rialObj.per_name,
TshortName: rialObj.ab_name,
Tvalue: offer.curGivenVal,
Ticon: rialObj.icon,
txType: 'buy',
createDate : offer.created_at,
expireDate : offer.expDate,
offerId: offer.offerId
})
}
})
Promise.all(offersMap)
.then(() => {
const orderedDataArray = _.orderBy(dataArray,({createDate}) => createDate, ['desc'])
successRes(res, 'fdasdf', orderedDataArray)
})
.catch((err) => {
next(err)
})
})
.catch((err) => {
console.log(err)
})
} else {
Currencies.find()
.then((curs) => {
offers.forEach(off => {
const givenCur = _.find(curs, (i) => { return i._id.toString()=== off.curGivenId.toString()})
const takenCur = _.find(curs, (i) => { return i._id.toString()=== off.curTakenId.toString()})
if(givenCur && takenCur) {
dataArray.push ({
//giveCurValue :off.curGivenVal,
giveCurname : givenCur.currencyName,
//givenCurPersianName : givenCur.per_name,
//givenCurShortName : givenCur.ab_name,
//givenCurIcon : givenCur.icon,
takenCurname : takenCur.currencyName,
//takenCurValue : off.curTakenVal,
//takenCurpersianName: takenCur.per_name,
//takenCurShortName : takenCur.ab_name,
//takenCurIcon : takenCur.icon,
createDate :off.created_at,
expireDate :off.expiredDate,
})
} else {
return
}
})
const orderedDataArray = _.orderBy(dataArray,({createDate}) => createDate, ['desc'])
successRes(res, 'fdasdf', orderedDataArray)
})
.catch((err) => {
next(err)
})
}
} else {
successRes(res, 'fdasdf', [])
}
})
.catch((err) =>{
next(err)
})
}))
userRoutes.get('/getUserWithdrawnOffers',
isAuthorized,
tryCatch((req, res, next) => {
const userId = req.session.userId
Withdraw_Offers.findOne({ userId: userId })
.then((theDoc) => {
if(theDoc && theDoc.userId.toString() === userId) {
if (theDoc.offers && Array.isArray(theDoc.offers) && theDoc.offers.length > 0) {
const modifiedOffers = _.orderBy(theDoc.offers, ['created_at', ['desc']])
successRes(res, '', modifiedOffers)
} else {
const error = new myError(
'the user does not have any withdrawnOffers',
400,
44,
'کاربر هیچ پیشنهاد بازپسگیری شده ندارد.',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'the user does not have any withdrawnOffers',
400,
44,
'کاربر هیچ پیشنهاد بازپسگیری شده ندارد.',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
})
)
userRoutes.get('/getOfferById',
isAuthorized,
userValidationRules('query', 'type'),
userValidationRules('query', 'offerId'),
validate,
tryCatch((req, res, next) => {
const userId = req.session.userId
const offerId = req.query.offerId
const type = req.query.type
let data
Currencies.find()
.then((currecies) => {
if (type === "1") {
Active_Offers.findOne({ $and: [ { offerId: offerId }, { expDate: { $gt: Date.now() } }] })
.then((theOffer => {
if(theOffer && theOffer.offerId === offerId) {
if(theOffer.userId.toString() === userId) {
const givenCur = _.find(currecies, (i) => { return i._id.toString() === theOffer.curGivenId.toString()})
const takenCur = _.find(currecies, (i) => { return i._id.toString() === theOffer.curTakenId.toString()})
data = {
givenCurName:givenCur.name,
takenCurName:takenCur.name,
offerCreatedDate:theOffer.created_at,
offerExpireDate:theOffer.expDate
}
successRes(res, '', data)
} else {
const error = new myError(
'you do not have pemissions',
400,
5,
'شما دسترسی ندارید!',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'there is no oofer with given offerId in Acive offers',
400,
5,
'پیشنهاد یافت نشد!',
'خطا رخ داد'
)
next(error)
}
}))
.catch((err) => {
next(err)
})
} else if(type === "2") {
Accepted_Offers.findOne({ offerId:offerId })
.then((theOffer => {
if(theOffer && theOffer.offerId === offerId) {
if(theOffer.acceptor.toString() === userId || theOffer.creator.toString() === userId) {
const givenCur = _.find(currecies, (i) => { return i._id.toString() === theOffer.curGivenId.toString()})
const takenCur = _.find(currecies, (i) => { return i._id.toString() === theOffer.curTakenId.toString()})
data = {
givenCurName:givenCur.name,
takenCurName:takenCur.name,
offerCreatedDate : theOffer.created_at,
offerAcceptedDate:theOffer.acceptedDate
}
successRes(res, '', data)
} else {
const error = new myError(
'you do not have pemissions',
400,
5,
'شما دسترسی ندارید!',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'there is no oofer with given offerId in Accepted offers',
400,
5,
'پیشنهاد یافت نشد!',
'خطا رخ داد'
)
next(error)
}
}))
.catch((err) => {
next(err)
})
} else if(type === "3") {
Withdraw_Offers.findOne({ 'offers.offerId': offerId })
.then((theDoc) => {
if(theDoc) {
if(theDoc.userId.toString() === userId) {
const theOffer = _.find(theDoc.offers, (i) => { return i.offerId === offerId })
const givenCur = _.find(currecies, (i) => { return i._id.toString() === theOffer.curGivenId.toString() })
const takenCur = _.find(currecies, (i) => { return i._id.toString() === theOffer.curTakenId.toString() })
data = {
givenCurName:givenCur.name,
takenCurName:takenCur.name,
offerCreatedDate:theOffer.offeredDate,
offerwhitdrawDate:theOffer.created_at
}
successRes(res, '', data)
} else {
const error = new myError(
'you do not have pemissions',
400,
5,
'شما دسترسی ندارید!',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'there is no oofer with given offerId in withdraw offers',
400,
5,
'پیشنهاد یافت نشد!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
}))
userRoutes.get('/acceptOffer',
isAuthorized,
userValidationRules('query','offerId'),
validate,
tryCatch(async(req, res, next) =>{
const acceptorId = req.session.userId
const offerId = req.query.offerId
const session = await mongoose.startSession()
Active_Offers.findOne({ offerId: offerId })
.then((offer: any) => {
if(offer && offer.offerId === offerId) {
const creatorId = offer.userId
if(creatorId.toString() !== acceptorId.toString()) {
const exp = new Date(offer.expDate).getTime()
if(exp >= Date.now()) {
console.log(exp)
console.log(offer.expDate)
session.withTransaction(async() => {
return User.findOne({_id : acceptorId}).session(session)
.then((acceptor: any) => {
let takenObjInAccWal = _.find(acceptor.wallet, (e) => e.currency.toString() === offer.curTakenId.toString())
if(takenObjInAccWal && takenObjInAccWal.value >= offer.curTakenVal) {
return User.findOne({_id : creatorId}).session(session)
.then(async (creator: any) => {
if(creator && creator._id.toString() === creatorId.toString()) {
let givenObjInCreWal = _.find(creator.wallet, (e) => e.currency.toString() === offer.curGivenId.toString())
if(givenObjInCreWal) {
// take from creator and give to acceptor
givenObjInCreWal.commitment -= Number(offer.curGivenVal)
let takenObjInCreWal = _.find(creator.wallet, (i) => i.currency.toString() === offer.curTakenId.toString())
if(takenObjInCreWal) {
takenObjInCreWal.value += offer.curTakenVal
} else {
const currencyObj = {
currency : offer.curTakenId,
value : offer.curTakenVal
}
creator.wallet.push(currencyObj)
}
takenObjInAccWal.value -= offer.curTakenVal
let giveObjInAccWal = _.find(acceptor.wallet, (e) => e.currency.toString() === offer.curGivenId.toString())
if(giveObjInAccWal) {
giveObjInAccWal.value += offer.curGivenVal
} else {
const currencyObj = {
currency : offer.curGivenId,
value : offer.curGivenVal,
}
acceptor.wallet.push(currencyObj)
}
const bodyAccOffer = {
acceptor : acceptorId,
creator: creatorId,
offerId: offer.offerId,
curGivenId: offer.curGivenId,
curGivenVal: offer.curGivenVal,
curTakenId: offer.curTakenId,
curTakenVal: offer.curTakenVal,
offeredDate: offer.created_at,
expiredDate: offer.expDate
}
Currencies.findOne({_id : offer.curGivenId})
.then((currency) => {
const currentPrice = bodyAccOffer.curTakenVal
let min
let max
redis.hashGetAll('L_' + currency.ab_name)
.then((redisGetObj) => {
if(redisGetObj != null) {
if(currentPrice < redisGetObj['min']) {
min = currentPrice
} else {
min = redisGetObj['min']
if(currentPrice > redisGetObj['max']) {
max = currentPrice
} else {
max = redisGetObj['max']
}
}
redis.hashHMset('L_' + currency.ab_name, {
currentPrice: currentPrice,
min : min,
max : max,
})
} else {
redis.hashHMset('L_' + currency.ab_name, {
currentPrice: currentPrice,
min : currentPrice,
max : currentPrice,
})
}
})
.catch((err) => {
throw(err)
})
})
.catch((err) => {
throw(err)
})
await Accepted_Offers.create([bodyAccOffer], { session })
await creator.save()
await acceptor.save()
await offer.remove()
} else {
const error = new myError(
'creator wallet does not have given object',
400,
5,
'در کیف پول فرشنده ارز مورد نظر پیدا نشد',
'خطا رخ داد'
)
throw(error)
}
}
})
.catch((err) => {
throw(err)
})
} else {
const error = new myError(
'There is no enough currency in acceptor wallet or acceptor does not have the currency',
400,
5,
'ارز مورد در کیف پول خریدار نیست یا موجودی آن کافی نیست',
'خطا رخ داد'
)
throw(error)
}
})
.catch((err) =>{
throw(err)
})
})
.then(() => {
successRes(res, 'Offer accepted succesfully ', offerId, {})
})
.catch((err) => {
next(err)
})
.finally(() => {
session.endSession()
})
} else {
const error = new myError(
'offer is expired',
400,
5,
'پیشنهاد منقضی شده است.',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'acceptor and creator must be different',
400,
5,
'فروشنده و خریدار باید متفاوت باشند.',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'There is no offer with the given offer Id',
400,
5,
'شناسه پیشنهادی یافت نشد.',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
})
)
userRoutes.post('/withdrawOffer',
isAuthorized,
// userValidationRules('query','offerId'),
// validate,
tryCatch(async(req, res, next) =>{
const userId = req.session.userId
const offerIds = req.body.offerIds
let nowithOffer = false
console.log('offerIds: ', offerIds)
console.log('userId: ', userId)
const session = await mongoose.startSession()
session.withTransaction(async() => {
return User.findOne({ _id : userId }).session(session)
.then((user: any) => {
return Active_Offers.find({ $and: [ { offerId : { $in: offerIds } }, { userId: userId } ] }).session(session)
.then((offers: any) => {
if(offers && offers.length > 0) {
return Withdraw_Offers.findOne({ userId : userId }).session(session)
.then(async (withOffer :any) => {
if(!withOffer) {
nowithOffer = true
withOffer = {
userId: userId,
offers: []
}
}
const offersMap = offers.map(async (offer, i) => {
const bodyWithOffer = {
userId : userId,
offers: {
offerId : offer.offerId,
curGivenId: offer.curGivenId,
curGivenVal: offer.curGivenVal,
curTakenId: offer.curTakenId,
curTakenVal: offer.curTakenVal,
offeredDate: offer.created_at,
expiredDate: offer.expDate,
withdrawDate: Date.now()
}
}
let userWalCurGivenObj = _.find(user.wallet, (i) => i.currency.toString() === offer.curGivenId.toString())
if(userWalCurGivenObj && userWalCurGivenObj.commitment >= Number(offer.curGivenVal)) {
userWalCurGivenObj.value += offer.curGivenVal
userWalCurGivenObj.commitment -= Number(offer.curGivenVal)
withOffer.offers.push(bodyWithOffer.offers)
console.log('i: ', i)
await offer.remove()
} else {
//error user does not have the currency in his/her wallet
const error = new myError(
'user does not have the given currency in his/her wallet',
400,
5,
'کاربر ارز مورد نظر را در کیف پول ندارد.',
'خطا رخ داد'
)
throw(error)
}
})
return Promise.all(offersMap)
.then(async () => {
if(nowithOffer) {
await Withdraw_Offers.create([withOffer], { session })
} else {
await withOffer.save()
}
await user.save()
})
.catch((err) => {
throw err
})
})
.catch((err) => {
throw(err)
})
} else {
const error = new myError(
'There is no offer with the given Id',
400,
5,
'شناسه پیشنهادی یافت نشد.',
'خطا رخ داد'
)
throw(error)
}
})
.catch((err) => {
throw(err)
})
})
.catch((err) => {
throw(err)
})
})
.then(() => {
successRes(res, 'Offer removed Successfully. ', true, {})
})
.catch((err) => {
console.log('error: ', err)
next(err)
})
.finally(() => {
session.endSession()
})
})
)
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////// POST ENDPOINTS /////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
userRoutes.post('/createOffer',
isAuthorized,
userValidationRules('body', 'curGivenId'),
userValidationRules('body', 'curGivenVal'),
userValidationRules('body', 'curTakenId'),
userValidationRules('body', 'curTakenVal'),
//userValidationRules('body', 'expDate'),
validate,
tryCatch(async(req, res, next) => {
const userId = req.session.userId
const curGivenId = req.body.curGivenId
const curGivenVal = req.body.curGivenVal
const curTakenId = req.body.curTakenId
const curTakenVal = req.body.curTakenVal
const expDate = req.body.expDate
let offerId
let bodyOffer
const exp = new Date(expDate)
const session = await mongoose.startSession()
if(exp.getTime() >= Date.now()) {
if(curGivenId != curTakenId) {
Currencies.findOne({_id : curGivenId})
.then((curGivenObj) => {
Currencies.findOne({_id : curTakenId})
.then((curTakenObj) => {
if(curGivenObj && curTakenObj && curGivenObj._id.toString() === curGivenId.toString() &&
curTakenObj._id.toString() === curTakenId.toString()) {
session.withTransaction(() => {
// console.log("sasan")
return User.findOne({_id : userId}).session(session)
.then(async(user: any) => {
if(user && user._id.toString() === userId.toString()) {
let userWallet = _.find(user.wallet, (e) => e.currency.toString() === curGivenId.toString()) // object of specific currency in user's wallet
if(userWallet) {
if(userWallet.value >= curGivenVal) {
offerId = uuidv4()
bodyOffer = {
userId : userId,
offerId: offerId,
curGivenId: curGivenId,
curGivenVal: curGivenVal,
curTakenId: curTakenId,
curTakenVal: curTakenVal,
expDate: expDate,
rank: user.rank
}
userWallet.value = userWallet.value - curGivenVal
userWallet.commitment = userWallet.commitment + Number(curGivenVal)
await Active_Offers.create([bodyOffer], { session })
await user.save()
} else {
const error = new myError(
'Given: user has not enough credit in his/her wallet',
400,
5,
'کاربر مقدار کافی از ارز برای پیشنهاد داده شده را ندارد.',
'خطا رخ داد'
)
throw(error)
}
} else {
const error = new myError(
'User does not have this kind of currency',
400,
5,
'کیف پول کاربر ارز پیشنهادی را ندارد.',
'خطا رخ داد'
)
throw(error)
}
}
else {
const err = new myError(
'userId not found',
400,
5,
'خطا رخ داد',
'کاربری با این شناسه کاربری پیدا نشد.'
)
throw(err)
}
})
.catch((err) => {
throw(err)
})
})
.then(() => {
successRes(res, 'Offer created succesfully ', offerId, {})
const modifiedBodyOffer = {
offerId: bodyOffer.offerId,
curGivenId: bodyOffer.curGivenId,
curGivenVal: bodyOffer.curGivenVal,
curTakenId: bodyOffer.curTakenId,
curTakenVal: bodyOffer.curTakenVal,
expDate: bodyOffer.expDate,
}
redis.hashSetMembers(userId)
.then((result) => {
console.log('result: ', result)
})
onlineLoginUsers.emit('new_offer', modifiedBodyOffer)
})
.catch((err) => {
console.log('error: ', err)
next(err)
})
.finally(() => {
session.endSession()
})
} else {
const err = new myError(
'curTakenId error',
400,
5,
'ارز وارد شده صحیح نیست',
'خطا رخ داد'
)
next(err)
}
})
.catch((err) => {
next(err)
})
})
.catch((err) => {
next (err)
})
} else {
const err = new myError(
'curGivenId must be different from curTakenId',
400,
5,
'ارز ها برای تبادل باید متفاوت باشند.',
'خطا رخ داد'
)
next(err)
}
} else {
const err = new myError(
'expire date must be in the future(not before creating offer date)',
400,
5,
'تاریخ انقضای پیشنهاد باید بعد از ایجاد پیشنهاد باشد.',
'خطا رخ داد'
)
next(err)
}
})
);
userRoutes.post('/getPrice',
isAuthorized,
userValidationRules('body','currency'),
userValidationRules('body','quantity'),
validate,
tryCatch((req, res, next) => {
const userId = req.session.userId
const currency = req.body.currency
const quantity = req.body.quantity
User.findOne({ _id: userId })
.then((user) => {
if(user && user._id.toString() === userId) {
GetPrice.findOne({ $and: [{ currency: currency }, { userId: user._id }] })
.then(async (doc) => {
const curRialPrice = await redis.getCurrentPrice(currency)
const bodyPrice = {
currency: currency,
userId: user._id,
quantity: quantity,
rialPricePerUnit: curRialPrice
}
if(doc) {
doc.remove()
const newGetPrice = new GetPrice({ ...bodyPrice })
newGetPrice.save()
.then(() => {
successRes(res, 'old getPrice doc removed and a new one created', curRialPrice, {})
})
.catch((err) => {
next(err)
})
} else {
const newGetPrice = new GetPrice({ ...bodyPrice })
newGetPrice.save()
.then(() => {
successRes(res, 'getPrice doc created', curRialPrice, {})
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'user not found',
400,
5,
'کاربر پیدا نشد',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
})
)
userRoutes.post('/addCurrencyValue',
isAuthorized,
userValidationRules('body','currencyId'),
userValidationRules('body','currencyValue'),
validate,
tryCatch((req, res, next) => {
const currency = req.body.currencyId
const value = Number(req.body.currencyValue)
console.log("req.body.currencyValue is type of ", typeof(req.body.currencyValue))
const userId = req.session.userId
Currencies.findOne({ _id : currency })
.then((cur: any) => {
if (cur && cur._id.toString() === currency) {
User.findOne({ _id : userId })
.then((user: any) => {
if(user && user._id.toString() === userId) {
let wall = _.find(user.wallet, (i) => { return i.currency.toString() === currency.toString() })
if(wall) {
console.log("wallet value is type of ", typeof(wall.value))
console.log(" value is type of ", typeof(value))
wall.value += value
} else {
user.wallet.push({ currency : cur._id , value : value })
}
user.save()
.then(() => {
successRes(res,"value added successfully")
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'user not found!',
400,
5,
'کاربر مربوطه پیدا نشد!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'currency not found!',
400,
5,
'ارز ها برای تبادل باید متفاوت باشند.',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
}))
userRoutes.post('/transferCuurency',
isAuthorized,
userValidationRules('body','currencyId'),
userValidationRules('body','currencyValue'),
userValidationRules('body','receiverUsername'),
validate,
tryCatch(async (req, res, next) => {
const currency = req.body.currencyId
const value = req.body.currencyValue
const receiverUsername = req.body.receiverUsername
let query
const userId = req.session.userId
let session = await mongoose.startSession()
Currencies.findOne({_id : currency})
.then((curr) => {
if(curr && curr._id.toString() === currency) {
session.withTransaction(async() => {
return User.findOne({ _id : userId }).session(session)
.then((sender: any) => {
if (sender && sender._id.toString() === userId) {
let theCur = _.find(sender.wallet, (i) => { return i.currency.toString() === currency })
if (theCur) {
if(Number(theCur.value) >= Number(value)) {
theCur.value -= value
if (isEmailValid(receiverUsername)) {
query = { 'email.address': receiverUsername }
} else if (isValidMobilePhone(receiverUsername)) {
query = { 'phoneNumber.number': receiverUsername }
}
return User.findOne(query).session(session)
.then(async(receiver: any) => {
if (receiver) {
let theCur2 = _.find(receiver.wallet, (i) => { return i.currency.toString() === currency })
if (theCur2) {
theCur2.value += value
await receiver.save()
await sender.save()
} else {
receiver.wallet.push({ currency: currency , value: value })
await receiver.save()
await sender.save()
}
} else {
const error = new myError(
'The reciever does not exist!',
400,
5,
'نام کاربری گیرنده معتبر نیست!',
'خطا رخ داد'
)
throw(error)
}
})
.catch((err) =>{
throw(err)
})
} else {
const error = new myError(
'you do not have enough currency',
400,
5,
'موجودی کافی نیست !',
'خطا رخ داد'
)
throw(error)
}
} else {
const error = new myError(
'you do not have this currency',
400,
5,
'ارز فوق در کیف پول شما موجود نیست !',
'خطا رخ داد'
)
throw(error)
}
} else {
const error = new myError(
'The user does not exist!',
400,
5,
'چنین کاربری در سیستم ثبت نشده است!',
'خطا رخ داد'
)
throw(error)
}
})
.catch((err) => {
throw(err)
})
})
.then(()=> {
successRes(res)
})
.catch((err) => {
console.log('error: ', err)
next(err)
})
.finally(() => {
session.endSession()
})
} else {
const error = new myError(
'the currency is not valid',
400,
5,
'ارز فوق متعبر نیست !',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) =>{
next(err)
})
}))
userRoutes.post('/chargeAcount',
isAuthorized,
// if we want to aurhorize again we need aonther middleware
tryCatch((req, res, next) => {
const rialObjectId = process.env.OBJECTID_RIAL
const value = req.body.value
const userId = req.session.userId
User.findOne({_id : userId})
.then((user: any) =>{
let wall = _.find(user.wallet, (i) => { return i.currency.toString()=== rialObjectId})
wall.value += value
user.save()
.then(() =>{
successRes(res)
}).catch((err) =>{
next(err)
})
}).catch((err) =>{
next(err)
})
}))