Files
barg-restuarant/server/controllers/orderController.js
T
hamid.zarghami1@gmail.com e644edbd65 transfer project in github
2024-05-12 15:29:27 +03:30

1937 lines
62 KiB
JavaScript

const CartItem = require('../models/CartItem')
const Order = require('../models/Order')
const User = require('../models/User')
const Food = require('../models/Food')
const Payment = require('../models/Payment')
const DiscountCode = require('../models/DiscountCode')
const StoreInfo = require('../models/StoreInfo')
const {body, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
const axios = require('axios')
const zarinpal = require('./../zarinpal')
const {sendSingle, sendMulti} = require('./../plugins/pushNotif').notification
const {sendNotifyOrder} = require('./../socket/adminNotify')
const moment = require('moment-jalaali');
const {sms} = require('./../SMSModule')
const CronJob = require('cron').CronJob
/////////// variables
const apiKey = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIn0.eyJhdWQiOiIxNDk3OSIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIiwiaWF0IjoxNjI3MzI2Mzc0LCJuYmYiOjE2MjczMjYzNzQsImV4cCI6MTYyOTkxODM3NCwic3ViIjoiIiwic2NvcGVzIjpbImJhc2ljIl19.hyKNSy4fmPps6yIdm33Wof-mES9ujh5lmI3VFWyecbkNCm9ATPwsZ9s53A3a1wPJmHfLBXpCcob5NGL-GjZlVfqfRBiReRMr_iniCjUOnqENfFwVEJutxI-xrzVe7PZzOgx1Vr6WwSUHvQ36eJSS1lBlHlqCgwRbkG0hs4YdZsKhzhfYdlAluNw9djjUAMbRWZVL0EluP9CYko4w8tB0KHUZMZYGQcevCfb_3OU9ygHo7B--Z5aTPfm7IK4eP0gHsZ_t857B3tu3ZJB1mkgxc2R9gZUflKqj1ZqkYiR0uMGP-571enXh6pYQLXL2k-gOxLIedCaE6XytxVXhENnotA';
const limit = 20
const zarinUrl = 'https://www.zarinpal.com/pg/StartPay'
const timeToStart = 1800000
// const timeToStart = 1800000
////////// functions
const deg2rad = (deg) => {
return deg * (Math.PI / 180)
}
const _computeShippingCost = async (addresses, location) => {
try {
if (addresses.length && location) {
const address = addresses[0]
const R = 6371; // Radius of the earth in km
const dLat = deg2rad(address.location.coordinates[1] - location.coordinates[1]); // deg2rad below
const dLon = deg2rad(address.location.coordinates[0] - location.coordinates[0]);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(address.location.coordinates[1])) * Math.cos(deg2rad(location.coordinates[1])) *
Math.sin(dLon / 2) * Math.sin(dLon / 2)
;
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
// Distance in km
return R * c;
} else {
return 0
}
} catch (error) {
return 0
}
}
const _computeShippingCostByRoad = async (addresses, storeLocation) => {
try {
if (addresses.length && storeLocation) {
const address = addresses.find(item2 => item2.used === true)
const lng = address.location.coordinates[0]
const lat = address.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 new Error(_sr['fa'].response.unknownError);
//@todo if distance under 1000 meter equal to 0
return getDistance.data.routes[0].distance <= 1000 ? 0 : Math.round(getDistance.data.routes[0].distance / 1000);
} else {
return 0
}
} catch (error) {
return 0
}
}
const getMinutes = (str) => {
var time = str.split(':');
return time[0] * 60 + time[1] * 1;
}
const getMinutesNow = (timezone) => {
var timeNow = new Date();
return timeNow.getUTCHours() * 60 + timeNow.getUTCMinutes();
}
const _computeHavePointPrice = async (items) => {
try {
let total = 0
for (const item of items) {
if (item.havePoint) {
let priceItem = item.price - (item.price * item.static_discount || 0 / 100)
let totalPrice = priceItem * item.quantity
total += totalPrice
}
}
return total
} catch (error) {
return 0
}
}
//////////////////////////////////////////////////////////////////public
////////////////////////////////////// cart
module.exports.addToCart = [
//// check start time and end time
// async (req, res, next) => {
// try {
// const getTime = await StoreInfo.findOne()
//
// if (getTime) {
// if (getTime?.open24){
// return next()
// } else if (getTime?.utcStartTime && getTime?.utcEndTime) {
// let start = getMinutes(getTime.utcStartTime)
// let end = getMinutes(getTime.utcEndTime)
// let now = getMinutesNow(getTime.timezone)
//
// if (
// (start < now && end > now) || (start > end && (now < end || now > start))
// ) {
// return next()
// } else if (start === end) {
// return res.status(503).json({message: `در حال حاظر پذیرش سفارش نداریم`})
// }else {
// return res.status(503).json({message: `پذیرش سفارش از ساعت ${getTime?.startTime} تا ${getTime?.endTime} می باشد`})
// }
//
// } else {
// return next()
// }
// } else {
// return next()
// }
//
// } catch (error) {
// return res500(res, _sr['fa'].response.unknownError)
// }
// },
[
body('product_id')
.custom((value, {req}) => {
return Food.findById(value)
.then(product => {
if (product) return true
else return Promise.reject(_sr['fa'].not_found.item_id)
})
.catch(err => {
return Promise.reject(_sr['fa'].not_found.item_id)
})
}),
body('type')
.notEmpty().withMessage(`نوع عملی که باید انجام شود را بفرستید`),
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 {product_id, type, branchId} = req.body;
const checkCart = await CartItem.findOne({branchId, product_id , user_id: req.user._id}).populate('product_id');
if (checkCart) {
if (Number(checkCart.quantity) > 0) {
if (type === 'positive') {
checkCart.quantity = Number(checkCart.quantity) + 1;
} else if (type === 'negative') {
checkCart.quantity = Number(checkCart.quantity) - 1;
}
await checkCart.save();
if (Number(checkCart.quantity) === 0 || checkCart.product_id.stock === 0) {
await checkCart.deleteOne()
}
}
return res.json({message: _sr['fa'].response.success_save})
} else {
const addCart = await CartItem.create({
branchId,
product_id,
user_id: req.user._id,
quantity: 1
})
if (!addCart) return res500(res, _sr['fa'].response.unknownError);
return res.json({message: _sr['fa'].response.success_save})
}
} catch (error) {
return res500(res, _sr['fa'].response.unknownError);
}
}
]
module.exports.getCartItems = [
async (req, res) => {
try {
const branchId = req?.params?.branchId
const allCartItems = await CartItem.find({branchId, user_id: req.user._id}).populate({
path: 'user_id',
select: '-password -token',
sort: {useRate: -1}
}).populate('product_id')
return res.json(allCartItems);
} catch (error) {
return res500(res, _sr['fa'].response.unknownError);
}
}
]
module.exports.updateCart = [
[
body('quantity')
.notEmpty()
.withMessage((value, {req}) => {
return _sr['fa'].required.quantity
})
.bail()
.isNumeric()
.withMessage((value, {req}) => {
return _sr['fa'].format.number
})
],
checkValidations(validationResult),
(req, res) => {
CartItem.findById(req.params.item_id)
.then(item => {
if (!item) return res404(res, _sr['fa'].not_found.item_id)
item.quantity = Number(req.body.quantity)
item.save()
return res.json({message: _sr['fa'].response.success_save})
})
.catch(err => {
return res404(res, err)
})
}
]
module.exports.deleteAllCartItem = [
(req, res) => {
CartItem.deleteMany({user_id: req.user._id}, (err, result) => {
if (err) return res500(res, _sr['fa'].response.unknownError)
else return res.json({message: _sr['fa'].response.success_remove})
})
}
]
/////////////////////////////////// reorder
module.exports.reOrder = [
//////////////////// validation step
// (req, res, next) => {
// CartItem.find({user_id: req.user._id})
// .then(items => {
// // check if cart is not empty
// if (items.length) {
// // check product stock
// let outOfRun = []
// items.forEach(async (item, index) => {
// await Food.findById(item.product_id)
// .then(product => {
// if (product.stock < item.quantity) {
// outOfRun.push({
// product_id: product._id,
// category_id: product.category,
// stock: product.stock
// })
// item.remove()
// }
// if (index + 1 === items.length) {
// if (!outOfRun.length) return next()
// else return res.status(422).json(outOfRun)
// }
// })
// })
// } else {
// return res.status(404).json({message: _sr['fa'].response.cart_empty})
// }
// })
// },
async (req, res) => {
try {
const orderId = req.params?.orderId
const checkOrder = await Order.findOne({'status': 'delivered', user_id: req.user._id, _id: orderId}).populate('product_id')
if (!checkOrder) return res404(res, `سفارش کاربر یافت نشد`);
await CartItem.deleteMany({user_id: req.user._id})
for (const food of checkOrder.order_items) {
if (food.product_id && !food.product_id?.deleted) {
await CartItem.create({
product_id: food.product_id._id,
user_id: req.user._id,
quantity: food.quantity
})
}
}
return res.json({message: _sr['fa'].response.success_save})
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
////////////////////////////////////// order
module.exports.addOrder = [
[
body('description')
.optional().isString().withMessage(`توضیحات سفارش باید به صورت رشته فرستاده شود`),
body('bag')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('score')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('discountCode')
.if((value, {req}) => {
return value;
})
.custom((value, {req}) => {
return DiscountCode.findOne({discount_code: value}).then(discount => {
if (!discount) return Promise.reject(`کد تخفیف وارد شده صحیح نمیباشد`);
if (Number(discount.discount_expire_date) > Date.now()) return Promise.reject(`تاریخ مصرف کد تخفیف به اتمام رشیده است`)
if (discount.used_by.includes(req?.user?._id)) return Promise.reject(`کد تخفیف قبلا استفاده شده است`);
if (!discount.isPublic) {
if (discount?.discount_user_id?.toString() !== req?.user?._id.toString()) return Promise.reject(`کد تخفیف وارد شده صحیح نمیباشد`)
} else return true
}).catch(error => {
return Promise.reject(`کد تخفیف وارد شده صحیح نمیباشد`);
})
}),
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),
//////////////////// validation step
(req, res, next) => {
CartItem.find({branchId: req?.body?.branchId, user_id: req.user._id})
.then(items => {
// check if cart is not empty
if (items.length) {
// check product stock
let outOfRun = []
items.forEach(async (item, index) => {
await Food.findById(item.product_id)
.then(product => {
if (product.stock < item.quantity) {
outOfRun.push({
name: product.name,
product_id: product._id,
category_id: product.category,
stock: product.stock
})
item.remove()
}
if (index + 1 === items.length) {
if (!outOfRun.length) return next()
else return res.status(422).json(outOfRun)
}
})
})
} else {
return res.status(404).json({message: _sr['fa'].response.cart_empty})
}
})
},
//////////////////// save order
async (req, res) => {
try {
const {branchId , description, bag, score, discountCode} = req.body;
const cartItems = await CartItem.find({branchId ,user_id: req.user._id}).populate('product_id');
const getUserInfo = await User.findById(req.user._id);
const getDiscountCode = await DiscountCode.findOne({branchId ,discount_code: discountCode});
if (!getUserInfo) return res404(res, `اطلاعات کاربر یافت نشد`);
if (!cartItems.length) return res.status(404).json({message: `هیچ محصولی در سبد خرید شما وجود ندارد`})
await Order.deleteMany({branchId, status: 'incomplete', user_id: req.user._id});
/// check order exist or not
// const checkOrder = await Order.findOne({'status': 'incomplete', user_id: req.user._id});
//
// if (checkOrder) {
// await checkOrder.remove()
// }
const orderItems = [];
for (const item of cartItems) {
orderItems.push({
product_id: item.product_id._id,
name: item.product_id.name,
quantity: item.quantity,
price: item.product_id.price,
static_discount: item.product_id.static_discount,
havePoint: item.product_id.havePoint
});
}
if (score && bag) return res.status(422).json({message: 'استفاده همزمان از کیف پول و امتیاز برای خرید مجاز نمی باشد'})
const orderData = {
branchId,
user_id: req.user._id,
number: Date.now(),
order_items: orderItems,
statuses: [{
status: 'incomplete'
}],
description,
bag,
score,
discount_code: getDiscountCode?.discount_code,
discount_amount: getDiscountCode?.discount_amount,
discount_menuType: getDiscountCode?.menuTypeId
};
await Order.create(orderData);
return res.json({message: _sr['fa'].response.success_save})
} catch (error) {
console.log(error)
return res500(res, _sr['fa'].response.unknownError);
}
}
]
module.exports.orderPay = [
[
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, next) => {
CartItem.find({branchId: req?.body?.branchId, user_id: req.user._id})
.then(items => {
// check if cart is not empty
if (items.length) {
// check product stock
let outOfRun = []
items.forEach(async (item, index) => {
await Food.findById(item.product_id)
.then(product => {
if (product.stock < item.quantity) {
outOfRun.push({
product_id: product._id,
category_id: product.category,
stock: product.stock
})
item.remove()
}
if (index + 1 === items.length) {
if (!outOfRun.length) return next()
else return res.status(422).json(outOfRun)
}
})
})
} else {
return res.status(404).json({message: _sr['fa'].response.cart_empty})
}
})
},
async (req, res) => {
try {
const branchId = req?.body?.branchId
const cartItems = await CartItem.find({branchId , user_id: req.user._id}).populate('product_id');
const checkOrder = await Order.findOne({branchId , 'status': 'incomplete', user_id: req.user._id})
const getUserInfo = await User.findById(req.user._id);
const getStoreInfo = await StoreInfo.findOne({_id : branchId})
if (!checkOrder) return res404(res, 'لطفا از مرحله سبد خرید دوباره ادامه دهید')
let pricePoint = Math.floor(getStoreInfo?.priceForChange/getStoreInfo?.pointForChange) || 0
let totalPricePoint = getStoreInfo?.totalPricePoint || 0
let pointForBuy = getStoreInfo?.pointForBuy || 0
let discount_percent = checkOrder?.discount_amount || 0;
let discount_menuType = checkOrder?.discount_menuType;
let specialDiscountMenuType = false;
let routePrice = 0;
let sum = 0;
let sumFoodByPercent = 0;
let sumFoodByPercentForDiscount = 0;
let total = 0
let firstTotal = 0
let percent = 0;
let tax = 0;
if (!getUserInfo) return res404(res, `اطلاعات کاربر یافت نشد`);
if (!cartItems.length) return res.status(404).json({message: `هیچ محصولی در سبد خرید شما وجود ندارد`})
const orderItems = [];
for (const item of cartItems) {
orderItems.push({
product_id: item.product_id._id,
name: item.product_id.name,
quantity: item.quantity,
price: item.product_id.price,
static_discount: item.product_id.static_discount,
havePoint: item.product_id.havePoint
});
const itemPercent = item.product_id.price * item.product_id.static_discount / 100;
const sumPercent = itemPercent * item.quantity;
const price = item.product_id.price;
const sumPriceItem = price * item.quantity;
let sumByPercentForDiscount = sumPriceItem - sumPercent
if (Boolean(discount_percent) && discount_menuType) {
specialDiscountMenuType = true
if (item?.product_id?.category.type?.toString() === discount_menuType?.toString()) {
sumFoodByPercentForDiscount += sumByPercentForDiscount
}
}
sum = sum + sumPriceItem; /// sum food price without percent
percent = percent + sumPercent; /// sum all food percent
}
/// sum food price with percent
sumFoodByPercent = sum - percent
/// compute shipping cost
if (getStoreInfo) {
if (getStoreInfo?.shippingType) {
routePrice = getStoreInfo?.shippingCost || 0;
} else {
routePrice = await _computeShippingCostByRoad(getUserInfo?.addresses, getStoreInfo?.location) * (getStoreInfo?.shippingCost || 0) || 0;
}
/// compute tax of order
if (getStoreInfo?.tax) {
tax = sumFoodByPercent * 9 / 100
}
}
/// compute discount code
if (Boolean(discount_percent)) {
let discountPercent = (specialDiscountMenuType ? sumFoodByPercentForDiscount : sumFoodByPercent) * discount_percent / 100
percent = percent + discountPercent
/// compute sum food with discount percent
sumFoodByPercent = sumFoodByPercent - discountPercent
}
/// compute total of order
total = sumFoodByPercent + tax + routePrice;
checkOrder.order_items = orderItems
checkOrder.createdOn = Date.now()
checkOrder.address = getUserInfo.addresses.find(item => item.used)
checkOrder.sum = Math.ceil(sum)
checkOrder.routePrice = Math.ceil(routePrice)
checkOrder.tax = Math.ceil(tax)
checkOrder.percent = Math.ceil(percent)
checkOrder.total = Math.ceil(total)
checkOrder.pricePoint = pricePoint
firstTotal = Math.ceil(total)
if (checkOrder.bag) {
const payPrice = total - getUserInfo?.bagAmount
total = payPrice <= 0 ? 0 : payPrice
}
if (checkOrder.score && pricePoint > 0) {
const payScore = total - (getUserInfo?.score * pricePoint)
total = payScore <= 0 ? 0 : payScore
}
checkOrder.payTotal = Math.ceil(total)
console.log('total', total)
console.log('payTotal', checkOrder?.payTotal)
/// if total pay is zero dont move to pay method
if (checkOrder?.payTotal <= 0) {
/// if bag true use the bagAmount of user
if (checkOrder?.bag) {
getUserInfo.bagAmount -= firstTotal
// add point for user only for available product
const computeAvaPro = await _computeHavePointPrice(checkOrder.order_items)
/// add score for order
if (computeAvaPro >= totalPricePoint && totalPricePoint > 0) {
const point = (Math.floor(computeAvaPro / totalPricePoint) * pointForBuy)
if (point > 0) {
getUserInfo.score = getUserInfo.score + point
getUserInfo.scoreLogs = [
{
score: point,
order_id: getUserInfo._id,
forWhat: 'buy',
action: 'increase'
}
]
}
}
await getUserInfo.save()
if (Boolean(discount_percent)) {
const updateDiscount = await DiscountCode.findOne({discount_code: checkOrder.discount_code})
if (!updateDiscount || (Number(updateDiscount.discount_expire_date) > Date.now())) return res.status(403).json({message: 'مشکلی در پرداخت و ثبت سفارش پیش آمده است لطفا با پشتیبانی تماس بگیرید'})
updateDiscount.used_by.push(getUserInfo._id)
await updateDiscount.save()
}
const addPayment = await Payment.create({
user_id: getUserInfo._id,
order_id: checkOrder._id,
transactionId: Date.now(),
refId: Date.now(),
getPayment: true,
action: 'decreaseBag',
status: 'paid',
cost: firstTotal,
})
checkOrder.payment.push(addPayment._id)
checkOrder.bagCost = firstTotal
} /// it was ok!
/// if score true use the score of user
if (checkOrder?.score && pricePoint > 0) {
const point = Math.ceil(firstTotal / pricePoint)
checkOrder.scoreCost = point * pricePoint
checkOrder.scorePoint = point
getUserInfo.score -= point
getUserInfo.scoreLogs = [
{
score: point,
order_id: checkOrder._id,
forWhat: 'buy',
action: 'decrease'
}
]
await getUserInfo.save()
}
checkOrder.statuses.push({
status: 'processing'
})
checkOrder.status = 'processing'
checkOrder.paymentStatus = 'paid'
await checkOrder.save()
for (const food of checkOrder.order_items) {
const getFood = await Food.findById(food.product_id)
if (getFood) {
getFood.stock = getFood.stock - food.quantity
// getFood.canReview.push(req.user._id)///add user id for review
getFood.save()
}
}
/// remove cart item
await CartItem.deleteMany({user_id: getUserInfo._id})
//----------------------- send notif for admins -----------------
const fcmTokens = []
const allAdmins = await User.find({scope: 'admin'})
for (const admin of allAdmins) {
if (admin.fcmToken) fcmTokens.push(admin.fcmToken)
}
const objNotif = {
title: 'سفارش جدید!',
body: 'یک سفارش جدید در پنل برگ من ثبت گردید'
}
const payload = {
notification: objNotif,
};
const input = {
registrationTokens: fcmTokens,
payload
}
await sendMulti(input)
sendNotifyOrder(checkOrder?.branchId)
//----------------------------------------------------------------
//--------------------- send notif to user --------------------------
const messageUser = {
title: 'ثبت سفارش',
body: 'با تشکر از اعتماد شما سفارش شما با موفقیت ثبت شد'
}
const payloadUser = {
notification: messageUser,
};
const inputUser = {
registrationTokens: getUserInfo.fcmToken,
payload: payloadUser
}
await sendSingle(inputUser)
//-------------------------------------------------------------------
//------------------------------- send sms --------------------------
const smsTemplate = `سفارش شما با موفقیت ثبت شد با تشکر از اعتماد شما برگ من لغو11`
const smsResult = await sms(getUserInfo.mobile_number, smsTemplate)
if (!smsResult || !smsResult.data.IsSuccessful) {
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
}
//-------------------------------------------------------------------
return res.json({message: _sr['fa'].response.success_save})
}
const request = await zarinpal.request(checkOrder?.payTotal, checkOrder?.number?.toString(), req.user)
if (!request.status) {
console.log(request)
return res500(res, _sr['fa'].response.unknownError)
}
// add payment to order
const addPayment = await Payment.create({
user_id: getUserInfo._id,
order_id: checkOrder._id,
transactionId: request.response.authority,
cost: checkOrder.payTotal,
})
if (addPayment) {
checkOrder.payment = addPayment._id
await checkOrder.save();
} else {
return res500(res, _sr['fa'].response.unknownError)
}
/// remove cart item
await CartItem.deleteMany({branchId , user_id: req.user._id})
return res.json({paymentUrl: `${zarinUrl}/${request.response.authority}`})
} catch (error) {
console.log(error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.getPaymentResponse = [
async (req, res) => {
try {
const checkPayment = await Payment.findOne({transactionId: req?.query?.Authority}).populate('order_id')
const user = await User.findById(checkPayment.user_id)
///check duplicate transaction
if (!checkPayment || checkPayment.getPayment || checkPayment.action === 'decreaseBag') {
return res.json({
status: false,
fromWhere : user?.fromWhere || 'app',
message: 'پرداخت ناموفق بود'
})
}
/// verify transaction
const verify = await zarinpal.verify(checkPayment.action === 'increaseBag' ? checkPayment.cost : checkPayment.order_id.payTotal, checkPayment.transactionId)
console.log(verify)
if (verify.status) {
if (verify.code === 101) {
console.log(verify)
return res.json({
status: false,
message: 'پرداخت ناموفق بود'
})
}
checkPayment.status = 'paid'
checkPayment.refId = verify?.response?.ref_id
checkPayment.getPayment = true
checkPayment.fee_type = verify?.response?.fee_type
checkPayment.card_hash = verify?.response?.card_hash
checkPayment.card_pan = verify?.response?.card_pan
checkPayment.fee = verify?.response?.fee
checkPayment.created_at = Date.now()
checkPayment.createdOn = Date.now()
await checkPayment.save()
/// only for buy food execute this action
if (checkPayment.action === 'payOrder') {
const getOrder = await Order.findById(checkPayment.order_id._id)
if (!getOrder) return res404(res, 'سفارش پیدا نشد')
for (const food of getOrder.order_items) {
const getFood = await Food.findById(food.product_id)
if (getFood) {
getFood.stock = getFood.stock - food.quantity
// getFood.canReview.push(req.user._id)///add user id for review
getFood.save()
}
}
if (getOrder.discount_code) {
const discount = await DiscountCode.findOne({discount_code: getOrder.discount_code})
if (discount) {
discount.used_by.push(getOrder.user_id)
await discount.save()
}
}
if (user) {
/// decrease score
if (getOrder?.score) {
getOrder.scorePoint = user.score
getOrder.scoreCost = user.score * getOrder?.pricePoint
user.scoreLogs = [
{
score: user.score,
order_id: getOrder._id,
forWhat: 'buy',
action: 'decrease'
}
]
user.score = 0
await user.save()
}
/// decrease bag
if (getOrder.bag) {
const addPayment = await Payment.create({
user_id: user._id,
order_id: getOrder._id,
transactionId: Date.now(),
refId: Date.now(),
getPayment: true,
action: 'decreaseBag',
status: 'paid',
cost: user.bagAmount,
})
getOrder.payment.push(addPayment._id)
getOrder.bagCost = user.bagAmount
user.bagAmount = 0
await user.save()
}
if (!getOrder.score || !getOrder?.discount_code) {
// add point for user only for available product
const computeAvaPro = await _computeHavePointPrice(getOrder?.order_items)
/// add score for order
if (computeAvaPro >= getOrder?.totalPricePoint && getOrder?.totalPricePoint > 0) {
const point = (Math.floor(computeAvaPro / getOrder?.totalPricePoint) * getOrder?.pointForBuy)
if (point > 0) {
user.score = user.score + point
user.scoreLogs = [
{
score: point,
order_id: getOrder._id,
forWhat: 'buy',
action: 'increase'
}
]
await user.save()
}
}
}
}
getOrder.statuses.push({
status: 'processing'
})
getOrder.status = 'processing'
getOrder.paymentStatus = 'paid'
await getOrder.save()
//----------------------- send notif for admins -----------------
const fcmTokens = []
const allAdmins = await User.find({scope: 'admin'})
for (const admin of allAdmins) {
if (admin.fcmToken) fcmTokens.push(admin.fcmToken)
}
const objNotif = {
title: 'سفارش جدید!',
body: 'یک سفارش جدید در پنل برگ من ثبت گردید'
}
const payload = {
notification: objNotif,
};
const input = {
registrationTokens: fcmTokens,
payload
}
await sendMulti(input)
sendNotifyOrder(getOrder?.branchId)
//----------------------------------------------------------------
//--------------------- send notif to user --------------------------
const messageUser = {
title: 'ثبت سفارش',
body: 'با تشکر از اعتماد شما سفارش شما با موفقیت ثبت شد'
}
const payloadUser = {
notification: messageUser,
};
const inputUser = {
registrationTokens: user.fcmToken,
payload: payloadUser
}
await sendSingle(inputUser)
//-------------------------------------------------------------------
//------------------------------- send sms --------------------------
const smsTemplate = `سفارش شما با موفقیت ثبت شد با تشکر از اعتماد شما برگ من لغو11`
const smsResult = await sms(user.mobile_number, smsTemplate)
if (!smsResult || !smsResult.data.IsSuccessful) {
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
}
//-------------------------------------------------------------------
} else if (checkPayment.action === 'increaseBag') {
if (!user) return res.json({
status: false,
message: 'مشکلی در افزایش موجودی کیف پول شما پیش آمده است لطفا با پشتیبانی تماس بگیرید'
})
user.bagAmount = user.bagAmount + checkPayment?.cost
await user.save()
//--------------------- send notif to user --------------------------
const messageUser = {
title: 'افزایش موجودی',
body: 'با تشکر از اعتماد شما کیف پول شما با موفقیت شارژ شد برگ من'
}
const payloadUser = {
notification: messageUser,
};
const inputUser = {
registrationTokens: user.fcmToken,
payload: payloadUser
}
await sendSingle(inputUser)
//-------------------------------------------------------------------
//------------------------------- send sms --------------------------
const smsTemplate = `با تشکر از اعتماد شما کیف پول شما با موفقیت شارژ شد برگ من لغو11`
const smsResult = await sms(user.mobile_number, smsTemplate)
if (!smsResult || !smsResult.data.IsSuccessful) {
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`)
}
//-------------------------------------------------------------------
}
return res.json({
status: true,
refId: verify?.response?.ref_id,
fromWhere : user?.fromWhere || 'app',
message: 'پرداخت با موفقیت انجام شد'
})
} else {
/// only for buy food execute this action
if (checkPayment.action === 'payOrder') {
let getOrder = await Order.findById(checkPayment.order_id._id)
if (getOrder) {
getOrder.statuses.push({
status: 'void'
})
getOrder.status = 'void'
getOrder.paymentStatus = 'unpaid'
await getOrder.save()
}
checkPayment.getPayment = true
checkPayment.created_at = new Date()
await checkPayment.save()
}
return res.json({
status: false,
fromWhere : user?.fromWhere || 'app',
message: 'پرداخت ناموفق بود'
})
}
} catch (error) {
console.log(error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.addAddressToOrder = [
(req, res) => {
Order.findById(req.params.order_id)
.then(order => {
if (!order.address) {
User.findOne({'addresses._id': req.body.address_id})
.then(user => {
order.address = user.addresses.id(req.body.address_id)
// add processing status to order
order.statuses.push({
status: 'processing'
})
order.save()
return res.json(order)
})
.catch(err => {
return res500(res, err)
})
} else {
return res.status(500).json({message: v_m[req.body.locale].response.already_has_address})
}
})
.catch(err => {
return res404(res, err)
})
}
]
module.exports.addStatusToOrder = [
async (req, res) => {
try {
const order = await Order.findById(req.params.order_id).populate('user_id')
if (!order) return res404(res, 'سفارش مورد نظر یافت نشد')
order.statuses.push({
status: req.body.status
})
order.status = req.body.status
order.save()
if (req.body.status === 'delivered') {
//--------------------- send notif to user --------------------------
const messageUser = {
title: 'ارسال سفارش',
body: 'سفارش شما ارسال گردید با تشکر برگ من'
}
const payloadUser = {
notification: messageUser,
};
const inputUser = {
registrationTokens: order?.user_id?.fcmToken,
payload: payloadUser
}
await sendSingle(inputUser)
//-------------------------------------------------------------------
setTimeout(async () => {
let smsTemplate = ''
if (order.user_id.fromWhere === 'app') smsTemplate = `لطفا با ثبت نظر برای سفارش خود به ما برای خدمات بهتر کمک کنید با تشکر برگ من`
else smsTemplate = `لطفا با ثبت نظر برای سفارش خود به ما برای خدمات بهتر کمک کنید با تشکر برگ من لغو11
لینک : https://app.bargrestaurant.com/rate/${req.params.order_id}`
const smsResult = await sms(order?.user_id?.mobile_number, smsTemplate)
//--------------------- send notif to user --------------------------
const messageUser = {
title: 'ثبت نظر',
body: 'لطفا با ثبت نظر برای سفارش خود به ما برای خدمات بهتر کمک کنید با تشکر'
}
const payloadUser = {
notification: messageUser,
};
const inputUser = {
registrationTokens: order?.user_id?.fcmToken,
payload: payloadUser
}
await sendSingle(inputUser)
//-------------------------------------------------------------------
if (!smsResult || !smsResult.data.IsSuccessful) {
console.log('order sms', smsResult)
}
}, timeToStart)
}
return res.json(order)
} catch (error) {
console.log(error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.changePayStatus = [
[
body('status')
.notEmpty().withMessage(_sr['fa'].required.field)
.bail()
.isIn(['refund', 'unpaid', 'paid']).withMessage('وضعیت ارسال شده صحیح نمی باشد')
],
checkValidations(validationResult),
async (req, res) => {
try {
const targetOrder = await Order.findById(req.params.id)
if (!targetOrder) return res404(res, 'سفارش مورد نظر پیدا نشد');
const targetPayment = await Payment.findById(targetOrder.payment)
if (targetPayment) {
targetPayment.status = req.body.status
await targetPayment.save()
}
targetOrder.paymentStatus = req.body.status
await targetOrder.save()
return res.json({message: _sr['fa'].response.success_save})
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.getOrders = [
(req, res) => {
const branchId = req?.params?.branchId
Order.find({
branchId,
user_id: req.user._id,
status: {$in: ['canceled' , 'processing', 'sent', 'delivered']},
paymentStatus: 'paid'
}).populate({
path: 'order_items.product_id',
select: 'name canReview ratings'
}).sort({_id: -1})
.then(orders => {
const allOrders = []
for (const item of orders) {
let clone = JSON.parse(JSON.stringify(item.order_items))
clone.map(food => {
// food.review = food?.product_id?.canReview?.includes(req.user._id.toString())
// food.rating = food?.product_id?.ratings?.find(rate => rate.user_id.toString() === req.user._id.toString() && rate?.order_id?.toString() === item?._id?.toString())?.rate || 0
food.rating = food?.product_id?.ratings?.find(rate => rate?.user_id?.toString() === req?.user?._id.toString())?.rate || 0
})
allOrders.push({
_id: item._id,
address: item.address,
status: item.status,
items: clone,
orderType: item.orderType,
review: item.rating.rate,
created_at: item.createdOn,
total: item.total
})
}
return res.json(allOrders)
})
.catch(err => {
console.log(err.message)
return res500(res, _sr['fa'].response.unknownError)
})
}
]
module.exports.getOrdersForReport = [
async (req, res) => {
try {
const branchId = req?.params?.branchId
const orders = await Order.find({
branchId,
status: {$in: ['canceled' ,'processing', 'sent', 'delivered']},
paymentStatus: 'paid'
})
return res.json(orders)
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.getOneOrderByUser = [
async (req, res) => {
try {
const targetOrder = await Order.findOne({_id: req.params.id, user_id: req.user._id}).select('status')
if (!targetOrder) return res404(res, 'سفارش مورد نظر پیدا نشد')
return res.json(targetOrder)
} catch (error) {
console.log('get one order by user |', error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.deleteOrder = [
async (req, res) => {
try {
const targetOrder = await Order.findById(req.params.id);
if (!targetOrder) return res404(res, 'سفارش مورد نظر پیدا نشد')
/// @todo maybe delete payment too
await targetOrder.deleteOne()
return res.json({message: _sr['fa'].response.success_remove})
} catch (error) {
console.log('delete order: ', error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.increaseBag = [
[
body('price')
.notEmpty().withMessage(`لطفا یک مقدار مشخص کنید`)
],
checkValidations(validationResult),
async (req, res) => {
try {
const cost = req.body.price;
const user = await User.findById(req.user._id)
if (!user) return res404(res, `اطلاعات کاربر پیدا نشد`)
const request = await zarinpal.request(cost, 'کیف پول', req.user)
if (!request.status) {
console.log(request)
return res500(res, _sr['fa'].response.unknownError)
}
// add payment to order
await Payment.create({
user_id: user._id,
order_id: null,
transactionId: request.response.authority,
cost: cost,
action: 'increaseBag'
})
return res.json({paymentUrl: `${zarinUrl}/${request.response.authority}`})
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
/////// admin panel
module.exports.getOneOrder = [
(req, res) => {
Order.findById(req.params.id).populate({
path: 'user_id',
select: 'first_name last_name scoreLogs'
}).populate('order_items.product_id')
.populate('payment')
.then(order => {
return res.json(order)
})
.catch(err => {
return res404(res, err)
})
}
]
module.exports.search = [
async (req, res) => {
try {
let {
branchId,
number,
orderStatus,
paymentStatus,
userId,
date
} = req.body;
let findQuery = {
branchId,
status: {$nin: ['incomplete', 'void']}
};
findQuery['$and'] = [];
findQuery['$or'] = [];
/** search by number */
if (number && !_.isEmpty(number)) {
findQuery['$and'].push({
number
});
}
/** search by orderStatus */
if (orderStatus && !_.isEmpty(orderStatus)) {
findQuery['$and'].push({
status: {
$in: orderStatus
}
});
}
/** search by paymentStatus */
if (paymentStatus && !_.isEmpty(paymentStatus)) {
findQuery['$and'].push({
paymentStatus: {
$in: paymentStatus
}
});
}
/** search by user_id */
if (userId && !_.isEmpty(userId)) {
findQuery['$and'].push({
user_id: userId
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
findQuery['$and'].push({
createdOn: {
$gte: moment(date[0]).startOf('days'),
$lt: moment(date[0]).endOf('days')
}
});
} else {
findQuery['$and'].push({
createdOn: {
$gte: new Date(date[0]),
$lt: new Date(date[1])
}
});
}
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get news */
const orders = await Order.paginate(findQuery, {
page: req.query.page, limit, populate: [{path: 'user_id', select: 'first_name last_name'}],
sort: {
_id: -1
}
});
/** show result */
return res.json(orders);
} catch (error) {
console.log(error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.reports = [
// [
// body('startDate')
// .notEmpty().withMessage(_sr['fa'].required.date),
//
// body('endDate')
// .notEmpty().withMessage(_sr['fa'].required.date),
// ],
// checkValidations(validationResult),
async (req, res) => {
try {
const branchId = req?.params?.branchId
let findQuery = {
branchId,
status: {$nin: ['incomplete', 'void']}
};
let {startDate,endDate} = req.body;
// if (!startDate || !endDate){
// findQuery.createdOn = {
// createdOn: {
// $gte: moment().startOf('days'),
// $lt: moment().endOf('days')
// }
// }
// }else {
if (startDate && endDate) {
findQuery.createdOn = {
$gte: new Date(startDate),
$lt: new Date(endDate)
}
}else if (startDate){
findQuery.createdOn = {
$gte: moment(startDate),
$lt: new Date()
}
}else if (endDate){
findQuery.createdOn = {
// $gte: '',
$lt: moment(endDate)
}
}
// }
/** search by date */
// if (startDate || endDate && !_.isEmpty(date)) {
// if (date.length === 1) {
// findQuery.createdOn = {
// $gte: moment(startDate),
// $lt: moment(startDate)
// }
// } else {
// findQuery.createdOn = {
// $gte: new Date(date[0]),
// $lt: new Date(date[1])
// }
// }
// } else {
//
// }
/** get news */
const orders = await Order.find(findQuery).populate({path: 'user_id', select: 'first_name last_name'}).sort({_id: -1});
let result = {
count: orders?.length || 0,
total: orders?.reduce((total, item) => {
return total + item?.total
}, 0) || 0,
payOnline: orders?.reduce((total, item) => {
return total + item?.payTotal
}, 0) || 0,
routePrice: orders?.reduce((total, item) => {
return total + item?.routePrice
}, 0) || 0,
bagCost: orders?.reduce((total, item) => {
return total + item?.bagCost
}, 0) || 0,
scorePoint: orders?.reduce((total, item) => {
return total + item?.scorePoint
}, 0) || 0,
scoreCost: orders?.reduce((total, item) => {
return total + item?.scoreCost
}, 0) || 0,
}
/** show result */
return res.json(result);
} catch (error) {
console.log(error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
//////////////////////////////////// compute price
module.exports.computePrice = [
//////////////////// validation step
(req, res, next) => {
const branchId = req?.params?.branchId
CartItem.find({branchId , user_id: req.user._id})
.then(items => {
// check if cart is not empty
if (items.length) {
// check product stock
let outOfRun = []
items.forEach(async (item, index) => {
await Food.findById(item.product_id)
.then(product => {
if (product.stock < item.quantity) {
outOfRun.push({
product_id: product._id,
category_id: product.category,
stock: product.stock
})
item.remove()
}
if (index + 1 === items.length) {
if (!outOfRun.length) return next()
else return res.status(422).json(outOfRun)
}
})
})
} else {
return res.status(404).json({message: _sr['fa'].response.cart_empty})
}
})
},
async (req, res) => {
try {
const branchId = req?.params?.branchId
const cartItems = await CartItem.find({branchId, user_id: req.user._id}).populate({
path: 'product_id',
populate: {
path: 'category',
model: 'FoodCategory'
}
});
const checkOrder = await Order.findOne({branchId , 'status': 'incomplete', user_id: req.user._id})
const getUserInfo = await User.findById(req.user._id);
const getStoreInfo = await StoreInfo.findOne({_id : branchId})
const product = [];
const userAddress = getUserInfo.addresses.find(item => item.used === true) || null
let specialDiscountMenuType = false;
let discount_percent = checkOrder?.discount_amount || 0;
let discount_menuType = checkOrder?.discount_menuType;
let routePrice = 0;
let sum = 0;
let sumFoodByPercent = 0;
let sumFoodByPercentForDiscount = 0;
let total = 0;
let percent = 0;
let tax = 0;
if (!getUserInfo) return res404(res, `اطلاعات کاربر یافت نشد`);
if (!cartItems.length) return res.status(404).json({message: `هیچ محصولی در سبد خرید شما وجود ندارد`})
if (checkOrder) {
const orderItems = [];
for (const item of cartItems) {
orderItems.push({
product_id: item.product_id._id,
name: item.product_id.name,
quantity: item.quantity,
price: item.product_id.price,
static_discount: item.product_id.static_discount,
havePoint: item.product_id.havePoint
});
product.push({
product: item.product_id,
quantity: item.quantity
})
const itemPercent = item.product_id.price * item.product_id.static_discount / 100;
const sumPercent = itemPercent * item.quantity;
const price = item.product_id.price;
const sumPriceItem = price * item.quantity;
let sumByPercentForDiscount = sumPriceItem - sumPercent
if (Boolean(discount_percent) && discount_menuType) {
specialDiscountMenuType = true
if (item?.product_id?.category.type?.toString() === discount_menuType?.toString()) {
sumFoodByPercentForDiscount += sumByPercentForDiscount
}
}
sum = sum + sumPriceItem; /// sum food price without percent
percent = percent + sumPercent; /// sum all food percent
}
/// sum food price with percent
sumFoodByPercent = sum - percent
/// compute shipping cost
if (getStoreInfo) {
if (getStoreInfo?.shippingType) {
routePrice = getStoreInfo?.shippingCost || 0;
} else {
routePrice = await _computeShippingCostByRoad(getUserInfo?.addresses, getStoreInfo?.location) * (getStoreInfo?.shippingCost || 0) || 0;
}
/// compute tax of order
if (getStoreInfo?.tax) {
tax = sumFoodByPercent * 9 / 100
}
}
/// compute discount code
if (Boolean(discount_percent)) {
let discountPercent = (specialDiscountMenuType ? sumFoodByPercentForDiscount : sumFoodByPercent) * discount_percent / 100
percent = percent + discountPercent
/// compute sum food with discount percent
sumFoodByPercent = sumFoodByPercent - discountPercent
}
/// compute total of order
total = sumFoodByPercent + tax + routePrice;
checkOrder.order_items = orderItems
checkOrder.createdOn = Date.now()
checkOrder.sum = Math.ceil(sum)
checkOrder.routePrice = Math.ceil(routePrice)
checkOrder.tax = Math.ceil(tax)
checkOrder.percent = Math.ceil(percent)
checkOrder.total = Math.ceil(total)
checkOrder.pricePoint = getStoreInfo?.pricePoint
if (checkOrder.bag) {
const payPrice = total - getUserInfo?.bagAmount
total = payPrice <= 0 ? 0 : payPrice
}
if (checkOrder.score && getStoreInfo?.pricePoint > 0) {
const payScore = total - (getUserInfo?.score * getStoreInfo?.pricePoint)
total = payScore <= 0 ? 0 : payScore
}
checkOrder.payTotal = Math.ceil(total)
checkOrder.save();
}
return res.json({
usePoint: getStoreInfo?.usePointWhenPay,
product,
userAddress,
sum: Math.ceil(sum),
routePrice: Math.ceil(routePrice),
tax: Math.ceil(tax),
percent: Math.ceil(percent),
total: Math.ceil(checkOrder.payTotal)
})
} catch (error) {
console.log(error.message)
return res500(res, _sr['fa'].response.unknownError)
}
}
]
////////////////////////////////////// get list of all orders for admin
module.exports.getAllOrders = [
async (req, res) => {
try {
const branchId = req?.params?.branchId
const orders = await Order.paginate({branchId, status: {$nin: ['incomplete', 'void']}}, {
page: req.query.page || 1,
limit,
populate: [
{path: 'user_id', select: 'first_name last_name'}
],
sort: {_id: -1}
})
return res.json(orders)
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
///////////////////////////////////// get payment list
module.exports.getAllPaymentByUser = [
async (req, res) => {
try {
const getAll = await Payment.find({user_id: req.user._id}).sort({_id: -1})
return res.json(getAll)
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
module.exports.getAllPaymentByAdmin = [
async (req, res) => {
try {
const getAll = await Payment.paginate({user_id: req.params.id}, {
page: req.query.page || 1,
limit,
sort: {_id: -1}
})
return res.json(getAll)
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
//////////////////////////////////// get all foods for rates
module.exports.getAllRateFood = [
async (req, res) => {
try {
const getOrder = await Order.findOne({
_id: req.params.order_id,
user_id: req.user._id,
status: 'delivered',
paymentStatus: 'paid'
}).populate({
path: 'order_items.product_id',
select: 'name ratings'
})
if (!getOrder) return res404(res, `سفارش مورد نظر پیدا نشد`)
return res.json(getOrder)
} catch (e) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
/////////////////////////////////// rate order
module.exports.rateOrderAndFood = [
[
body('rateOrder')
.notEmpty().withMessage(_sr['fa'].required.field)
],
checkValidations(validationResult),
async (req, res) => {
try {
const orderId = req?.params?.order_id
const {rateOrder, reason, foods} = req.body
const getOrder = await Order.findOne({
_id: orderId,
user_id: req.user._id,
status: 'delivered',
paymentStatus: 'paid'
})
if (!getOrder) return res404(res, `سفارش مورد نظر پیدا نشد`)
//// add rate for all foods
for (const food of foods) {
const data = {
rate: food.rate,
comment: food.comment,
order_id: getOrder._id,
user_id: getOrder.user_id
}
//// check food exist or not
const getFood = await Food.findById(food?.product_id?._id)
if (getFood && getOrder?.order_items.some(item => item?.product_id?._id?.toString() === getFood?._id?.toString())) {
getFood.ratings.push(data)
let rateSUM = 0
getFood?.ratings?.forEach(item => rateSUM += Number(item.rate))
getFood.rate = (rateSUM / getFood?.ratings?.length).toFixed(1)
await getFood.save()
}
}
//// add rate to order
getOrder.rating = {
rate: rateOrder,
reasonForBad: reason
}
await getOrder.save()
return res.json({message: _sr['fa'].response.success_save})
} catch (e) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
////////////////////////////////// buy club
module.exports.buyClub = [
[
body('clubId')
.notEmpty().withMessage(_sr['fa'].required.field)
],
checkValidations(validationResult),
async (req, res) => {
try {
const clubId = req.body?.clubId
const user = await User.findById(req.user._id)
if (!user) return res404(res, 'اطلاعات کاربر یافت نشد')
const club = await Food.findOne({_id: clubId, club: true})
if (!club) return res404(res, 'کلاب مورد نظر پیدا نشد')
if (user.score < club.point) return res.status(422).json({message: 'امتیاز شما برای خرید این محصول کافی نمی باشد'})
const data = {
user_id: user._id,
score: true,
scorePoint: club.point,
scoreCost: club.price,
orderType: 'club',
number: Date.now(),
address: user?.addresses.find(item => item.used),
createdOn: Date.now(),
paymentStatus: 'paid',
statuses: [{
status: 'processing'
}],
status: 'processing',
order_items: [{
product_id: club._id,
name: club.name,
quantity: 1,
price: club.price,
point: club.point,
havePoint: true
}],
sum: club.point,
routePrice: 0,
tax: 0,
percent: 0,
total: club.price
}
const order = await Order.create(data)
if (!order) return res500(res, _sr['fa'].response.unknownError)
user.score -= club.point
user.scoreLogs = [
{
score: club.point,
order_id: order._id,
forWhat: 'buy',
action: 'decrease'
}
]
await user.save()
club.stock -= club?.clubQuantity || 1
await club.save()
return res.json({message: _sr['fa'].response.success_save})
} catch (error) {
return res500(res, _sr['fa'].response.unknownError)
}
}
]
////////////////////////////////// test notif
module.exports.testNotif = [
async (req, res) => {
try {
sendNotifyOrder('6126313206f2593a6a4f71db')
return res.json({})
} catch (error) {
return res500(res, error.message)
}
}
]
module.exports.chromeNotif = [
async (req, res) => {
try {
const fcmTokens = []
const allAdmins = await User.find({scope: 'admin'})
for (const admin of allAdmins) {
if (admin.fcmToken) fcmTokens.push(admin.fcmToken)
}
const objNotif = {
title: "سفارش جدید!",
body: "یک سفارش جدید در پنل برگ من ثبت گردید"
}
const payload = {
notification: objNotif,
data: {
routeName: 'test',
type: "bazaar",
routeType: "viewBazaar",
},
};
console.log(fcmTokens)
const input = {
registrationTokens: fcmTokens,
payload
}
console.log(input)
const test = await sendMulti(input)
return res.json(test)
// const payload = JSON.stringify({
// title: 'Push notifications with Service Workers',
// });
//
// webPush.sendNotification('test', payload)
// .catch(error => console.error(error));
} catch (error) {
}
}
]