357 lines
12 KiB
JavaScript
357 lines
12 KiB
JavaScript
const fs = require('fs')
|
|
const jimp = require('jimp')
|
|
const { body, validationResult } = require('express-validator')
|
|
const moment = require('moment-jalaali')
|
|
const Lottery = require('../models/Lottery')
|
|
const { serialChecker } = require('../plugins/asanServiceSerialChecker')
|
|
const { _sr } = require('../plugins/serverResponses')
|
|
const {
|
|
res404,
|
|
res406,
|
|
res500,
|
|
checkValidations,
|
|
removeWhiteSpaces,
|
|
checkMobileNumber,
|
|
normalizeMobileNumber
|
|
} = require('../plugins/controllersHelperFunctions')
|
|
const sms = require('../plugins/SMS_Module')
|
|
|
|
///
|
|
const _faSr = _sr.fa
|
|
|
|
module.exports.addLottery = [
|
|
[
|
|
body('title').notEmpty().withMessage(_faSr.required.title),
|
|
|
|
body('winnersCount')
|
|
.notEmpty()
|
|
.withMessage('تعداد برندگان قرعه کشی را مشخص کنید')
|
|
.bail()
|
|
.isNumeric()
|
|
.withMessage(_faSr.format.number)
|
|
.bail()
|
|
.custom((value, { req }) => {
|
|
if (Number(value) < 1) return Promise.reject(new Error('تعداد برندگان نمیتواند کمتر از 1 باشد'))
|
|
else return Promise.resolve()
|
|
}),
|
|
|
|
body('expireDate')
|
|
.notEmpty()
|
|
.withMessage('تاریخ پایان قرعه کشی را مشخص کنید')
|
|
.bail()
|
|
.isNumeric()
|
|
.withMessage('فرمت صحیح نیست')
|
|
.bail()
|
|
.custom((value, { req }) => {
|
|
if (Number(value) < Date.now()) return Promise.reject(new Error('نمیتوان تاریخ روز جاری یا قبل تر انتخاب کرد.'))
|
|
else return Promise.resolve()
|
|
})
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
const { title, winnersCount, expireDate } = req.body
|
|
const supportedImageFormats = ['png', 'jpg', 'jpeg', 'webp']
|
|
let entryBgImgName, resultBgImgName, entryWidth, entryHeight, resultWidth, resultHeight
|
|
|
|
try {
|
|
// check for other open lotteries
|
|
const openLotteries = await Lottery.find({ expired: false })
|
|
if (openLotteries.length) return res406(res, 'تا بسته شدن قرعه کشی قبلی نمیتوان قرعه کشی جدید ثبت کرد')
|
|
|
|
// required image validations
|
|
if (!req.files || !req.files.entryBgImg)
|
|
return res.status(422).json({ validation: { entryBgImg: { msg: 'عکس صفحه شرکت در قرعه کشی اجباری است' } } })
|
|
|
|
if (!req.files || !req.files.resultBgImg)
|
|
return res.status(422).json({
|
|
validation: {
|
|
resultBgImg: {
|
|
msg: 'عکس صفحه نتایج قرعه کشی اجباری است'
|
|
}
|
|
}
|
|
})
|
|
|
|
// save images
|
|
if (req.files) {
|
|
// save entry bg image
|
|
if (req.files.entryBgImg) {
|
|
const image = req.files.entryBgImg
|
|
|
|
// validate image format
|
|
if (!supportedImageFormats.includes(image.mimetype.split('/')[1])) {
|
|
return res.status(422).json({ validation: { entryBgImg: { msg: _faSr.format.image } } })
|
|
}
|
|
|
|
entryBgImgName = 'lotteryEntryBg_' + Date.now() + '.' + image.mimetype.split('/')[1]
|
|
const jimpImg = await jimp.read(image.data)
|
|
jimpImg.quality(100).write(`./static/uploads/images/lottery/${entryBgImgName}`)
|
|
entryWidth = jimpImg.bitmap.width
|
|
entryHeight = jimpImg.bitmap.height
|
|
}
|
|
|
|
// save result bg image
|
|
if (req.files.resultBgImg) {
|
|
const image = req.files.resultBgImg
|
|
|
|
// validate image format
|
|
if (!supportedImageFormats.includes(image.mimetype.split('/')[1])) {
|
|
return res.status(422).json({ validation: { resultBgImg: { msg: _faSr.format.image } } })
|
|
}
|
|
|
|
resultBgImgName = 'lotteryResultBg_' + Date.now() + '.' + image.mimetype.split('/')[1]
|
|
const jimpImg = await jimp.read(image.data)
|
|
jimpImg.quality(100).write(`./static/uploads/images/lottery/${resultBgImgName}`)
|
|
resultWidth = jimpImg.bitmap.width
|
|
resultHeight = jimpImg.bitmap.height
|
|
}
|
|
}
|
|
|
|
const data = {
|
|
title,
|
|
winnersCount,
|
|
expireDate
|
|
}
|
|
if (entryBgImgName) {
|
|
data.entryWidth = entryWidth
|
|
data.entryHeight = entryHeight
|
|
data.entryBgImg = entryBgImgName
|
|
}
|
|
if (resultBgImgName) {
|
|
data.resultWidth = resultWidth
|
|
data.resultHeight = resultHeight
|
|
data.resultBgImg = resultBgImgName
|
|
}
|
|
data.lotteryCode = 'L'.concat(moment(Date.now()).format('jMMMjDDjYYYY').toUpperCase())
|
|
|
|
const lottery = new Lottery(data)
|
|
await lottery.save()
|
|
return res.json({ message: _faSr.response.success_save })
|
|
} catch (e) {
|
|
return res500(res, `there is an error here --- ${e}`)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.updateLottery = [
|
|
[
|
|
body('title').notEmpty().withMessage(_faSr.required.title),
|
|
|
|
body('winnersCount')
|
|
.notEmpty()
|
|
.withMessage('تعداد برندگان قرعه کشی را مشخص کنید')
|
|
.bail()
|
|
.isNumeric()
|
|
.withMessage(_faSr.format.number)
|
|
.bail()
|
|
.custom((value, { req }) => {
|
|
if (Number(value) < 1) return Promise.reject(new Error('تعداد برندگان نمیتواند کمتر از 1 باشد'))
|
|
else return Promise.resolve()
|
|
}),
|
|
|
|
body('expireDate')
|
|
.notEmpty()
|
|
.withMessage('تاریخ پایان قرعه کشی را مشخص کنید')
|
|
.bail()
|
|
.isNumeric()
|
|
.withMessage('فرمت صحیح نیست')
|
|
.bail()
|
|
.custom((value, { req }) => {
|
|
if (Number(value) < Date.now()) return Promise.reject(new Error('نمیتوان تاریخ روز جاری یا قبل تر انتخاب کرد.'))
|
|
else return Promise.resolve()
|
|
})
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
const { title, winnersCount, expireDate } = req.body
|
|
const supportedImageFormats = ['png', 'jpg', 'jpeg', 'webp']
|
|
let entryBgImgName, resultBgImgName, entryWidth, entryHeight, resultWidth, resultHeight
|
|
|
|
try {
|
|
// check lottery expiration
|
|
const lottery = await Lottery.findById(req.params?.lotteryId)
|
|
if (lottery.expired) return res406(res, 'نمیتوان قرعه کشی بسته شده را ویرایش کرد')
|
|
|
|
// save images
|
|
if (req.files) {
|
|
// save entry bg image
|
|
if (req.files.entryBgImg) {
|
|
const image = req.files.entryBgImg
|
|
|
|
// validate image format
|
|
if (!supportedImageFormats.includes(image.mimetype.split('/')[1])) {
|
|
return res.status(422).json({ validation: { entryBgImg: { msg: _faSr.format.image } } })
|
|
}
|
|
|
|
entryBgImgName = 'lotteryEntryBg_' + Date.now() + '.' + image.mimetype.split('/')[1]
|
|
const jimpImg = await jimp.read(image.data)
|
|
jimpImg.quality(100).write(`./static/uploads/images/lottery/${entryBgImgName}`)
|
|
entryWidth = jimpImg.bitmap.width
|
|
entryHeight = jimpImg.bitmap.height
|
|
lottery.entryBgImg &&
|
|
fs.unlink(`./static/${lottery.entryBgImg}`, err => {
|
|
if (err) console.log(err)
|
|
})
|
|
}
|
|
|
|
// save result bg image
|
|
if (req.files.resultBgImg) {
|
|
const image = req.files.resultBgImg
|
|
|
|
// validate image format
|
|
if (!supportedImageFormats.includes(image.mimetype.split('/')[1])) {
|
|
return res.status(422).json({ validation: { resultBgImg: { msg: _faSr.format.image } } })
|
|
}
|
|
|
|
resultBgImgName = 'lotteryResultBg_' + Date.now() + '.' + image.mimetype.split('/')[1]
|
|
const jimpImg = await jimp.read(image.data)
|
|
jimpImg.quality(100).write(`./static/uploads/images/lottery/${resultBgImgName}`)
|
|
resultWidth = jimpImg.bitmap.width
|
|
resultHeight = jimpImg.bitmap.height
|
|
lottery.resultBgImg &&
|
|
fs.unlink(`./static/${lottery.resultBgImg}`, err => {
|
|
if (err) console.log(err)
|
|
})
|
|
}
|
|
}
|
|
|
|
lottery.title = title
|
|
lottery.winnersCount = winnersCount
|
|
lottery.expireDate = expireDate
|
|
|
|
if (entryBgImgName) {
|
|
lottery.entryWidth = entryWidth
|
|
lottery.entryHeight = entryHeight
|
|
lottery.entryBgImg = entryBgImgName
|
|
}
|
|
if (resultBgImgName) {
|
|
lottery.resultWidth = resultWidth
|
|
lottery.resultHeight = resultHeight
|
|
lottery.resultBgImg = resultBgImgName
|
|
}
|
|
await lottery.save()
|
|
return res.json({ message: _faSr.response.success_save })
|
|
} catch (e) {
|
|
return res500(res, `there is an error here --- ${e}`)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.getAllLotteries = [
|
|
(req, res) => {
|
|
Lottery.find({})
|
|
.sort({ _id: -1 })
|
|
.exec((err, data) => {
|
|
if (err || !data) return res500(res, err)
|
|
else return res.json(data)
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.getOneLottery = [
|
|
(req, res) => {
|
|
Lottery.findById(req.params?.lotteryId, (err, data) => {
|
|
if (err || !data) return res404(err)
|
|
else return res.json(data)
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.getLastLottery = [
|
|
(req, res) => {
|
|
Lottery.find({})
|
|
.sort({ _id: -1 })
|
|
.select('-participants -winnersCount')
|
|
.exec((err, data) => {
|
|
if (err || !data?.length) return res404(res, 'هیچ قرعه کشی ای در دسترس نیست')
|
|
else return res.json(data[0])
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.enrollParticipant = [
|
|
[
|
|
body('fullName')
|
|
.notEmpty()
|
|
.withMessage(_faSr.required.name)
|
|
.bail()
|
|
.isLength({ min: 4 })
|
|
.withMessage(_faSr.min_char.min4)
|
|
.bail()
|
|
.custom((value, { req }) => {
|
|
if (removeWhiteSpaces(value).length < 4) return Promise.reject(_faSr.min_char.min4)
|
|
if (removeWhiteSpaces(value).match(/^[A-Za-z]+$/g))
|
|
return Promise.reject(new Error('لطفا با حروف فارسی تایپ کنید.'))
|
|
else return true
|
|
}),
|
|
|
|
body('mobile')
|
|
.notEmpty()
|
|
.withMessage(_faSr.required.phone_number)
|
|
.bail()
|
|
.custom((value, { req }) => {
|
|
const mobileNStatus = checkMobileNumber(value)
|
|
if (!mobileNStatus) return Promise.reject(_faSr.format.phone_number)
|
|
else return Promise.resolve()
|
|
}),
|
|
|
|
body('serial')
|
|
.notEmpty()
|
|
.withMessage('شماره سریال گارانتی را وارد کنید')
|
|
.bail()
|
|
.custom(async (value, { req }) => {
|
|
try {
|
|
const serialStatus = await serialChecker(value)
|
|
if (!serialStatus) return Promise.reject(new Error('شماره سریال معتبر نمیباشد'))
|
|
else return Promise.resolve()
|
|
} catch (e) {
|
|
console.log('error in check serials for enrollLotteryController ---- error message: ', e)
|
|
return Promise.reject(new Error('مشکلی در بررسی شماره سریال پیش آمده'))
|
|
}
|
|
})
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
const { fullName, mobile, serial, lotteryId } = req.body
|
|
try {
|
|
const lottery = await Lottery.findById(lotteryId)
|
|
if (!lottery) throw new Error('incorrect lottery id')
|
|
if (lottery.expired) return res404(res, 'مهلت شرکت در قرعه کشی به پایان رسیده')
|
|
|
|
for await (const item of lottery.participants) {
|
|
if (item.serial === serial) return res404(res, 'این شماره سریال از قبل توسط شخص دیگری ثبت شده است')
|
|
}
|
|
|
|
const enrollCode = lottery.lotteryCode
|
|
.concat(lottery.participants.length)
|
|
.concat((Math.random() * 100).toFixed(0))
|
|
|
|
const normalizedMN = normalizeMobileNumber(mobile)
|
|
|
|
const data = { fullName, mobile: normalizedMN, serial, enrollCode }
|
|
lottery.participants.push(data)
|
|
lottery.markModified('participants')
|
|
await lottery.save()
|
|
|
|
await sms.lottery.enrollment(normalizedMN, fullName, enrollCode, Date.now())
|
|
return res.json({ message: 'اطلاعات شما با موفیقت در سیستم ثبت شد. کد پیگیری به تلفن همراه شما ارسال گردید' })
|
|
} catch (e) {
|
|
return res500(res, `there is an error here --- ${e}`)
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.deleteLottery = [
|
|
(req, res) => {
|
|
Lottery.findByIdAndDelete(req.params?.lotteryId, (err, oldData) => {
|
|
if (err || !oldData) return res404(res, err)
|
|
fs.unlink(`./static/${oldData.entryBgImg}`, err => {
|
|
if (err) console.log(err)
|
|
})
|
|
fs.unlink(`./static/${oldData.resultBgImg}`, err => {
|
|
if (err) console.log(err)
|
|
})
|
|
return res.json({ message: _faSr.response.success_remove })
|
|
})
|
|
}
|
|
]
|