Files
2025-07-09 11:55:58 +03:30

322 lines
11 KiB
JavaScript

/* eslint-disable no-unused-vars */
const User = require('../models/User')
const InstalledDevice = require('../models/GPS.InstalledDevice')
const Lottery = require('../models/Lottery')
const SurveyCheck = require('../models/SurveyCheck')
const Survey = require('../models/Survey')
const Announcement = require('../models/Announcement')
const { saveUserToArpa, updateUserOnArpa } = require('../ArpaWebservice')
const { generateRandomDigitsInRangeOf } = require('./controllersHelperFunctions')
const sms = require('./SMS_Module')
const { phrases } = require('./SMS_Phrases')
// eslint-disable-next-line import/order
const Cron = require('cron').CronJob
/// /////// times
const minute = 1000 * 60
const hour = minute * 60
const day = hour * 24
/// /////// jobs
const job = new Cron('0 0 * * *', async () => {
console.log('✅ --job: check devices for activation is running')
try {
const devices = await InstalledDevice.find({
$or: [{ status: 0 }, { status: 2 }]
})
.populate('userId', 'mobile_number')
.populate('deviceId', 'model')
for await (const device of devices) {
// item time and timeout
const itemTime = Date.parse(device.created_at)
const timeout = itemTime + day * 3
if (Date.now() >= timeout && !device.check) {
device.check = true
await device.save()
await sms.auth.sendOTP(
device.userId.mobile_number,
`کاربر گرامی\n \n \nجهت ثبت سیمکارت برای دستگاه ${device.deviceId.model} \nبا شناسه : ${device.IMEI} \nلطفا زود تر اقدام کنید `
)
}
}
} catch (e) {
console.log(e)
}
})
const jobs = {
checkUserActivation() {
console.log('✅ --job: check users for activation is running')
return setInterval(async () => {
try {
const users = await User.find({ confirmed: false })
for await (const user of users) {
// item time and timeout
const itemTime = Date.parse(user.created_at)
const timeout = itemTime + day
// check if passed 24 hours and remove registration
if (Date.now() >= timeout) {
await user.remove()
}
}
} catch (e) {
console.log(e)
}
}, hour)
},
checkIfAnnouncementsExpired() {
console.log('✅ --job: check announcements for expire date is running')
return setInterval(async () => {
try {
const announcements = await Announcement.find({ expired: false })
for await (const notif of announcements) {
if (Date.now() > notif.expireDate) {
notif.expired = true
await notif.save()
}
}
} catch (e) {
console.log(e)
}
}, hour)
},
drawLottery() {
console.log('✅ --job: check for lottery draw is running')
return setInterval(async () => {
try {
const lottery = await Lottery.findOne({ expired: false })
if (!lottery || lottery.expireDate > Date.now()) return
/// ///////// assets (arrays)
const winnersCount = lottery.winnersCount
const participants = lottery.participants
const participantsMobileNumbers = []
const winnersArray = []
const winnersMobileNumbers = []
/// ///////// assets (functions)
function getWinner(array) {
return new Promise(async (resolve, reject) => {
const winner = array[generateRandomDigitsInRangeOf(array.length - 1)]
if (await winnersMobileNumbers.includes(winner.mobile)) resolve(await getWinner(array))
else {
winnersMobileNumbers.push(winner.mobile)
winnersArray.push(winner)
resolve()
}
})
}
// normalize repeated mobile numbers to decide which method to use
for await (const item of participants) {
if (!participantsMobileNumbers.includes(item.mobile)) participantsMobileNumbers.push(item.mobile)
}
// draw function
if (participantsMobileNumbers.length > 1000) {
// console.log('------------------------- larg number block ran')
// chunk all participants to n part (Number(winnersCount) part)
const partLength = Math.floor(participants.length / winnersCount)
const chunckedArrayToParts = []
for (let i = 0; i < winnersCount; i++) {
const chunck = await participants.slice(i * partLength, i * partLength + partLength)
await chunckedArrayToParts.push(chunck)
}
for await (const item of chunckedArrayToParts) {
await getWinner(item)
}
} else if (participantsMobileNumbers.length > winnersCount) {
// console.log('------------------------- grater than winnersCount block ran')
const winnersCountArray = []
for (let i = 0; i < winnersCount; i++) {
winnersCountArray.push(i)
}
for await (const item of winnersCountArray) {
await getWinner(participants)
}
} else {
// console.log('------------------------- less or equal to winnersCount block ran')
for await (const item of participants) {
if (!winnersMobileNumbers.includes(item.mobile)) {
winnersMobileNumbers.push(item.mobile)
winnersArray.push(item)
}
}
}
// save result to db
lottery.winnersList = winnersArray
lottery.markModified('winnersList')
lottery.expired = true
lottery.save()
// send sms for winners
for await (const item of winnersArray) {
const msg = [
'تبریک!!!',
'\n',
item.fullName,
' عزیز شما در قرعه کشی آسان سرویس با کد پیگیری ',
item.enrollCode,
' برنده شدید. به زودی از شرکت آسان سرویس با شما تماس گرفته خواهد شد. در صورتی که تا 3 روز کاری با شما تماس گرفته نشد میتوانید از طریق شماره 02167341 داخلی 200 و کد پیگیری خود جهت دریافت جایزه اقدام نماید.',
'\n',
phrases.thanks,
'\n',
phrases.signature
]
await sms.auth.sendOTP(item.mobile, msg.join(''))
}
/// /////////////////////////////////////////////////////// fake data for tests
// for (let i = 0; i < 4; i++) {
// participants.push({
// fullName: 'Amir Mohamadi 2',
// mobile: '34dfssdkfisjdf34534',
// serial: `S-ffasdfdf`,
// enrollCode: `CODE-${i}`
// })
// console.log('--',i)
// }
// lottery.participants = []
// lottery.markModified('participants')
// return lottery.save()
} catch (e) {
console.log('an error happend in drawLottery job --- error: ', e)
}
}, hour)
},
checkUserSurveys() {
console.log('✅ --job: check users for surveys is running')
return setInterval(async () => {
try {
const surveyCheck = await SurveyCheck.find({ smsSent: false }).populate('user')
for await (const item of surveyCheck) {
// timeout
const timeout = item.timeAdded + day * 7
// check if passed one week
if (Date.now() >= timeout) {
const survey = await Survey.findOne({ code: item.code })
if (!survey?._id) {
const msg = [
'مشتری گرامی',
item.user.first_name + ' ' + item.user.last_name,
'\n',
'لطفا با شرکت در نظرسنجی خدمات پس از فروش آسان سرویس، میزان رضایت خود از خدمات گارانتی را به ما اعلام کنید و ما را در ارائه خدمات بهتر یاری نمایید. به پاس همراهی شما عزیزان، بین شرکت کنندگان در نظرسنجی ابتدای هرماه به قید قرعه جوایزی اهدا خواهد شد.',
'\n',
'لینک شرکت در نظر سنجی:',
'\n',
`https://asan-service.com/account/survey?code=${item.code}`
]
await sms.auth.sendOTP(item.user.mobile_number, msg.join(' '))
item.smsSent = true
await item.save()
}
}
}
} catch (e) {
console.log(e)
}
}, day)
}
}
/// /////// for develop usages
const permissions = require('./permissions')
const devTools = {
async checkUsersArpaAccounts() {
try {
const users = await User.find({ scope: ['user'], confirmed: true })
let index = 0
for await (const user of users) {
if (user.scope.includes('user')) {
// if (!user.panatech_businessID && !user.panatech_businessCode) {
// const panatechID = await saveUserToArpa(user, 'panatech')
// user.panatech_businessID = panatechID.businessID
// user.panatech_businessCode = panatechID.businessCode
// await user.save()
// console.log('🚀 ~ file: cronJobs.js ~ panatechID.businessCode', index)
// }
index++
}
}
} catch (e) {
console.log('we got error --- ', e)
}
},
async addNewPermissionsToPrivateAdmin() {
console.log('addNewPermissionsToPrivateAdmin started')
try {
const users = await User.find({ private: true })
for await (const user of users) {
// console.log('🚀 ~ file: cronJobs.js ~ line 187 ~ forawait ~ user', user)
user.permissions = []
for await (const permission of permissions) {
user.permissions.push(permission.value)
// console.log('🚀 ~ file: cronJobs.js ~ line 190 ~ forawait ~ permission', permission.value)
}
await user.save()
}
} catch (e) {
console.log(e)
}
},
async findDuplicatedUsers() {
try {
const usersArray = new Set()
const duplicatedUsersArray = new Set()
const users = await User.find({ scope: ['user'] })
for await (const user of users) {
if (!usersArray.has(user.mobile_number)) usersArray.add(user.mobile_number)
else duplicatedUsersArray.add(user.mobile_number)
}
console.log(
'🚀 ~ file: cronJobs.js ~ line 220 ~ findDuplicatedUsers ~ duplicatedUsersArray',
duplicatedUsersArray
)
console.log(
'🚀 ~ file: cronJobs.js ~ line 220 ~ findDuplicatedUsers ~ duplicatedUsersArray',
duplicatedUsersArray.size
)
} catch (e) {
console.log('🚀 ~ file: cronJobs.js ~ line 223 ~ findDuplicatedUsers - catch ~ e', e)
}
}
}
module.exports = () => {
job.start()
jobs.checkUserActivation()
jobs.drawLottery()
jobs.checkIfAnnouncementsExpired()
jobs.checkUserSurveys()
// remember to run it once !!!
// devTools.checkUsersArpaAccounts()
// devTools.addNewPermissionsToPrivateAdmin()
// devTools.findDuplicatedUsers()
}