somewhere

This commit is contained in:
Swift
2023-08-17 13:05:51 +03:30
parent 30c7eb0e7b
commit 53843207cc
429 changed files with 117489 additions and 1 deletions
@@ -0,0 +1,114 @@
const { body, validationResult } = require('express-validator')
const Announcement = require('../models/Announcement')
const { _sr } = require('../plugins/serverResponses')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { notifyAllUsers } = require('../WebSocket/controllers/user_EventsController')
const { notifyAllAgents } = require('../WebSocket/controllers/agent_EventsController')
const _faSr = _sr.fa
module.exports.create = [
[
body('title').notEmpty().withMessage(_faSr.required.title),
body('caption').notEmpty().withMessage(_faSr.required.caption),
body('expireDate')
.notEmpty()
.withMessage('تاریخ انقضا را مشخص کنید')
.bail()
.isNumeric()
.withMessage('فرمت تاریخ باید timestamp باشد')
.bail()
.custom((value, { req }) => {
if (Number(value) < Date.now()) return Promise.reject(new Error('نمیتوان تاریخ روز جاری یا قبل تر انتخاب کرد.'))
else return Promise.resolve()
}),
body('isForAgents')
.notEmpty()
.withMessage('this param is required')
.bail()
.isBoolean()
.withMessage(_faSr.format.boolean)
],
checkValidations(validationResult),
(req, res) => {
const { title, caption, expireDate, isForAgents } = req.body
const { user_id } = req
const data = { title, caption, expireDate, isForAgents, _creator: user_id }
const announcement = new Announcement(data)
announcement.save(err => {
if (err) return res500(res, err)
if (isForAgents) notifyAllAgents('fetchNewAnnouncements')
if (!isForAgents) notifyAllUsers('fetchNewAnnouncements')
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.getAllForAdmin = [
(req, res) => {
Announcement.find({}, (err, notifs) => {
if (err) return res500(res, err)
return res.json(notifs)
})
}
]
module.exports.getOneForAdmin = [
async (req, res) => {
try {
const announcement = await Announcement.findById(req.params.id)
return res.json(announcement)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.getNotifsForUsers = [
async (req, res) => {
try {
const userID = req.user_id
const announcements = await Announcement.find({ users: { $ne: userID } })
for await (const item of announcements) {
item.users.push(userID)
await item.save()
}
return res.json(announcements)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.deleteAnnouncement = [
(req, res) => {
Announcement.findByIdAndRemove(req.params.id, (err, oldData) => {
if (err || !oldData) return res404(res, err)
return res.json({ message: _faSr.response.success_remove })
})
}
]
// module.exports.updateByAdmin = [
// [
// body('title')
// .notEmpty().withMessage(_faSr.required.title),
//
// body('caption')
// .notEmpty().withMessage(_faSr.required.caption),
// ],
// checkValidations(validationResult),
// async (req, res) => {
// try {
// const {title, caption} = req.body
// const data = {title, caption, _creator: req.user_id}
// Announcement.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
// if (err || !oldData) return res404(res, err)
// return res.json({message: _faSr.response.success_save})
// })
// } catch (e) {
// return res500(res, e)
// }
// }
// ]
@@ -0,0 +1,70 @@
/* eslint-disable node/handle-callback-err */
const axios = require('axios')
const { verityAxiosConfig, panatechAxiosConfig } = require('../ArpaWebservice')
function axiosConfig(db) {
if (db === 'verity') return verityAxiosConfig()
else if (db === 'panatech') return panatechAxiosConfig()
else return {}
}
/// //// cross server requests
module.exports.getRouteManager = [
(req, res) => {
const { url, db } = req.body
axios
.get(url, axiosConfig(db))
.then(arpaRes => {
if (arpaRes.data.error) return res.status(404).json(arpaRes.data.error)
else return res.json(arpaRes.data)
})
.catch(err => {
// console.log('🚀 ~ file: arpaConnectionController.js ~ getRouteManager ~ err', err)
return res.status(500).json({ message: 'WebService Error' })
})
}
]
module.exports.postRouteManager = [
(req, res) => {
const { url, db, data } = req.body
axios
.post(url, data, axiosConfig(db))
.then(arpaRes => {
if (arpaRes.data.error) return res.status(404).json(arpaRes.data.error)
else return res.json(arpaRes.data)
})
.catch(err => {
// console.log('🚀 ~ file: arpaConnectionController.js ~ postRouteManager ~ err', err)
return res.status(500).json({ message: 'WebService Error' })
})
}
]
module.exports.putRouteManager = [
(req, res) => {
const { url, db, data } = req.body
axios
.put(url, data, axiosConfig(db))
.then(arpaRes => {
if (arpaRes.data.error) return res.status(404).json(arpaRes.data.error)
else return res.json(arpaRes.data)
})
.catch(err => {
// console.log('🚀 ~ file: arpaConnectionController.js ~ putRouteManager ~ err', err)
return res.status(500).json({ message: 'WebService Error' })
})
}
]
module.exports.deleteRouteManager = [
(req, res) => {
const { url, db, data } = req.body
axios
.delete(url, data, axiosConfig(db))
.then(arpaRes => {
if (arpaRes.data.error) return res.status(404).json(arpaRes.data.error)
else return res.json(arpaRes.data)
})
.catch(err => {
// console.log('🚀 ~ file: arpaConnectionController.js ~ deleteRouteManager ~ err', err)
return res.status(500).json({ message: 'WebService Error' })
})
}
]
@@ -0,0 +1,335 @@
const moment = require('moment-jalaali')
const { body, validationResult } = require('express-validator')
const BufferRequest = require('../models/BufferRequest')
const { _sr } = require('../plugins/serverResponses')
const {
res404,
res406,
res500,
checkValidations,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
// const { phrases } = require('../plugins/SMS_Phrases')
// const { notifyAgent } = require('../WebSocket/controllers/agent_EventsController')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const _faSr = _sr.fa
// date formaters
function ArpaDateFormat(date) {
return moment(date).format('YYYY-MM-DD HH:mm:ss')
}
function SmsDateFormat(date) {
return moment(date).format('jYYYY/jMM/jDD')
}
/// ///////////////// agent
module.exports.add_buffer_request = [
async (req, res) => {
try {
const { user_id, agent_id } = req
const thisTime = Date.now()
const data = {
user_id,
agent_id,
createDate: ArpaDateFormat(thisTime),
statusHistory: [{ status: 'temp', date: thisTime }]
}
const br = BufferRequest(data)
await br.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.add_buffer_to_br = [
[
body('ItemName').notEmpty().withMessage('نام کالا را مشخص کنید'),
body('ItemID').notEmpty().withMessage('Include ItemID'),
body('ItemCode').notEmpty().withMessage('Include ItemCode'),
body('bufferQuantity')
.notEmpty()
.withMessage('تعداد قطعه را مشخص کنید')
.isNumeric()
.withMessage(_faSr.format.number)
],
checkValidations(validationResult),
async (req, res) => {
try {
const brId = req.params?.brId
const { ItemName, ItemID, ItemCode, bufferQuantity } = req.body
const data = {
ItemName,
ItemID,
ItemCode,
bufferQuantity
}
const br = await BufferRequest.findById(brId)
br.items.push(data)
await br.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res404(res, e)
}
}
]
module.exports.remove_buffer_from_br = [
async (req, res) => {
try {
const bufferItemId = req.params?.bufferItemId
if (!bufferItemId) throw new Error('invalid id')
const br = await BufferRequest.findOne({ 'items._id': bufferItemId })
br.items.id(bufferItemId).remove()
await br.save()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
console.log(e)
return res500(res, e)
}
}
]
module.exports.update_br_description = [
(req, res) => {
const { description } = req.body
const data = {
description
}
BufferRequest.findByIdAndUpdate(req.params?.id, data, (err, oldData) => {
if (err) return res404(res, 'invalid id')
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.get_all_br_for_agent = [
(req, res) => {
const agent_id = req.agent_id
BufferRequest.find({ agent_id }, (err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.get_one_br_for_agent = [
(req, res) => {
BufferRequest.findById(req.params.id)
.populate(
'agent_id',
'full_name province_name city_name address agent_code postal_code tel_number fax_number mobile_number'
)
.exec((err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.delete_br = [
async (req, res) => {
try {
const br = await BufferRequest.findById(req.params?.id)
if (br.status !== 'temp') return res406(res, 'نمیتوانید درخواست ارسال شده را حذف کنید')
await br.remove()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
return res404(res, 'invalid id')
}
}
]
module.exports.change_br_status_to_sent_by_agent = [
async (req, res) => {
try {
const thisTime = Date.now()
const br = await BufferRequest.findById(req.params?.id).populate('agent_id')
if (!br) throw new Error('invalid br id')
const totalBr = await BufferRequest.find({ status: { $ne: 'temp' } })
if (br.status !== 'temp') return res406(res, 'این فرم قبلا برای آسان سرویس ارسال شده')
if (!br.items.length) return res406(res, 'هیچ قطعه ای به فرم اضافه نکرده اید')
// generate tracking code
const trackingCode = 'BP' + totalBr.length.toString().padStart(4, '0') + generateRandomDigits(2)
// modify br
br.status = 'sent'
br.statusHistory.push({ status: 'sent', date: thisTime })
br.trackingCode = trackingCode
br.sendDate = ArpaDateFormat(thisTime)
// send sms for agent
const smsMsg = [
' نماینده گرامی درخواست کالای بافر شما در تاریخ ',
SmsDateFormat(thisTime),
' با کد پیگیری ',
trackingCode,
' برای شرکت ارسال شد. '
]
SMS([br.agent_id.mobile_number], smsMsg.join(''))
await br.save()
notifyAdmin('updateNewBufferRequests')
return res.json({ message: 'درخواست کالای بافر ارسال شد' })
} catch (e) {
console.log(e)
return res404(res, e)
}
}
]
/// ///////////////// admin
module.exports.get_all_br_for_admin = [
async (req, res) => {
try {
const brList = await BufferRequest.find({
status: { $ne: 'temp' }
}).populate(
'agent_id',
'full_name agent_code mobile_number national_code province_name city_name province_id city_id'
)
return res.json(brList)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_oneAgent_br_for_admin = [
async (req, res) => {
const agent_id = req.params?.agent_id
try {
const brList = await BufferRequest.find({
status: { $ne: 'temp' },
agent_id
}).populate('agent_id', 'full_name agent_code mobile_number national_code province_name city_name')
return res.json(brList)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_one_br_for_admin = [
async (req, res) => {
try {
const { user_id } = req
const thisTime = Date.now()
const br = await BufferRequest.findById(req.params?.id)
.populate(
'agent_id',
'agent_code full_name mobile_number fax_number tel_number province_name city_name national_code address postal_code store_name'
)
.populate('_openedBy', 'username first_name last_name')
.populate('_updatedBy', 'username first_name last_name')
if (!br.seen) {
br.seen = true
br._openedBy = user_id
br.status = 'ongoing'
br.statusHistory.push({ status: 'ongoing', date: thisTime })
await br.save()
const smsMsg = [
' نماینده گرامی درخواست کالای بافر شما با کد پیگیری ',
br.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' در دست اقدام قرار گرفت. '
]
SMS([br.agent_id.mobile_number], smsMsg.join(''))
notifyAdmin('updateNewBufferRequests')
}
return res.json(br)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.change_br_status_by_admin = [
[
body('status')
.notEmpty()
.withMessage('status is required')
.bail()
.custom((value, { req }) => {
const acceptablvalues = ['waiting', 'delivered']
if (!acceptablvalues.includes(value)) return Promise.reject(new Error('invalid status'))
else return true
})
],
checkValidations(validationResult),
async (req, res) => {
const { user_id } = req
const { status, deliveryCode } = req.body
const thisTime = Date.now()
try {
const br = await BufferRequest.findById(req.params?.id).populate('agent_id')
if (!br) throw new Error('invalid br id')
// check statuses
const statusErrMsg = 'invalid status for this time'
if (br.status === 'delivered') return res406(res, statusErrMsg)
if (br.status === 'waiting' && status === 'waiting') return res406(res, statusErrMsg)
// save status
br._updatedBy = user_id
br.status = status
br.statusHistory.push({ status, date: thisTime })
let smsMessage
// differenet status methods
if (status === 'waiting') {
smsMessage = [
' نماینده گرامی درخواست کالای بافر شما با کد پیگیری ',
br.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' در انتظار قطعه میباشد. '
]
}
if (status === 'delivered') {
if (deliveryCode) br.deliveryCode = deliveryCode
function deliveryCodePhrase() {
if (deliveryCode.length) return `کد پیگیری مرسوله: ${deliveryCode}` + '\n'
else return ''
}
smsMessage = [
' نماینده گرامی درخواست کالای بافر شما با کد پیگیری ',
br.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' تحویل شد. ',
'\n',
deliveryCodePhrase()
]
}
await SMS([br.agent_id.mobile_number], smsMessage.join(''))
await br.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
@@ -0,0 +1,68 @@
const { body, validationResult } = require('express-validator')
const ContactPageMessage = require('../models/ContactPageMessage')
const { _sr } = require('../plugins/serverResponses')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const { res404 } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
module.exports.create = [
[
body('full_name')
.notEmpty()
.withMessage(_faSr.required.name)
.bail()
.isLength({ min: 2 })
.withMessage(_faSr.min_char.min2),
body('email').notEmpty().withMessage(_faSr.required.email).bail().isEmail().withMessage(_faSr.format.email),
body('message').isLength({ min: 20 }).withMessage(_faSr.min_char.min20)
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({ validation: errors.mapped() })
const data = {
full_name: req.body.full_name,
email: req.body.email,
message: req.body.message
}
const message = new ContactPageMessage(data)
message.save((err, message) => {
if (err) console.log(err)
notifyAdmin('updateUnreadCuMsgs')
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.getAll = [
(req, res) => {
ContactPageMessage.find({})
.select('-message')
.then(messages => {
return res.json(messages)
})
.catch(err => {
return res.status(500).json({ message: err })
})
}
]
module.exports.getOne = [
async (req, res) => {
try {
const message = await ContactPageMessage.findById(req.params.id).populate('read_by', 'first_name last_name')
if (!message.read) {
message.read_by = req.user_id
message.read = true
await message.save()
notifyAdmin('updateUnreadCuMsgs')
}
return res.json(message)
} catch (e) {
return res404(res, _faSr.not_found.item_id)
}
}
]
@@ -0,0 +1,96 @@
const { body, validationResult } = require('express-validator')
const DownloadCategory = require('../models/download/DownloadCategory')
const Download = require('../models/download/Download')
const { _sr } = require('../plugins/serverResponses')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
module.exports.create = [
[
body('name')
.notEmpty()
.withMessage(_faSr.required.name)
.bail()
.custom((value, { req }) => {
return DownloadCategory.findOne({ name: value }).then(category => {
if (category) return Promise.reject(_faSr.duplicated.name)
else return true
})
})
],
checkValidations(validationResult),
(req, res) => {
const data = {
_creator: req.user_id,
name: req.body.name
}
const dCategory = new DownloadCategory(data)
dCategory.save(err => {
if (err) console.log(err)
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.getAll = [
(req, res) => {
DownloadCategory.find({}, (err, categories) => {
if (err) return res500(res, err)
return res.json(categories)
})
}
]
module.exports.getOne = [
(req, res) => {
DownloadCategory.findById(req.params?.id)
.populate('_creator', 'first_name last_name')
.exec((err, category) => {
if (err) return res404(res, err)
return res.json(category)
})
}
]
module.exports.update = [
[
body('name')
.notEmpty()
.withMessage(_faSr.required.name)
.bail()
.custom((value, { req }) => {
return DownloadCategory.findOne({ name: value }).then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject(_faSr.duplicated.name)
else return true
})
})
],
checkValidations(validationResult),
(req, res) => {
const data = {
_creator: req.user_id,
name: req.body.name
}
DownloadCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) return res404(res, err)
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.delete = [
(req, res) => {
Download.findOne({ category: req.params.id }, (err, item) => {
if (err) return res404(res, err)
if (item) return res.status(403).json({ message: 'این دسته بندی دارای آیتم میباشد.' })
else {
DownloadCategory.findByIdAndDelete(req.params.id, (err, category) => {
if (err) return res404(res, err)
return res.json({ message: _faSr.response.success_remove })
})
}
})
}
]
+267
View File
@@ -0,0 +1,267 @@
const fs = require('fs')
const mongoose = require('mongoose')
const { body, validationResult } = require('express-validator')
const jimp = require('jimp')
const Download = require('../models/download/Download')
const DownloadCategory = require('../models/download/DownloadCategory')
const { _sr } = require('../plugins/serverResponses')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
const imageWidth = 400
const imageHeight = 400
const imageQuality = 100
const shortDescriptionLength = 200
const paginateLimit = 8
module.exports.create = [
[
body('title')
.notEmpty()
.withMessage(_faSr.required.title)
.bail()
.custom((value, { req }) => {
return Download.findOne({ title: value }).then(item => {
if (item) return Promise.reject(_faSr.duplicated.title)
else return true
})
}),
body('short_description').notEmpty().withMessage(_faSr.required.description),
body('description').notEmpty().withMessage(_faSr.required.description),
body('category').notEmpty().withMessage(_faSr.required.category)
],
checkValidations(validationResult),
(req, res) => {
if (!req.files || !req.files.image)
return res.status(422).json({ validation: { image: { msg: _faSr.required.image } } })
const data = {
_creator: req.user_id,
title: req.body.title,
short_description: req.body.short_description.slice(0, shortDescriptionLength),
description: req.body.description,
category: req.body.category
}
const image = req.files.image
// validate image format
const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
if (!supportedFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { image: { msg: _faSr.format.image } } })
}
const imageName = 'download_' + Date.now() + '.' + image.mimetype.split('/')[1]
data.image = imageName
jimp
.read(image.data)
.then(img => {
img.cover(imageWidth, imageHeight)
img.quality(imageQuality)
img.write(`./static/uploads/images/downloads/${imageName}`, err => {
if (err) console.log(err)
})
})
.catch(err => {
console.log(err)
})
const download = new Download(data)
download.save((err, data) => {
if (err) console.log(err)
return res.json(data)
})
}
]
module.exports.getAll = [
async (req, res) => {
try {
if (req.params.category === 'all') {
const downloads = await Download.paginate({}, { page: req.params.page, limit: paginateLimit })
if (!downloads.docs.length && Number(req.params.page) !== 1)
return res.status(404).json({ message: _faSr.not_found.item_id })
return res.json(downloads)
} else {
let catID
if (mongoose.isValidObjectId(req.params.category)) catID = req.params.category
else {
const category = await DownloadCategory.findOne({ name: req.params.category })
if (!category) return res.status(404).json({ message: _faSr.not_found.item_id })
catID = category._id
}
const downloads = await Download.paginate({ category: catID }, { page: req.params.page, limit: paginateLimit })
if (!downloads.docs.length && Number(req.params.page) !== 1)
return res.status(404).json({ message: _faSr.not_found.item_id })
return res.json(downloads)
}
} catch (e) {
return res.status(404).json({ message: _faSr.not_found.item_id })
}
}
]
module.exports.getNewest = [
(req, res) => {
Download.find({})
.sort({ _id: -1 })
.limit(3)
.exec((err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getOne = [
(req, res) => {
const query = {}
if (mongoose.isValidObjectId(req.params.id)) query._id = req.params.id
else query.title = req.params.id
Download.findOne(query)
.populate('_creator', 'first_name last_name')
.exec((err, item) => {
if (err) return res.status(404).json({ message: err })
return res.json(item)
})
}
]
module.exports.update = [
[
body('title')
.notEmpty()
.withMessage(_faSr.required.title)
.bail()
.custom((value, { req }) => {
return Download.findOne({ title: value }).then(item => {
if (item && item._id.toString() !== req.params.id) return Promise.reject(_faSr.duplicated.title)
else return true
})
}),
body('short_description').notEmpty().withMessage(_faSr.required.description),
body('description').notEmpty().withMessage(_faSr.required.description),
body('category').notEmpty().withMessage(_faSr.required.category)
],
checkValidations(validationResult),
(req, res) => {
const data = {
_creator: req.user_id,
title: req.body.title,
short_description: req.body.short_description.slice(0, shortDescriptionLength),
description: req.body.description,
category: req.body.category
}
if (req.files && req.files.image) {
const image = req.files.image
// validate image format
const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
if (!supportedFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { image: { msg: _faSr.format.image } } })
}
const imageName = 'download_' + Date.now() + '.' + image.mimetype.split('/')[1]
data.image = imageName
jimp
.read(image.data)
.then(img => {
img.cover(imageWidth, imageHeight)
img.quality(imageQuality)
img.write(`./static/uploads/images/downloads/${imageName}`, err => {
if (err) console.log(err)
})
})
.catch(err => {
console.log(err)
})
}
Download.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) return res.status(404).json({ message: _faSr.not_found.item_id })
if (req.files && req.files.image) {
fs.unlink(`./static/${oldData.image}`, err => {
if (err) console.log(err)
})
}
Download.findById(oldData._id, (err, result) => {
if (err) return res.status(404).json({ message: _faSr.not_found.item_id })
return res.json(result)
})
})
}
]
module.exports.delete = [
(req, res) => {
Download.findByIdAndDelete(req.params.id, (err, data) => {
if (err) return res.status(404).json({ message: _faSr.not_found.item_id })
data.files.forEach(item => {
fs.unlink(`./static/${item.file}`, err => {
if (err) console.log(err)
})
})
return res.json({ message: _faSr.response.success_remove })
})
}
]
/// /////////////////////////////////////////////////////////// add files
module.exports.addFile = [
[
body('name').notEmpty().withMessage(_faSr.required.name),
body('os').notEmpty().withMessage(_faSr.required.category)
],
checkValidations(validationResult),
(req, res) => {
if (!req.files || !req.files.file)
return res.status(422).json({ validation: { file: { msg: _faSr.required.file } } })
const file = req.files.file
const fileName = 'AsanService-' + Math.ceil(Math.random() * 1000) + '_' + file.name
file.mv(`./static/uploads/apps/${fileName}`)
const data = {
_creator: req.user_id,
name: req.body.name,
os: req.body.os,
file: fileName
}
Download.findById(req.body.page_id, (err, page) => {
if (err || !page) return res404(res, err)
page.files.push(data)
page.save(err => {
if (err) console.log(err)
return res.json(page.files)
})
})
}
]
module.exports.deletFile = [
(req, res) => {
Download.findOne({ 'files._id': req.params.id }, (err, page) => {
if (err || !page) return res404(res, err)
const app = page.files.id(req.params.id)
app.remove(err => {
if (err) console.log(err)
fs.unlink(`./static/${app.file}`, err => {
if (err) console.log(err)
})
})
page.save(err => {
if (err) console.log(err)
return res.json({ message: _faSr.response.success_remove })
})
})
}
]
+76
View File
@@ -0,0 +1,76 @@
const { body, validationResult } = require('express-validator')
const FAQ = require('../models/FAQ')
const { _sr } = require('../plugins/serverResponses')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
module.exports.create = [
[
body('question').notEmpty().withMessage(_faSr.required.question),
body('answer').notEmpty().withMessage(_faSr.required.answer)
],
checkValidations(validationResult),
(req, res) => {
const data = {
_creator: req.user_id,
question: req.body.question,
answer: req.body.answer
}
const faq = new FAQ(data)
faq.save(cb => {
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.getAll = [
(req, res) => {
FAQ.find({}, (err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getOne = [
(req, res) => {
FAQ.findById(req.params.id)
.populate('_creator', 'first_name last_name')
.exec((err, data) => {
if (err) return res.status(404).json({ message: err })
return res.json(data)
})
}
]
module.exports.update = [
[
body('question').notEmpty().withMessage(_faSr.required.question),
body('answer').notEmpty().withMessage(_faSr.required.answer)
],
checkValidations(validationResult),
(req, res) => {
const data = {
_creator: req.user_id,
question: req.body.question,
answer: req.body.answer
}
FAQ.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) return res404(res, err)
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.delete = [
(req, res) => {
FAQ.findByIdAndDelete(req.params.id, (err, oldData) => {
if (err) return res.status(404).json({ message: err })
return res.json({ message: _faSr.response.success_remove })
})
}
]
@@ -0,0 +1,334 @@
const moment = require('moment-jalaali')
const { body, validationResult } = require('express-validator')
const GuaranteeReport = require('../models/GuaranteeReport')
const { _sr } = require('../plugins/serverResponses')
const {
res404,
res406,
res500,
checkValidations,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const _faSr = _sr.fa
// date formaters
function ArpaDateFormat(date) {
return moment(date).format('YYYY-MM-DD HH:mm:ss')
}
function SmsDateFormat(date) {
return moment(date).format('jYYYY/jMM/jDD')
}
/// ///////////////// agent
module.exports.add_guaranteeReport = [
async (req, res) => {
try {
const { user_id, agent_id } = req
const thisTime = Date.now()
const data = {
user_id,
agent_id,
createDate: ArpaDateFormat(thisTime)
}
const gr = GuaranteeReport(data)
await gr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.add_report_to_gr = [
[
body('customerTel').notEmpty().withMessage('شماره تماس مشتری را وارد کنید'),
body('ItemName').notEmpty().withMessage('نام کالا را مشخص کنید'),
body('ItemID').notEmpty().withMessage('Include ItemID'),
body('ItemCode').notEmpty().withMessage('Include ItemCode'),
body('productIssue').notEmpty().withMessage('ایراد کالا را وارد کنید'),
body('usedPieces').notEmpty().withMessage('قطعات مصرفی را وارد کنید'),
body('recieveDate').notEmpty().withMessage('تاریخ دریافت از مشتری را مشخص کنید'),
body('deliverDate')
.notEmpty()
.withMessage('تاریخ تحویل به مشتری را مشخص کنید')
.bail()
.custom((value, { req }) => {
function timeStamp(date) {
return Number(moment(date).format('x'))
}
const start = timeStamp(req.body.recieveDate)
const end = timeStamp(value)
if (end < start)
return Promise.reject(new Error('تاریخ تحویل به مشتری نباید از تاریخ دریافت از مشتری کوچکتر باشد'))
else return true
})
],
checkValidations(validationResult),
async (req, res) => {
try {
const grId = req.params?.grId
const {
customerName,
customerTel,
ItemName,
SerialNo1,
ItemID,
ItemCode,
productIssue,
usedPieces,
recieveDate,
deliverDate
} = req.body
const data = {
customerName,
customerTel,
ItemName,
SerialNo1,
ItemID,
ItemCode,
productIssue,
usedPieces,
recieveDate,
deliverDate
}
const gr = await GuaranteeReport.findById(grId)
gr.items.push(data)
await gr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res404(res, e)
}
}
]
module.exports.remove_report_from_gr = [
async (req, res) => {
try {
const reportItemId = req.params?.reportItemId
if (!reportItemId) throw new Error('invalid id')
const gr = await GuaranteeReport.findOne({ 'items._id': reportItemId })
gr.items.id(reportItemId).remove()
await gr.save()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.update_gr_description = [
(req, res) => {
const { description } = req.body
const data = {
description
}
GuaranteeReport.findByIdAndUpdate(req.params?.id, data, (err, oldData) => {
if (err) return res404(res, 'invalid id')
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.get_all_gr_for_agent = [
(req, res) => {
const { agent_id } = req
GuaranteeReport.find({ agent_id }, (err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.get_one_gr_for_agent = [
(req, res) => {
GuaranteeReport.findById(req.params?.id)
.populate(
'agent_id',
'full_name province_name city_name address agent_code postal_code tel_number fax_number mobile_number'
)
.exec((err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.delete_gr = [
async (req, res) => {
try {
const gr = await GuaranteeReport.findById(req.params?.id)
if (gr.status !== 'temp') return res406(res, 'نمیتوانید درخواست ارسال شده را حذف کنید')
await gr.remove()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
return res404(res, 'invalid id')
}
}
]
module.exports.change_gr_status_to_sent_by_agent = [
async (req, res) => {
try {
const thisTime = Date.now()
const gr = await GuaranteeReport.findById(req.params?.id).populate('agent_id')
if (!gr) throw new Error('invalid gr id')
const totalGr = await GuaranteeReport.find({ status: { $ne: 'temp' } })
if (gr.status !== 'temp') return res406(res, 'این فرم قبلا برای آسان سرویس ارسال شده')
if (!gr.items.length) return res406(res, 'هیچ آیتمی ای به فرم اضافه نکرده اید')
// generate tracking code
const trackingCode = 'GR' + totalGr.length.toString().padStart(4, '0') + generateRandomDigits(2)
// modify gr
gr.status = 'sent'
gr.trackingCode = trackingCode
gr.sendDate = ArpaDateFormat(thisTime)
// send sms for agent
const smsMsg = [
' نماینده گرامی فرم گزارش عملکرد گارانتی شما در تاریخ ',
SmsDateFormat(thisTime),
' با کد پیگیری ',
trackingCode,
' برای شرکت ارسال شد. '
]
SMS([gr.agent_id.mobile_number], smsMsg.join(''))
await gr.save()
notifyAdmin('updateNewGuaranteeReports')
return res.json({ message: 'فرم گزارش عملکرد گارانتی ارسال شد' })
} catch (e) {
console.log(e)
return res404(res, e)
}
}
]
/// ///////////////// admin
module.exports.get_all_gr_for_admin = [
async (req, res) => {
try {
const grList = await GuaranteeReport.find({ status: { $ne: 'temp' } }).populate(
'agent_id',
'full_name agent_code mobile_number national_code province_name city_name province_id city_id'
)
return res.json(grList)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_one_gr_for_admin = [
async (req, res) => {
try {
const { user_id } = req
const gr = await GuaranteeReport.findById(req.params?.id)
.populate(
'agent_id',
'agent_code full_name mobile_number fax_number tel_number province_name city_name national_code address postal_code store_name'
)
.populate('_openedBy', 'username first_name last_name')
.populate('_updatedBy', 'username first_name last_name')
if (!gr.seen) {
gr._openedBy = user_id
gr.seen = true
await gr.save()
notifyAdmin('updateNewGuaranteeReports')
}
return res.json(gr)
} catch (e) {
return res500(res, e)
}
}
]
// module.exports.change_gr_status_by_admin = [
// [
// body('status')
// .notEmpty()
// .withMessage('status is required')
// .bail()
// .custom((value, { req }) => {
// acceptablvalues = ['waiting', 'delivered']
// if (!acceptablvalues.includes(value)) return Promise.reject('invalid status')
// else return true
// })
// ],
// checkValidations(validationResult),
// async (req, res) => {
// const { user_id } = req
// const { status, deliveryCode } = req.body
// const thisTime = Date.now()
// try {
// const gr = await GuaranteeReport.findById(req.params?.id).populate('agent_id')
// if (!gr) throw 'invalid gr id'
// // check statuses
// const statusErrMsg = 'invalid status for this time'
// if (gr.status === 'delivered') return res406(res, statusErrMsg)
// if (gr.status === 'waiting' && status === 'waiting') return res406(res, statusErrMsg)
// // save status
// gr._updatedBy = user_id
// gr.status = status
// gr.statusHistory.push({ status: status, date: thisTime })
// let smsMessage
// // differenet status methods
// if (status === 'waiting') {
// smsMessage = [
// ' نماینده گرامی درخواست قطعه شما با کد پیگیری ',
// gr.trackingCode,
// ' در تاریخ ',
// SmsDateFormat(thisTime),
// ' در انتظار قطعه میباشد. '
// ]
// }
// if (status === 'delivered') {
// if (deliveryCode) gr.deliveryCode = deliveryCode
// function deliveryCodePhrase() {
// if (deliveryCode.length) return `کد پیگیری مرسوله: ${deliveryCode}` + '\n'
// else return ''
// }
// smsMessage = [
// ' نماینده گرامی درخواست قطعه شما با کد پیگیری ',
// gr.trackingCode,
// ' در تاریخ ',
// SmsDateFormat(thisTime),
// ' تحویل شد. ',
// '\n',
// deliveryCodePhrase()
// ]
// }
// await SMS([gr.agent_id.mobile_number], smsMessage.join(''))
// await gr.save()
// return res.json({ message: _faSr.response.success_save })
// } catch (e) {
// return res500(res, e)
// }
// }
// ]
+49
View File
@@ -0,0 +1,49 @@
const Help = require('../models/Help')
const { _sr } = require('../plugins/serverResponses')
const { res500 } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
module.exports.set = [
async (req, res) => {
const { helpId } = req.body
try {
const help = await Help.findOne()
if (help) {
help.helpId = helpId
help._creator = req.user_id
await help.save()
return res.json({ message: _faSr.response.success_save })
} else {
const help = new Help({
helpId,
_creator: req.user_id
})
help.save()
return res.json({ message: _faSr.response.success_save })
}
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get = [
(req, res) => {
const front = req.query?.front
if (front) {
Help.findOne({})
.populate('helpId', '_id title')
.exec((err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
} else {
Help.findOne({})
.populate('_creator', 'first_name last_name')
.exec((err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
}
]
@@ -0,0 +1,7 @@
const { iranCities } = require('../plugins/iranCities')
module.exports.getIranCities = [
(req, res) => {
return res.json(iranCities)
}
]
+247
View File
@@ -0,0 +1,247 @@
const fs = require('fs')
const mongoose = require('mongoose')
const { body, validationResult } = require('express-validator')
const jimp = require('jimp')
const Learning = require('../models/Learning')
const { _sr } = require('../plugins/serverResponses')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
//
const coverWidth = 1300
const coverHeight = 620
const thumbWidth = 636
const thumbHeight = 400
const coverQuality = 80
// const coverThumbQuality = 100
const shortDescriptionLength = 260
const paginateLimit = 5
module.exports.create = [
[
// title
body('title')
.notEmpty()
.withMessage(_faSr.required.title)
.custom((value, { req }) => {
return Learning.findOne({ title: value }).then(post => {
if (post) return Promise.reject(_faSr.duplicated.title)
return true
})
}),
// description
body('description').notEmpty().withMessage(_faSr.required.description),
// short description
body('short_description').notEmpty().withMessage(_faSr.required.description)
],
checkValidations(validationResult),
(req, res) => {
if (!req.files || !req.files.cover)
return res.status(422).json({ validation: { cover: { msg: _faSr.required.cover } } })
const data = {
_creator: req.user_id,
title: req.body.title,
description: req.body.description,
short_description: req.body.short_description.slice(0, shortDescriptionLength) + ' ... '
}
if (req.files && req.files.cover) {
const cover = req.files.cover
// validate image format
const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
if (!supportedFormats.includes(cover.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { cover: { msg: _faSr.format.image } } })
}
const coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1]
data.cover = data.thumb = coverName
jimp
.read(cover.data)
.then(img => {
img
.cover(coverWidth, coverHeight)
.quality(coverQuality)
.write(`./static/uploads/images/blog/${coverName}`)
.resize(thumbWidth, jimp.AUTO)
.cover(thumbWidth, thumbHeight)
.write(`./static/uploads/images/blog/thumb/${coverName}`)
})
.catch(err => {
console.log(err)
})
}
if (req.files && req.files.video) {
const video = req.files.video
// validate video format
const supportedFormats = ['mp4', 'avi', 'wmv']
if (!supportedFormats.includes(video.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { video: { msg: _faSr.format.video } } })
}
const videoName = 'blog_' + Date.now() + '.' + video.mimetype.split('/')[1]
data.video = videoName
video.mv(`./static/uploads/videos/${videoName}`, err => {
if (err) console.log(err)
})
}
const post = new Learning(data)
post.save(err => {
if (err) console.log(err)
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.getAll = [
(req, res) => {
const page = req.params?.page
if (page === 'all') {
Learning.find({}, (err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
} else {
Learning.paginate({}, { page: page || 1, limit: paginateLimit, sort: { _id: -1 } }, (err, data) => {
if (err) return res500(res, err)
if (!data.docs.length && Number(req.params.page) !== 1)
return res.status(404).json({ message: _faSr.not_found.item_id })
else return res.json(data)
})
}
}
]
module.exports.getOne = [
(req, res) => {
const query = {}
if (mongoose.isValidObjectId(req.params.id)) query._id = req.params.id
else query.title = req.params.id
Learning.findOne(query)
.populate('_creator', 'first_name last_name')
.exec((err, post) => {
if (err || !post) return res404(res, err)
return res.json(post)
})
}
]
module.exports.update = [
[
// title
body('title')
.notEmpty()
.withMessage(_faSr.required.title)
.custom((value, { req }) => {
return Learning.findOne({ title: value }).then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject(_faSr.duplicated.title)
return true
})
}),
// description
body('description').notEmpty().withMessage(_faSr.required.description),
// short description
body('short_description').notEmpty().withMessage(_faSr.required.description)
],
checkValidations(validationResult),
(req, res) => {
const data = {
_creator: req.user_id,
title: req.body.title,
description: req.body.description,
short_description: req.body.short_description.slice(0, shortDescriptionLength) + ' ... '
}
if (req.files && req.files.cover) {
const cover = req.files.cover
// validate image format
const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
if (!supportedFormats.includes(cover.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { cover: { msg: _faSr.format.image } } })
}
const coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1]
data.cover = data.thumb = coverName
jimp
.read(cover.data)
.then(img => {
img
.cover(coverWidth, coverHeight)
.quality(coverQuality)
.write(`./static/uploads/images/blog/${coverName}`)
.resize(thumbWidth, jimp.AUTO)
.cover(thumbWidth, thumbHeight)
.write(`./static/uploads/images/blog/thumb/${coverName}`)
})
.catch(err => {
console.log(err)
})
}
if (req.files && req.files.video) {
const video = req.files.video
// validate video format
const supportedFormats = ['mp4', 'avi', 'wmv']
if (!supportedFormats.includes(video.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { video: { msg: _faSr.format.video } } })
}
const videoName = 'blog_' + Date.now() + '.' + video.mimetype.split('/')[1]
data.video = videoName
video.mv(`./static/uploads/videos/${videoName}`, err => {
if (err) console.log(err)
})
}
Learning.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) return res404(res, err)
if (req.files && req.files.cover) {
fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, err => {
if (err) console.log(err)
})
}
if (req.files && req.files.video && oldData.video)
fs.unlink(`./static/${oldData.video}`, err => {
if (err) console.log(err)
})
Learning.findById(oldData._id, (err, newData) => {
if (err) return res404(res, err)
return res.json(newData)
})
})
}
]
module.exports.delete = [
(req, res) => {
Learning.findByIdAndDelete(req.params.id, (err, post) => {
if (err) return res.status(404).json({ message: err })
fs.unlink(`./static/${post.cover}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${post.thumb}`, err => {
if (err) console.log(err)
})
if (post.video)
fs.unlink(`./static/${post.video}`, err => {
if (err) console.log(err)
})
return res.json({ message: _faSr.response.success_remove })
})
}
]
+373
View File
@@ -0,0 +1,373 @@
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 { phrases } = require('../plugins/SMS_Phrases')
///
const _faSr = _sr.fa
// date formaters
function SmsDateFormat(date) {
return moment(date).format('jYYYY/jMM/jDD')
}
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()
const msg = [
fullName,
' عزیز، اطلاعات شما در تاریخ ',
SmsDateFormat(Date.now()),
' برای شرکت در قرعه کشی آسان سرویس ثبت گردید. ',
'\n',
'کد پیگیری: ',
enrollCode,
'\n',
phrases.signature
]
SMS([normalizedMN], msg.join(''))
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 })
})
}
]
@@ -0,0 +1,108 @@
const fs = require('fs')
const jimp = require('jimp')
const { body, validationResult } = require('express-validator')
const LotteryPopUp = require('../models/LotteryPopUp')
const { _sr } = require('../plugins/serverResponses')
const { res500, checkValidations } = require('../plugins/controllersHelperFunctions')
///
const _faSr = _sr.fa
module.exports.modify = [
[
body('visible').exists().withMessage(_faSr.required.field).bail().isBoolean().withMessage(_faSr.format.boolean),
body('x').exists().withMessage(_faSr.required.field).bail().isNumeric().withMessage(_faSr.format.number),
body('y').exists().withMessage(_faSr.required.field).bail().isNumeric().withMessage(_faSr.format.number)
],
checkValidations(validationResult),
async (req, res) => {
const { visible, x, y } = req.body
let imageName = null
// check for background image
if (req.files?.bgImg) {
const image = req.files.bgImg
// validate image format
if (image.mimetype.split('/')[1] !== 'png') {
return res.status(422).json({ validation: { bgImg: { msg: 'فقط فرمت png قابل قبول است' } } })
}
imageName = 'popupBtn_' + Date.now() + '.png'
jimp
.read(image.data)
.then(img => {
img.quality(100).write(`./static/uploads/images/lottery/${imageName}`)
})
.catch(err => {
console.log(err)
})
}
try {
const lotteryPopUp = await LotteryPopUp.findOne()
if (!lotteryPopUp) {
const data = {
visible,
x,
y
}
if (imageName) {
data.bgImg = imageName
// get width & height from image
const imageDimensions = await jimp.read(`./static/uploads/images/lottery/${imageName}`)
data.w = imageDimensions.bitmap.width
data.h = imageDimensions.bitmap.height
}
await LotteryPopUp.create(data)
return res.json({ message: _faSr.response.success_save })
} else {
if (imageName) {
lotteryPopUp.bgImg &&
fs.unlink(`./static/${lotteryPopUp.bgImg}`, err => {
if (err) console.log(err)
})
lotteryPopUp.bgImg = imageName
}
lotteryPopUp.visible = visible
lotteryPopUp.x = x
lotteryPopUp.y = y
// get width & height from image
const imageDimensions = await jimp.read(`./static/${lotteryPopUp.bgImg}`)
lotteryPopUp.w = imageDimensions.bitmap.width
lotteryPopUp.h = imageDimensions.bitmap.height
await lotteryPopUp.save()
return res.json({ message: _faSr.response.success_save })
}
} catch (e) {
return res500(res, `there is an error here --- ${e}`)
}
}
]
module.exports.getPopUpInfo = [
async (req, res) => {
try {
const lotterPopUp = await LotteryPopUp.findOne()
return res.json(
lotterPopUp || {
visible: false,
x: 15,
y: 15,
w: 40,
h: 40
}
)
} catch (e) {
return res500(res, `there is an error here --- ${e}`)
}
}
]
@@ -0,0 +1,338 @@
const moment = require('moment-jalaali')
const { body, validationResult } = require('express-validator')
const OldPieceRequest = require('../models/OldPieceRequest')
const { _sr } = require('../plugins/serverResponses')
const {
res404,
res406,
res500,
checkValidations,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const _faSr = _sr.fa
// date formaters
function ArpaDateFormat(date) {
return moment(date).format('YYYY-MM-DD HH:mm:ss')
}
function SmsDateFormat(date) {
return moment(date).format('jYYYY/jMM/jDD')
}
/// ///////////////// agent
module.exports.add_oldPiece_request = [
async (req, res) => {
try {
const { user_id, agent_id } = req
const thisTime = Date.now()
const data = {
user_id,
agent_id,
createDate: ArpaDateFormat(thisTime),
statusHistory: [{ status: 'temp', date: thisTime }]
}
const opr = OldPieceRequest(data)
await opr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.add_oldPieces_to_opr = [
[
body('ItemReceptionTransDate').notEmpty().withMessage('تاریخ پذیرش را مشخص کنید'),
body('ItemName').notEmpty().withMessage('نام کالا را مشخص کنید'),
body('ItemID').notEmpty().withMessage('Include ItemID'),
body('ItemCode').notEmpty().withMessage('Include ItemCode'),
body('pieceName').notEmpty().withMessage('نام قطعه را مشخص کنید'),
body('pieceCode').notEmpty().withMessage('Include pieceCode'),
body('pieceId').notEmpty().withMessage('Include pieceId')
],
checkValidations(validationResult),
async (req, res) => {
try {
const oprId = req.params?.oprId
const { ItemReceptionTransDate, ItemName, SerialNo1, ItemID, ItemCode, pieceName, pieceCode, pieceId } = req.body
const data = {
ItemReceptionTransDate,
ItemName,
SerialNo1,
ItemID,
ItemCode,
pieceName,
pieceCode,
pieceId
}
const opr = await OldPieceRequest.findById(oprId)
opr.items.push(data)
await opr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res404(res, e)
}
}
]
module.exports.remove_oldPiece_from_opr = [
async (req, res) => {
try {
const oldPieceItemId = req.params?.oldPieceItemId
if (!oldPieceItemId) throw new Error('invalid id')
const opr = await OldPieceRequest.findOne({ 'items._id': oldPieceItemId })
opr.items.id(oldPieceItemId).remove()
await opr.save()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
console.log(e)
return res500(res, e)
}
}
]
module.exports.update_opr_description = [
(req, res) => {
const { description } = req.body
const data = {
description
}
OldPieceRequest.findByIdAndUpdate(req.params?.id, data, (err, oldData) => {
if (err) return res404(res, 'invalid id')
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.get_all_opr_for_agent = [
(req, res) => {
const agent_id = req.agent_id
OldPieceRequest.find({ agent_id }, (err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.get_one_opr_for_agent = [
(req, res) => {
OldPieceRequest.findById(req.params.id)
.populate(
'agent_id',
'full_name province_name city_name address agent_code postal_code tel_number fax_number mobile_number'
)
.exec((err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.delete_opr = [
async (req, res) => {
try {
const opr = await OldPieceRequest.findById(req.params?.id)
if (opr.status !== 'temp') return res406(res, 'نمیتوانید درخواست ارسال شده را حذف کنید')
await opr.remove()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
return res404(res, 'invalid id')
}
}
]
module.exports.change_opr_status_to_sent_by_agent = [
async (req, res) => {
try {
const thisTime = Date.now()
const opr = await OldPieceRequest.findById(req.params?.id).populate('agent_id')
if (!opr) throw new Error('invalid opr id')
const totalOpr = await OldPieceRequest.find({ status: { $ne: 'temp' } })
if (opr.status !== 'temp') return res406(res, 'این فرم قبلا برای آسان سرویس ارسال شده')
if (!opr.items.length) return res406(res, 'هیچ قطعه ای به فرم اضافه نکرده اید')
// generate tracking code
const trackingCode = 'OR' + totalOpr.length.toString().padStart(4, '0') + generateRandomDigits(2)
// modify opr
opr.status = 'sent'
opr.statusHistory.push({ status: 'sent', date: thisTime })
opr.trackingCode = trackingCode
opr.sendDate = ArpaDateFormat(thisTime)
// send sms for agent
const smsMsg = [
' نماینده گرامی درخواست قطعه داغی شما در تاریخ ',
SmsDateFormat(thisTime),
' با کد پیگیری ',
trackingCode,
' برای شرکت ارسال شد. '
]
SMS([opr.agent_id.mobile_number], smsMsg.join(''))
await opr.save()
notifyAdmin('updateNewOldPieceRequests')
return res.json({ message: 'درخواست قطعه داغی ارسال شد' })
} catch (e) {
console.log(e)
return res404(res, e)
}
}
]
/// ///////////////// admin
module.exports.get_all_opr_for_admin = [
async (req, res) => {
try {
const oprList = await OldPieceRequest.find({ status: { $ne: 'temp' } }).populate(
'agent_id',
'full_name agent_code mobile_number national_code province_name city_name province_id city_id'
)
return res.json(oprList)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_oneAgent_opr_for_admin = [
async (req, res) => {
const agent_id = req.params?.agent_id
try {
const oprList = await OldPieceRequest.find({ status: { $ne: 'temp' }, agent_id }).populate(
'agent_id',
'full_name agent_code mobile_number national_code province_name city_name'
)
return res.json(oprList)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_one_opr_for_admin = [
async (req, res) => {
try {
const { user_id } = req
const thisTime = Date.now()
const opr = await OldPieceRequest.findById(req.params?.id)
.populate(
'agent_id',
'agent_code full_name mobile_number fax_number tel_number province_name city_name national_code address postal_code store_name'
)
.populate('_openedBy', 'username first_name last_name')
.populate('_updatedBy', 'username first_name last_name')
if (!opr.seen) {
opr.seen = true
opr._openedBy = user_id
opr.status = 'ongoing'
opr.statusHistory.push({ status: 'ongoing', date: thisTime })
await opr.save()
const smsMsg = [
' نماینده گرامی درخواست قطعه داغی شما با کد پیگیری ',
opr.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' در دست اقدام قرار گرفت. '
]
SMS([opr.agent_id.mobile_number], smsMsg.join(''))
notifyAdmin('updateNewOldPieceRequests')
}
return res.json(opr)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.change_opr_status_by_admin = [
[
body('status')
.notEmpty()
.withMessage('status is required')
.bail()
.custom((value, { req }) => {
const acceptablvalues = ['waiting', 'delivered']
if (!acceptablvalues.includes(value)) return Promise.reject(new Error('invalid status'))
else return true
})
],
checkValidations(validationResult),
async (req, res) => {
const { user_id } = req
const { status, deliveryCode } = req.body
const thisTime = Date.now()
try {
const opr = await OldPieceRequest.findById(req.params?.id).populate('agent_id')
if (!opr) throw new Error('invalid opr id')
// check statuses
const statusErrMsg = 'invalid status for this time'
if (opr.status === 'delivered') return res406(res, statusErrMsg)
if (opr.status === 'waiting' && status === 'waiting') return res406(res, statusErrMsg)
// save status
opr._updatedBy = user_id
opr.status = status
opr.statusHistory.push({ status, date: thisTime })
let smsMessage
// differenet status methods
if (status === 'waiting') {
smsMessage = [
' نماینده گرامی درخواست قطعه داغی شما با کد پیگیری ',
opr.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' در انتظار قطعه میباشد. '
]
}
if (status === 'delivered') {
if (deliveryCode) opr.deliveryCode = deliveryCode
function deliveryCodePhrase() {
if (deliveryCode.length) return `کد پیگیری مرسوله: ${deliveryCode}` + '\n'
else return ''
}
smsMessage = [
' نماینده گرامی درخواست قطعه داغی شما با کد پیگیری ',
opr.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' تحویل شد. ',
'\n',
deliveryCodePhrase()
]
}
await SMS([opr.agent_id.mobile_number], smsMessage.join(''))
await opr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
+63
View File
@@ -0,0 +1,63 @@
const { body, validationResult } = require('express-validator')
const Piece = require('../models/Piece')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { _sr } = require('../plugins/serverResponses')
const _faSr = _sr.fa
module.exports.add_piece = [
[body('name').notEmpty().withMessage(_faSr.required.title)],
checkValidations(validationResult),
(req, res) => {
const { name, code } = req.body
const data = { name, code }
const piece = new Piece(data)
piece.save(err => {
if (err) console.log(err)
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.update_piece = [
[body('name').notEmpty().withMessage(_faSr.required.title)],
checkValidations(validationResult),
(req, res) => {
const { name, code } = req.body
const data = { name, code }
Piece.findByIdAndUpdate(req.params?.id, data, (err, oldData) => {
if (err) return res404(res, 'invalid id')
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.get_one_pieces = [
(req, res) => {
Piece.findById(req.params?.id, (err, data) => {
if (err) return res404(res, 'invalid id')
return res.json(data)
})
}
]
module.exports.get_all_pieces = [
(req, res) => {
Piece.find({}, (err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.remove_piece = [
(req, res) => {
Piece.findByIdAndRemove(req.params?.id, (err, data) => {
if (err) return res404(res, 'invalid id')
return res.json({ message: _faSr.response.success_remove })
})
}
]
@@ -0,0 +1,359 @@
const moment = require('moment-jalaali')
const { body, validationResult } = require('express-validator')
const PieceRequest = require('../models/PieceRequest')
const { _sr } = require('../plugins/serverResponses')
const {
res404,
res406,
res500,
checkValidations,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const _faSr = _sr.fa
// date formaters
function ArpaDateFormat(date) {
return moment(date).format('YYYY-MM-DD HH:mm:ss')
}
function SmsDateFormat(date) {
return moment(date).format('jYYYY/jMM/jDD')
}
/// ///////////////// agent
module.exports.add_piece_request = [
async (req, res) => {
try {
const { user_id, agent_id } = req
const thisTime = Date.now()
const data = {
user_id,
agent_id,
createDate: ArpaDateFormat(thisTime),
statusHistory: [{ status: 'temp', date: thisTime }]
}
const pr = PieceRequest(data)
await pr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.add_pieces_to_pr = [
[
body('ItemReceptionTransDate').notEmpty().withMessage('تاریخ پذیرش را مشخص کنید'),
body('ItemName').notEmpty().withMessage('نام کالا را مشخص کنید'),
body('ItemID').notEmpty().withMessage('Include ItemID'),
body('ItemCode').notEmpty().withMessage('Include ItemCode'),
body('gStatus').notEmpty().withMessage('وضعیت گارانتی را مشخص کنید'),
body('pieceName').notEmpty().withMessage('نام قطعه را مشخص کنید'),
body('pieceQuantity')
.notEmpty()
.withMessage('تعداد قطعه را مشخص کنید')
.isNumeric()
.withMessage(_faSr.format.number),
body('pieceCode').notEmpty().withMessage('Include pieceCode'),
body('pieceId').notEmpty().withMessage('Include pieceId')
],
checkValidations(validationResult),
async (req, res) => {
try {
const prId = req.params?.prId
const {
ItemReceptionTransDate,
ItemName,
SerialNo1,
ItemID,
ItemCode,
gStatus,
pieceName,
pieceCode,
pieceQuantity,
pieceId
} = req.body
const data = {
ItemReceptionTransDate,
ItemName,
SerialNo1,
ItemID,
ItemCode,
gStatus,
pieceName,
pieceCode,
pieceQuantity,
pieceId
}
const pr = await PieceRequest.findById(prId)
pr.items.push(data)
await pr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res404(res, e)
}
}
]
module.exports.remove_piece_from_pr = [
async (req, res) => {
try {
const pieceItemId = req.params?.pieceItemId
if (!pieceItemId) throw new Error('invalid id')
const pr = await PieceRequest.findOne({ 'items._id': pieceItemId })
pr.items.id(pieceItemId).remove()
await pr.save()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
console.log(e)
return res500(res, e)
}
}
]
module.exports.update_pr_description = [
(req, res) => {
const { description } = req.body
const data = {
description
}
PieceRequest.findByIdAndUpdate(req.params?.id, data, (err, oldData) => {
if (err) return res404(res, 'invalid id')
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.get_all_pr_for_agent = [
(req, res) => {
const agent_id = req.agent_id
PieceRequest.find({ agent_id }, (err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.get_one_pr_for_agent = [
(req, res) => {
PieceRequest.findById(req.params.id)
.populate(
'agent_id',
'full_name province_name city_name address agent_code postal_code tel_number fax_number mobile_number'
)
.exec((err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.delete_pr = [
async (req, res) => {
try {
const pr = await PieceRequest.findById(req.params?.id)
if (pr.status !== 'temp') return res406(res, 'نمیتوانید درخواست ارسال شده را حذف کنید')
await pr.remove()
return res.json({ message: _faSr.response.success_remove })
} catch (e) {
return res404(res, 'invalid id')
}
}
]
module.exports.change_pr_status_to_sent_by_agent = [
async (req, res) => {
try {
const thisTime = Date.now()
const pr = await PieceRequest.findById(req.params?.id).populate('agent_id')
if (!pr) throw new Error('invalid pr id')
const totalPr = await PieceRequest.find({ status: { $ne: 'temp' } })
if (pr.status !== 'temp') return res406(res, 'این فرم قبلا برای آسان سرویس ارسال شده')
if (!pr.items.length) return res406(res, 'هیچ قطعه ای به فرم اضافه نکرده اید')
// generate tracking code
const trackingCode = 'PR' + totalPr.length.toString().padStart(4, '0') + generateRandomDigits(2)
// modify pr
pr.status = 'sent'
pr.statusHistory.push({ status: 'sent', date: thisTime })
pr.trackingCode = trackingCode
pr.sendDate = ArpaDateFormat(thisTime)
// send sms for agent
const smsMsg = [
' نماینده گرامی درخواست قطعه شما در تاریخ ',
SmsDateFormat(thisTime),
' با کد پیگیری ',
trackingCode,
' برای شرکت ارسال شد. '
]
SMS([pr.agent_id.mobile_number], smsMsg.join(''))
await pr.save()
notifyAdmin('updateNewPieceRequests')
return res.json({ message: 'درخواست قطعه ارسال شد' })
} catch (e) {
console.log(e)
return res404(res, e)
}
}
]
/// ///////////////// admin
module.exports.get_all_pr_for_admin = [
async (req, res) => {
try {
const prList = await PieceRequest.find({ status: { $ne: 'temp' } }).populate(
'agent_id',
'full_name agent_code mobile_number national_code province_name city_name province_id city_id'
)
return res.json(prList)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_oneAgent_pr_for_admin = [
async (req, res) => {
const agent_id = req.params?.agent_id
try {
const prList = await PieceRequest.find({ status: { $ne: 'temp' }, agent_id }).populate(
'agent_id',
'full_name agent_code mobile_number national_code province_name city_name'
)
return res.json(prList)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_one_pr_for_admin = [
async (req, res) => {
try {
const { user_id } = req
const thisTime = Date.now()
const pr = await PieceRequest.findById(req.params?.id)
.populate(
'agent_id',
'agent_code full_name mobile_number fax_number tel_number province_name city_name national_code address postal_code store_name'
)
.populate('_openedBy', 'username first_name last_name')
.populate('_updatedBy', 'username first_name last_name')
if (!pr.seen) {
pr.seen = true
pr._openedBy = user_id
pr.status = 'ongoing'
pr.statusHistory.push({ status: 'ongoing', date: thisTime })
await pr.save()
const smsMsg = [
' نماینده گرامی درخواست قطعه شما با کد پیگیری ',
pr.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' در دست اقدام قرار گرفت. '
]
SMS([pr.agent_id.mobile_number], smsMsg.join(''))
notifyAdmin('updateNewPieceRequests')
}
return res.json(pr)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.change_pr_status_by_admin = [
[
body('status')
.notEmpty()
.withMessage('status is required')
.bail()
.custom((value, { req }) => {
const acceptablvalues = ['waiting', 'delivered']
if (!acceptablvalues.includes(value)) return Promise.reject(new Error('invalid status'))
else return true
})
],
checkValidations(validationResult),
async (req, res) => {
const { user_id } = req
const { status, deliveryCode } = req.body
const thisTime = Date.now()
try {
const pr = await PieceRequest.findById(req.params?.id).populate('agent_id')
if (!pr) throw new Error('invalid pr id')
// check statuses
const statusErrMsg = 'invalid status for this time'
if (pr.status === 'delivered') return res406(res, statusErrMsg)
if (pr.status === 'waiting' && status === 'waiting') return res406(res, statusErrMsg)
// save status
pr._updatedBy = user_id
pr.status = status
pr.statusHistory.push({ status, date: thisTime })
let smsMessage
// differenet status methods
if (status === 'waiting') {
smsMessage = [
' نماینده گرامی درخواست قطعه شما با کد پیگیری ',
pr.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' در انتظار قطعه میباشد. '
]
}
if (status === 'delivered') {
if (deliveryCode) pr.deliveryCode = deliveryCode
function deliveryCodePhrase() {
if (deliveryCode.length) return `کد پیگیری مرسوله: ${deliveryCode}` + '\n'
else return ''
}
smsMessage = [
' نماینده گرامی درخواست قطعه شما با کد پیگیری ',
pr.trackingCode,
' در تاریخ ',
SmsDateFormat(thisTime),
' تحویل شد. ',
'\n',
deliveryCodePhrase()
]
}
await SMS([pr.agent_id.mobile_number], smsMessage.join(''))
await pr.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
File diff suppressed because it is too large Load Diff
+113
View File
@@ -0,0 +1,113 @@
const fs = require('fs')
const { body, validationResult } = require('express-validator')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { _sr } = require('../plugins/serverResponses')
const { serialChecker } = require('../plugins/asanServiceSerialChecker')
const _faSr = _sr.fa
const guaranteeSerialsPath = './static/uploads/serials'
const productSerialsPath = './static/uploads/serials_products'
/// // router modules
module.exports.addExel = [
[
body('type')
.notEmpty()
.withMessage('choose type')
.bail()
.custom((value, { rew }) => {
const validValues = ['guaranteeSerial', 'orginality']
if (!validValues.includes(value)) return Promise.reject(new Error('invalid type'))
else return Promise.resolve()
})
],
checkValidations(validationResult),
async (req, res) => {
if (!req.files?.file) return res.status(422).json({ validation: { file: { msg: 'فایل را اضافه کنید' } } })
if (!req.files?.file.name.split('.').some(item => ['xlsx', 'xltx', 'xlsm', 'xlsb'].includes(item)))
return res.status(422).json({ validation: { file: { msg: 'فرمت فایل درست نمیباشد' } } })
const file = req.files.file
const { type } = req.body
try {
const path = type === 'guaranteeSerial' ? guaranteeSerialsPath : productSerialsPath
const files = await fs.readdirSync(path)
for await (const item of files) {
if (file.name === item) return res.status(422).json({ validation: { file: { msg: 'نام فایل تکراریست' } } })
}
await file.mv(`${path}/${file.name}`)
return res.json({ message: _faSr.response.success_save })
} catch (err) {
return res500(res, err)
}
}
]
module.exports.getAllExels = [
(req, res) => {
const type = req.query?.type
if (!type) return res500(res, 'choose type')
const validValues = ['guaranteeSerial', 'orginality']
if (!validValues.includes(type)) return res500(res, 'choose type')
const path = type === 'guaranteeSerial' ? guaranteeSerialsPath : productSerialsPath
const downloadAblePath = type === 'guaranteeSerial' ? '/uploads/serials/' : '/uploads/serials_products/'
fs.readdir(path, (err, files) => {
if (err) return res500(res, err)
const filesWithURL = files.map(item => {
return { url: downloadAblePath, name: item }
})
return res.json(filesWithURL)
})
}
]
module.exports.removeExel = [
(req, res) => {
const type = req.query?.type
if (!type) return res500(res, 'choose type')
const validValues = ['guaranteeSerial', 'orginality']
if (!validValues.includes(type)) return res500(res, 'choose type')
const path = type === 'guaranteeSerial' ? guaranteeSerialsPath : productSerialsPath
fs.unlink(`${path}/${req.params.name}`, err => {
if (err) return res404(res, _faSr.not_found.item_id)
else return res.json({ message: _faSr.response.success_remove })
})
}
]
module.exports.checkSerial = [
[
body('serial').notEmpty().withMessage('شماره سریال را وارد کنید'),
body('type')
.notEmpty()
.withMessage('choose type')
.bail()
.custom((value, { rew }) => {
const validValues = ['guaranteeSerial', 'orginality']
if (!validValues.includes(value)) return Promise.reject(new Error('invalid type'))
else return Promise.resolve()
})
],
checkValidations(validationResult),
async (req, res) => {
try {
const { serial, type } = req.body
const serialStatus = await serialChecker(serial, type)
let okMsg
if (type === 'guaranteeSerial') okMsg = 'شماره سریال گارانتی معتبر میباشد.'
else okMsg = 'شماره سریال کالا معتبر میباشد.'
let errMsg
if (type === 'guaranteeSerial') errMsg = 'شماره سریال گارانتی معتبر نیست.'
else errMsg = 'شماره سریال کالا معتبر نیست.'
if (serialStatus) return res.json({ message: okMsg })
else return res404(res, errMsg)
} catch (e) {
return res500(res, `there is an error here --- ${e}`)
}
}
]
@@ -0,0 +1,52 @@
const { body, validationResult } = require('express-validator')
const SMSBroadcast = require('../models/SMSBroadcast')
const { _sr } = require('../plugins/serverResponses')
const { res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
const _faSr = _sr.fa
module.exports.broadcast = [
[
body('message').notEmpty().withMessage(_faSr.required.message),
body('recievers').notEmpty().withMessage('لیست دریافت کنندگان را پر کنید')
],
checkValidations(validationResult),
async (req, res) => {
try {
const { message, recievers } = req.body
const { user_id } = req
const data = { message, recievers, _creator: user_id }
const smsBroadcast = new SMSBroadcast(data)
await smsBroadcast.save()
for await (const item of recievers) {
await SMS([item.mobile_number], message)
}
return res.json({ message: 'پیامک برای همه مخاطبین ارسال گردید' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.getAllForAdmin = [
(req, res) => {
SMSBroadcast.find({}, (err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getOneForAdmin = [
async (req, res) => {
try {
const sms = await SMSBroadcast.findById(req.params.id)
.populate('recievers.user_id', 'mobile_number first_name last_name verity_businessCode panatech_businessCode')
.populate('_creator', 'username first_name last_name')
return res.json(sms)
} catch (e) {
return res500(res, e)
}
}
]
+70
View File
@@ -0,0 +1,70 @@
const Survey = require('../models/Survey')
const { _sr } = require('../plugins/serverResponses')
const { res404, res500 } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
module.exports.create = [
(req, res) => {
const {
purchasedProduct,
guaranteeWorkFlow,
employeeResponsibility,
serviceQuality,
serviceTime,
repairQuality,
coast,
description,
code
} = req.body
const data = {
purchasedProduct,
guaranteeWorkFlow,
employeeResponsibility,
serviceQuality,
serviceTime,
repairQuality,
coast,
description,
code,
user: req.user_id
}
const survey = new Survey(data)
survey.save(err => {
if (err) return res500(res, err)
return res.json({ message: _faSr.response.success_save })
})
}
]
module.exports.getAllForUser = [
(req, res) => {
Survey.find({ user: req.user_id }, (err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getAllForAdmin = [
(req, res) => {
Survey.find({})
.populate('user', 'first_name last_name')
.exec((err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getOneForAdmin = [
(req, res) => {
Survey.findById(req.params.id)
.populate('user', 'first_name last_name')
.exec((err, data) => {
if (err) return res404(res, err)
return res.json(data)
})
}
]
+130
View File
@@ -0,0 +1,130 @@
const { body, validationResult } = require('express-validator')
const User = require('../models/User')
const SurveyCheck = require('../models/SurveyCheck')
const { res406, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
const { phrases } = require('../plugins/SMS_Phrases')
module.exports.reception = [
[
body('BusinessID').notEmpty().withMessage('BusinessID is required'),
body('TempReceiptTransNumber').notEmpty().withMessage('TempReceiptTransNumber is required'),
body('ItemReceptionTransNumber').notEmpty().withMessage('ItemReceptionTransNumber is required')
],
checkValidations(validationResult),
async (req, res) => {
const { BusinessID, TempReceiptTransNumber, ItemReceptionTransNumber } = req.body
try {
// check user id and agent status
const user = await User.findOne({ $or: [{ verity_businessID: BusinessID }, { panatech_businessID: BusinessID }] })
if (!user) return res406(res, 'Incorrect BusinessID')
function getMessageTxt() {
const msgArray = [
'مشتری گرامی',
user.first_name + ' ' + user.last_name,
'\n',
'کالاهای شما با شماره پذیرش موقت',
TempReceiptTransNumber,
'توسط واحد گارانتی آسان سرویس دریافت شد و با شماره پذیرش دائم',
ItemReceptionTransNumber,
'دردست بررسی می باشد. به محض آماده شدن کالاها به شما اطلاع رسانی خواهد شد.',
'\n',
phrases.signature
]
return msgArray.join(' ')
}
SMS([user.mobile_number], getMessageTxt())
return res.json({ message: 'Message sent successfully' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.repair = [
[
body('BusinessID').notEmpty().withMessage('BusinessID is required'),
body('TransNumber').notEmpty().withMessage('TransNumber is required'),
body('ItemReceptionTransNumber').notEmpty().withMessage('ItemReceptionTransNumber is required')
],
checkValidations(validationResult),
async (req, res) => {
const { BusinessID, ItemReceptionTransNumber, TransNumber } = req.body
try {
// check user id and agent status
const user = await User.findOne({ $or: [{ verity_businessID: BusinessID }, { panatech_businessID: BusinessID }] })
if (!user) return res406(res, 'Incorrect BusinessID')
function getMessageTxt() {
const msgArray = [
'مشتری گرامی',
user.first_name + ' ' + user.last_name,
'\n',
'مراحل تعمیر و بررسی کالاهای ارسالی شما با شماره پذیرش',
ItemReceptionTransNumber,
'توسط واحد گارانتی آسان سرویس انجام شد و با شماره فاکتور گارانتی',
TransNumber,
'ثبت شد. به زودی کالاها به آدرس شما ارسال می گردد. ',
'\n',
phrases.signature
]
return msgArray.join(' ')
}
SMS([user.mobile_number], getMessageTxt())
return res.json({ message: 'Message sent successfully' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.sendBack = [
[
body('BusinessID').notEmpty().withMessage('BusinessID is required'),
body('DeliveryCode').notEmpty().withMessage('DeliveryCode is required'),
body('ItemReceptionTransNumber').notEmpty().withMessage('ItemReceptionTransNumber is required')
],
checkValidations(validationResult),
async (req, res) => {
const { BusinessID, ItemReceptionTransNumber, DeliveryCode } = req.body
try {
// check user id and agent status
const user = await User.findOne({ $or: [{ verity_businessID: BusinessID }, { panatech_businessID: BusinessID }] })
if (!user) return res406(res, 'Incorrect BusinessID')
function getMessageTxt() {
const msgArray = [
'مشتری گرامی',
user.first_name + ' ' + user.last_name,
'\n',
'کالاهای ارسالی شما با شماره پذیرش',
ItemReceptionTransNumber,
'پس از انجام مراحل گارانتی توسط واحد گارانتی به آدرس شما ارسال شد. شماره بیجک بسته ارسالی',
DeliveryCode,
'می باشد. از همراهی و خرید شما سپاس گزاریم. ',
'\n',
phrases.signature
]
return msgArray.join(' ')
}
const surveyData = {
code: ItemReceptionTransNumber,
user: user._id,
timeAdded: Date.now()
}
const surveyCheck = new SurveyCheck(surveyData)
surveyCheck.save(err => {
if (err) console.log('surveyCheck save error', err)
})
SMS([user.mobile_number], getMessageTxt())
return res.json({ message: 'Message sent successfully' })
} catch (e) {
return res500(res, e)
}
}
]
+157
View File
@@ -0,0 +1,157 @@
const { body, validationResult } = require('express-validator')
const TicketConversation = require('../models/TicketConversation')
const User = require('../models/User')
const { notifyUser } = require('../WebSocket/controllers/user_EventsController')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { _sr } = require('../plugins/serverResponses')
const _faSr = _sr.fa
// env variables
const maxAttachmentSize = 2048
const userIdPopulation = 'first_name last_name verity_businessCode panatech_businessCode'
/// ////////// user
module.exports.add_ticket = [
[
body('title').notEmpty().withMessage(_faSr.required.title),
body('user_id').notEmpty().withMessage('کد مشتری را وارد کنید')
],
checkValidations(validationResult),
(req, res) => {
const { title, transaction_id, user_id } = req.body
const data = { title, transaction_id, user_id }
const ticketConversation = new TicketConversation(data)
ticketConversation.save((err, data) => {
if (err) console.log(err)
return res.json(data)
})
}
]
module.exports.add_message_to_ticket = [
[
body('message')
.if((value, { req }) => !req.files)
.notEmpty()
.withMessage(_faSr.required.message)
],
checkValidations(validationResult),
async (req, res) => {
const { message } = req.body
const { user_id } = req
const data = { message, user_id, isUser: true }
try {
// check user scope
const user = await User.findById(user_id)
if (user.scope.includes('admin')) data.isUser = false
// save files
if (req.files?.image) {
const image = req.files.image
const fileName = 'TicketAttachment_' + Date.now() + '.' + image.mimetype.split('/')[1]
const acceptableFormats = ['png', 'jpg', 'jpeg', 'webp']
if (!acceptableFormats.includes(image.mimetype.split('/')[1]))
return res.status(422).json({ validation: { image: { msg: _faSr.format.image } } })
if (image.size / 1024 > maxAttachmentSize)
return res
.status(422)
.json({ validation: { image: { msg: `حجم تصویر نباید بیشتر از ${maxAttachmentSize} KB باشد.` } } })
data.image = fileName
await image.mv(`./static/uploads/images/tickets/${fileName}`)
}
// find conversation and update messages
const conversation = await TicketConversation.findById(req.params.id)
.populate('user_id', userIdPopulation)
.populate('messages.user_id', userIdPopulation)
conversation.messages.push(data)
await conversation.save()
if (data.isUser) {
notifyAdmin('newTicketMsg')
notifyAdmin('updateUnreadTickets')
} else {
notifyUser('updateUnreadTickets', conversation.user_id._id)
notifyUser('newTicketMsg', conversation.user_id._id)
}
return res.json(conversation)
} catch (e) {
return res404(res, e)
}
}
]
module.exports.get_all_tickets = [
(req, res) => {
const { user_id } = req
TicketConversation.find({ user_id }, (err, conversations) => {
if (err) return res500(res, err)
else return res.json(conversations)
})
}
]
module.exports.get_one_ticket = [
(req, res) => {
TicketConversation.findById(req.params.id)
.populate('user_id', userIdPopulation)
.populate('messages.user_id', userIdPopulation)
.exec((err, data) => {
if (err) return res404(res, err)
// after sending messages to user set read status to true
const messages = data.messages
setTimeout(async () => {
try {
const user = await User.findById(req.user_id)
if (messages.length) {
let userNeedsNotify = false
let adminNeedsNotify = false
messages.forEach((item, index) => {
if (item.isUser && user.scope.includes('admin') && !item.read) {
// console.log(index, ' these are user messages')
adminNeedsNotify = true
item.read = true
}
if (!item.isUser && !user.scope.includes('admin') && !item.read) {
// console.log(index, ' these are admin messages')
userNeedsNotify = true
item.read = true
}
if (index === messages.length - 1) {
data.save(err => {
if (err) console.log(err)
if (userNeedsNotify) notifyUser('updateUnreadTickets', data.user_id._id)
if (adminNeedsNotify) notifyAdmin('updateUnreadTickets')
})
}
})
}
} catch (e) {
return res500(res, e)
}
}, 500)
return res.json(data)
})
}
]
/// ///////// admin
module.exports.get_all_tickets_for_admin = [
(req, res) => {
TicketConversation.find({})
.populate('user_id', userIdPopulation)
.exec((err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
+333
View File
@@ -0,0 +1,333 @@
const moment = require('moment-jalaali')
const { body, validationResult } = require('express-validator')
const TransactionDraft = require('../models/TransactionDraft')
const Transaction = require('../models/Transaction')
const User = require('../models/User')
const SurveyCheck = require('../models/SurveyCheck')
const { _sr } = require('../plugins/serverResponses')
const { saveTransactionToArpa } = require('../ArpaWebservice.js')
const {
res404,
res406,
res500,
checkValidations,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
const { phrases } = require('../plugins/SMS_Phrases')
const { notifyAgent } = require('../WebSocket/controllers/agent_EventsController')
const { notifyUser } = require('../WebSocket/controllers/user_EventsController')
const _faSr = _sr.fa
// date formatters
function ArpaDateFormat(date) {
return moment(date).format('YYYY-MM-DD HH:mm:ss')
}
function SmsDateFormat(date) {
return moment(date).format('jYYYY/jMM/jDD')
}
/// ///////////////// users
module.exports.add_transaction = [
[
body('BusinessID').notEmpty().withMessage('Enter businessID'),
body('cAddress1').notEmpty().withMessage(_faSr.required.address),
body('TransCCustom1').notEmpty().withMessage(_faSr.required.receiver_first_name),
body('cTel1').notEmpty().withMessage(_faSr.required.receiver_mobile)
],
checkValidations(validationResult),
async (req, res) => {
if (!req.body.termsOfUse) return res406(res, 'با متن تعهدنامه موافقت نکرده اید')
if (!req.body.items?.length) return res406(res, 'هیچ کالایی به فرم اضافه نکرده اید')
const { BusinessID, Description, cAddress1, TransCCustom1, cTel1, items, draftId, db_name, agent } = req.body
const data = {
BusinessID,
Description,
cAddress1,
TransCCustom1,
cTel1
}
try {
const userId = req.user_id
const thisTime = Date.now()
// check user id and agent status
const user = await User.findById(userId)
if (!user) return res406(res, 'اطلاعات کاربری صحیح نمیباشد')
if (user.isAgent && agent !== 'main')
return res406(res, 'نمایندگان فقط میتوانند به خود شرکت آسان سرویس فرم ارسال نمایند')
function getMessageTxt(transNumber) {
const msgArray = [
'مشتری گرامی',
user.first_name + ' ' + user.last_name,
'\n',
'کالاهای شما با شماره پذیرش موقت',
transNumber,
'در سایت آسان سرویس ثبت گردید. کالاهای ارسالی شما پس از دریافت توسط واحد گارانتی، بررسی شده و به شما اطلاع رسانی خواهد شد.',
'\n',
phrases.signature
]
return msgArray.join(' ')
}
// save transaction
if (agent === 'main') {
const ArpaResponse = await saveTransactionToArpa(data, items, db_name)
await TransactionDraft.findByIdAndRemove(draftId)
SMS([user.mobile_number], getMessageTxt(ArpaResponse))
notifyUser('updateDraftsCount', userId)
return res.json({
host: 'ar',
transNumber: ArpaResponse
})
} else {
// get transactions count
const transactions = await Transaction.find()
// fill specific fields
data.user_id = userId
data.agent_id = agent
data.db_name = db_name
data.items = items
data.TempReceiptTransDate = ArpaDateFormat(thisTime)
data.TempReceiptTransNumber = 'AG' + transactions.length.toString().padStart(4, '0')
data.statusHistory = [{ status: 'saved', date: thisTime }]
const transaction = new Transaction(data)
await transaction.save()
await TransactionDraft.findByIdAndRemove(draftId)
SMS([user.mobile_number], getMessageTxt(transaction.TempReceiptTransNumber))
notifyUser('updateDraftsCount', userId)
notifyAgent('newAgentInbox', agent)
notifyAgent('updateAgentInbox', agent)
return res.json({
host: 'as',
transNumber: transaction.TempReceiptTransNumber
})
}
} catch (e) {
// console.log('there is an error in (Post Transaction to Arpa)', e)
return res500(res, e)
}
}
]
module.exports.get_all_transactions_for_user = [
(req, res) => {
const { user_id } = req
Transaction.find({ user_id }, (err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.get_one_transaction_for_user = [
(req, res) => {
const { user_id } = req
Transaction.findOne({ user_id, TempReceiptTransNumber: req.params?.ttn })
.populate('agent_id', 'full_name province_name city_name address postal_code tel_number mobile_number')
.exec((err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
/// ///////////////// agents
module.exports.get_all_transactions_for_agent = [
async (req, res) => {
try {
const { agent_id } = req
const transactions = await Transaction.find({ agent_id })
return res.json(transactions)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_one_transaction_for_agent = [
async (req, res) => {
try {
const { agent_id } = req
const transaction = await Transaction.findOne({ agent_id, _id: req.params?.id })
if (!transaction) return res404(res, 'invalid transaction id')
if (!transaction.seen) {
transaction.seen = true
await transaction.save()
notifyAgent('updateAgentInbox', agent_id)
}
return res.json(transaction)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.change_transaction_status_by_agent = [
[
body('status')
.notEmpty()
.withMessage('status is required')
.bail()
.custom((value, { req }) => {
const acceptablvalues = ['recieved', 'ongoing', 'waiting', 'delivered']
if (!acceptablvalues.includes(value)) return Promise.reject(new Error('invalid status'))
else return true
})
],
checkValidations(validationResult),
async (req, res) => {
const { status, deliveryCode } = req.body
const { agent_id } = req
const thisTime = Date.now()
try {
const transaction = await Transaction.findOne({ agent_id, _id: req.params?.id })
if (!transaction) return res404(res, 'invalid transaction id')
// status order check
const errMsg = 'invalid status for this time'
if (transaction.status === 'saved' && status !== 'recieved') return res406(res, errMsg)
if (transaction.status === 'recieved' && status !== 'ongoing') return res406(res, errMsg)
// avoid repeated status
if (transaction.status === 'waiting' && status === 'waiting') return res406(res, errMsg)
if (transaction.status === 'delivered' && status === 'delivered') return res406(res, errMsg)
// save status
transaction.status = status
transaction.statusHistory.push({ status, date: thisTime })
let smsMessage
// different status methods
if (status === 'recieved') {
const receiptTN = transaction.TempReceiptTransNumber + 'R' + generateRandomDigits(2)
transaction.ItemReceptionTransNumber = receiptTN
transaction.ItemReceptionTransDate = ArpaDateFormat(thisTime)
smsMessage = [
' کاربر گرامی فرم گارانتی شما با کد پذیرش موقت ',
transaction.TempReceiptTransNumber,
' در تاریخ ',
SmsDateFormat(thisTime),
' تحویل دفتر نمایندگی و پذیرش شد. ',
'\n',
' کد پذیرش: ',
receiptTN,
'\n',
phrases.signature
]
}
if (status === 'ongoing') {
smsMessage = [
' کاربر گرامی فرم گارانتی شما با کد پذیرش ',
transaction.ItemReceptionTransNumber,
' در تاریخ ',
SmsDateFormat(thisTime),
' در دست اقدام قرار گرفت. ',
'\n',
phrases.signature
]
}
if (status === 'waiting') {
smsMessage = [
' کاربر گرامی فرم گارانتی شما با کد پذیرش ',
transaction.ItemReceptionTransNumber,
' در تاریخ ',
SmsDateFormat(thisTime),
' در انتظار قطعه میباشد. ',
'\n',
phrases.signature
]
}
if (status === 'delivered') {
if (deliveryCode) transaction.deliveryCode = deliveryCode
function deliveryCodePhrase() {
if (deliveryCode.length) return `کد پیگیری مرسوله: ${deliveryCode}` + '\n'
else return ''
}
smsMessage = [
' کاربر گرامی فرم گارانتی شما با کد پذیرش ',
transaction.ItemReceptionTransNumber,
' در تاریخ ',
SmsDateFormat(thisTime),
' تحویل شد. ',
'\n',
deliveryCodePhrase(),
phrases.signature
]
const surveyData = {
code: transaction.ItemReceptionTransNumber,
user: transaction.user_id,
timeAdded: Date.now()
}
const surveyCheck = new SurveyCheck(surveyData)
surveyCheck.save(err => {
if (err) console.log('surveyCheck save error', err)
})
}
await SMS([transaction.cTel1], smsMessage.join(''))
await transaction.save()
return res.json({ message: _faSr.response.success_save })
} catch (e) {
return res500(res, e)
}
}
]
/// ///////////////// admin
module.exports.get_all_agents_inbox_for_admin = [
async (req, res) => {
try {
const transactions = await Transaction.find()
.populate('agent_id', 'agent_code full_name')
.populate('user_id', 'province_id province_name city_id city_name')
return res.json(transactions)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_one_agent_inbox_for_admin = [
async (req, res) => {
try {
const agent_id = req.params?.agent_id
const transactions = await Transaction.find({ agent_id })
return res.json(transactions)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.get_one_transaction_for_admin = [
(req, res) => {
Transaction.findById(req.params?.id)
.populate(
'agent_id',
'full_name province_name city_name address postal_code tel_number fax_number mobile_number store_name agent_code'
)
.populate(
'user_id',
'first_name last_name province_name city_name panatech_businessCode verity_businessCode national_code mobile_number address postal_code'
)
.exec((err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
@@ -0,0 +1,168 @@
const { body, validationResult } = require('express-validator')
const TransactionDraft = require('../models/TransactionDraft')
const { VerityStockAreaId, PanatechStockAreaId } = require('../_env')
const { res404, res406, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { notifyUser } = require('../WebSocket/controllers/user_EventsController')
module.exports.add_transaction_draft = [
[
body('db_name')
.notEmpty()
.withMessage('db param is required')
.bail()
.custom((value, { req }) => {
if (value === 'verity' || value === 'panatech') return Promise.resolve()
else return Promise.reject(new Error('incorrect db value'))
})
],
checkValidations(validationResult),
(req, res) => {
const { user_id } = req
if (!user_id) return res404(res, 'invalid userID')
const { db_name, description } = req.body
const data = { user_id, db_name, description }
const draft = new TransactionDraft(data)
draft.save((err, data) => {
if (err) return res500(res, err)
notifyUser('updateDraftsCount', user_id)
return res.json({ draftId: data._id })
})
}
]
module.exports.update_draft_description = [
(req, res) => {
const draftId = req.params?.draftId
const { description } = req.body
TransactionDraft.findByIdAndUpdate(draftId, { description }, (err, oldData) => {
if (err || !oldData) return res404(res, err)
else return res.json({ message: 'توضیحات فرم با موفقیت بروزرسانی شد' })
})
}
]
module.exports.get_user_drafts = [
async (req, res) => {
try {
const { user_id } = req
const drafts = await TransactionDraft.find({ user_id })
return res.json(drafts)
} catch (e) {
return res.status(500).json({ message: e })
}
}
]
module.exports.get_one_user_draft = [
(req, res) => {
TransactionDraft.findById(req.params?.draftId, (err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.add_stuff_to_draft = [
async (req, res) => {
const userId = req.user_id
const draftId = req.params?.draftId
const { ItemID, ItemCode, MjQty, SerialNo1, GStartDate, GEndDate } = req.body
try {
// custom validations
if (!Number(MjQty) || !Number.isInteger(Number(MjQty))) return res406(res, 'تعداد باید از جنس عدد صحیح باشد')
if (!ItemID?.length || !ItemCode?.length) return res406(res, 'کالا را انتخاب کنید')
if (Number(MjQty) < 1) return res406(res, 'تعداد نباید کمتر از 1 باشد')
if (SerialNo1?.length && Number(MjQty) !== 1)
return res406(res, 'تعداد کالاهایی که شماره سریال اختصاصی دارند نمیتواند بیشتر از یکی باشد')
const draft = await TransactionDraft.findOne({ user_id: userId, _id: draftId })
if (!draft) return res404(res, 'this transaction does not exist or not belongs to you')
// check if item already exists
for (let i = 0; i < draft.items.length; i++) {
if ((await draft.items[i].SerialNo1) !== '') {
if ((await draft.items[i].SerialNo1) === SerialNo1) return res406(res, 'این شماره سریال قبلا افزوده شده')
} else {
// eslint-disable-next-line no-lonely-if
if ((await draft.items[i].ItemID) === ItemID) {
draft.items[i].MjQty = Number(draft.items[i].MjQty) + Number(MjQty)
draft.markModified('items')
await draft.save()
return res.json({ message: 'این کالا به تعداد کالای مشابه داخل لیست اضافه گردید' })
}
}
}
function stockAreaID(db) {
if (db === 'verity') return VerityStockAreaId
else if (db === 'panatech') return PanatechStockAreaId
else return null
}
const item = {
ItemID,
ItemCode,
MjQty: Number(MjQty),
SerialNo1,
GStartDate,
GEndDate,
StockAreaID: stockAreaID(draft.db_name),
TransLineID: 'null',
Price: 0,
DiscountAmount: 0,
DiscountPercent: 0,
TaxAmount: 0,
TollAmount: 0
}
draft.items.push(item)
await draft.save()
return res.json({ message: 'کالا با موفقیت به فرم افزوده شد' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.remove_stuff_from_draft = [
async (req, res) => {
const draftId = req.params?.draftId
const { user_id } = req
const { itemId, itemSerial } = req.body
try {
const draft = await TransactionDraft.findOne({ user_id, _id: draftId })
if (!draft) return res404(res, 'this transaction does not exist or not belongs to you')
draft.items = await draft.items.filter(item => {
if (itemSerial === '') {
return item.ItemID !== itemId
} else {
return item.SerialNo1 !== itemSerial
}
})
draft.markModified('items')
await draft.save()
return res.json({ message: 'آیتم با موفقیت از لیست حذف شد' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.remove_draft = [
(req, res) => {
const draftId = req.params?.draftId
TransactionDraft.findByIdAndDelete(draftId, (err, data) => {
if (err || !data) return res404(res, err)
notifyUser('updateDraftsCount', data.user_id)
return res.json({ message: 'پیشنویس با موفقیت حذف شد' })
})
}
]
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,144 @@
const fs = require('fs')
const { body, validationResult } = require('express-validator')
const jimp = require('jimp')
const Warranty = require('../models/WarrantyTerms')
const { _sr } = require('../plugins/serverResponses')
const { res404, checkValidations } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
const shortDescriptionLength = 200
const paginateLimit = 10
module.exports.create = [
[
body('title').notEmpty().withMessage(_faSr.required.title),
body('short_description').notEmpty().withMessage(_faSr.required.description),
body('description').notEmpty().withMessage(_faSr.required.description)
],
checkValidations(validationResult),
(req, res) => {
if (!req.files || !req.files.image)
return res.status(422).json({ validation: { image: { msg: _faSr.required.image } } })
const image = req.files.image
const fileName = 'warranty_' + Date.now() + '.' + image.mimetype.split('/')[1]
// validate image format
const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
if (!supportedFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { image: { msg: _faSr.format.image } } })
}
const data = {
_creator: req.user_id,
title: req.body.title,
short_description: req.body.short_description.slice(0, shortDescriptionLength),
description: req.body.description,
image: fileName
}
jimp
.read(image.data)
.then(img => {
img.cover(350, 350).write(`./static/uploads/images/warrantyTerms/${fileName}`, cb => {
const warranty = new Warranty(data)
warranty.save(err => {
if (err) console.log(err)
return res.json({ message: _faSr.response.success_save })
})
})
})
.catch(err => {
console.log(err)
})
}
]
module.exports.getAll = [
(req, res) => {
Warranty.paginate({}, { page: req.params?.page || 1, limit: paginateLimit }, (err, result) => {
if (err) return res.status(404).json({ message: _faSr.not_found.item_id })
if (!result.docs.length && Number(req.params.page) !== 1)
return res.status(404).json({ message: _faSr.not_found.item_id })
else return res.json(result)
})
}
]
module.exports.getOne = [
(req, res) => {
Warranty.findById(req.params.id)
.populate('_creator', 'first_name last_name')
.exec((err, data) => {
if (err) return res.status(404).json({ message: err })
return res.json(data)
})
}
]
module.exports.update = [
[
body('title').notEmpty().withMessage(_faSr.required.title),
body('short_description').notEmpty().withMessage(_faSr.required.description),
body('description').notEmpty().withMessage(_faSr.required.description)
],
checkValidations(validationResult),
(req, res) => {
const data = {
_creator: req.user_id,
title: req.body.title,
short_description: req.body.short_description.slice(0, shortDescriptionLength),
description: req.body.description
}
if (req.files && req.files.image) {
const image = req.files.image
const fileName = 'warranty_' + Date.now() + '.' + image.mimetype.split('/')[1]
// validate image format
const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
if (!supportedFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({ validation: { image: { msg: _faSr.format.image } } })
}
data.image = fileName
jimp
.read(image.data)
.then(img => {
img.cover(350, 350).write(`./static/uploads/images/warrantyTerms/${fileName}`)
})
.catch(err => {
console.log(err)
})
}
Warranty.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) return res404(res, err)
if (req.files && req.files.image)
fs.unlink(`./static/${oldData.image}`, err => {
if (err) console.log(err)
})
Warranty.findById(req.params.id, (err, data) => {
if (err) return res404(res, err)
return res.json(data)
})
})
}
]
module.exports.delete = [
(req, res) => {
Warranty.findByIdAndDelete(req.params.id, (err, data) => {
if (err) return res.status(404).json({ message: _faSr.not_found.item_id })
fs.unlink(`./static/${data.image}`, err => {
if (err) console.log(err)
})
return res.json({ message: _faSr.response.success_remove })
})
}
]