modified: controllers/application/academy/academyCategoryController.js
modified: controllers/application/academy/academyControllers.js modified: controllers/application/academy/helpers/chatHelpers.js modified: controllers/application/academy/middlewares/404.js modified: controllers/application/academy/middlewares/adminAuth.js modified: controllers/application/academy/middlewares/auth.js modified: controllers/application/academy/middlewares/blockCheck.js modified: controllers/application/academy/middlewares/exception.js modified: controllers/application/academy/middlewares/index.js modified: controllers/application/academy/middlewares/isHalfRegister.js modified: controllers/application/academy/middlewares/isRegister.js modified: controllers/application/academy/middlewares/lastOnline.js modified: controllers/application/academy/middlewares/upload.js modified: controllers/application/academy/models/AcademyCategoryModel.js modified: controllers/application/academy/models/AcademyContentModel.js modified: controllers/application/academy/models/AcademyLikeModel.js modified: controllers/application/academy/models/AcademyModel.js modified: controllers/application/academy/models/AcademyPaymentModel.js modified: controllers/application/academy/models/AdminModel.js modified: controllers/application/academy/models/AdvertisingCategoryModel.js modified: controllers/application/academy/models/AdvertisingCommentModel.js modified: controllers/application/academy/models/AdvertisingFeaturesModel.js modified: controllers/application/academy/models/AdvertisingLikeModel.js modified: controllers/application/academy/models/AdvertisingModel.js modified: controllers/application/academy/models/AdvertisingProfile.js modified: controllers/application/academy/models/AdvertisingRatingModel.js modified: controllers/application/academy/models/AdvertisingTypeModel.js modified: controllers/application/academy/models/CommentModel.js modified: controllers/application/academy/models/CourseComentModel.js modified: controllers/application/academy/models/CourseModel.js modified: controllers/application/academy/models/CoursePaymentModel.js modified: controllers/application/academy/models/ExpertiseModel.js modified: controllers/application/academy/models/IsPaymentCourseModel.js modified: controllers/application/academy/models/LikeModel.js modified: controllers/application/academy/models/MessageModel.js modified: controllers/application/academy/models/NotificationModel.js modified: controllers/application/academy/models/OfferModel.js modified: controllers/application/academy/models/OfferTypeModel.js modified: controllers/application/academy/models/PaymentModel.js modified: controllers/application/academy/models/PostModel.js modified: controllers/application/academy/models/ProjectModel.js modified: controllers/application/academy/models/RequestModel.js modified: controllers/application/academy/models/SettingsModel.js modified: controllers/application/academy/models/StateCity.js modified: controllers/application/academy/models/TaxModel.js modified: controllers/application/academy/models/TicketMessageModel.js modified: controllers/application/academy/models/TicketModel.js modified: controllers/application/academy/models/TypeAndPriceModel.js modified: controllers/application/academy/models/UserModel.js modified: controllers/application/academy/models/VersionModel.js modified: controllers/application/academy/models/license.js modified: controllers/application/advertising/advertisingController.js modified: controllers/application/citysController.js modified: controllers/application/expertise/expertiseController.js modified: controllers/application/financial/financialController.js modified: controllers/application/login/changePasswordController.js modified: controllers/application/login/loginController.js modified: controllers/application/login/loginWithUserName.js modified: controllers/application/login/verifyController.js modified: controllers/application/messages/messageController.js modified: controllers/application/notification/notificationController.js modified: controllers/application/offer/offerController.js modified: controllers/application/payment/paymentController.js modified: controllers/application/payment/paymentControllerWeb.js modified: controllers/application/posts/likeController.js modified: controllers/application/posts/postController.js modified: controllers/application/profile/profileController.js modified: controllers/application/projects/createProjectController.js modified: controllers/application/projects/getProjectController.js modified: controllers/application/projects/projectTypesController.js modified: controllers/application/projects/requestProjectController.js modified: controllers/application/projects/updateProjectController.js modified: controllers/application/provincesController.js modified: controllers/application/register/registerController.js modified: controllers/application/register/userFullNameController.js modified: controllers/application/register/userTypeController.js modified: controllers/application/register/usernameController.js modified: controllers/application/register/verifyController.js modified: controllers/application/search-web/searchController.js modified: controllers/application/search/searchController.js modified: controllers/application/settings/settingsController.js modified: controllers/application/tickets/ticketsController.js modified: controllers/application/users/getUserController.js modified: controllers/application/verify/addressController.js modified: controllers/application/verify/authController.js modified: controllers/application/verify/colorsController.js modified: controllers/application/verify/conversationController.js modified: controllers/application/verify/cooperationTypeController.js modified: controllers/application/verify/expertiseController.js modified: controllers/application/verify/genderController.js modified: controllers/application/verify/servicesController.js modified: controllers/application/verify/setNationalCardImageController.js modified: controllers/application/verify/setProfileImageController.js modified: controllers/application/verify/sizesController.js modified: controllers/application/version/versionController.js modified: controllers/application/workroom/workroomController.js modified: controllers/panel/advertising/academyCategoryController.js modified: controllers/panel/advertising/advertisingController.js modified: controllers/panel/comments/advertisingCommentController.js modified: controllers/panel/comments/commentController.js modified: controllers/panel/expertise/expertiseController.js modified: controllers/panel/financial/financialController.js modified: controllers/panel/login/loginController.js modified: controllers/panel/posts/postController.js modified: controllers/panel/projects/projectController.js modified: controllers/panel/projects/projectTypesController.js modified: controllers/panel/settings/settingsController.js modified: controllers/panel/shops/shopsController.js modified: controllers/panel/tickets/ticketsController.js modified: controllers/panel/users/usersController.js modified: controllers/panel/version/versionController.js modified: helpers/chatHelpers.js modified: index.js deleted: logs/sms-irs/13-03-2024.log modified: middlewares/404.js modified: middlewares/adminAuth.js modified: middlewares/auth.js modified: middlewares/blockCheck.js modified: middlewares/exception.js modified: middlewares/index.js modified: middlewares/isHalfRegister.js modified: middlewares/isRegister.js modified: middlewares/lastOnline.js modified: middlewares/upload.js modified: models/AcademyCategoryModel.js modified: models/AcademyContentModel.js modified: models/AcademyLikeModel.js modified: models/AcademyModel.js modified: models/AcademyPaymentModel.js modified: models/AdminModel.js modified: models/AdvertisingCategoryModel.js modified: models/AdvertisingCommentModel.js modified: models/AdvertisingFeaturesModel.js modified: models/AdvertisingLikeModel.js modified: models/AdvertisingModel.js modified: models/AdvertisingProfile.js modified: models/AdvertisingRatingModel.js modified: models/AdvertisingTypeModel.js modified: models/CommentModel.js modified: models/CourseComentModel.js modified: models/CourseModel.js modified: models/CoursePaymentModel.js modified: models/ExpertiseModel.js modified: models/IsPaymentCourseModel.js modified: models/LikeModel.js modified: models/MessageModel.js modified: models/NotificationModel.js modified: models/OfferModel.js modified: models/OfferTypeModel.js modified: models/PaymentModel.js modified: models/PostModel.js modified: models/ProjectModel.js modified: models/RequestModel.js modified: models/SettingsModel.js modified: models/StateCity.js modified: models/TaxModel.js modified: models/TicketMessageModel.js modified: models/TicketModel.js modified: models/TypeAndPriceModel.js modified: models/UserModel.js modified: models/VersionModel.js modified: models/license.js modified: routes/application/academy/index.js modified: routes/application/advertising/index.js modified: routes/application/city/index.js modified: routes/application/expertise/index.js modified: routes/application/financial/index.js modified: routes/application/login/index.js modified: routes/application/messages/index.js modified: routes/application/notification/index.js modified: routes/application/offers/index.js modified: routes/application/posts/index.js modified: routes/application/profile/index.js modified: routes/application/projects/index.js modified: routes/application/provinces/index.js modified: routes/application/register/index.js modified: routes/application/search-web/index.js modified: routes/application/search/index.js modified: routes/application/settings/index.js modified: routes/application/tickets/index.js modified: routes/application/users/index.js modified: routes/application/verify/index.js modified: routes/application/version/index.js modified: routes/application/workroom/index.js modified: routes/index.js modified: routes/panel/advertising/index.js modified: routes/panel/comments/index.js modified: routes/panel/expertise/index.js modified: routes/panel/financial/index.js modified: routes/panel/login/index.js modified: routes/panel/posts/index.js modified: routes/panel/projects/index.js modified: routes/panel/settings/index.js modified: routes/panel/shops/index.js modified: routes/panel/tickets/index.js modified: routes/panel/users/index.js modified: routes/panel/version/index.js modified: scripts/dns/db.modstagram.com modified: scripts/dns/db.modstagram.ir modified: scripts/dns/named.conf.local.snippet modified: scripts/nginx/api.modstagram.com.conf modified: scripts/nginx/app.modstagram.com.conf modified: scripts/nginx/blog.modstagram.com.conf modified: scripts/nginx/cdn.modstagram.com.conf modified: scripts/nginx/cdn.modstagram.com.http.conf modified: scripts/nginx/modstagram-redirects.conf modified: scripts/nginx/modstagram.com.conf modified: scripts/nginx/panel.modstagram.com.conf modified: scripts/nginx/pay.modstagram.com.conf modified: scripts/server-setup.sh modified: services/AdvertisingCron.js modified: services/ProjectCron.js modified: services/TokenService.js deleted: storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257437373.mp4 deleted: storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257586892.mp4 deleted: storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257829783.mp4 deleted: storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257903018.mp4 deleted: storage/posts/videos/1766758940571-0-video_2025-05-21_16-30-58.mp4 deleted: storage/posts/videos/1766781626514-0-video_2025-05-21_16-30-58.mp4 deleted: storage/posts/videos/1766824222908-0-Find 'modeling videos' on TikTok - TikTok Search_7.mp4 deleted: storage/posts/videos/1766824281937-0-Find 'modeling videos' on TikTok - TikTok Search_6.mp4 deleted: storage/posts/videos/1766824360366-0-Find 'bridal makeup' on TikTok - TikTok Search_4.mp4 deleted: storage/posts/videos/1766824425868-0-Find 'Makeup' on TikTok - TikTok Search_25.mp4 deleted: storage/posts/videos/1766824503238-0-Find 'Makeup' on TikTok - TikTok Search.mp4 deleted: storage/posts/videos/1766824554864-0-Jalal.hafed (@jalal.hafed) Official.mp4 deleted: storage/posts/videos/1766824618322-0-Find 'Hairdressing' on TikTok - TikTok Search_3.mp4 deleted: storage/posts/videos/1766824689078-0-Find 'Beauty clinic' on TikTok - TikTok Search_22.mp4 deleted: storage/posts/videos/1766824721659-0-Find 'Beauty clinic' on TikTok - TikTok Search_13.mp4 deleted: storage/posts/videos/1766824796958-0-Find 'photography' on TikTok - TikTok Search_6.mp4 deleted: storage/posts/videos/1766825351987-0-aaaa.mp4 deleted: storage/posts/videos/1766825448136-0-sasasa.mp4 deleted: storage/posts/videos/1766825535111-0-qqq.mp4 deleted: "storage/posts/videos/1766825855902-0-Nail desin by Labella beauty salon\360\237\214\270\360\237\222\205\360\237\217\273 #nail #nailart #manicure #manicure\360\237\222\205 #salon #pedicure #labella.mp4" deleted: storage/posts/videos/1766825905907-0-dsdsdsdsdsds.mp4 deleted: "storage/posts/videos/1766826114243-0-Every piece of jewelry tells a story\360\237\217\271 @mirjaliligold @mohseneh_b.mp4" deleted: "storage/posts/videos/1766826180365-0-Romeo, save me\360\237\246\242.mp4" deleted: storage/posts/videos/1766826458195-0-aaaaa.mp4 deleted: storage/posts/videos/1766826609640-0-asasa.mp4 deleted: storage/posts/videos/1766826685281-0-s.mp4 deleted: storage/posts/videos/1766826815345-0-asasa.mp4 deleted: storage/posts/videos/1766826842822-0-aaa.mp4 deleted: "storage/posts/videos/1766827337926-0-Snow, mountains, and me\342\200\246 a story that never gets old! #backstage #stylish #snow #style#streetstyle.mp4" deleted: "storage/posts/videos/1766828100639-0-\330\263\330\263\330\263\330\263.mp4" deleted: storage/posts/videos/1766828130001-0-aaa.mp4 deleted: storage/posts/videos/1766828157845-0-ssss.mp4 deleted: storage/posts/videos/1766828203643-0-aaaa.mp4 deleted: "storage/posts/videos/1766828345460-0-You deserve to be happy, and you can\342\200\231t stay where your heart doesn\342\200\231t belong #\330\252\331\210\331\204\330\257\331\205_\331\205\330\250\330\247\330\261\332\251 #\330\242\330\250\333\214 #\330\247\331\207\331\210\330\247\330\262 #\330\252\331\210\331\204\330\257 #\330\250\331\204\330\247\332\257\330\261 @gallery.nilai.mp4" deleted: storage/posts/videos/1766828424672-0-1111.mp4 deleted: storage/posts/videos/1766828464781-0-sss.mp4 deleted: storage/posts/videos/1766828486889-0-aaaa.mp4 deleted: storage/posts/videos/1766828514279-0-sss.mp4 deleted: storage/posts/videos/1766828727356-0-ddd.mp4 deleted: "storage/posts/videos/1766828816020-0-Jewlery project Brand- @houseofme_official Dop- @_alishariatt Videographer- @peyman_bozorgomid Assistant- @amir.kh.k Model- @ana.elitee #jewleryphotography #fashionreels #\330\261\333\214\331\204.mp4" deleted: "storage/posts/videos/1766828848513-0-Some of my favorite shots Models- @saharjalilii @setayesh.ghalenoeii @parmisaadat @paaarand @asalllbayat @bitakhaajoii #photographer #\330\271\332\251\330\247\330\263\333\214_\331\201\330\264\331\206 #photosoftheday.mp4" deleted: "storage/posts/videos/1766831745457-0-\330\263\330\263\330\263.mp4" deleted: "storage/posts/videos/1766831795030-0-\330\264\330\264\330\264\330\264.mp4" deleted: "storage/posts/videos/1766833279276-0-\330\247\330\262 \332\206\330\264\330\247\331\205 \331\207\331\204\330\252 \330\257\330\247\330\257\331\205\342\200\214 \331\210\331\204\333\214 .....mp4" deleted: "storage/posts/videos/1766835292259-0-\330\263\333\214\330\263.mp4" deleted: storage/posts/videos/1766835327424-0-a.mp4 deleted: storage/posts/videos/1766835787091-0-s.mp4 deleted: storage/posts/videos/1767012113143-0-aaa.mp4 deleted: "storage/posts/videos/1767012137018-0-Makeup by-\360\237\221\207\360\237\217\275\360\237\215\267 @pegah.mua @kiavash_royalvideo.mp4" deleted: storage/posts/videos/1767012672738-0-dddd.mp4 deleted: storage/posts/videos/1767012722043-0-Instagram.mp4 deleted: "storage/posts/videos/1768740975998-0-Faouzia\343\200\212Desert Rose\343\200\213.mp4" deleted: storage/posts/videos/1768741493380-0-a.mp4 deleted: "storage/posts/videos/1771318409261-0-\330\266\330\265\330\266\330\265\330\266\330\265\330\266.mp4" deleted: "storage/posts/videos/1771319189820-0-\330\263\330\263\330\263\330\263.mp4" deleted: storage/posts/videos/1771937200099-0-WhatsApp Video 2025-05-17 at 11.50.09.mp4 deleted: storage/posts/videos/1772005435124-0-qqqq.mp4 deleted: storage/posts/videos/1772005611958-0-aaaaa.mp4 deleted: storage/posts/videos/1772006456443-0-qqqqww.mp4 deleted: storage/posts/videos/1772006543741-0-1111.mp4 deleted: storage/posts/videos/1772006606627-0-wewewe.mp4 deleted: storage/posts/videos/1772006663579-0-wwww.mp4 deleted: storage/posts/videos/1772006685382-0-333.mp4 deleted: storage/posts/videos/1772006740696-0-www.mp4 deleted: storage/posts/videos/1772006786181-0-4444.mp4 deleted: storage/posts/videos/1772009213487-0-aaaa.mp4 deleted: storage/posts/videos/1772009260843-0-sss.mp4 deleted: "storage/posts/videos/1772013946491-0-\330\250\330\250\330\250\330\250\330\250.mp4" deleted: "storage/posts/videos/1772089789739-0-\330\266\330\266\330\266\330\266.mp4" deleted: storage/posts/videos/1772090631353-0-qqqq.mp4 deleted: "storage/posts/videos/1772092053138-0-\330\265\330\265\330\265.mp4" deleted: storage/posts/videos/1772101142214-0-2222.mp4 deleted: "storage/posts/videos/1772101261385-0-\330\266\330\266\330\266\330\266.mp4" deleted: storage/posts/videos/1772101312006-0-Instagram.mp4 deleted: "storage/posts/videos/1772101434744-0-\330\263\333\214\330\263\333\214\330\263\333\214.mp4" deleted: "storage/posts/videos/1772203614700-0-\330\263\330\247\331\205\330\250\330\261\331\207 \330\250\331\204\331\210\331\206\330\257 \330\250\330\261\330\247\333\214 \331\201\330\247\330\267\331\205\331\207 \330\271\330\262\333\214\330\262\331\205\360\237\222\225.mp4" deleted: "storage/posts/videos/1772203641829-0-\330\257\332\251\331\204\330\261\331\207 \331\210 \330\261\331\206\332\257 \331\210 \332\251\331\210\330\252\330\247\331\207\333\214 \330\250\330\261\330\247\333\214 \330\263\331\210\330\257\330\247 \331\202\330\264\331\206\332\257\331\205\360\237\222\225.mp4" deleted: "storage/posts/videos/1772203698315-0-\330\247\333\214\331\206 \332\251\330\247\330\261 \330\262\333\214\330\250\330\247\331\205\331\210\331\206 \330\250\330\261\330\247\333\214 \330\255\330\250\333\214\330\250\331\207 \330\256\330\247\331\206\331\205 \330\271\330\262\333\214\330\262\360\237\222\225.mp4" deleted: "storage/posts/videos/1772205300232-0-\330\264\330\264\330\264\330\264.mp4" deleted: "storage/posts/videos/1772205333900-0-\330\265\330\265\330\265\330\265\330\265.mp4" deleted: "storage/posts/videos/1772207461030-0-\330\265\330\265\330\265.mp4" deleted: "storage/posts/videos/1772207616124-0-\330\264\330\264\330\264.mp4" deleted: "storage/posts/videos/1772207684446-0-\330\253\330\253\330\253\330\253.mp4" deleted: "storage/posts/videos/1772208440984-0-\331\201\331\201\331\201.mp4" deleted: "storage/posts/videos/1772208506469-0-\330\253\330\253\330\253\330\253.mp4" deleted: "storage/posts/videos/1772208627195-0-\330\264\330\264\330\264\330\264.mp4" deleted: "storage/posts/videos/1772208646258-0-\330\250\330\263\333\214\330\263.mp4" deleted: storage/posts/videos/1772208704438-0-111.mp4 deleted: "storage/posts/videos/1772211057722-0-\330\266\330\266\330\266.mp4" deleted: "storage/posts/videos/1772211118907-0-\330\265\330\265\330\265\330\265.mp4" deleted: "storage/posts/videos/1772211184550-0-\330\253\330\253\330\253.mp4" deleted: "storage/posts/videos/1772211618341-0-\330\265\330\265\330\265\330\265.mp4" deleted: storage/posts/videos/1772211740270-0-4444.mp4
This commit is contained in:
@@ -1,439 +1,439 @@
|
||||
/* eslint-disable camelcase */
|
||||
const jwt = require('jsonwebtoken')
|
||||
const jMoment = require('moment-jalaali')
|
||||
const OfferModel = require('../../../models/OfferModel')
|
||||
const UserModel = require('../../../models/UserModel')
|
||||
const OfferTypeModel = require('../../../models/OfferTypeModel')
|
||||
const PaymentModel = require('../../../models/PaymentModel')
|
||||
const NotificationModel = require('../../../models/NotificationModel')
|
||||
const { default: axios } = require('axios')
|
||||
const CommentModel = require('../../../models/CommentModel')
|
||||
|
||||
const getOfferPriceFromDatabase = async (itemName) => {
|
||||
const item = await OfferTypeModel.findOne({ name: itemName })
|
||||
if (!item) {
|
||||
throw new Error('Item not found in database')
|
||||
}
|
||||
return item.price
|
||||
}
|
||||
|
||||
const getOfferTypes = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
const user = await UserModel.findById(userId)
|
||||
if (!user) {
|
||||
return res.status(422).json({
|
||||
error: true,
|
||||
message: 'کاربر یافت نشد'
|
||||
})
|
||||
}
|
||||
let offerTypes = await OfferTypeModel.find({}, 'name price')
|
||||
|
||||
// بررسی برای مواردی مانند پیدا نشدن انواع پروژه
|
||||
if (!offerTypes) {
|
||||
return res.status(404).json({ message: 'انواع پروژه یافت نشد.' })
|
||||
}
|
||||
// اگر کاربر درخواست ماهانه نداشته باشد، نوع پروژه ماهانه را حذف کنید
|
||||
if (user.monthly_free_offer <= 0) {
|
||||
offerTypes = offerTypes.filter(projectType => projectType.name !== 'free')
|
||||
}
|
||||
// ارسال انواع پروژه به کاربر
|
||||
res.status(200).json({ offerTypes })
|
||||
} catch (error) {
|
||||
// در صورت بروز خطا، ارسال پیام خطا به کاربر
|
||||
console.error('Error in getOfferTypes:', error)
|
||||
res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' })
|
||||
}
|
||||
}
|
||||
const getUserOffers = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
const { page = 1, limit = 10, status_filter, id } = req.query // افزودن پارامترهای صفحهبندی به درخواست
|
||||
let filter = {}
|
||||
let filterbyid = {receiver: id}
|
||||
let filterbyidsender = {sender: id}
|
||||
if (status_filter === 'درخواست') {
|
||||
filter = { sender: userId }
|
||||
} else {
|
||||
filter = { receiver: userId }
|
||||
}
|
||||
|
||||
// تنظیم گزینههای صفحهبندی
|
||||
const options = {
|
||||
page: parseInt(page), // تبدیل صفحه به عدد صحیح
|
||||
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
|
||||
sort: { createdAt: -1 }, // بر اساس زمان ایجاد (createdAt) مرتب کنید (نزولی)
|
||||
populate: [
|
||||
{
|
||||
path: 'sender',
|
||||
select: 'profile_image user_level first_name last_name user_name is_verified user_score rate'
|
||||
},
|
||||
{
|
||||
path: 'receiver',
|
||||
select: 'profile_image user_level first_name last_name user_name is_verified user_score rate'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// دریافت آفرهای صفحهبندی شده
|
||||
let offer = await OfferModel.paginate(filter, options)
|
||||
let offerbyid = await OfferModel.paginate(filterbyid, options)
|
||||
let offerbyidsender = await OfferModel.paginate(filterbyidsender, options)
|
||||
|
||||
const totalPages = offer.totalPages
|
||||
const totalItems = offer.totalDocs
|
||||
|
||||
// فرمت کردن تاریخ و ارسال پاسخ
|
||||
offer = offer?.docs.map(offer => {
|
||||
const jDate = jMoment(offer.createdAt).format('jYYYY-jMM-jDD HH:mm')
|
||||
return {
|
||||
...offer._doc,
|
||||
createdAt: jDate
|
||||
}
|
||||
})
|
||||
res.json({
|
||||
offerbyidsender,
|
||||
offerbyid,
|
||||
offer,
|
||||
totalPages, // ارسال تعداد کل صفحات
|
||||
totalItems // ارسال تعداد کل آیتمها
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateOfferStatus = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id // ID کاربری که درخواست را بهروزرسانی میکند
|
||||
const reciverUser = await UserModel.findById(userId)
|
||||
|
||||
const { offerId, action } = req.body // آیدی آفر و اکشن (accept یا reject)
|
||||
|
||||
// بررسی اعتبار ورودیها
|
||||
if (!offerId || !['accept', 'reject'].includes(action)) {
|
||||
return res.status(400).json({ error: 'Invalid input' })
|
||||
}
|
||||
|
||||
// یافتن آفر موردنظر
|
||||
const offer = await OfferModel.findById(offerId)
|
||||
const senderUser = await UserModel.findById(offer?.sender)
|
||||
|
||||
if (!offer) {
|
||||
return res.status(404).json({ error: 'Offer not found' })
|
||||
}
|
||||
|
||||
// بررسی اینکه آیا کاربر گیرنده این آفر است یا خیر
|
||||
if (offer.receiver.toString() !== userId) {
|
||||
return res.status(403).json({ error: 'You are not authorized to update this offer' })
|
||||
}
|
||||
|
||||
// بررسی اینکه آیا آفر قبلاً بهروزرسانی شده یا نه
|
||||
if (offer.status !== 'pending') {
|
||||
return res.status(400).json({ error: 'Offer has already been updated', message: 'وضعیت این درخواست قبلا تغییر کرده است.' })
|
||||
}
|
||||
|
||||
// بهروزرسانی وضعیت آفر بر اساس اکشن
|
||||
offer.status = action === 'accept' ? 'accepted' : 'rejected'
|
||||
await offer.save()
|
||||
|
||||
if (action === 'accept') {
|
||||
const data = JSON.stringify({
|
||||
mobile: senderUser?.mobile,
|
||||
templateId: '633448',
|
||||
parameters: [
|
||||
{ name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name },
|
||||
{ name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name }
|
||||
]
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: 'https://api.sms.ir/v1/send/verify',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'text/plain',
|
||||
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
|
||||
},
|
||||
data
|
||||
}
|
||||
axios(config)
|
||||
.then(function (response) {
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
} else {
|
||||
const data = JSON.stringify({
|
||||
mobile: senderUser?.mobile,
|
||||
templateId: '682678',
|
||||
parameters: [
|
||||
{ name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name },
|
||||
{ name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name }
|
||||
]
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: 'https://api.sms.ir/v1/send/verify',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'text/plain',
|
||||
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
|
||||
},
|
||||
data
|
||||
}
|
||||
axios(config)
|
||||
.then(function (response) {
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
res.status(200).json({
|
||||
message: `Offer has been ${offer.status} successfully`,
|
||||
offerId: offer._id,
|
||||
status: offer.status
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Controller function for handling successful advertising payment
|
||||
const handleSuccessfulOfferPayment = async (req, res) => {
|
||||
try {
|
||||
const { reciverId, offerType } = req.body
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
// Check user's free offer eligibility
|
||||
const user = await UserModel.findById(userId)
|
||||
if (!user) return res.status(404).json({ error: 'User not found' })
|
||||
// Check user's free offer eligibility
|
||||
const reciverUser = await UserModel.findById(reciverId)
|
||||
if (!user) return res.status(404).json({ error: 'User not found' })
|
||||
|
||||
let price
|
||||
if (user.monthly_free_offer > 0 && offerType === 'free') {
|
||||
// Use free offer and decrement counter
|
||||
price = 0
|
||||
user.monthly_free_offer -= 1
|
||||
await user.save()
|
||||
} else {
|
||||
// Retrieve offer price based on type
|
||||
price = await getOfferPriceFromDatabase(offerType)
|
||||
|
||||
// Create a new payment entry
|
||||
const payment = new PaymentModel({
|
||||
amount: Number(price),
|
||||
status: 'successful',
|
||||
authority: '', // Add authority if available
|
||||
user_id: userId,
|
||||
type: 'offer',
|
||||
installment_step: null
|
||||
})
|
||||
await payment.save()
|
||||
}
|
||||
// Create a new payment entry
|
||||
const payment = new PaymentModel({
|
||||
amount: Number(price),
|
||||
status: 'successful',
|
||||
authority: '', // Add authority if available
|
||||
user_id: userId,
|
||||
type: 'offer',
|
||||
installment_step: null
|
||||
})
|
||||
await payment.save()
|
||||
|
||||
// Create a new offer
|
||||
const offer = new OfferModel({
|
||||
sender: userId,
|
||||
receiver: reciverId,
|
||||
transaction_id: payment._id // Link the payment to the offer
|
||||
})
|
||||
await offer.save()
|
||||
console.log(reciverUser?.first_name)
|
||||
|
||||
// Send notification to selected user
|
||||
const notification = new NotificationModel({
|
||||
user_id: reciverId,
|
||||
project_post_id: offer?._id,
|
||||
type: 'new_offer',
|
||||
title: 'درخواست همکاری جدید',
|
||||
description: `${reciverUser?.first_name} عزیز یک درخواست همکاری برای شما در مجموعه مدستاگرام ثبت شد`
|
||||
})
|
||||
await notification.save()
|
||||
|
||||
// Send Sms
|
||||
const data = JSON.stringify({
|
||||
mobile: reciverUser?.mobile,
|
||||
templateId: '569006',
|
||||
parameters: [
|
||||
{ name: 'FIRSTNAME', value: reciverUser?.first_name },
|
||||
{ name: 'LASTNAME', value: reciverUser?.last_name }
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: 'https://api.sms.ir/v1/send/verify',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'text/plain',
|
||||
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
|
||||
},
|
||||
data
|
||||
}
|
||||
axios(config)
|
||||
.then(function (response) {
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
|
||||
// Send event based on payment status
|
||||
|
||||
// Emit a success event
|
||||
if ('eventEmitter' in req.app) {
|
||||
req.app.get('eventEmitter').emit('paymentSuccess', {
|
||||
message: 'Payment and offer created successfully',
|
||||
offerId: offer._id
|
||||
})
|
||||
} else {
|
||||
console.error('Error: eventEmitter is not defined or not properly configured.')
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
message: 'Payment and offer recorded successfully',
|
||||
offerId: offer._id,
|
||||
price
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error occurred:', error)
|
||||
res.status(500).json({ error: 'Internal server error' })
|
||||
}
|
||||
}
|
||||
// Controller function for handling failed advertising payment
|
||||
const handleFailedOfferPayment = async (req, res) => {
|
||||
try {
|
||||
const { offerType } = req.body
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
const price = await getOfferPriceFromDatabase(offerType)
|
||||
|
||||
// Create a new payment entry
|
||||
const payment = new PaymentModel({
|
||||
amount: Number(price),
|
||||
status: 'failed',
|
||||
authority: '', // Add authority if available
|
||||
user_id: userId,
|
||||
type: 'offer',
|
||||
installment_step: null
|
||||
})
|
||||
await payment.save()
|
||||
|
||||
// Emit a failure event
|
||||
if ('eventEmitter' in req.app) {
|
||||
req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment failed' })
|
||||
} else {
|
||||
console.error('Error: eventEmitter is not defined or not properly configured.')
|
||||
}
|
||||
|
||||
res.status(200).json({ message: 'Payment failed', price })
|
||||
} catch (error) {
|
||||
console.error('Error occurred:', error)
|
||||
res.status(500).json({ error: 'Internal server error' })
|
||||
}
|
||||
}
|
||||
|
||||
const createOfferComment = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
const { offerId, comment, rate, user_id } = req.body
|
||||
if (!offerId || !comment || !rate || !user_id) {
|
||||
return res.status(400).send({ message: 'All fields are required' })
|
||||
}
|
||||
// بررسی اینکه آیا کاربر قبلاً برای این پیشنهاد نظر داده است
|
||||
const existingComment = await CommentModel.findOne({
|
||||
offer: offerId,
|
||||
creator: userId
|
||||
})
|
||||
if (existingComment) {
|
||||
return res.status(400).send({ message: 'شما قبلاً نظر خود را برای این درخواست ثبت کردهاید' })
|
||||
}
|
||||
const newComment = new CommentModel({
|
||||
user: user_id,
|
||||
offer: offerId,
|
||||
creator: userId,
|
||||
rating: rate,
|
||||
comment,
|
||||
comment_for: 'user',
|
||||
status: 'pending'
|
||||
})
|
||||
await newComment.save()
|
||||
|
||||
const user = await UserModel.findById(user_id)
|
||||
|
||||
// پیدا کردن کامنتها و محاسبهی امتیاز کل
|
||||
const comments = await CommentModel.find({ user: user_id, comment_for: 'user' })
|
||||
const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0))
|
||||
|
||||
let userLevel
|
||||
if (user.expertise === 'مدل') {
|
||||
if (totalRating <= 50) userLevel = 'تازه وارد'
|
||||
else if (totalRating <= 100) userLevel = 'استاندارد'
|
||||
else if (totalRating <= 300) userLevel = 'حرفهای'
|
||||
else userLevel = 'استاد'
|
||||
} else if (['زیبایی', 'عکاس'].includes(user.expertise)) {
|
||||
if (totalRating <= 50) userLevel = 'تازه وارد'
|
||||
else if (totalRating <= 100) userLevel = 'استاندارد'
|
||||
else if (totalRating <= 300) userLevel = 'حرفهای'
|
||||
else userLevel = 'استاد'
|
||||
}
|
||||
|
||||
user.user_score = totalRating
|
||||
user.user_level = userLevel
|
||||
|
||||
const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' })
|
||||
const averageRating = totalRating / totalComments
|
||||
user.rate = averageRating.toFixed(1)
|
||||
await user.save()
|
||||
|
||||
res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد' })
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getUserOffers,
|
||||
getOfferTypes,
|
||||
handleSuccessfulOfferPayment,
|
||||
handleFailedOfferPayment,
|
||||
updateOfferStatus,
|
||||
createOfferComment
|
||||
}
|
||||
/* eslint-disable camelcase */
|
||||
const jwt = require('jsonwebtoken')
|
||||
const jMoment = require('moment-jalaali')
|
||||
const OfferModel = require('../../../models/OfferModel')
|
||||
const UserModel = require('../../../models/UserModel')
|
||||
const OfferTypeModel = require('../../../models/OfferTypeModel')
|
||||
const PaymentModel = require('../../../models/PaymentModel')
|
||||
const NotificationModel = require('../../../models/NotificationModel')
|
||||
const { default: axios } = require('axios')
|
||||
const CommentModel = require('../../../models/CommentModel')
|
||||
|
||||
const getOfferPriceFromDatabase = async (itemName) => {
|
||||
const item = await OfferTypeModel.findOne({ name: itemName })
|
||||
if (!item) {
|
||||
throw new Error('Item not found in database')
|
||||
}
|
||||
return item.price
|
||||
}
|
||||
|
||||
const getOfferTypes = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
const user = await UserModel.findById(userId)
|
||||
if (!user) {
|
||||
return res.status(422).json({
|
||||
error: true,
|
||||
message: 'کاربر یافت نشد'
|
||||
})
|
||||
}
|
||||
let offerTypes = await OfferTypeModel.find({}, 'name price')
|
||||
|
||||
// بررسی برای مواردی مانند پیدا نشدن انواع پروژه
|
||||
if (!offerTypes) {
|
||||
return res.status(404).json({ message: 'انواع پروژه یافت نشد.' })
|
||||
}
|
||||
// اگر کاربر درخواست ماهانه نداشته باشد، نوع پروژه ماهانه را حذف کنید
|
||||
if (user.monthly_free_offer <= 0) {
|
||||
offerTypes = offerTypes.filter(projectType => projectType.name !== 'free')
|
||||
}
|
||||
// ارسال انواع پروژه به کاربر
|
||||
res.status(200).json({ offerTypes })
|
||||
} catch (error) {
|
||||
// در صورت بروز خطا، ارسال پیام خطا به کاربر
|
||||
console.error('Error in getOfferTypes:', error)
|
||||
res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' })
|
||||
}
|
||||
}
|
||||
const getUserOffers = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
const { page = 1, limit = 10, status_filter, id } = req.query // افزودن پارامترهای صفحهبندی به درخواست
|
||||
let filter = {}
|
||||
let filterbyid = {receiver: id}
|
||||
let filterbyidsender = {sender: id}
|
||||
if (status_filter === 'درخواست') {
|
||||
filter = { sender: userId }
|
||||
} else {
|
||||
filter = { receiver: userId }
|
||||
}
|
||||
|
||||
// تنظیم گزینههای صفحهبندی
|
||||
const options = {
|
||||
page: parseInt(page), // تبدیل صفحه به عدد صحیح
|
||||
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
|
||||
sort: { createdAt: -1 }, // بر اساس زمان ایجاد (createdAt) مرتب کنید (نزولی)
|
||||
populate: [
|
||||
{
|
||||
path: 'sender',
|
||||
select: 'profile_image user_level first_name last_name user_name is_verified user_score rate'
|
||||
},
|
||||
{
|
||||
path: 'receiver',
|
||||
select: 'profile_image user_level first_name last_name user_name is_verified user_score rate'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// دریافت آفرهای صفحهبندی شده
|
||||
let offer = await OfferModel.paginate(filter, options)
|
||||
let offerbyid = await OfferModel.paginate(filterbyid, options)
|
||||
let offerbyidsender = await OfferModel.paginate(filterbyidsender, options)
|
||||
|
||||
const totalPages = offer.totalPages
|
||||
const totalItems = offer.totalDocs
|
||||
|
||||
// فرمت کردن تاریخ و ارسال پاسخ
|
||||
offer = offer?.docs.map(offer => {
|
||||
const jDate = jMoment(offer.createdAt).format('jYYYY-jMM-jDD HH:mm')
|
||||
return {
|
||||
...offer._doc,
|
||||
createdAt: jDate
|
||||
}
|
||||
})
|
||||
res.json({
|
||||
offerbyidsender,
|
||||
offerbyid,
|
||||
offer,
|
||||
totalPages, // ارسال تعداد کل صفحات
|
||||
totalItems // ارسال تعداد کل آیتمها
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateOfferStatus = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id // ID کاربری که درخواست را بهروزرسانی میکند
|
||||
const reciverUser = await UserModel.findById(userId)
|
||||
|
||||
const { offerId, action } = req.body // آیدی آفر و اکشن (accept یا reject)
|
||||
|
||||
// بررسی اعتبار ورودیها
|
||||
if (!offerId || !['accept', 'reject'].includes(action)) {
|
||||
return res.status(400).json({ error: 'Invalid input' })
|
||||
}
|
||||
|
||||
// یافتن آفر موردنظر
|
||||
const offer = await OfferModel.findById(offerId)
|
||||
const senderUser = await UserModel.findById(offer?.sender)
|
||||
|
||||
if (!offer) {
|
||||
return res.status(404).json({ error: 'Offer not found' })
|
||||
}
|
||||
|
||||
// بررسی اینکه آیا کاربر گیرنده این آفر است یا خیر
|
||||
if (offer.receiver.toString() !== userId) {
|
||||
return res.status(403).json({ error: 'You are not authorized to update this offer' })
|
||||
}
|
||||
|
||||
// بررسی اینکه آیا آفر قبلاً بهروزرسانی شده یا نه
|
||||
if (offer.status !== 'pending') {
|
||||
return res.status(400).json({ error: 'Offer has already been updated', message: 'وضعیت این درخواست قبلا تغییر کرده است.' })
|
||||
}
|
||||
|
||||
// بهروزرسانی وضعیت آفر بر اساس اکشن
|
||||
offer.status = action === 'accept' ? 'accepted' : 'rejected'
|
||||
await offer.save()
|
||||
|
||||
if (action === 'accept') {
|
||||
const data = JSON.stringify({
|
||||
mobile: senderUser?.mobile,
|
||||
templateId: '633448',
|
||||
parameters: [
|
||||
{ name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name },
|
||||
{ name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name }
|
||||
]
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: 'https://api.sms.ir/v1/send/verify',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'text/plain',
|
||||
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
|
||||
},
|
||||
data
|
||||
}
|
||||
axios(config)
|
||||
.then(function (response) {
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
} else {
|
||||
const data = JSON.stringify({
|
||||
mobile: senderUser?.mobile,
|
||||
templateId: '682678',
|
||||
parameters: [
|
||||
{ name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name },
|
||||
{ name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name }
|
||||
]
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: 'https://api.sms.ir/v1/send/verify',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'text/plain',
|
||||
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
|
||||
},
|
||||
data
|
||||
}
|
||||
axios(config)
|
||||
.then(function (response) {
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
res.status(200).json({
|
||||
message: `Offer has been ${offer.status} successfully`,
|
||||
offerId: offer._id,
|
||||
status: offer.status
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Controller function for handling successful advertising payment
|
||||
const handleSuccessfulOfferPayment = async (req, res) => {
|
||||
try {
|
||||
const { reciverId, offerType } = req.body
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
// Check user's free offer eligibility
|
||||
const user = await UserModel.findById(userId)
|
||||
if (!user) return res.status(404).json({ error: 'User not found' })
|
||||
// Check user's free offer eligibility
|
||||
const reciverUser = await UserModel.findById(reciverId)
|
||||
if (!user) return res.status(404).json({ error: 'User not found' })
|
||||
|
||||
let price
|
||||
if (user.monthly_free_offer > 0 && offerType === 'free') {
|
||||
// Use free offer and decrement counter
|
||||
price = 0
|
||||
user.monthly_free_offer -= 1
|
||||
await user.save()
|
||||
} else {
|
||||
// Retrieve offer price based on type
|
||||
price = await getOfferPriceFromDatabase(offerType)
|
||||
|
||||
// Create a new payment entry
|
||||
const payment = new PaymentModel({
|
||||
amount: Number(price),
|
||||
status: 'successful',
|
||||
authority: '', // Add authority if available
|
||||
user_id: userId,
|
||||
type: 'offer',
|
||||
installment_step: null
|
||||
})
|
||||
await payment.save()
|
||||
}
|
||||
// Create a new payment entry
|
||||
const payment = new PaymentModel({
|
||||
amount: Number(price),
|
||||
status: 'successful',
|
||||
authority: '', // Add authority if available
|
||||
user_id: userId,
|
||||
type: 'offer',
|
||||
installment_step: null
|
||||
})
|
||||
await payment.save()
|
||||
|
||||
// Create a new offer
|
||||
const offer = new OfferModel({
|
||||
sender: userId,
|
||||
receiver: reciverId,
|
||||
transaction_id: payment._id // Link the payment to the offer
|
||||
})
|
||||
await offer.save()
|
||||
console.log(reciverUser?.first_name)
|
||||
|
||||
// Send notification to selected user
|
||||
const notification = new NotificationModel({
|
||||
user_id: reciverId,
|
||||
project_post_id: offer?._id,
|
||||
type: 'new_offer',
|
||||
title: 'درخواست همکاری جدید',
|
||||
description: `${reciverUser?.first_name} عزیز یک درخواست همکاری برای شما در مجموعه مدستاگرام ثبت شد`
|
||||
})
|
||||
await notification.save()
|
||||
|
||||
// Send Sms
|
||||
const data = JSON.stringify({
|
||||
mobile: reciverUser?.mobile,
|
||||
templateId: '569006',
|
||||
parameters: [
|
||||
{ name: 'FIRSTNAME', value: reciverUser?.first_name },
|
||||
{ name: 'LASTNAME', value: reciverUser?.last_name }
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: 'https://api.sms.ir/v1/send/verify',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'text/plain',
|
||||
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
|
||||
},
|
||||
data
|
||||
}
|
||||
axios(config)
|
||||
.then(function (response) {
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
|
||||
// Send event based on payment status
|
||||
|
||||
// Emit a success event
|
||||
if ('eventEmitter' in req.app) {
|
||||
req.app.get('eventEmitter').emit('paymentSuccess', {
|
||||
message: 'Payment and offer created successfully',
|
||||
offerId: offer._id
|
||||
})
|
||||
} else {
|
||||
console.error('Error: eventEmitter is not defined or not properly configured.')
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
message: 'Payment and offer recorded successfully',
|
||||
offerId: offer._id,
|
||||
price
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error occurred:', error)
|
||||
res.status(500).json({ error: 'Internal server error' })
|
||||
}
|
||||
}
|
||||
// Controller function for handling failed advertising payment
|
||||
const handleFailedOfferPayment = async (req, res) => {
|
||||
try {
|
||||
const { offerType } = req.body
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
const price = await getOfferPriceFromDatabase(offerType)
|
||||
|
||||
// Create a new payment entry
|
||||
const payment = new PaymentModel({
|
||||
amount: Number(price),
|
||||
status: 'failed',
|
||||
authority: '', // Add authority if available
|
||||
user_id: userId,
|
||||
type: 'offer',
|
||||
installment_step: null
|
||||
})
|
||||
await payment.save()
|
||||
|
||||
// Emit a failure event
|
||||
if ('eventEmitter' in req.app) {
|
||||
req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment failed' })
|
||||
} else {
|
||||
console.error('Error: eventEmitter is not defined or not properly configured.')
|
||||
}
|
||||
|
||||
res.status(200).json({ message: 'Payment failed', price })
|
||||
} catch (error) {
|
||||
console.error('Error occurred:', error)
|
||||
res.status(500).json({ error: 'Internal server error' })
|
||||
}
|
||||
}
|
||||
|
||||
const createOfferComment = async (req, res, next) => {
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
if (!token) return res.status(401).send('Access Denied')
|
||||
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = decodedToken.id
|
||||
|
||||
const { offerId, comment, rate, user_id } = req.body
|
||||
if (!offerId || !comment || !rate || !user_id) {
|
||||
return res.status(400).send({ message: 'All fields are required' })
|
||||
}
|
||||
// بررسی اینکه آیا کاربر قبلاً برای این پیشنهاد نظر داده است
|
||||
const existingComment = await CommentModel.findOne({
|
||||
offer: offerId,
|
||||
creator: userId
|
||||
})
|
||||
if (existingComment) {
|
||||
return res.status(400).send({ message: 'شما قبلاً نظر خود را برای این درخواست ثبت کردهاید' })
|
||||
}
|
||||
const newComment = new CommentModel({
|
||||
user: user_id,
|
||||
offer: offerId,
|
||||
creator: userId,
|
||||
rating: rate,
|
||||
comment,
|
||||
comment_for: 'user',
|
||||
status: 'pending'
|
||||
})
|
||||
await newComment.save()
|
||||
|
||||
const user = await UserModel.findById(user_id)
|
||||
|
||||
// پیدا کردن کامنتها و محاسبهی امتیاز کل
|
||||
const comments = await CommentModel.find({ user: user_id, comment_for: 'user' })
|
||||
const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0))
|
||||
|
||||
let userLevel
|
||||
if (user.expertise === 'مدل') {
|
||||
if (totalRating <= 50) userLevel = 'تازه وارد'
|
||||
else if (totalRating <= 100) userLevel = 'استاندارد'
|
||||
else if (totalRating <= 300) userLevel = 'حرفهای'
|
||||
else userLevel = 'استاد'
|
||||
} else if (['زیبایی', 'عکاس'].includes(user.expertise)) {
|
||||
if (totalRating <= 50) userLevel = 'تازه وارد'
|
||||
else if (totalRating <= 100) userLevel = 'استاندارد'
|
||||
else if (totalRating <= 300) userLevel = 'حرفهای'
|
||||
else userLevel = 'استاد'
|
||||
}
|
||||
|
||||
user.user_score = totalRating
|
||||
user.user_level = userLevel
|
||||
|
||||
const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' })
|
||||
const averageRating = totalRating / totalComments
|
||||
user.rate = averageRating.toFixed(1)
|
||||
await user.save()
|
||||
|
||||
res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد' })
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getUserOffers,
|
||||
getOfferTypes,
|
||||
handleSuccessfulOfferPayment,
|
||||
handleFailedOfferPayment,
|
||||
updateOfferStatus,
|
||||
createOfferComment
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user