'use strict'; const fs = require("fs"); const moment = require("jalali-moment"); const {parseMultipartData, sanitizeEntity} = require('strapi-utils'); const url = require("url"); module.exports = { async getCourseUsers(ctx){ //const {user} = ctx.state; const {levelId} = ctx.params; const confirmUsers = await strapi.services["user-course"].find({ course_levels_in: [levelId], _limit :-1, isConfirm: true }); let result={}; if (confirmUsers && confirmUsers.length){ result ={courseTitle:confirmUsers[0].course_levels[0].title,items:[]} result.items = confirmUsers.map(cu => { if (cu.expiredDate==null){ let expiredDate = cu.expiredDate; if (!expiredDate){ expiredDate= strapi.services.helpers.addDays(cu.factorDate,366); } cu.expiredDate= expiredDate; } return { name:cu.user.name, phoneNo:cu.user.phoneNo, buyDate:cu.buyDate, expiredDate:cu.expiredDate, inactiveLicense:cu.inactiveLicense, canDownload:cu.canDownload, buyPrice:cu.buyPrice, payBy:cu.payBy, expiredInDays: strapi.services.helpers.howMuchDaysLeft(cu.expiredDate) } }); } ctx.send(result); }, async getTeacherUsers(ctx) { const {user} = ctx.state; const teacherCourse = await strapi.services["course-level"].getTeacherLevels(user.id); if (teacherCourse.result) { const levelIds = teacherCourse.entity.map(x => x.id); const confirmUsers = await strapi.services["user-course"].find({ course_levels_in: levelIds, _limit :-1, isConfirm: true }); const result = []; confirmUsers.map(cu => { let exist = result.find(x => x.id === cu.user.id); if (!exist) { exist = {id: cu.user.id, name: cu.user.name + " " + (cu.user.family? cu.user.family:''), phoneNo: cu.user.phoneNo, courses: []}; result.push(exist); } if (!exist.courses.find(x => x.id === cu.id)) { exist.courses.push({ id: cu.id, buyDate: cu.buyDate, discountAmount: cu.discount ? cu.discount.amount : 0, buyPrice: cu.buyPrice, level: cu.course_levels[0].title, canDownload: cu.canDownload, inactiveLicense: cu.inactiveLicense }) } }); ctx.send(result); } else { return ctx.badRequest(null, teacherCourse.entity); } }, async updateAccess(ctx) { const {list} = ctx.request.body; try { list.map(async x => { await strapi.services["user-course"].update({id: x.id}, x); }); return ctx.send(true); } catch (ex) { return ctx.badRequest(null, ex.message); } }, async paycallBack(ctx){ console.log("BODY:::",ctx.request.body); let {RefId,ResCode,SaleOrderId,SaleReferenceId,CardHolderPan,FinalAmount} = ctx.request.body; const userCourse = await strapi.services["user-course"].findOne({authority:RefId}); if (ResCode==='0' && userCourse.buyPrice * 10 != Number(FinalAmount) ){ ResCode= 'InAmount'; } await strapi.services["user-course"].update({id: userCourse.id}, { bankRefNo: ResCode=='0'? SaleReferenceId: SaleOrderId, payCardNo:CardHolderPan }); return ctx.redirect(`https://app.optimyar.com/paycallBack?refId=${RefId}&resCode=${ResCode}`); }, async verifyPay(ctx) { const {authority,isMellat} = ctx.request.body; const {user} = ctx.state; let userCourse = await strapi.services["user-course"].findOne({user: user.id, authority}); if (userCourse === null) { return ctx.badRequest(null, "errors.factorNotFound") } let result=null; if (isMellat){ result = await strapi.services.helpers.verifyMellatPay(userCourse.factorNumber, userCourse.buyPrice,Number(userCourse.bankRefNo)); }else{ result = await strapi.services.helpers.verifyZarinpalPay(authority, userCourse.buyPrice); } const titles = userCourse.course_levels.map(x => x.title); const productName = titles.join(" - "); if (result.result === false) { strapi.services.helpers.sendEmail(userCourse.user.email, "ثبت نام دوره آپتیم یار", `

ثبت نام شما با خطا مواجه شده است

دوره مد نظز شما : ${productName}

شماره فاکتور : ${userCourse.factorNumber}

`).then(); return ctx.badRequest(null, result.entity); } if (result.entity.code === 100 || result.entity.code === 101) { const buyDate = new Date(); await strapi.services["user-course"].update({id: userCourse.id}, { buyDate, bankRefNo: isMellat? userCourse.bankRefNo: result.entity.ref_id.toString(), isConfirm: true, payCardNo: isMellat? userCourse.payCardNo: result.entity.card_pan, payBy: isMellat ? "Mellat" : "Zarinpal" }); let inputData = [{ "course_title": productName, }]; //delete if discount is disposable if (userCourse.discount && userCourse.discount.disposable) { //may user use with together is same time const discount = await strapi.services.discount.verifyDiscountForUse(userCourse.discount); if (discount.result === false) { return ctx.badRequest(null, discount.entity); } await strapi.services.discount.update({id: userCourse.discount.id}, {isEnabled: false}); } await strapi.services.helpers.sendSms(userCourse.user.phoneNo, "jvcbauf2c5", inputData); const data = fs.readFileSync('resources/emailTemplate/Factor.html', 'utf8'); const faBuyDate = moment.from(buyDate.toUTCString(), 'en').locale("fa").format("YYYY/MM/DD HH:mm"); const html = data.replace(/COURSE_TITLE/g, productName) .replace(/FACTOR_NUMBER/g, userCourse.factorNumber) .replace(/PAY_AMOUNT/g, userCourse.buyPrice + " تومان ") .replace(/COURSE_LEVEL_ID/g, userCourse.course_levels[0].id) .replace(/USER_PHONE_NO/g, userCourse.user.phoneNo) .replace(/USER_FULL_NAME/g, userCourse.user.name) .replace(/BUY_Date/g, faBuyDate); strapi.services.helpers.sendEmail(userCourse.user.email, "تاییدیه ثبت‌‌نام و شرکت در دوره‌های آکادمی آموزشی و پژوهشی آپتیم‌یار", html).then(); const invite= fs.readFileSync('resources/emailTemplate/InvitToTelegram.html', 'utf8'); const inviteHtml = invite.replace(/COURSE_TITLE/g, productName) .replace(/USER_FULL_NAME/g, userCourse.user.name); strapi.services.helpers.sendEmail(userCourse.user.email, "آکادمی آموزشی و پژوهشی آپتیم‌یار", inviteHtml).then(); inputData = [{ "name": userCourse.user.name, }]; await strapi.services.helpers.sendSms(userCourse.user.phoneNo, "drmdp9hfi60p8hc", inputData); return ctx.send({ bankRefNo: isMellat? userCourse.authority: result.entity.ref_id, factorNumber: userCourse.factorNumber, paidAmount: userCourse.buyPrice, isOk: true, productName }); } else { strapi.services.helpers.sendEmail(userCourse.user.email, "ثبت نام دوره آپتیم یار", `

ثبت نام شما با خطا مواجه شده است

دوره مد نظز شما : ${productName}

شماره فاکتور : ${userCourse.factorNumber}

`).then(); return ctx.send({ errorCode: result.entity.code, isOk: false, productName }) } }, async pay(ctx) { const {id,payType} = ctx.request.body; const userCourse = await strapi.services["user-course"].findOne({id}); if (userCourse == null) { return ctx.badRequest(null, "buyCourse.errors.factorNotFound"); } let discount; if (userCourse.discount && userCourse.discount.id) { discount = await strapi.services.discount.verifyDiscountForUse(userCourse.discount); if (discount.result === false) { return ctx.badRequest(null, discount.entity); } } const levels = await strapi.services["course-level"].getByIds(userCourse.course_levels); const prices = levels.map(x => x.price); userCourse.buyPrice = await strapi.services["user-course"].calculatePrice(userCourse.groupCount, prices, discount ? discount.entity.amount : 0); const amount = userCourse.buyPrice; const description = `فاکتور شماره ${userCourse.factorNumber} آکادمی آموزشی و پژوهشی آپتیم یار`; const mobile = userCourse.user.phoneNo.toString(); const email = userCourse.user.email; let result=null; if (payType===2){ result = await strapi.services.helpers.verifyForPayZarinpal(amount, description, mobile, email); }else{ //result = await strapi.services.helpers.verifyForPayZarinpal(amount, description, mobile, email); result = await strapi.services.helpers.requestForPayBP(amount, description, mobile, email,userCourse.factorNumber); } if (result.result === false) { return ctx.badRequest(null, result.entity); } const update = await strapi.services["user-course"].update({id: userCourse.id}, { authority: result.entity.authority }); return ctx.send(result.entity); //const userCourse= await strapi.services["user-course"].verifyBeforePay(factorId); }, async create(ctx) { let entity; if (ctx.is('multipart')) { const {data, files} = parseMultipartData(ctx); entity = await strapi.services["user-course"].create(data, {files}); } else { const {user} = ctx.state; const model = ctx.request.body; const {discountCode} = ctx.request.body; let discount; if (discountCode) { discount = await strapi.services.discount.verifyGetByCodeAndCourse(discountCode, model.course_levels[0]); if (discount.result === false) { return ctx.badRequest(null, discount.entity); } } const levels = await strapi.services["course-level"].getByIds(model.course_levels); let isValid = await strapi.services["user-course"].isValidData(model, discount ? discount.entity : null, levels); if (isValid !== true) { return ctx.badRequest(null, isValid); } model.discount = discount ? discount.entity.id : null; model.factorDate = new Date(); model.factorNumber = await strapi.services["user-course"].getNextFactorNumber(); model.user = user.id; if (discount && discount.entity.isFreePay) { model.buyPrice = 0; model.isConfirm = true; model.buyDate = model.factorDate; model.payBy = "FreePayDiscount"; model.bankRefNo = "1000"; //delete if discount is disposable if (discount && discount.entity.disposable) { //may user use with together is same time discount = await strapi.services.discount.verifyDiscountForUse(discount.entity); if (discount.result === false) { return ctx.badRequest(null, discount.entity); } await strapi.services.discount.update({id: discount.entity.id}, {isEnabled: false}); } //-------------------- const titles = levels.map(x => x.title); const productName = titles.join(" - "); let inputData = [{ "course_title": productName, }]; await strapi.services.helpers.sendSms(user.phoneNo, "jvcbauf2c5", inputData); const data = fs.readFileSync('resources/emailTemplate/Factor.html', 'utf8'); const faBuyDate = moment.from(model.buyDate.toUTCString(), 'en').locale("fa").format("YYYY/MM/DD HH:mm"); const html = data.replace(/COURSE_TITLE/g, productName) .replace(/FACTOR_NUMBER/g, model.factorNumber) .replace(/PAY_AMOUNT/g, " رایگان ") .replace(/COURSE_LEVEL_ID/g, levels[0].id) .replace(/USER_PHONE_NO/g, user.phoneNo) .replace(/USER_FULL_NAME/g, user.name) .replace(/BUY_Date/g, faBuyDate); strapi.services.helpers.sendEmail(user.email, "تاییدیه ثبت‌‌نام و شرکت در دوره‌های آکادمی آموزشی و پژوهشی آپتیم‌یار", html).then(); const invite= fs.readFileSync('resources/emailTemplate/InvitToTelegram.html', 'utf8'); const inviteHtml = invite.replace(/COURSE_TITLE/g, productName) .replace(/USER_FULL_NAME/g, user.name); strapi.services.helpers.sendEmail(user.email, "آکادمی آموزشی و پژوهشی آپتیم‌یار", inviteHtml).then(); inputData = [{ "name": user.name, }]; await strapi.services.helpers.sendSms(user.phoneNo, "drmdp9hfi60p8hc", inputData); } else { const prices = levels.map(x => x.price); model.buyPrice = await strapi.services["user-course"].calculatePrice(model.groupCount, prices, discount ? discount.entity.amount : 0); } entity = await strapi.services["user-course"].create(model); } return sanitizeEntity(entity, {model: strapi.models["user-course"]}); }, async isCourseLive(ctx){ const {user} = ctx.state; const {id} = ctx.params; const response={ isAdobe:false, isLive:false, link:'', liveLevelId:null } const uc = await strapi.services["user-course"].findOne({id}); const liveLevelId = await strapi.services["user-course"].isUserCourseMeetingRunning(uc.course_levels[0]); if (liveLevelId && liveLevelId.isAdobe) { response.isAdobe = true; link.link = liveLevelId.link } else { response.isLive = liveLevelId != null; response.liveLevelId = liveLevelId; } return ctx.send(response); }, async joinUserToMeeting(ctx) { const {user} = ctx.state; const {id} = ctx.params; //we can use this function to join just registerd user to adobe meeting //https://helpx.adobe.com/adobe-connect/webservices/create-meetings.html const userCourse = await strapi.services["user-course"].findOne({id}); if (userCourse.user.id !== user.id || !userCourse.isConfirm) { return ctx.badRequest(null, "buyCourse.errors.courseIsNotConfirm"); } const liveLevelId = await strapi.services["user-course"].isUserCourseMeetingRunning(userCourse.course_levels[0]); if (liveLevelId == null) { return ctx.badRequest(null, "errors.classIsNotLive"); } const info = await strapi.services.helpers.getBBBMeetingInfo(liveLevelId); let fullName = user.name + " "; if (user.family){ fullName += user.family; } const userId= user.id+"-"+user.phoneNo; const result = { joinUrl: await strapi.services.helpers.joinUserToMeeting(fullName, info.meetingID, info.attendeePW, userId, false), disallowRecording: !userCourse.inactiveLicense && info.metadata.disallowrecording }; return ctx.send(result); }, async checkOfflineAccess(ctx){ const {fileName}= ctx.request.body; const {user} = ctx.state; const session = await strapi.services.session.findOne({internalMeetingID:fileName}); if (!session){ return ctx.send({result:false,error:"مشخصات جلسه مرتبط یافت نشد"}); } const levelId = session.course_level.id; const userCourse= await strapi.services["user-course"].findOne({course_levels_in:[levelId],user:user.id,isConfirm:true}); if (!userCourse){ return ctx.send({result:false,error:"شما دسترسی به این دوره ندارید"}); } if (!userCourse.canDownload){ return ctx.send({result:false,error:"شما اجازه پخش آفلاین جلسات این دوره را ندارید"}); } return ctx.send({result:true}); }, async getFactorInfo(ctx){ const {id} = ctx.params; const entity = await strapi.services["user-course"].findOne({id}); return sanitizeEntity(entity, {model: strapi.models["user-course"]}); }, async find(ctx) { const isVersionOk= await strapi.services.helpers.checkVersion(ctx); if (!isVersionOk){ return ctx.badRequest(null, "NEW VERSION RELEASED"); } let entities; const {user} = ctx.state; const {query} = ctx; delete query.version; if (!strapi.services.helpers.isAdmin(user)) { query["user_eq"] = user.id; } else { const teacherLevels = await strapi.query("course-level").find({teacher: user.id}); query["course_levels_in"] = teacherLevels.map(x => x.id); query["user_ne"]=null; } //query["_sort"]="updateAt:DESC"; if (query._q) { entities = await strapi.services["user-course"].search(query); } else { entities = await strapi.services["user-course"].find(query); } entities.map(uc => { uc.course_levels[0].isLive = false; }); return entities.map(entity => sanitizeEntity(entity, {model: strapi.models["user-course"]})); }, };