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
+173
View File
@@ -0,0 +1,173 @@
const axios = require('axios')
/// /////////////////////////////////////////////////////////////////////////////////////////////////// verity WebService
const {
// verity
verityBaseUrl,
verityTokenUrl,
// VerityUserGroupId,
VerityBusinessCategoryId,
// VerityStockAreaId,
verityAccount,
// panatech
panatechBaseUrl,
panatechTokenUrl,
// PanatechUserGroupId,
PanatechBusinessCategoryId,
// PanatechStockAreaId,
panatechAccount
} = require('./_env')
// get verity token
let verityToken = ''
module.exports.getVerityToken = async () => {
try {
const getToken = await axios.get(verityTokenUrl, { params: verityAccount })
verityToken = getToken.data
console.log(verityToken)
} catch (err) {
console.log(err)
}
}
const verityAxiosConfig = () => {
return {
baseURL: verityBaseUrl,
headers: {
Authorization: verityToken
}
}
}
// export verity values
module.exports.verityAxiosConfig = verityAxiosConfig
/// /////////////////////////////////////////////////////////////////////////////////////////////////// panatech WebService
// get panatech token
let panatechToken = ''
module.exports.getPanatechToken = async () => {
try {
const getToken = await axios.get(panatechTokenUrl, { params: panatechAccount })
panatechToken = getToken.data
console.log(panatechToken)
} catch (err) {
console.log(err)
}
}
const panatechAxiosConfig = () => {
return {
baseURL: panatechBaseUrl,
headers: {
Authorization: panatechToken
}
}
}
// export panatech values
module.exports.panatechAxiosConfig = panatechAxiosConfig
/// /////////////////////////////////////////////////////////////////////////////////////////////////// methods
function axiosConfig(db) {
if (db === 'verity') return verityAxiosConfig()
else if (db === 'panatech') return panatechAxiosConfig()
else return {}
}
function BusinessCategoryId(db) {
if (db === 'panatech') return PanatechBusinessCategoryId
else if (db === 'verity') return VerityBusinessCategoryId
else return null
}
module.exports.saveTransactionToArpa = (data, items, db) => {
// add static values to data
data.TransactionID = 'null'
data.BusinessCode = 'null'
data.DocAliasID = 144
data.TrMessage = ''
const ArpaData = {
Data: data,
Items: items
}
// @example
// const arpaExample = {
// "Data": {"TransactionID": null, "BusinessID": 3, "DocAliasId": 144, "Description": "تست", "cAddress1": "تهران", "cTel1": "0218884455", "TransCCustom1": "آقای موسوی"},
// "Items": [{"TransLineID": null, "itemId": 5302, "MjQty": 20, "StockAreaId": 1}, {"TransLineID": null, "itemId": 5302, "MjQty": 20, "StockAreaId": 1}]
// }
return new Promise(async (resolve, reject) => {
try {
const transaction = await axios.post('/api/NewTransaction', ArpaData, axiosConfig(db))
const ArpaResponse = transaction.data
if (ArpaResponse.data) resolve(ArpaResponse.data[0].TransNumber)
else reject(ArpaResponse.error || 'ARPA WebService Error')
} catch (e) {
reject(e)
}
})
}
module.exports.saveUserToArpa = (userData, db) => {
const data = {
BusName: userData.first_name + ' ' + userData.last_name + ' (گارانتی سایت) ',
Email: userData.email,
PhoneNo: userData.tel_number,
Mobile: userData.mobile_number,
Name: userData.first_name,
Family: userData.last_name,
NationalCode: userData.national_code,
ProvinceId: userData.province_id,
CityId: userData.city_id,
Address: userData.address,
PostalCode: userData.postal_code,
BusinessCategoryId: BusinessCategoryId(db)
}
return new Promise(async (resolve, reject) => {
try {
const ArpaID = await axios.get('/api/postBusiness', { ...axiosConfig(db), params: { ...data } })
if (!ArpaID.data.data) return reject(new Error('Cant save new user -- There is a problem in ArpaWebService'))
resolve({
businessID: ArpaID.data.data.BusinessId,
businessCode: ArpaID.data.data.BusinessCode
})
} catch (e) {
reject(e)
}
})
}
module.exports.updateUserOnArpa = (userData, arpa_businessID, db) => {
const data = {
BusName: userData.first_name + ' ' + userData.last_name + ' (گارانتی سایت) ',
Email: userData.email,
PhoneNo: userData.tel_number,
Mobile: userData.mobile_number,
Name: userData.first_name,
Family: userData.last_name,
NationalCode: userData.national_code,
ProvinceId: userData.province_id,
CityId: userData.city_id,
Address: userData.address,
PostalCode: userData.postal_code,
BusinessCategoryId: BusinessCategoryId(db),
BusinessID: arpa_businessID
}
return new Promise(async (resolve, reject) => {
try {
const ArpaUpdate = await axios.post('/api/putBusiness', data, axiosConfig(db))
if (!ArpaUpdate.data.status) reject(new Error('Cant update user -- There is a problem in ArpaWebService'))
resolve('updated successfully')
} catch (e) {
reject(e)
}
})
}
@@ -0,0 +1,112 @@
const User = require('../../models/User')
const ContactPageMessage = require('../../models/ContactPageMessage')
const TicketConversation = require('../../models/TicketConversation')
const Representation = require('../../models/Representation')
const PieceRequest = require('../../models/PieceRequest')
const OldPieceRequest = require('../../models/OldPieceRequest')
const BufferRequest = require('../../models/BufferRequest')
const GuaranteeReport = require('../../models/GuaranteeReport')
module.exports.getAllNotifs = async socket => {
try {
const allData = await Promise.all([
// unreadCuMsgs
ContactPageMessage.find({ read: false }),
// unreadTickets
TicketConversation.find({ messages: { $elemMatch: { isUser: true, read: false } } }),
// newCustomers
User.find({ scope: ['user'], seenByAdmin: false, confirmed: true }),
// newRepresentations
Representation.find({ status: 'registered' }),
// newPieceRequests
PieceRequest.find({ status: 'sent' }),
// newOldPieceRequests
OldPieceRequest.find({ status: 'sent' }),
// newBufferRequests
BufferRequest.find({ status: 'sent' }),
// newGuaranteeReports
GuaranteeReport.find({ status: 'sent', seen: false })
])
const unreadCuMsgs = allData[0]
const unreadTickets = allData[1]
const newCustomers = allData[2]
const newRepresentations = allData[3]
const newPieceRequests = allData[4]
const newOldPieceRequests = allData[5]
const newBufferRequests = allData[6]
const newGuaranteeReports = allData[7]
socket.emit(`admin:allNotifs`, {
unreadCuMsgs: unreadCuMsgs.length,
unreadTickets: unreadTickets.length,
newCustomers: newCustomers.length,
newRepresentations: newRepresentations.length,
newPieceRequests: newPieceRequests.length,
newOldPieceRequests: newOldPieceRequests.length,
newBufferRequests: newBufferRequests.length,
newGuaranteeReports: newGuaranteeReports.length
})
} catch (e) {
console.log(e)
}
}
module.exports.notifyAdmin = async type => {
try {
const io = global._io
const admin = io.of('/admin')
const data = { type }
if (type === 'updateNewCustomers') {
const newCustomers = await User.find({ scope: ['user'], seenByAdmin: false })
data.newCustomers = newCustomers.length
}
if (type === 'updateUnreadCuMsgs') {
const unreadCuMsgs = await ContactPageMessage.find({ read: false })
data.unreadCuMsgs = unreadCuMsgs.length
}
if (type === 'updateUnreadTickets') {
const unreadTickets = await TicketConversation.find({ messages: { $elemMatch: { isUser: true, read: false } } })
data.unreadTickets = unreadTickets.length
}
if (type === 'updateNewRepresentations') {
const newRepresentations = await Representation.find({ status: 'registered' })
data.newRepresentations = newRepresentations.length
}
if (type === 'updateNewPieceRequests') {
const newPieceRequests = await PieceRequest.find({ status: 'sent' })
data.newPieceRequests = newPieceRequests.length
}
if (type === 'updateNewOldPieceRequests') {
const newOldPieceRequests = await OldPieceRequest.find({ status: 'sent' })
data.newOldPieceRequests = newOldPieceRequests.length
}
if (type === 'updateNewBufferRequests') {
const newBufferRequests = await BufferRequest.find({ status: 'sent' })
data.newBufferRequests = newBufferRequests.length
}
if (type === 'updateNewGuaranteeReports') {
const newGuaranteeReports = await GuaranteeReport.find({ status: 'sent', seen: false })
data.newGuaranteeReports = newGuaranteeReports.length
}
admin.emit(`admin:notify`, data)
} catch (e) {
console.log(e)
}
}
@@ -0,0 +1,84 @@
const Transaction = require('../../models/Transaction')
const Announcement = require('../../models/Announcement')
module.exports.getAllNotifs = async socket => {
try {
const agentInbox = await Transaction.find({ agent_id: socket.agentId, seen: false })
socket.emit(`agent:allNotifs`, {
agentInbox: agentInbox.length
})
} catch (e) {
console.log(e)
}
}
module.exports.notifyAgent = async (type, agent_id) => {
try {
const io = global._io
const agent = io.of('/agent')
const data = { type }
if (type === 'updateAgentInbox') {
const agentInbox = await Transaction.find({ agent_id, seen: false })
data.agentInbox = agentInbox.length
}
agent.to(agent_id.toString()).emit(`agent:notify`, data)
} catch (e) {
console.log(e)
}
}
module.exports.notifyAllAgents = type => {
try {
const io = global._io
const agent = io.of('/agent')
const data = { type }
agent.emit('agent:notifyAll', data)
} catch (e) {
console.log(e)
}
}
module.exports.fetchAnnouncements = async socket => {
try {
const announcements = await Announcement.find({ expired: false, isForAgents: true })
const modifiedAnnouncements = []
let newAnnouncementsCount = 0
for await (const announcement of announcements) {
const notif = { ...announcement._doc, seen: true }
if (!notif.seenBy.includes(socket.userId)) {
notif.seen = false
newAnnouncementsCount++
}
delete notif.seenBy
delete notif.expired
delete notif.isForAgents
delete notif._creator
modifiedAnnouncements.push(notif)
}
socket.emit('agent:announcements', {
newAgentAnnosCount: newAnnouncementsCount,
agentAnnouncements: modifiedAnnouncements.reverse()
})
} catch (e) {
console.log(e)
}
}
module.exports.updateAnnouncement = async (socket, id) => {
try {
if (id) {
const announcment = await Announcement.findById(id)
if (!announcment) throw new Error('invalid announcemnet id')
if (!announcment.seenBy.includes(socket.userId)) announcment.seenBy.push(socket.userId)
await announcment.save()
socket.emit('agent:fetchNewAnnouncements')
}
} catch (e) {
console.log(e)
}
}
@@ -0,0 +1,98 @@
const TransactionDrafts = require('../../models/TransactionDraft')
const TicketConversation = require('../../models/TicketConversation')
const Announcement = require('../../models/Announcement')
module.exports.getAllNotifs = async socket => {
try {
const drafts = await TransactionDrafts.find({ user_id: socket.userId })
const unreadTickets = await TicketConversation.find({
user_id: socket.userId,
messages: { $elemMatch: { isUser: false, read: false } }
})
socket.emit(`user:allNotifs`, {
unreadTickets: unreadTickets.length,
draftsCount: drafts.length
})
} catch (e) {
console.log(e)
}
}
module.exports.notifyUser = async (type, user_id) => {
try {
const io = global._io
const user = io.of('/user')
const data = { type }
if (type === 'updateUnreadTickets') {
const unreadTickets = await TicketConversation.find({
user_id,
messages: { $elemMatch: { isUser: false, read: false } }
})
data.unreadTickets = unreadTickets.length
}
if (type === 'updateDraftsCount') {
const drafts = await TransactionDrafts.find({ user_id })
data.draftsCount = drafts.length
}
user.to(user_id.toString()).emit(`user:notify`, data)
} catch (e) {
console.log(e)
}
}
module.exports.notifyAllUsers = type => {
try {
const io = global._io
const user = io.of('/user')
const data = { type }
user.emit(`user:notifyAll`, data)
} catch (e) {
console.log(e)
}
}
module.exports.fetchAnnouncements = async socket => {
try {
const announcements = await Announcement.find({ expired: false, isForAgents: false })
const modifiedAnnouncements = []
let newAnnouncementsCount = 0
for await (const announcement of announcements) {
const notif = { ...announcement._doc, seen: true }
if (!notif.seenBy.includes(socket.userId)) {
notif.seen = false
newAnnouncementsCount++
}
delete notif.seenBy
delete notif.expired
delete notif.isForAgents
delete notif._creator
modifiedAnnouncements.push(notif)
}
socket.emit('user:announcements', {
newUserAnnosCount: newAnnouncementsCount,
userAnnouncements: modifiedAnnouncements.reverse()
})
} catch (e) {
console.log(e)
}
}
module.exports.updateAnnouncement = async (socket, id) => {
try {
if (id) {
const announcment = await Announcement.findById(id)
if (!announcment) throw new Error('invalid announcemnet id')
if (!announcment.seenBy.includes(socket.userId)) announcment.seenBy.push(socket.userId)
await announcment.save()
socket.emit('user:fetchNewAnnouncements')
}
} catch (e) {
console.log(e)
}
}
@@ -0,0 +1,67 @@
const jwt = require('jsonwebtoken')
const User = require('../../models/User')
const authentication = require('../../authentication')
module.exports.isAdmin = async (socket, next) => {
try {
const token = socket.handshake?.auth?.token
if (!token) throw new Error('unauthenticated')
// verifies secret and checks if the token is expired
const decodedToken = await jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey)
if (!decodedToken) throw new Error('unauthorized')
// find user
const user = await User.findById(decodedToken._id)
if (!user || !user.scope.includes('admin')) throw new Error('unauthorized')
socket.userId = decodedToken._id.toString()
return next()
} catch (e) {
// console.log('ws user middleware error --- ', e)
next(new Error(e))
}
}
module.exports.isUser = async (socket, next) => {
try {
const token = socket.handshake?.auth?.token
if (!token) throw new Error('unauthenticated')
// verifies secret and checks if the token is expired
const decodedToken = await jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey)
if (!decodedToken) throw new Error('unauthorized')
// find user
const user = await User.findById(decodedToken._id)
if (!user || !user.scope.includes('user')) throw new Error('unauthorized')
socket.userId = decodedToken._id.toString()
return next()
} catch (e) {
// console.log('ws user middleware error --- ', e)
next(new Error(e))
}
}
module.exports.isAgent = async (socket, next) => {
try {
const token = socket.handshake?.auth?.token
if (!token) throw new Error('unauthenticated')
// verifies secret and checks if the token is expired
const decodedToken = await jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey)
if (!decodedToken) throw new Error('unauthorized')
// find user
const user = await User.findById(decodedToken._id)
if (!user || !user.scope.includes('user')) throw new Error('unauthorized')
if (!user.isAgent) throw new Error('شما نماینده نیستید')
socket.userId = decodedToken._id.toString()
socket.agentId = user.representation_id.toString()
return next()
} catch (e) {
next(new Error(e))
}
}
@@ -0,0 +1,23 @@
const { isAdmin } = require('../middlewares/ws_authentication')
const adminEventsController = require('../controllers/admin_EventsController')
module.exports.adminNamespace = () => {
const io = global._io
const admin = io.of('/admin')
// admins middlewares
admin.use(isAdmin)
// attach events
admin.on('connection', socket => {
adminEventsController.getAllNotifs(socket)
/// /////////////////////////////////////////////////////// handle connection error
socket.on('connect_error', err => {
console.log(err.message)
})
/// ////////////////////////////////////////////////////// events
// socket.on('admin:getNotifs', () => adminEventsController.getAllNotifs(socket))
})
}
@@ -0,0 +1,25 @@
const { isAgent } = require('../middlewares/ws_authentication')
const agentEventsController = require('../controllers/agent_EventsController')
module.exports.agentNamespace = () => {
const io = global._io
const agent = io.of('/agent')
// agents middlewares
agent.use(isAgent)
// attach events
agent.on('connection', socket => {
socket.join(socket.agentId)
agentEventsController.getAllNotifs(socket)
/// /////////////////////////////////////////////////////// handle connection error
socket.on('connect_error', err => {
console.log(err.message)
})
/// ////////////////////////////////////////////////////// events
socket.on('agent:fetchAnnouncements', data => agentEventsController.fetchAnnouncements(socket))
socket.on('agent:updateAnnouncement', data => agentEventsController.updateAnnouncement(socket, data))
})
}
@@ -0,0 +1,25 @@
const { isUser } = require('../middlewares/ws_authentication')
const userEventsController = require('../controllers/user_EventsController')
module.exports.userNamespace = () => {
const io = global._io
const user = io.of('/user')
// users middlewares
user.use(isUser)
// attach events
user.on('connection', socket => {
socket.join(socket.userId)
userEventsController.getAllNotifs(socket)
/// /////////////////////////////////////////////////////// handle connection error
socket.on('connect_error', err => {
console.log(err.message)
})
/// ////////////////////////////////////////////////////// events
socket.on('user:fetchAnnouncements', data => userEventsController.fetchAnnouncements(socket))
socket.on('user:updateAnnouncement', data => userEventsController.updateAnnouncement(socket, data))
})
}
+23
View File
@@ -0,0 +1,23 @@
function init(server) {
// init params
const { WebSocketPort, NuxtPort, isProduction } = require('../_env')
const { userNamespace } = require('./namespaces/user_NameSpace')
const { agentNamespace } = require('./namespaces/agent_NameSpace')
const { adminNamespace } = require('./namespaces/admin_NameSpace')
const { Server } = require('socket.io')
const socketIO = require('socket.io')
// init ws
let io
if (isProduction) io = socketIO(server)
else io = new Server(WebSocketPort, { cors: { origin: '*' } })
console.log(`🟢 ~ WebSocket Server is listening on port ${isProduction ? NuxtPort : WebSocketPort}`)
global._io = io
// namespaces
userNamespace()
agentNamespace()
adminNamespace()
}
module.exports = init
+39
View File
@@ -0,0 +1,39 @@
const EnvirementVariables = {
// node envirements
isDev: process.env.NODE_ENV === 'devServer',
isProduction: process.env.NODE_ENV === 'production',
// server ports
DevServerPort: 4000,
WebSocketPort: 5000,
NuxtPort: 7420,
NuxtHost: '0.0.0.0',
WebSocketURL() {
return EnvirementVariables.isProduction ? '' : `ws://localhost:${EnvirementVariables.WebSocketPort}`
},
/// ////////////// arpa configurations
// veriry
verityBaseUrl: 'http://80.210.26.100:8080/serv',
verityTokenUrl: 'http://80.210.26.100:8080/serv/token/GetServiceToken',
VerityUserGroupId: 28,
VerityBusinessCategoryId: 28,
VerityStockAreaId: 328,
verityAccount: {
username: 'arpa',
password: 'Arpa159@951'
},
// panatech
panatechBaseUrl: 'http://80.210.26.100:8083/serv',
panatechTokenUrl: 'http://80.210.26.100:8083/serv/token/GetServiceToken',
PanatechUserGroupId: 25,
PanatechBusinessCategoryId: 19,
PanatechStockAreaId: 13,
panatechAccount: {
username: 'arpa',
password: 'Arpa159@951'
}
}
module.exports = EnvirementVariables
+104
View File
@@ -0,0 +1,104 @@
const jwt = require('jsonwebtoken')
const User = require('./models/User')
function res401(res, message) {
return res.status(401).json({ message })
}
const authentication = {
// secret for generating jwt token
secretKey:
'6fdd08afdb7ec5b7b83ba5d7635a4ad78a5c9545a9ccd90b0b74299b5ab3a69f640cdd1e0c47655daebe099c96e3172da9be76892f14ef2aec34937757c75f27',
// check if just logged in (admin-or-user) (middleware)
isLoggedIn(req, res, next) {
try {
const token = req.headers?.authorization
if (!token) throw new Error('err')
const decoded = jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey)
if (!decoded) throw new Error('err')
else return next()
} catch (err) {
return res401(res, 'unauthenticated')
}
},
// check if admin logged in (middleware)
async isAdmin(req, res, next) {
try {
const token = req.headers?.authorization
if (!token) throw new Error('err')
const decoded = jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey)
if (!decoded) throw new Error('err')
const user = await User.findById(decoded._id)
if (!user || !user.scope.includes('admin')) throw new Error('err')
req.user_id = decoded._id
return next()
} catch (err) {
return res401(res, 'unauthorized')
}
},
// check if user logged in (middleware)
async isUser(req, res, next) {
try {
const token = req.headers?.authorization
if (!token) throw new Error('err')
const decoded = jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey)
if (!decoded) throw new Error('err')
const user = await User.findById(decoded._id)
if (!user || !user.scope.includes('user')) throw new Error('err')
req.user_id = decoded._id
return next()
} catch (err) {
return res401(res, 'unauthorized')
}
},
// check if user is agent and add agent id to body(middleware)
async isAgent(req, res, next) {
try {
const token = req.headers?.authorization
if (!token) throw new Error('err')
const decoded = jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey)
if (!decoded) throw new Error('err')
const user = await User.findById(decoded._id)
if (!user || !user.isAgent || !user.scope.includes('user')) throw new Error('err')
req.user_id = decoded._id
req.agent_id = user.representation_id
return next()
} catch (err) {
return res401(res, 'unauthorized')
}
},
// get user id from token
getID: req => {
const token = req.headers?.authorization
return jwt.verify(token?.replace(/^Bearer\s/, ''), authentication.secretKey, (err, decoded) => {
if (err) return null
else return decoded._id
})
},
// check if admin has permission (middleware - web only)
hasPermission: permission => {
return async (req, res, next) => {
try {
const token = req.headers?.authorization
if (!token) throw new Error('err')
const user = await User.findOne({ token })
if (!user || !user.permissions.includes(permission)) throw new Error('err')
else return next()
} catch (err) {
return res401(res, 'unauthorized')
}
}
}
}
module.exports = authentication
@@ -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 })
})
}
]
+31
View File
@@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const mongoose = require('mongoose')
mongoose.plugin(schema => {
schema.set('toObject', { getters: true })
schema.set('toJSON', { getters: true })
schema.set('timestamps', {
createdAt: 'created_at',
updatedAt: 'updated_at'
})
})
// mongodb database connection string. change it as per your needs. here "mydb" is the name of the database. You don't need to create DB from mongodb terminal. mongoose create the database automatically.
const inHostUrl = 'mongodb://asanserv_admin:admin1234@localhost:27017/asanserv_database'
const outHostUrl =
'mongodb://asanserv_admin:admin1234@www.asan-service.com:27017/asanserv_database?serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=asanserv_database'
const locaUrl = 'mongodb://localhost:27017/AsanService'
mongoose.connect(locaUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
})
const database = mongoose.connection
database.on('error', console.error.bind(console, 'connection error:'))
database.once('open', function callback() {
console.log('🟠 ~ MongoDB Connected...')
})
module.exports = database
+65
View File
@@ -0,0 +1,65 @@
/// / develop environment config
const { isDev, isProduction, DevServerPort } = require('./_env')
const wss = require('./WebSocket/wss')
/// / init express app (wrapping all functions into init() to prevent running in development mode by nuxt dev mode)
function init() {
// run preConfigured modules
require('./database')
require('body-parser')
// include modules to configure
const express = require('express')
const fileUpload = require('express-fileupload')
const authentication = require('./authentication')
const { checkThirdPartyAccess } = require('./plugins/checkThirdPartyAccess')
// const { getVerityToken, getPanatechToken } = require('./ArpaWebService')
const cronJobs = require('./plugins/cronJobs')
const router = express.Router()
// Create express instance
const app = express()
// Init body-parser options (inbuilt with express)
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(fileUpload())
// load plugins
// getVerityToken()
// getPanatechToken()
cronJobs()
// API routes
const Public = require('./routes/public')
const admin = require('./routes/admin')
const user = require('./routes/user')
const agent = require('./routes/agent')
const auth = require('./routes/auth')
const cross = require('./routes/cross')
const thirdParty = require('./routes/thirdParty')
// Use API Routes
router.use('/public', Public)
router.use('/admin', authentication.isAdmin, admin)
router.use('/user', authentication.isUser, user)
router.use('/agent', authentication.isAgent, agent)
router.use('/auth', auth)
router.use('/cross', cross)
router.use('/thirdParty', checkThirdPartyAccess, thirdParty)
app.use(isDev ? '/api' : '', router)
return app
}
/// / development server
if (isDev) {
init().listen(DevServerPort, () => {
console.log('🟢 ~ Node Server is running in development mode on port:', DevServerPort)
})
wss()
}
/// / server middleware (production mode)
module.exports.serverMiddleware = isProduction && { path: '/api', handler: init() }
+13
View File
@@ -0,0 +1,13 @@
const mongoose = require('mongoose')
const AnnouncementSchema = mongoose.Schema({
title: String,
caption: String,
seenBy: [mongoose.ObjectId],
expireDate: Number,
expired: { type: Boolean, default: false },
isForAgents: { type: Boolean, default: false },
_creator: { type: mongoose.ObjectId, ref: 'User' }
})
module.exports = mongoose.model('Announcement', AnnouncementSchema)
+36
View File
@@ -0,0 +1,36 @@
const mongoose = require('mongoose')
const BufferRequestSchema = mongoose.Schema({
// system structure
_openedBy: { type: mongoose.ObjectId, ref: 'User' },
_updatedBy: { type: mongoose.ObjectId, ref: 'User' },
user_id: { type: mongoose.ObjectId, ref: 'User' },
agent_id: { type: mongoose.ObjectId, ref: 'Representation' },
// form info
description: String,
createDate: String,
sendDate: String,
trackingCode: String,
items: [
{
ItemName: String,
ItemID: String,
ItemCode: String,
bufferQuantity: Number
}
],
// admin operations
seen: { type: Boolean, default: false },
status: { type: String, enum: ['temp', 'sent', 'ongoing', 'waiting', 'delivered'], default: 'temp' },
statusHistory: [
{
status: String,
date: Number
}
],
deliveryCode: String
})
module.exports = mongoose.model('BufferRequest', BufferRequestSchema)
+11
View File
@@ -0,0 +1,11 @@
const mongoose = require('mongoose')
const ContactPageMessageSchema = new mongoose.Schema({
full_name: String,
email: String,
message: String,
read: { type: Boolean, default: false },
read_by: { type: mongoose.ObjectId, ref: 'User' }
})
module.exports = mongoose.model('ContactPageMessage', ContactPageMessageSchema)
+9
View File
@@ -0,0 +1,9 @@
const mongoose = require('mongoose')
const FAQSchema = mongoose.Schema({
_creator: { type: mongoose.ObjectId, ref: 'User' },
question: String,
answer: String
})
module.exports = mongoose.model('FAQ', FAQSchema)
+42
View File
@@ -0,0 +1,42 @@
const mongoose = require('mongoose')
const GuaranteeReportSchema = mongoose.Schema({
// system structure
_openedBy: { type: mongoose.ObjectId, ref: 'User' },
_updatedBy: { type: mongoose.ObjectId, ref: 'User' },
user_id: { type: mongoose.ObjectId, ref: 'User' },
agent_id: { type: mongoose.ObjectId, ref: 'Representation' },
// form info
description: String,
createDate: String,
sendDate: String,
trackingCode: String,
items: [
{
// customer info
customerName: String,
customerTel: String,
// product info
ItemName: String,
SerialNo1: String,
ItemID: String,
ItemCode: String,
// product issue
productIssue: String,
usedPieces: String,
// dates
recieveDate: String,
deliverDate: String
}
],
// admin operations
seen: { type: Boolean, default: false },
archived: { type: Boolean, default: false },
status: { type: String, enum: ['temp', 'sent'], default: 'temp' }
})
module.exports = mongoose.model('GuaranteeReport', GuaranteeReportSchema)
+8
View File
@@ -0,0 +1,8 @@
const mongoose = require('mongoose')
const HelpSchema = mongoose.Schema({
_creator: { type: mongoose.ObjectId, ref: 'User' },
helpId: { type: mongoose.ObjectId, ref: 'Learning' }
})
module.exports = mongoose.model('Help', HelpSchema)
+27
View File
@@ -0,0 +1,27 @@
const mongoose = require('mongoose')
const paginate = require('mongoose-paginate-v2')
function video(vid) {
if (vid) return '/uploads/videos/' + vid
}
function image(img) {
return '/uploads/images/blog/' + img
}
function thumb(img) {
return '/uploads/images/blog/thumb/' + img
}
const LearningSchema = mongoose.Schema({
_creator: { type: mongoose.ObjectId, ref: 'User' },
title: String,
short_description: String,
description: String,
cover: { type: String, get: image },
video: { type: String, get: video },
thumb: { type: String, get: thumb }
})
LearningSchema.plugin(paginate)
module.exports = mongoose.model('Learning', LearningSchema)
+23
View File
@@ -0,0 +1,23 @@
const mongoose = require('mongoose')
function image(img) {
if (img) return '/uploads/images/lottery/' + img
}
const LotterySchema = mongoose.Schema({
entryWidth: Number,
entryHeight: Number,
entryBgImg: { type: String, get: image },
resultWidth: Number,
resultHeight: Number,
resultBgImg: { type: String, get: image },
title: String,
lotteryCode: String,
participants: [],
winnersCount: { type: Number, default: 1 },
winnersList: [],
expireDate: Number,
expired: { type: Boolean, default: false }
})
module.exports = mongoose.model('Lottery', LotterySchema)
+16
View File
@@ -0,0 +1,16 @@
const mongoose = require('mongoose')
function image(img) {
if (img) return '/uploads/images/lottery/' + img
}
const LotteryPopUpSchema = mongoose.Schema({
visible: { type: Boolean, default: true },
x: { type: Number, default: 15 },
y: { type: Number, default: 15 },
w: { type: Number, default: 40 },
h: { type: Number, default: 40 },
bgImg: { type: String, get: image }
})
module.exports = mongoose.model('LotteryPopUp', LotteryPopUpSchema)
+45
View File
@@ -0,0 +1,45 @@
const mongoose = require('mongoose')
const OldPieceRequestSchema = mongoose.Schema({
// system structure
_openedBy: { type: mongoose.ObjectId, ref: 'User' },
_updatedBy: { type: mongoose.ObjectId, ref: 'User' },
user_id: { type: mongoose.ObjectId, ref: 'User' },
agent_id: { type: mongoose.ObjectId, ref: 'Representation' },
// form info
description: String,
createDate: String,
sendDate: String,
trackingCode: String,
items: [
{
// product info
ItemReceptionTransDate: String,
ItemName: String,
SerialNo1: String,
ItemID: String,
ItemCode: String,
// GStartDate: String,
// GEndDate: String,
// piece info
pieceName: String,
pieceCode: String,
pieceId: { type: mongoose.ObjectId, ref: 'Piece' }
}
],
// admin operations
seen: { type: Boolean, default: false },
status: { type: String, enum: ['temp', 'sent', 'ongoing', 'waiting', 'delivered'], default: 'temp' },
statusHistory: [
{
status: String,
date: Number
}
],
deliveryCode: String
})
module.exports = mongoose.model('OldPieceRequest', OldPieceRequestSchema)
+8
View File
@@ -0,0 +1,8 @@
const mongoose = require('mongoose')
const PieceSchema = mongoose.Schema({
name: String,
code: String
})
module.exports = mongoose.model('Piece', PieceSchema)
+47
View File
@@ -0,0 +1,47 @@
const mongoose = require('mongoose')
const PieceRequestSchema = mongoose.Schema({
// system structure
_openedBy: { type: mongoose.ObjectId, ref: 'User' },
_updatedBy: { type: mongoose.ObjectId, ref: 'User' },
user_id: { type: mongoose.ObjectId, ref: 'User' },
agent_id: { type: mongoose.ObjectId, ref: 'Representation' },
// form info
description: String,
createDate: String,
sendDate: String,
trackingCode: String,
items: [
{
// product info
ItemReceptionTransDate: String,
ItemName: String,
SerialNo1: String,
ItemID: String,
ItemCode: String,
// GStartDate: String,
// GEndDate: String,
gStatus: Boolean,
// piece info
pieceName: String,
pieceCode: String,
pieceQuantity: Number,
pieceId: { type: mongoose.ObjectId, ref: 'Piece' }
}
],
// admin operations
seen: { type: Boolean, default: false },
status: { type: String, enum: ['temp', 'sent', 'ongoing', 'waiting', 'delivered'], default: 'temp' },
statusHistory: [
{
status: String,
date: Number
}
],
deliveryCode: String
})
module.exports = mongoose.model('PieceRequest', PieceRequestSchema)
+111
View File
@@ -0,0 +1,111 @@
const mongoose = require('mongoose')
function file(file) {
return '/uploads/representation_docs/' + this.name
}
const FilesSchema = mongoose.Schema({
name: String
})
FilesSchema.virtual('url').get(file)
const RepresentationSchema = mongoose.Schema({
// user info
user_id: { type: mongoose.ObjectId, ref: 'User' },
representation_code: String,
agent_code: String,
editAccess: { type: Boolean, default: false },
// personal info
full_name: String,
birth_date: String,
id_number: String,
place_of_issue: String,
national_code: String,
fathers_name: String,
education_level: String,
military_status: String,
certificates: String,
// contact info
store_name: String,
province_name: String,
province_id: String,
city_name: String,
city_id: String,
postal_code: String,
mobile_number: String,
tel_number: String,
fax_number: String,
economic_code: String,
email: String,
address: String,
// location info
business_license: Boolean,
ownership_type: { type: String, enum: ['owner', 'rent', 'rghit_of_business'] },
total_area: String,
repair_area: String,
stock_area: String,
customer_reference_floor: String,
place_location: { type: String, enum: ['tech_passage', 'other'] },
geo_location: { type: String, enum: ['main_street', 'side_street', 'alley', 'inside_passage', 'outside_passage'] },
banner_info: String,
repair_technicians: String,
repair_masters: String,
office_workers: String,
bike_deliveries: String,
// experience info
computer_repair_exp: String,
multimedia_repair_exp: String,
business_exp: String,
// common questions
representation_type: {
type: String,
enum: ['verity', 'panatech', 'both'],
default: 'both'
},
know_asanServ_from: {
type: String,
enum: ['company_agents', 'website', 'company_workers', 'exhibition', 'introduced', 'other']
},
introducer_info: String,
asanServ_products_knowledge: { type: Number, enum: [0, 1, 2, 3, 4] },
computer_saling_exp: Boolean,
computer_saling_description: String,
other_representations: [
{
trademark: String,
company_name: String,
cooperation_history: String,
cooperation_start_year: String
}
],
more_descriptions: String,
// admins
status: {
type: String,
enum: ['registered', 'ongoing', 'verification', 'accepted', 'rejected'],
default: 'registered'
},
// files
upload: { type: Boolean, default: true },
tradeUnion: [FilesSchema],
expertise: [FilesSchema],
ownership: [FilesSchema],
repairShop: [FilesSchema],
itEmployee: [FilesSchema],
itExpert: [FilesSchema],
financialGuarantees: [FilesSchema],
//
archived: { type: Boolean, default: false },
_updatedBy: { type: mongoose.ObjectId, ref: 'User' },
_revoked: { type: Boolean, default: false },
_revokedBy: { type: mongoose.ObjectId, ref: 'User' }
})
module.exports = mongoose.model('Representation', RepresentationSchema)
+14
View File
@@ -0,0 +1,14 @@
const mongoose = require('mongoose')
const SMSBroadcastSchema = mongoose.Schema({
message: String,
recievers: [
{
user_id: { type: mongoose.ObjectId, ref: 'User' },
mobile_number: String
}
],
_creator: { type: mongoose.ObjectId, ref: 'User' }
})
module.exports = mongoose.model('SMSBroadcast', SMSBroadcastSchema)
+16
View File
@@ -0,0 +1,16 @@
const mongoose = require('mongoose')
const SurveySchema = mongoose.Schema({
purchasedProduct: { type: Number, enum: [1, 2, 3, 4, 5] },
guaranteeWorkFlow: { type: Number, enum: [1, 2, 3, 4, 5] },
employeeResponsibility: { type: Number, enum: [1, 2, 3, 4, 5] },
serviceQuality: { type: Number, enum: [1, 2, 3, 4, 5] },
serviceTime: { type: Number, enum: [1, 2, 3, 4, 5] },
repairQuality: { type: Number, enum: [1, 2, 3, 4, 5] },
coast: { type: Number, enum: [1, 2, 3, 4, 5] },
description: String,
code: String,
user: { type: mongoose.ObjectId, ref: 'User' },
})
module.exports = mongoose.model('Survey', SurveySchema)
+10
View File
@@ -0,0 +1,10 @@
const mongoose = require('mongoose')
const SurveyCheckSchema = mongoose.Schema({
code: String,
user: { type: mongoose.ObjectId, ref: 'User' },
smsSent: { type: Boolean, default: false },
timeAdded: Number // timestamp
})
module.exports = mongoose.model('SurveyCheck', SurveyCheckSchema)
+22
View File
@@ -0,0 +1,22 @@
const mongoose = require('mongoose')
function image(img) {
if (img) return '/uploads/images/tickets/' + img
}
const Ticket = mongoose.Schema({
message: String,
image: { type: String, get: image },
isUser: { type: Boolean, default: true },
read: { type: Boolean, default: false },
user_id: { type: mongoose.ObjectId, ref: 'User' }
})
const TicketConversation = mongoose.Schema({
title: String,
transaction_id: String,
user_id: { type: mongoose.ObjectId, ref: 'User' },
messages: [Ticket]
})
module.exports = mongoose.model('TicketConversation', TicketConversation)
+34
View File
@@ -0,0 +1,34 @@
const mongoose = require('mongoose')
const TransactionSchema = mongoose.Schema({
// system structure
user_id: { type: mongoose.ObjectId, ref: 'User' },
agent_id: { type: mongoose.ObjectId, ref: 'Representation' },
db_name: { type: String, enum: ['verity', 'panatech'] },
// form info
BusinessID: String,
Description: String,
cAddress1: String,
TransCCustom1: String,
cTel1: String,
items: Array,
//
TempReceiptTransNumber: String,
ItemReceptionTransNumber: String,
TempReceiptTransDate: String,
ItemReceptionTransDate: String,
// agent operations
seen: { type: Boolean, default: false },
status: { type: String, enum: ['saved', 'recieved', 'ongoing', 'waiting', 'delivered'], default: 'saved' },
statusHistory: [
{
status: String,
date: Number
}
],
deliveryCode: String
})
module.exports = mongoose.model('Transaction', TransactionSchema)
+10
View File
@@ -0,0 +1,10 @@
const mongoose = require('mongoose')
const TransactionDraftSchema = mongoose.Schema({
user_id: { type: mongoose.ObjectId, ref: 'User' },
db_name: { type: String, enum: ['verity', 'panatech'] },
description: String,
items: { type: Array, default: [] }
})
module.exports = mongoose.model('TransactionDraft', TransactionDraftSchema)
+59
View File
@@ -0,0 +1,59 @@
const mongoose = require('mongoose')
const UserSchema = mongoose.Schema({
// for admins
_creator: { type: mongoose.ObjectId, ref: 'User' },
private: { type: Boolean, default: false },
username: String,
permissions: Array,
// for user
national_code: String,
province_id: String,
city_id: String,
province_name: String,
city_name: String,
address: String,
postal_code: String,
tel_number: String,
mobile_number: String,
email: String,
store_name: String,
// verity info
verity_businessID: String,
verity_businessCode: String,
old_verity_businessID: String,
old_verity_businessCode: String,
// panatech info
panatech_businessID: String,
panatech_businessCode: String,
old_panatech_businessID: String,
old_panatech_businessCode: String,
isAgent: { type: Boolean, default: false },
representation_id: { type: mongoose.ObjectId, ref: 'Representation' },
representation_code: String,
askedForRepresentation: { type: Boolean, default: false },
// for both
first_name: String,
last_name: String,
password: String,
/// //////////////////////////////// user confirmations
confirmed: { type: Boolean, default: false },
email_confirmed: { type: Boolean, default: false },
mobile_confirmed: { type: Boolean, default: false },
emailConfirmationKey: String,
mobileConfirmationKey: String,
seenByAdmin: { type: Boolean, default: false },
/// /////////////
scope: { type: Array, default: ['user'] },
token: String,
appToken: String,
resetPassToken: String
})
module.exports = mongoose.model('User', UserSchema)
+17
View File
@@ -0,0 +1,17 @@
const mongoose = require('mongoose')
const paginate = require('mongoose-paginate-v2')
function image(img) {
return '/uploads/images/warrantyTerms/' + img
}
const WarrantySchema = mongoose.Schema({
_creator: { type: mongoose.ObjectId, ref: 'User' },
title: String,
short_description: String,
description: String,
image: { type: String, get: image }
})
WarrantySchema.plugin(paginate)
module.exports = mongoose.model('Warranty', WarrantySchema)
+33
View File
@@ -0,0 +1,33 @@
const mongoose = require('mongoose')
const paginate = require('mongoose-paginate-v2')
function image(img) {
return '/uploads/images/downloads/' + img
}
function file(file) {
return '/uploads/apps/' + file
}
const DownloadFilesSchema = mongoose.Schema({
_creator: { type: mongoose.ObjectId, ref: 'User' },
name: String,
os: {
type: String,
enum: ['windows', 'linux', 'mac', 'android', 'ios']
},
file: { type: String, get: file }
})
const DownloadSchema = mongoose.Schema({
_creator: { type: mongoose.ObjectId, ref: 'User' },
title: String,
short_description: String,
description: String,
image: { type: String, get: image },
category: mongoose.ObjectId,
files: [DownloadFilesSchema]
})
DownloadSchema.plugin(paginate)
module.exports = mongoose.model('Download', DownloadSchema)
@@ -0,0 +1,8 @@
const mongoose = require('mongoose')
const DownloadCategorySchema = mongoose.Schema({
_creator: { type: mongoose.ObjectId, ref: 'User' },
name: String
})
module.exports = mongoose.model('DownloadCategory', DownloadCategorySchema)
+53
View File
@@ -0,0 +1,53 @@
const axios = require('axios')
const accountInfo = {
Username: 'asanservice.sms@gmail.com',
Password: '7ea2243a',
Number: '5000467341',
url: 'http://www.afe.ir/WebService/V4/BoxService.asmx'
}
/// /////// http post soap method
module.exports.SMS = (mobileNumbersArray, message) => {
return new Promise((resolve, reject) => {
function renderMobileNumbers(array) {
return array.map(item => `<string>${item}</string>`).join('')
}
const xml = `<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendMessage xmlns="http://www.afe.ir/">
<Username>${accountInfo.Username}</Username>
<Password>${accountInfo.Password}</Password>
<Number>${accountInfo.Number}</Number>
<Mobile>
${renderMobileNumbers(mobileNumbersArray)}
</Mobile>
<Message>${message}</Message>
<Type>1</Type>
</SendMessage>
</soap:Body>
</soap:Envelope>`
axios
.post(accountInfo.url, xml, {
headers: {
'Content-Type': 'text/xml; charset=utf-8',
SOAPAction: 'http://www.afe.ir/SendMessage'
}
})
.then(res => {
resolve(res)
})
.catch(err => {
console.log(
'this is sms module error ------------------ status code: ',
err.response.status,
'error message: ',
err.response.data
)
resolve(err)
})
})
}
+4
View File
@@ -0,0 +1,4 @@
module.exports.phrases = {
signature: ' asan-service.com ',
thanks: ' از همراهی شما سپاس گزاریم. '
}
@@ -0,0 +1,58 @@
const fs = require('fs')
const readXlsxFile = require('read-excel-file/node')
const guaranteeSerialsPath = './static/uploads/serials'
const productSerialsPath = './static/uploads/serials_products'
const serialChecker = async (serial, type = 'guaranteeSerial') => {
let exelsPath
if (type === 'guaranteeSerial') exelsPath = guaranteeSerialsPath
if (type === 'orginality') exelsPath = productSerialsPath
const lowerSerial = serial.toLowerCase()
// a promise to lowercase items and filter null or DateObjects
const toLowerCaseArray = array => {
return new Promise((resolve, reject) => {
const newArray = []
array.forEach((item, index) => {
if (item !== null && typeof item === 'string') newArray.push(item.toLowerCase())
if (item !== null && typeof item === 'number') newArray.push(item.toString())
if (index === array.length - 1) return resolve(newArray)
})
})
}
// create an array of all exel files data
const exelFilesData = []
try {
// get a list of all exel files
const serialFiles = await fs.readdirSync(exelsPath)
// push each exel file data to exelFilesData array
let n0 = 0
for await (const file of serialFiles) {
// reading all exel files one by one
const exelFile = await readXlsxFile(`${exelsPath}/${file}`)
exelFilesData.push(exelFile)
// flat exelFilesData and filter and lowerCase it's items
if (n0 === serialFiles.length - 1) {
const flattedArray = exelFilesData.flat(10000)
const lowerCaseFlattedArray = await toLowerCaseArray(flattedArray)
// loop throw lowerCased items to find exact match item
let n1 = 0
for await (const item of lowerCaseFlattedArray) {
if (item === lowerSerial) return true
if (n1 === lowerCaseFlattedArray.length - 1) return false
n1++
}
}
n0++
}
} catch (e) {
throw new Error(e)
}
}
module.exports.serialChecker = serialChecker
+9
View File
@@ -0,0 +1,9 @@
const token = '8f552d860d0cdbbf4afaa0749acb7f3e32efcdc85fc4b49bb3d356ff30f0504a'
module.exports.checkThirdPartyAccess = (req, res, next) => {
try {
if (req.headers?.authorization?.trim() !== token) throw new Error('unauthorized')
else next()
} catch {
return res.status(422).json({ message: 'unauthorized' })
}
}
@@ -0,0 +1,114 @@
/// ///////////////////////////////////////////////////////////////////////////////////////// expresjs methods
module.exports.res404 = (res, err) => {
return res.status(404).json({ message: err })
}
module.exports.res406 = (res, err) => {
return res.status(406).json({ message: err })
}
module.exports.res500 = (res, err) => {
return res.status(500).json({ message: err })
}
module.exports.checkValidations = validationResult => {
return (req, res, next) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({ validation: errors.mapped() })
else next()
}
}
/// ///////////////////////////////////////////////////////////////////////////////////////// sting methods
module.exports.removeWhiteSpaces = str => {
return str.replace(/ /g, '')
}
module.exports.isPersian = str => {
return str.match(/^[\u0600-\u06FF\s]+$/)
}
module.exports.isPersianWithDigits = str => {
return str.match(/^[\u0600-\u06FF\s\d]+$/)
}
module.exports.isLatin = str => {
return str.match(/^[A-Za-z\s]+$/g)
}
module.exports.isLatinWithDigits = str => {
return str.match(/^[a-zA-Z\s0-9()*_\-!#$%^&*,."'\][]*$/g)
}
module.exports.hasWhiteSpaces = str => {
return str.includes(' ')
}
/// ///////////////////////////////////////////////////////////////////////////////////////// number methods
module.exports.generateRandomDigits = digitsLength => {
function generateRandomDigits(DIGITS_LENGTH) {
const add = 1
let max = 12 - add // 12 is the min safe number Math.random() can generate without it starting to pad the end with zeros.
if (DIGITS_LENGTH > max) {
return generateRandomDigits(max) + generateRandomDigits(DIGITS_LENGTH - max)
}
max = Math.pow(10, DIGITS_LENGTH + add)
const min = max / 10 // Math.pow(10, n) basically
const number = Math.floor(Math.random() * (max - min + 1)) + min
return ('' + number).substring(add)
}
return generateRandomDigits(digitsLength)
}
module.exports.generateRandomDigitsInRangeOf = max => {
return Math.floor(Math.random() * max) + 1
}
/// ///////////////////////////////////////////////////////////////////////////////////////// iran region methods
module.exports.checkNationalCode = code => {
/* eslint-disable eqeqeq */
const L = code.length
if (L < 8 || parseInt(code, 10) == 0) return false
code = ('0000' + code).substr(L + 4 - 10)
if (parseInt(code.substr(3, 6), 10) == 0) return false
const c = parseInt(code.substr(9, 1), 10)
let s = 0
for (let i = 0; i < 9; i++) {
s += parseInt(code.substr(i, 1), 10) * (10 - i)
}
s = s % 11
return (s < 2 && c == s) || (s >= 2 && c == 11 - s)
/* eslint-enable eqeqeq */
}
module.exports.checkMobileNumber = number => {
const regex = /^(\+98|0)?9\d{9}$/
const result = regex.test(number)
return result
}
module.exports.normalizeMobileNumber = number => {
return number.split('').reverse().join('').slice(0, 10).concat('0').split('').reverse().join('')
}
module.exports.nameOptimizer = name => {
function regex(str) {
return new RegExp(str)
}
return name
.replace(regex('آقای'), '')
.replace(regex('آقا'), '')
.replace(regex('جنابه'), '')
.replace(regex('جناب'), '')
.replace(regex('سرکار خانوم'), '')
.replace(regex('سرکار خانم'), '')
.replace(regex('سرکارخانوم'), '')
.replace(regex('سرکارخانومه'), '')
.replace(regex('سرکارخانمه'), '')
.replace(regex('سرکارخانم'), '')
.replace(regex('سرکار'), '')
.replace(regex('خانوم'), '')
.replace(regex('خانم'), '')
}
+289
View File
@@ -0,0 +1,289 @@
/* eslint-disable no-unused-vars */
const User = require('../models/User')
const Lottery = require('../models/Lottery')
const SurveyCheck = require('../models/SurveyCheck')
const Survey = require('../models/Survey')
const Announcement = require('../models/Announcement')
const { saveUserToArpa, updateUserOnArpa } = require('../ArpaWebservice')
const { generateRandomDigitsInRangeOf } = require('./controllersHelperFunctions')
const { SMS } = require('./SMS_Module')
const { phrases } = require('./SMS_Phrases')
/// /////// times
const minute = 1000 * 60
const hour = minute * 60
const day = hour * 24
/// /////// jobs
const jobs = {
checkUserActivation() {
console.log('✅ --job: check users for activation is running')
return setInterval(async () => {
try {
const users = await User.find({ confirmed: false })
for await (const user of users) {
// item time and timeout
const itemTime = Date.parse(user.created_at)
const timeout = itemTime + day
// check if passed 24 hours and remove registration
if (Date.now() >= timeout) {
await user.remove()
}
}
} catch (e) {
console.log(e)
}
}, hour)
},
checkIfAnnouncementsExpired() {
console.log('✅ --job: check announcements for expire date is running')
return setInterval(async () => {
try {
const announcements = await Announcement.find({ expired: false })
for await (const notif of announcements) {
if (Date.now() > notif.expireDate) {
notif.expired = true
await notif.save()
}
}
} catch (e) {
console.log(e)
}
}, hour)
},
drawLottery() {
console.log('✅ --job: check for lottery draw is running')
return setInterval(async () => {
try {
const lottery = await Lottery.findOne({ expired: false })
if (!lottery || lottery.expireDate > Date.now()) return
/// ///////// assets (arrays)
const winnersCount = lottery.winnersCount
const participants = lottery.participants
const participantsMobileNumbers = []
const winnersArray = []
const winnersMobileNumbers = []
/// ///////// assets (functions)
function getWinner(array) {
return new Promise(async (resolve, reject) => {
const winner = array[generateRandomDigitsInRangeOf(array.length - 1)]
if (await winnersMobileNumbers.includes(winner.mobile)) resolve(await getWinner(array))
else {
winnersMobileNumbers.push(winner.mobile)
winnersArray.push(winner)
resolve()
}
})
}
// normalize repeated mobile numbers to decide which method to use
for await (const item of participants) {
if (!participantsMobileNumbers.includes(item.mobile)) participantsMobileNumbers.push(item.mobile)
}
// draw function
if (participantsMobileNumbers.length > 1000) {
// console.log('------------------------- larg number block ran')
// chunk all participants to n part (Number(winnersCount) part)
const partLength = Math.floor(participants.length / winnersCount)
const chunckedArrayToParts = []
for (let i = 0; i < winnersCount; i++) {
const chunck = await participants.slice(i * partLength, i * partLength + partLength)
await chunckedArrayToParts.push(chunck)
}
for await (const item of chunckedArrayToParts) {
await getWinner(item)
}
} else if (participantsMobileNumbers.length > winnersCount) {
// console.log('------------------------- grater than winnersCount block ran')
const winnersCountArray = []
for (let i = 0; i < winnersCount; i++) {
winnersCountArray.push(i)
}
for await (const item of winnersCountArray) {
await getWinner(participants)
}
} else {
// console.log('------------------------- less or equal to winnersCount block ran')
for await (const item of participants) {
if (!winnersMobileNumbers.includes(item.mobile)) {
winnersMobileNumbers.push(item.mobile)
winnersArray.push(item)
}
}
}
// save result to db
lottery.winnersList = winnersArray
lottery.markModified('winnersList')
lottery.expired = true
lottery.save()
// send sms for winners
for await (const item of winnersArray) {
const msg = [
'تبریک!!!',
'\n',
item.fullName,
' عزیز شما در قرعه کشی آسان سرویس با کد پیگیری ',
item.enrollCode,
' برنده شدید. به زودی از شرکت آسان سرویس با شما تماس گرفته خواهد شد. در صورتی که تا 3 روز کاری با شما تماس گرفته نشد میتوانید از طریق شماره 02167341 داخلی 200 و کد پیگیری خود جهت دریافت جایزه اقدام نماید.',
'\n',
phrases.thanks,
'\n',
phrases.signature
]
SMS([item.mobile], msg.join(''))
}
/// /////////////////////////////////////////////////////// fake data for tests
// for (let i = 0; i < 4; i++) {
// participants.push({
// fullName: 'Amir Mohamadi 2',
// mobile: '34dfssdkfisjdf34534',
// serial: `S-ffasdfdf`,
// enrollCode: `CODE-${i}`
// })
// console.log('--',i)
// }
// lottery.participants = []
// lottery.markModified('participants')
// return lottery.save()
} catch (e) {
console.log('an error happend in drawLottery job --- error: ', e)
}
}, hour)
},
checkUserSurveys() {
console.log('✅ --job: check users for surveys is running')
return setInterval(async () => {
try {
const surveyCheck = await SurveyCheck.find({ smsSent: false }).populate('user')
for await (const item of surveyCheck) {
// timeout
const timeout = item.timeAdded + day * 7
// check if passed one week
if (Date.now() >= timeout) {
const survey = await Survey.findOne({ code: item.code })
if (!survey?._id) {
const msg = [
'مشتری گرامی',
item.user.first_name + ' ' + item.user.last_name,
'\n',
'لطفا با شرکت در نظرسنجی خدمات پس از فروش آسان سرویس، میزان رضایت خود از خدمات گارانتی را به ما اعلام کنید و ما را در ارائه خدمات بهتر یاری نمایید. به پاس همراهی شما عزیزان، بین شرکت کنندگان در نظرسنجی ابتدای هرماه به قید قرعه جوایزی اهدا خواهد شد.',
'\n',
'لینک شرکت در نظر سنجی:',
'\n',
`https://asan-service.com/account/survey?code=${item.code}`
]
SMS([item.user.mobile_number], msg.join(' '))
item.smsSent = true
await item.save()
}
}
}
} catch (e) {
console.log(e)
}
}, day)
}
}
/// /////// for develop usages
const permissions = require('./permissions')
const devTools = {
async checkUsersArpaAccounts() {
try {
const users = await User.find({ scope: ['user'], confirmed: true })
let index = 0
for await (const user of users) {
if (user.scope.includes('user')) {
// if (!user.panatech_businessID && !user.panatech_businessCode) {
// const panatechID = await saveUserToArpa(user, 'panatech')
// user.panatech_businessID = panatechID.businessID
// user.panatech_businessCode = panatechID.businessCode
// await user.save()
// console.log('🚀 ~ file: cronJobs.js ~ panatechID.businessCode', index)
// }
index++
}
}
} catch (e) {
console.log('we got error --- ', e)
}
},
async addNewPermissionsToPrivateAdmin() {
console.log('addNewPermissionsToPrivateAdmin started')
try {
const users = await User.find({ private: true })
for await (const user of users) {
// console.log('🚀 ~ file: cronJobs.js ~ line 187 ~ forawait ~ user', user)
user.permissions = []
for await (const permission of permissions) {
user.permissions.push(permission.value)
// console.log('🚀 ~ file: cronJobs.js ~ line 190 ~ forawait ~ permission', permission.value)
}
await user.save()
}
} catch (e) {
console.log(e)
}
},
async findDuplicatedUsers() {
try {
const usersArray = new Set()
const duplicatedUsersArray = new Set()
const users = await User.find({ scope: ['user'] })
for await (const user of users) {
if (!usersArray.has(user.mobile_number)) usersArray.add(user.mobile_number)
else duplicatedUsersArray.add(user.mobile_number)
}
console.log(
'🚀 ~ file: cronJobs.js ~ line 220 ~ findDuplicatedUsers ~ duplicatedUsersArray',
duplicatedUsersArray
)
console.log(
'🚀 ~ file: cronJobs.js ~ line 220 ~ findDuplicatedUsers ~ duplicatedUsersArray',
duplicatedUsersArray.size
)
} catch (e) {
console.log('🚀 ~ file: cronJobs.js ~ line 223 ~ findDuplicatedUsers - catch ~ e', e)
}
}
}
module.exports = () => {
jobs.checkUserActivation()
jobs.drawLottery()
jobs.checkIfAnnouncementsExpired()
jobs.checkUserSurveys()
// remember to run it once !!!
// devTools.checkUsersArpaAccounts()
// devTools.addNewPermissionsToPrivateAdmin()
// devTools.findDuplicatedUsers()
}
+386
View File
@@ -0,0 +1,386 @@
// province cities
const eastazarbaijan1 = [
'آذرشهر',
'اسکو',
'اهر',
'بستان‌آباد',
'بناب',
'تبریز',
'جلفا',
'چاراویماق',
'سراب',
'شبستر',
'مراغه'
]
const westazarbaijan2 = [
'ارومیه',
'اشنویه',
'بوکان',
'پیرانشهر',
'تکاب',
'چالدران',
'خوی',
'سردشت',
'سلماس',
'شاهین‌دژ',
'ماکو',
'مهاباد',
'میاندوآب',
'نقده'
]
const ardabil3 = ['اردبیل', 'بیله‌سوار', 'پارس‌آباد', 'خلخال', 'کوثر', 'گِرمی', 'مِشگین‌شهر', 'نَمین', 'نیر']
const esfahan4 = [
'آران و بیدگل',
'اردستان',
'اصفهان',
'برخوار و میمه',
'تیران و کرون',
'چادگان',
'خمینی‌شهر',
'خوانسار',
'سمیرم',
'شهرضا',
'سمیرم سفلی',
'فریدن',
'فریدون‌شهر',
'فلاورجان',
'کاشان',
'گلپایگان',
'لنجان',
'مبارکه',
'نائین',
'نجف‌آباد',
'نطنز'
]
const ilam5 = ['آبدانان', 'ایلام', 'ایوان', 'دره‌شهر', 'دهلران', 'شیروان و چرداول', 'مهران']
const booshehr6 = ['بوشهر', 'تنگستان', 'جم', 'دشتستان', 'دشتی', 'دیر', 'دیلم', 'کنگان', 'گناوه']
const tehran7 = [
'اسلام‌شهر',
'پاکدشت',
'تهران',
'دماوند',
'رباط‌کریم',
'ری',
'ساوجبلاغ',
'شمیرانات',
'شهریار',
'فیروزکوه',
'ورامین'
]
const chaharmahalobakhtiari8 = ['اردل', 'بروجن', 'شهرکرد', 'فارسان', 'کوهرنگ', 'لردگان']
const khorasanjonoobi9 = ['بیرجند', 'درمیان', 'سرایان', 'سربیشه', 'فردوس', 'قائنات', 'نهبندان']
const khorasanrazavi10 = [
'بردسکن',
'تایباد',
'تربت جام',
'تربت حیدریه',
'چناران',
'خلیل‌آباد',
'خواف',
'درگز',
'رشتخوار',
'سبزوار',
'سرخس',
'فریمان',
'قوچان',
'کاشمر',
'کلات',
'گناباد',
'مشهد',
'مه ولات',
'نیشابور'
]
const khorasanshomali11 = ['اسفراین', 'بجنورد', 'جاجرم', 'شیروان', 'فاروج', 'مانه و سملقان']
const khoozestan12 = [
'آبادان',
'امیدیه',
'اندیمشک',
'اهواز',
'ایذه',
'باغ‌ملک',
'بندر ماهشهر',
'بهبهان',
'خرمشهر',
'دزفول',
'دشت آزادگان',
'رامشیر',
'رامهرمز',
'شادگان',
'شوش',
'شوشتر'
]
const zanjan13 = ['ابهر', 'ایجرود', 'خدابنده', 'خرمدره', 'زنجان', 'طارم', 'ماه‌نشان']
const semnan14 = ['دامغان', 'سمنان', 'شاهرود', 'گرمسار', 'مهدی‌شهر']
const sistanobaloochestan15 = [
'ایرانشهر',
'چابهار',
'خاش',
'دلگان',
'زابل',
'زاهدان',
'زهک',
'سراوان',
'سرباز',
'کنارک',
'نیک‌شهر'
]
const fars16 = [
'آباده',
'ارسنجان',
'استهبان',
'اقلید',
'بوانات',
'پاسارگاد',
'جهرم',
'خرم‌بید',
'خنج',
'داراب',
'زرین‌دشت',
'سپیدان',
'شیراز',
'فراشبند',
'فسا',
'فیروزآباد',
'قیر و کارزین',
'کازرون',
'لارستان',
'لامِرد',
'مرودشت',
'ممسنی',
'مهر',
'نی‌ریز'
]
const qazvin17 = ['آبیک', 'البرز', 'بوئین‌زهرا', 'تاکستان', 'قزوین']
const qom18 = ['قم']
const kordestan19 = ['بانه', 'بیجار', 'دیواندره', 'سروآباد', 'سقز', 'سنندج', 'قروه', 'کامیاران', 'مریوان']
const kerman20 = [
'بافت',
'بردسیر',
'بم',
'جیرفت',
'راور',
'رفسنجان',
'رودبار جنوب',
'زرند',
'سیرجان',
'شهر بابک',
'عنبرآباد',
'قلعه گنج',
'کرمان',
'کوهبنان',
'کهنوج',
'منوجان'
]
const kermanshah21 = [
'اسلام‌آباد غرب',
'پاوه',
'ثلاث باباجانی',
'جوانرود',
'دالاهو',
'روانسر',
'سرپل ذهاب',
'سنقر',
'صحنه',
'قصر شیرین',
'کرمانشاه',
'کنگاور',
'گیلان غرب',
'هرسین'
]
const kohkilooyevaboyrahmad22 = ['بویراحمد', 'بهمئی', 'دنا', 'کهگیلویه', 'گچساران']
const golestan23 = [
'آزادشهر',
'آق‌قلا',
'بندر گز',
'ترکمن',
'رامیان',
'علی‌آباد',
'کردکوی',
'کلاله',
'گرگان',
'گنبد کاووس',
'مراوه‌تپه',
'مینودشت'
]
const gilan24 = [
'آستارا',
'آستانه اشرفیه',
'اَملَش',
'بندر انزلی',
'رشت',
'رضوانشهر',
'رودبار',
'رودسر',
'سیاهکل',
'شَفت',
'صومعه‌سرا',
'طوالش',
'فومَن',
'لاهیجان',
'لنگرود',
'ماسال'
]
const lorestan25 = ['ازنا', 'الیگودرز', 'بروجرد', 'پل‌دختر', 'خرم‌آباد', 'دورود', 'دلفان', 'سلسله ,کوهدشت']
const mazandaran26 = [
'آمل',
'بابل',
'بابلسر',
'بهشهر',
'تنکابن',
'جویبار',
'چالوس',
'رامسر',
'ساری',
'سوادکوه',
'قائم‌شهر',
'گلوگاه',
'محمودآباد',
'نکا',
'نور',
'نوشهر'
]
const markazi27 = ['آشتیان', 'اراک', 'تفرش', 'خمین', 'دلیجان', 'زرندیه', 'ساوه', 'شازند', 'کمیجان', 'محلات']
const hormozgan28 = [
'ابوموسی',
'بستک',
'بندر عباس',
'بندر لنگه',
'جاسک',
'حاجی‌آباد',
'شهرستان خمیر',
'رودان',
'قشم',
'گاوبندی',
'میناب'
]
const hamedan29 = ['اسدآباد', 'بهار', 'تویسرکان', 'رزن', 'کبودرآهنگ', 'ملایر', 'نهاوند', 'همدان']
const yazd30 = ['ابرکوه', 'اردکان', 'بافق', 'تفت', 'خاتم', 'صدوق', 'طبس', 'مهریز', 'مِیبُد', 'یزد']
const alborz31 = ['کرج', 'نظرآباد', 'فردیس', 'اشتهارد', 'هشتگرد', 'طالقان']
// provinces list
module.exports.iranCities = [
{
name: 'آذربایجان شرقی',
cities: eastazarbaijan1
},
{
name: 'آذربایجان غربی',
cities: westazarbaijan2
},
{
name: 'اردبیل',
cities: ardabil3
},
{
name: 'اصفهان',
cities: esfahan4
},
{
name: 'ایلام',
cities: ilam5
},
{
name: 'بوشهر',
cities: booshehr6
},
{
name: 'تهران',
cities: tehran7
},
{
name: 'چهارمحال بختیاری',
cities: chaharmahalobakhtiari8
},
{
name: 'خراسان جنوبی',
cities: khorasanjonoobi9
},
{
name: 'خراسان رضوی',
cities: khorasanrazavi10
},
{
name: 'خراسان شمالی',
cities: khorasanshomali11
},
{
name: 'خوزستان',
cities: khoozestan12
},
{
name: 'زنجان',
cities: zanjan13
},
{
name: 'سمنان',
cities: semnan14
},
{
name: 'سیستان بلوچستان',
cities: sistanobaloochestan15
},
{
name: 'فارس',
cities: fars16
},
{
name: 'قزوین',
cities: qazvin17
},
{
name: 'قم',
cities: qom18
},
{
name: 'کردستان',
cities: kordestan19
},
{
name: 'کرمان',
cities: kerman20
},
{
name: 'کرمانشاه',
cities: kermanshah21
},
{
name: 'کهکیلویه و بویراحمد',
cities: kohkilooyevaboyrahmad22
},
{
name: 'گلستان',
cities: golestan23
},
{
name: 'گیلان',
cities: gilan24
},
{
name: 'لرستان',
cities: lorestan25
},
{
name: 'مازندران',
cities: mazandaran26
},
{
name: 'مرکزی',
cities: markazi27
},
{
name: 'هرمزگان',
cities: hormozgan28
},
{
name: 'همدان',
cities: hamedan29
},
{
name: 'یزد',
cities: yazd30
},
{
name: 'البرز',
cities: alborz31
}
]
+106
View File
@@ -0,0 +1,106 @@
module.exports = [
{
name: 'مدیریت کاربران',
value: 'admins'
},
{
name: 'مشاهده پیام های تماس با ما',
value: 'contact-us'
},
{
name: 'مدیریت دسته بندی دانلودها',
value: 'download-categories'
},
{
name: 'مدیریت دانلودها',
value: 'downloads'
},
{
name: 'مدیریت سوالات متداول',
value: 'faq'
},
{
name: 'مدیریت آموزش ها',
value: 'learning'
},
{
name: 'مدیریت تیکت ها',
value: 'tickets'
},
{
name: 'اپلود فایل اکسل (شماره سریال گارانتی)',
value: 'serials-exel'
},
{
name: 'مدیریت شرایط گارانتی',
value: 'warranty-terms'
},
{
name: 'مدیریت مشتریان',
value: 'customers'
},
{
name: 'مدیریت راهنمای ثبت گارانتی',
value: 'help'
},
{
name: 'مدیریت اعلانات و اطلاعیه ها',
value: 'announcements'
},
{
name: 'ارسال پیامک',
value: 'sms'
},
{
name: 'مدیریت ظاهر دکمه قرعه کشی',
value: 'lotteryPopUp'
},
{
name: 'مدیریت قرعه کشی',
value: 'lottery'
},
{
name: 'مدیریت درخواست های نمایندگی',
value: 'representations'
},
{
name: 'مدیریت نمایندگان',
value: 'agents'
},
{
name: 'ویرایش اطلاعات نمایندگان',
value: 'agentUpdate'
},
{
name: 'مشاهده صندوق ورودی نمایندگان',
value: 'agentsInbox'
},
{
name: 'مدیریت قطعات',
value: 'pieces'
},
{
name: 'مدیریت درخواست قطعه',
value: 'piece-requests'
},
{
name: 'مدیریت درخواست کالای بافر',
value: 'buffer-requests'
},
{
name: 'مدیریت درخواست قطعه داغی',
value: 'op-requests'
},
{
name: 'مشاهده فرم عملکرد گارانتی نمایندگان',
value: 'guarantee-reports'
},
{
name: 'گزارشات',
value: 'agentReports'
},
{
name: 'نظر سنجی',
value: 'surveys'
}
]
+744
View File
@@ -0,0 +1,744 @@
module.exports._sr = {
fa: {
required: {
token: 'توکن را وارد کنید',
field: 'این فیلد نباید خالی باشد',
// developer validations
remember_me: 'پارامتر remember_me الزامی است',
// registration validations
name: 'نام را وارد کنید',
first_name: 'نام را وارد کنید',
last_name: 'نام خانوادگی را وارد کنید',
email: 'ایمیل را وارد کنید',
national_code: 'کد ملی الزامی است',
email_personal: 'ایمیل شخصی الزامی است',
email_company: 'ایمیل کمپانی برای اشخاص حقوقی الزامی است',
company_name: 'درصورتی که شخص حقوقی هستید، نام کمپانی را وارد کنید',
username: 'نام کاربری را وارد کنید',
phone_number: 'شماره تماس را وارد کنید',
password: 'پسورد را وارد کنید',
birthdate: 'تاریخ تولد را وارد کنید',
// addressing validations
country: 'کشور را وارد کنید',
province: 'استان را وارد کنید',
city: 'شهر را وارد کنید',
address: 'آدرس را وارد کنید',
postal_code: 'کد پستی را وارد کنید',
plaque: 'پلاک را وارد کنید',
receiver_first_name: 'نام گیرنده را وارد کنید',
receiver_last_name: 'نام خانوادگی گیرنده را وارد کنید',
receiver_mobile: 'شماره موبایل گیرنده را وارد کنید',
// global (post - gallery - ...)
title: 'عنوان را وارد کنید',
caption: 'متن را وارد کنید',
description: 'توضیحات را وارد کنید',
category: 'دسته بندی را انتخاب کنید',
image: 'عکس اجباری است',
cover: 'کاور اجباری است',
file: 'فایل اجباری است',
message: 'پیام را بنویسید',
quantity: 'تعداد را وارد کنید',
date: 'تاریخ را وارد کنید',
reason: 'دلیل را انتخاب کنید',
question: 'سوال را بنویسید',
answer: 'جواب را بنویسید',
price: 'قیمت را وارد کنید',
type: 'نوع را انتخاب کنید',
discount_code: 'کد تخفیف را وارد کنید',
discount_amount: 'مقدار تخفیف را وارد کنید',
discount_expire_date: 'تاریخ انقضای کد تخفیف را مشخص کنید',
user_id: 'کاربر را انتخاب کنید',
video: 'ویدیو اجباری است'
},
format: {
phone_number: 'فرمت شماره تماس صحیح نیست',
email: 'فرمت ایمیل قابل قبول نیست',
number: 'مقدار باید از جنس عدد باشد',
boolean: 'مقدار باید از جنس Boolean باشد',
image: 'فرمت عکس قابل قبول نیست',
video: 'فرمت ویدیو قابل قبول نیست',
national_code: 'کد ملی صحیح نیست'
},
min_char: {
min2: 'حداقل 2 کاراکتر',
min4: 'حداقل 4 کاراکتر',
min8: 'حداقل 8 کاراکتر',
min10: 'حداقل 10 کاراکتر',
min20: 'حداقل 20 کاراکتر',
min30: 'حداقل 30 کاراکتر',
min40: 'حداقل 40 کاراکتر',
min50: 'حداقل 50 کاراکتر',
min60: 'حداقل 60 کاراکتر',
min100: 'حداقل 100 کاراکتر',
min120: 'حداقل 120 کاراکتر',
min150: 'حداقل 150 کاراکتر',
min200: 'حداقل 200 کاراکتر',
data_size: 'حجم قابل قبول حداقل: ',
image_width_size: 'عرض حداقل: ',
image_height_size: 'ارتفاع حداقل: '
},
max_char: {
max4: 'حداکثر 4 کاراکتر',
max8: 'حداکثر 8 کاراکتر',
max10: 'حداکثر 10 کاراکتر',
max15: 'حداکثر 15 کاراکتر',
max20: 'حداکثر 20 کاراکتر',
max30: 'حداکثر 30 کاراکتر',
max40: 'حداکثر 40 کاراکتر',
max50: 'حداکثر 50 کاراکتر',
max60: 'حداکثر 60 کاراکتر',
max100: 'حداکثر 100 کاراکتر',
max120: 'حداکثر 120 کاراکتر',
max150: 'حداکثر 150 کاراکتر',
max200: 'حداکثر 200 کاراکتر',
data_size: 'حجم قابل قبول حداکثر: ',
image_width_size: 'عرض حداکثر: ',
image_height_size: 'ارتفاع حداکثر: '
},
not_found: {
user_id: 'کاربری با این مشخصات وجود ندارد',
admin_id: 'ادمینی با این مشخصات وجود ندارد',
order_id: 'سفارشی با این مشخصات وجود ندارد',
item_id: 'موردی با این مشخصات وجود ندارد',
password: 'رمز عبور یا آیدی درست نیست'
},
duplicated: {
username: 'این نام کاربری از قبل وجود دارد',
email: 'این ایمیل از قبل وجود دارد',
name: 'نام تکراری است',
title: 'عنوان تکراری است',
phone_number: 'این شماره تماس از قبل وجود دارد'
},
response: {
logged_in: 'شما وارد سیستم شدید',
not_logged_in: 'شما وارد سیستم نشدید',
logged_out: 'شما از سیستم خارج شدید',
unauthenticated: 'غیرمجاز',
recovery_link: 'لینک بازیابی فرستاده شد',
success_save: 'با موفقیت ثبت شد',
success_remove: 'با موفقیت حذف شد',
cart_empty: 'سبد خرید خالی است',
already_has_address: 'آدرس قبلا اضافه شده',
activation_code: 'کد فعالسازی برای شما ارسال شد',
activation_email: 'ایمیل فعال سازی برای شما ارسال شد',
expired_reset_link: 'این لینک بازیابی منقضی شده است',
email_not_confirmed: 'ابتدا ایمیل خود را تایید کنید،لینک فعال سازی قبلا برای شما فرستاده شده است.',
expired_activation_link: 'این لینک فعال سازی منقضی شده است',
success_activation: 'اکانت شما با موفقیت فعال شد',
passwords_not_match: 'پسورد ها یکی نیست',
problem: 'مشکلی پیش آمده، لطفا دوباره تلاش کنید.',
latinChar: 'لطفا با حروف لاتین بنویسید',
persianChar: 'لطفا با حروف فارسی بنویسید',
whiteSpace: 'بین حروف و کلمات نباید فاصله باشد'
},
file_types: {
jpg: 'فقط فرمت jpg قابل قبول است',
png: 'فقط فرمت png قابل قبول است',
gif: 'فقط فرمت gif قابل قبول است',
pdf: 'فقط فرمت pdf قابل قبول است',
txt: 'فقط فرمت txt قابل قبول است',
log: 'فقط فرمت log قابل قبول است',
mp3: 'فقط فرمت mp3 قابل قبول است',
ogg: 'فقط فرمت ogg قابل قبول است',
wmv: 'فقط فرمت wmv قابل قبول است',
mp4: 'فقط فرمت mp4 قابل قبول است',
mov: 'فقط فرمت mov قابل قبول است',
mkv: 'فقط فرمت mkv قابل قبول است',
flv: 'فقط فرمت flv قابل قبول است'
}
},
en: {
required: {
token: 'Token is required',
field: 'This field is required',
// developer validations
remember_me: 'Remember_me parameter required',
// registration validations
name: 'Enter name',
first_name: 'Enter first name',
last_name: 'Enter last name',
national_code: 'National code is required',
email: 'Enter email',
email_personal: 'Personal email is required',
email_company: 'Company email is required for legal entities',
company_name: 'Enter company name if you are a legal entity',
username: 'Enter username',
phone_number: 'Enter phone number',
password: 'Enter password',
birthdate: 'Enter birthdate',
// addressing validations
country: 'Enter country',
province: 'Enter province',
city: 'Enter city',
address: 'Enter address',
postal_code: 'Enter postal code',
plaque: 'Enter plaque',
receiver_first_name: 'Enter recipient name',
receiver_last_name: 'Enter recipient surname',
receiver_mobile: "Enter recipient's mobile number",
// global (post - gallery - ...)
title: 'Enter title',
caption: 'Enter caption',
description: 'Enter description',
category: 'Select category',
image: 'Image is required',
cover: 'Cover is required',
file: 'File is required',
message: 'Write message',
quantity: 'Enter quantity',
date: 'Enter date',
reason: 'Select reason',
question: 'Write the question',
answer: 'Write the answer',
price: 'Enter Price',
type: 'Select type',
discount_code: 'Enter discount code',
discount_amount: 'Enter discount amount',
discount_expire_date: 'Specify discount code expiration date',
user_id: 'Select user',
video: 'Video is required'
},
format: {
phone_number: 'Phone number format in incorrect',
email: 'Email format is not correct',
number: 'Value must be number',
boolean: 'Value must be Boolean',
image: 'Photo format is not acceptable',
video: 'Video format is not acceptable',
national_code: 'National code format is not correct'
},
min_char: {
min2: 'At least 2 characters',
min4: 'At least 4 characters',
min8: 'At least 8 characters',
min10: 'At least 10 characters',
min20: 'At least 20 characters',
min30: 'At least 30 characters',
min40: 'At least 40 characters',
min50: 'At least 50 characters',
min60: 'At least 60 characters',
min100: 'At least 100 characters',
min120: 'At least 120 characters',
min150: 'At least 150 characters',
min200: 'At least 200 characters',
data_size: 'Acceptable minimum size: ',
image_width_size: 'Minimum width: ',
image_height_size: 'Minimum height: '
},
max_char: {
max4: 'Maximum 4 characters',
max8: 'Maximum 8 characters',
max10: 'Maximum 10 characters',
max15: 'Maximum 15 characters',
max20: 'Maximum 20 characters',
max30: 'Maximum 30 characters',
max40: 'Maximum 40 characters',
max50: 'Maximum 50 characters',
max60: 'Maximum 60 characters',
max100: 'Maximum 100 characters',
max120: 'Maximum 120 characters',
max150: 'Maximum 150 characters',
max200: 'Maximum 200 characters',
data_size: 'Maximum acceptable size: ',
image_width_size: 'Maximum width: ',
image_height_size: 'Maximum height: '
},
not_found: {
user_id: 'There is no user with this profile',
admin_id: 'There is no admin with this profile',
order_id: 'There is no order with this profile',
item_id: 'There is no item with this specification',
password: 'Password or ID is incorrect'
},
duplicated: {
username: 'This username already exists',
email: 'This email already exists',
name: 'Name already exists',
title: 'Title already exists',
phone_number: 'Phone number already exists'
},
response: {
logged_in: 'You are logged in',
not_logged_in: 'You are not logged in',
logged_out: 'You are logged out',
unauthenticated: 'unauthenticated',
recovery_link: 'Recovery link sent',
success_save: 'Successfully saved',
success_remove: 'Successfully removed',
cart_empty: 'Cart is empty',
already_has_address: 'Already has address',
activation_code: 'Activation code sent to you',
activation_email: 'Activation email sent to you',
expired_reset_link: 'The current reset pass link has been expired',
email_not_confirmed: 'Confirm your email first, the activation link has already been sent to you.',
expired_activation_link: 'This activation link has expired',
success_activation: 'Your account has been successfully activated',
passwords_not_match: 'Passwords are not the same',
problem: 'There is a problem, please try again.',
latinChar: 'Please write in Latin letters',
persianChar: 'Please write in Persian letters',
whiteSpace: 'There should be no space between letters and words'
},
file_types: {
jpg: 'Only jpg format is acceptable',
png: 'Only png format is acceptable',
gif: 'Only gif format is acceptable',
pdf: 'Only pdf format is acceptable',
txt: 'Only txt format is acceptable',
log: 'Only log format is acceptable',
mp3: 'Only mp3 format is acceptable',
ogg: 'Only ogg format is acceptable',
wmv: 'Only wmv format is acceptable',
mp4: 'Only mp4 format is acceptable',
mov: 'Only mov format is acceptable',
mkv: 'Only mkv format is acceptable',
flv: 'Only flv format is acceptable'
}
},
de: {
required: {
token: 'Token is required',
field: 'This field is required',
// developer validations
remember_me: 'Remember_me-Parameter erforderlich',
// registration validations
name: 'Name eingeben',
first_name: 'Name eingeben',
last_name: 'Nachnamen eingeben',
national_code: 'Nationaler Code ist erforderlich',
email: 'Email eingeben',
email_personal: 'Persönliche E-Mail ist erforderlich',
email_company: 'Für juristische Personen ist eine Unternehmens-E-Mail erforderlich',
company_name: 'Geben Sie den Firmennamen ein, wenn Sie eine juristische Person sind',
username: 'Geben Sie den Benutzernamen ein',
phone_number: 'Telefonnummer eingeben',
password: 'Passwort eingeben',
birthdate: 'Enter birthdate',
// addressing validations
country: 'Land eingeben',
province: 'Stadt betreten',
city: 'Stadt betreten',
address: 'Adresse eingeben',
postal_code: 'Postleitzahl eingeben',
plaque: 'Plakette eingeben',
receiver_first_name: 'Empfängername eingeben',
receiver_last_name: 'Nachname des Empfängers eingeben',
receiver_mobile: 'Handynummer des Empfängers eingebenr',
// global (post - gallery - ...)
title: 'Titel eingeben',
caption: 'Beschriftung eingeben',
description: 'Beschreibung eingeben',
category: 'Kategorie wählen',
image: 'Bild ist erforderlich',
cover: 'Bild ist erforderlich Abdeckung ist erforderlich',
file: 'Datei ist erforderlich',
message: 'Nachricht schreiben',
quantity: 'Menge eingeben',
date: 'Enter date',
reason: 'Grund auswählen',
question: 'Schreibe die Frage',
answer: 'Schreibe die Antwort',
price: 'Enter Price',
type: 'Select type',
discount_code: 'Enter discount code',
discount_amount: 'Enter discount amount',
discount_expire_date: 'Specify discount code expiration date',
user_id: 'Select user',
video: 'Video is required'
},
format: {
phone_number: 'Telefonnummernformat falsch',
email: 'E-Mail-Format nicht korrekt',
number: 'Wert muss Nummer sein',
boolean: 'Wert muss Boolescher Wert sein',
image: 'Photo format is not acceptable',
video: 'Video format is not acceptable',
national_code: 'Nationales Codeformat ist nicht korrekt'
},
min_char: {
min2: 'Mindestens 2 Zeichen',
min4: 'Mindestens 4 Zeichen',
min8: 'Mindestens 8 Zeichen',
min10: 'Mindestens 10 Zeichen',
min20: 'Mindestens 20 Zeichen',
min30: 'Mindestens 30 Zeichen',
min40: 'Mindestens 40 Zeichen',
min50: 'Mindestens 50 Zeichen',
min60: 'Mindestens 60 Zeichen',
min100: 'Mindestens 100 Zeichen',
min120: 'Mindestens 120 Zeichen',
min150: 'Mindestens 150 Zeichen',
min200: 'Mindestens 200 Zeichen',
data_size: 'Akzeptable Mindestgröße: ',
image_width_size: 'Mindestbreite: ',
image_height_size: 'Mindesthöhe: '
},
max_char: {
max4: 'Maximal 4 Zeichen',
max8: 'Maximal 8 Zeichen',
max10: 'Maximal 10 Zeichen',
max15: 'Maximal 15 Zeichen',
max20: 'Maximal 20 Zeichen',
max30: 'Maximal 30 Zeichen',
max40: 'Maximal 40 Zeichen',
max50: 'Maximal 50 Zeichen',
max60: 'Maximal 60 Zeichen',
max100: 'Maximal 100 Zeichen',
max120: 'Maximal 120 Zeichen',
max150: 'Maximal 150 Zeichen',
max200: 'Maximal 200 Zeichen',
data_size: 'Maximal zulässige Größe: ',
image_width_size: 'Maximale Breite: ',
image_height_size: 'Maximale Höhe: '
},
not_found: {
user_id: 'Es gibt keinen Benutzer mit diesem Profil',
admin_id: 'Es gibt keinen Administrator mit diesem Profil',
order_id: 'Es gibt keine Bestellung mit diesem Profil',
item_id: 'Es gibt keinen Artikel mit dieser Spezifikation',
password: 'Passwort oder ID ist falsch'
},
duplicated: {
username: 'Dieser Benutzername existiert bereits',
email: 'Diese E-Mail existiert bereits',
name: 'Name ist doppelt',
title: 'Titel ist doppelt',
phone_number: 'Phone number already exists'
},
response: {
logged_in: 'Sie sind angemeldet',
not_logged_in: 'Sie sind nicht angemeldet',
logged_out: 'Sie sind abgemeldet',
unauthenticated: 'nicht authentifiziert',
recovery_link: 'Wiederherstellungslink gesendet',
success_save: 'Erfolgreich gespeichert',
success_remove: 'Erfolgreich entfernt',
cart_empty: 'Warenkorb ist leer',
ready_has_address: 'Hat bereits Adresse',
activation_code: 'Activation code sent to you',
activation_email: 'Activation email sent to you',
expired_reset_link: 'Der aktuelle Reset-Pass-Link ist abgelaufen',
email_not_confirmed: 'Bestätigen Sie zuerst Ihre E-Mail, der Aktivierungslink wurde bereits an Sie gesendet.',
expired_activation_link: 'Dieser Aktivierungslink ist abgelaufen',
success_activation: 'Ihr Konto wurde erfolgreich aktiviert',
passwords_not_match: 'Passwörter sind nicht dasselbe',
problem: 'Es gibt ein Problem, bitte versuchen Sie es erneut.',
latinChar: 'Please write in Latin letters',
persianChar: 'Please write in Persian letters',
whiteSpace: 'There should be no space between letters and words'
},
file_types: {
jpg: 'Nur das jpg-Format ist akzeptabel',
png: 'Nur das png-Format ist akzeptabel',
gif: 'Nur das gif-Format ist akzeptabel',
pdf: 'Nur das PDF-Format ist akzeptabel',
txt: 'Nur das txt-Format ist akzeptabel',
log: 'Nur das log-Format ist akzeptabel',
mp3: 'Nur das mp3-Format ist akzeptabel',
ogg: 'Nur das ogg-Format ist akzeptabel',
wmv: 'Nur das wmv-Format ist akzeptabel',
mp4: 'Nur das mp4-Format ist akzeptabel',
mov: 'Nur das mov-Format ist akzeptabel',
mkv: 'Nur das mkv-Format ist akzeptabel',
flv: 'Nur das flv-Format ist akzeptabel'
}
},
tr: {
required: {
token: 'Token is required',
field: 'This field is required',
// geliştirici doğrulamaları
Remember_me: 'Remember_me parametresi gerekli',
// kayıt doğrulamaları
name: 'Adı girin',
first_name: 'Adı girin',
last_name: 'Soyadı girin',
national_code: 'Nationaler Kodu erforderlich',
email: 'E-posta girin',
email_personal: 'Kişisel e-posta gereklidir',
email_company: 'Tüzel kişiler için şirket e-postası gereklidir',
company_name: 'Tüzel kişiyseniz şirket adını girin',
username: 'Kullanıcı adını girin',
phone_number: 'Telefon numarasını girin',
password: 'Şifre girin',
birthdate: 'Enter birthdate',
// doğrulamaları adresleme
country: 'Ülke girin',
province: 'İl girin',
city: 'Şehir girin',
address: 'Adres girin',
postal_code: 'Posta kodunu girin',
plaque: 'Plak girin',
receiver_first_name: 'Alıcı adını girin',
receiver_last_name: 'Alıcının soyadını girin',
receiver_mobile: 'Alıcının cep telefonu numarasını girin',
// global (post - galeri - ...)
title: 'Başlığı girin',
caption: 'Başlık girin',
description: 'Açıklama girin',
category: 'Kategori seçin',
image: 'Resim gerekli',
cover: 'Kapak gereklidir',
file: 'Dosya gerekli',
message: 'Mesaj yaz',
quantity: 'Miktar girin',
date: 'Enter date',
reason: 'Nedeni seçin',
question: 'Soruyu yazın',
answer: 'Cevabı yaz',
price: 'Enter Price',
type: 'Select type',
discount_code: 'Enter discount code',
discount_amount: 'Enter discount amount',
discount_expire_date: 'Specify discount code expiration date',
user_id: 'Select user',
video: 'Video is required'
},
format: {
phone_number: 'Telefon numarası biçimi yanlış',
email: 'E-posta formatı doğru değil',
number: 'Değer sayı olmalıdır',
boolean: 'Değer Boole olmalıdır',
image: 'Photo format is not acceptable',
video: 'Video format is not acceptable',
national_code: 'Ulusal kod formatı doğru değil'
},
min_char: {
min2: 'En az 2 karakter',
min4: 'En az 4 karakter',
min8: 'En az 8 karakter',
min10: 'En az 10 karakter',
min20: 'En az 20 karakter',
min30: 'En az 30 karakter',
min40: 'En az 40 karakter',
min50: 'En az 50 karakter',
min60: 'En az 60 karakter',
min100: 'En az 100 karakter',
min120: 'En az 120 karakter',
min150: 'En az 150 karakter',
min200: 'En az 200 karakter',
data_size: 'Kabul edilebilir minimum boyut: ',
image_width_size: 'Minimum genişlik: ',
image_height_size: 'Minimum yükseklik: '
},
max_char: {
max4: 'Maksimum 4 karakter',
max8: 'Maksimum 8 karakter',
max10: 'Maksimum 10 karakter',
max15: 'Maksimum 15 karakter',
max20: 'Maksimum 20 karakter',
max30: 'Maksimum 30 karakter',
max40: 'Maksimum 40 karakter',
max50: 'Maksimum 50 karakter',
max60: 'Maksimum 60 karakter',
max100: 'Maksimum 100 karakter',
max120: 'Maksimum 120 karakter',
max150: 'Maksimum 150 karakter',
max200: 'Maksimum 200 karakter',
data_size: 'Kabul edilebilir maksimum boyut: ',
image_width_size: 'Maksimum genişlik: ',
image_height_size: 'Maksimum yükseklik: '
},
not_found: {
user_id: 'Bu profile sahip kullanıcı yok',
admin_id: 'Bu profile sahip yönetici yok',
order_id: 'Bu profilde sipariş yok',
item_id: 'Bu spesifikasyona sahip hiçbir öğe yok',
password: 'Şifre veya kimlik yanlış'
},
duplicated: {
username: 'Bu kullanıcı adı zaten mevcut',
email: 'Bu email zaten var',
name: 'Ad çift',
title: 'Başlık yineleniyor',
phone_number: 'Phone number already exists'
},
response: {
logged_in: 'Giriş yaptınız',
not_logged_in: 'Giriş yapmadınız',
logged_out: 'Çıkış yaptınız',
unauthenticated: 'unauthenticated',
recovery_link: 'Kurtarma bağlantısı gönderildi',
success_save: 'Başarıyla kaydedildi',
success_remove: 'Başarıyla kaldırıldı',
cart_empty: 'Sepet boş',
already_has_address: 'Zaten adresi var',
activation_code: 'Activation code sent to you',
activation_email: 'Activation email sent to you',
expired_reset_link: 'Mevcut sıfırlama geçiş bağlantısının süresi doldu',
email_not_confirmed: 'Önce e-postanızı onaylayın, aktivasyon bağlantısı size zaten gönderildi.',
expired_activation_link: 'Bu aktivasyon bağlantısının süresi doldu',
success_activation: 'Hesabınız başarıyla etkinleştirildi',
passwords_not_match: 'Şifreler aynı değil',
problem: 'Bir sorun var, lütfen tekrar deneyin.',
latinChar: 'Please write in Latin letters',
persianChar: 'Please write in Persian letters',
whiteSpace: 'There should be no space between letters and words'
},
file_types: {
jpg: 'Yalnızca jpg formatı kabul edilebilir',
png: 'Sadece png formatı kabul edilebilir',
gif: 'Yalnızca gif formatı kabul edilebilir',
pdf: 'Yalnızca pdf formatı kabul edilebilir',
txt: 'Yalnızca txt formatı kabul edilebilir',
log: 'Yalnızca log formatı kabul edilebilir',
mp3: 'Yalnızca mp3 formatı kabul edilebilir',
ogg: 'Yalnızca ogg formatı kabul edilebilir',
wmv: 'Yalnızca wmv formatı kabul edilebilir',
mp4: 'Yalnızca mp4 formatı kabul edilebilir',
mov: 'Yalnızca mov formatı kabul edilebilir',
mkv: 'Yalnızca mkv formatı kabul edilebilir',
flv: 'Yalnızca flv biçimi kabul edilebilir'
}
},
it: {
required: {
token: 'Token is required',
field: 'This field is required',
// convalide dello sviluppatore
Remember_me: 'Remember_me parameter required',
// convalide della registrazione
name: 'Inserisci nome',
first_name: 'Inserisci nome',
last_name: 'Inserisci il cognome',
national_code: 'Il codice Nationaler è comune',
email: 'Enter email',
email_personal: "L'email personale è obbligatoria",
email_company: "L'email aziendale è obbligatoria per le persone giuridiche",
company_name: "Inserisci il nome dell'azienda se sei una persona giuridica",
username: 'Inserisci nome utente',
phone_number: 'Inserisci numero di telefono',
password: 'Inserisci password',
birthdate: 'Enter birthdate',
// indirizzamento delle convalide
country: 'Inserisci paese',
province: 'Inserisci provincia',
city: 'Inserisci città',
address: 'Inserisci indirizzo',
postal_code: 'Inserisci codice postale',
plaque: 'Inserisci targa',
receiver_first_name: 'Inserisci il nome del destinatario',
receiver_last_name: 'Inserisci il cognome del destinatario',
receiver_mobile: 'Inserisci il numero di cellulare del destinatario',
// globale (post - gallery - ...)
title: 'Inserisci titolo',
caption: 'Inserisci didascalia',
description: 'Inserisci descrizione',
category: 'Seleziona categoria',
image: "L'immagine è obbligatoria",
cover: 'Cover is required',
file: 'Il file è obbligatorio',
message: 'Scrivi messaggio',
quantity: 'Inserisci quantità',
date: 'Enter date',
reason: 'Seleziona motivo',
question: 'Scrivi la domanda',
answer: 'Scrivi la risposta',
price: 'Enter Price',
type: 'Select type',
discount_code: 'Enter discount code',
discount_amount: 'Enter discount amount',
discount_expire_date: 'Specify discount code expiration date',
user_id: 'Select user',
video: 'Video is required'
},
format: {
phone_number: 'Formato del numero di telefono non corretto',
email: 'Formato email non corretto',
number: 'Il valore deve essere un numero',
boolean: 'Il valore deve essere booleano',
image: 'Photo format is not acceptable',
video: 'Video format is not acceptable',
national_code: 'Il formato del codice nazionale non è corretto'
},
min_char: {
min2: 'Almeno 2 caratteri',
min4: 'Almeno 4 caratteri',
min8: 'Almeno 8 caratteri',
min10: 'Almeno 10 caratteri',
min20: 'Almeno 20 caratteri',
min30: 'Almeno 30 caratteri',
min40: 'Almeno 40 caratteri',
min50: 'Almeno 50 caratteri',
min60: 'Almeno 60 caratteri',
min100: 'Almeno 100 caratteri',
min120: 'Almeno 120 caratteri',
min150: 'Almeno 150 caratteri',
min200: 'Almeno 200 caratteri',
data_size: 'Dimensione minima accettabile: ',
image_width_size: 'Larghezza minima: ',
image_height_size: 'Altezza minima: '
},
max_char: {
max4: 'Massimo 4 caratteri',
max8: 'Massimo 8 caratteri',
max10: 'Massimo 10 caratteri',
max15: 'Massimo 15 caratteri',
max20: 'Massimo 20 caratteri',
max30: 'Massimo 30 caratteri',
max40: 'Massimo 40 caratteri',
max50: 'Massimo 50 caratteri',
max60: 'Massimo 60 caratteri',
max100: 'Massimo 100 caratteri',
max120: 'Massimo 120 caratteri',
max150: 'Massimo 150 caratteri',
max200: 'Massimo 200 caratteri',
data_size: 'Dimensione massima accettabile: ',
image_width_size: 'Larghezza massima: ',
image_height_size: 'Altezza massima: '
},
not_found: {
user_id: 'Nessun utente con questo profilo',
admin_id: 'Nessun amministratore con questo profilo',
order_id: 'Nessun ordine con questo profilo',
item_id: 'Nessun articolo con questa specifica',
password: "La password o l'ID non sono corretti"
},
duplicated: {
username: 'Questo nome utente esiste già',
email: 'Questa email esiste già',
name: 'Il nome è duplicato',
title: 'Il titolo è duplicato',
phone_number: 'Phone number already exists'
},
response: {
logged_in: "Hai effettuato l'accesso",
not_logged_in: 'Non sei loggato',
logged_out: 'Sei disconnesso',
unauthenticated: 'unauthenticated',
recovery_link: 'Link di ripristino inviato',
success_save: 'Salvataggio riuscito',
success_remove: 'Rimosso con successo',
cart_empty: 'Il carrello è vuoto',
already_has_address: 'Ha già indirizzo',
activation_code: 'Activation code sent to you',
activation_email: 'Activation email sent to you',
expired_reset_link: "L'attuale link del passaggio di reimpostazione è scaduto",
email_not_confirmed: 'Conferma prima la tua email, il link di attivazione ti è già stato inviato.',
expired_activation_link: 'Questo link di attivazione è scaduto',
success_activation: 'Il tuo account è stato attivato con successo',
passwords_not_match: 'Le password non sono le stesse',
problem: 'Si è verificato un problema, riprova.',
latinChar: 'Please write in Latin letters',
persianChar: 'Please write in Persian letters',
whiteSpace: 'There should be no space between letters and words'
},
file_types: {
jpg: 'È accettabile solo il formato jpg',
png: 'È accettabile solo il formato png',
gif: 'È accettabile solo il formato GIF',
pdf: 'È accettabile solo il formato pdf',
txt: 'È accettabile solo il formato txt',
log: 'È accettabile solo il formato log',
mp3: 'È accettabile solo il formato mp3',
ogg: 'È accettabile solo il formato ogg',
wmv: 'È accettabile solo il formato wmv',
mp4: 'È accettabile solo il formato mp4',
mov: 'È accettabile solo il formato mov',
mkv: 'È accettabile solo il formato mkv',
flv: 'È accettabile solo il formato flv'
}
},
supportedImageFormats: ['jpg', 'jpeg', 'png', 'svg', 'svg+xml', 'webp'],
supportedVideoFormats: ['mp4', 'wmv']
}
+194
View File
@@ -0,0 +1,194 @@
const { Router } = require('express')
const router = Router()
/// //////////////////////////////////////////////////////// controllers
const { hasPermission } = require('../authentication')
const warrantyTermsController = require('../controllers/warrantyTermsController')
const contactPageController = require('../controllers/contactPageController')
const faqController = require('../controllers/faqController')
const learningController = require('../controllers/learningController')
const downloadCategoryController = require('../controllers/downloadCategoryController')
const downloadController = require('../controllers/downloadController')
const userController = require('../controllers/userController')
const ticketsController = require('../controllers/ticketsController')
const serialsExelController = require('../controllers/serialsExelController')
const helpController = require('../controllers/helpController')
const announcementController = require('../controllers/announcementController')
const lotteryPopUpController = require('../controllers/lotteryPopUpController')
const lotteryController = require('../controllers/lotteryController')
const representationController = require('../controllers/representationController')
const pieceController = require('../controllers/pieceController')
const pieceRequestController = require('../controllers/pieceRequestController')
const oldPieceRequestController = require('../controllers/oldPieceRequestController')
const bufferRequestController = require('../controllers/bufferRequestController')
const guaranteeReportController = require('../controllers/guaranteeReportController')
const transactionController = require('../controllers/transactionController')
const smsBroadcastController = require('../controllers/smsBroadcastController')
const surveyController = require('../controllers/surveyController')
/// //////////////////////////////////////////////////////// routes
/// ///////////// warranty terms
router.post('/warranty', hasPermission('warranty-terms'), warrantyTermsController.create)
router.put('/warranty/:id', hasPermission('warranty-terms'), warrantyTermsController.update)
router.delete('/warranty/:id', hasPermission('warranty-terms'), warrantyTermsController.delete)
/// ///////////// FAQ
router.post('/faq', hasPermission('faq'), faqController.create)
router.put('/faq/:id', hasPermission('faq'), faqController.update)
router.delete('/faq/:id', hasPermission('faq'), faqController.delete)
/// ///////////// Learning
router.post('/learning', hasPermission('learning'), learningController.create)
router.put('/learning/:id', hasPermission('learning'), learningController.update)
router.delete('/learning/:id', hasPermission('learning'), learningController.delete)
/// ///////////// download category
router.post('/dCategory', hasPermission('download-categories'), downloadCategoryController.create)
router.put('/dCategory/:id', hasPermission('download-categories'), downloadCategoryController.update)
router.delete('/dCategory/:id', hasPermission('download-categories'), downloadCategoryController.delete)
/// ///////////// downloads
router.post('/downloads', hasPermission('downloads'), downloadController.create)
router.put('/downloads/:id', hasPermission('downloads'), downloadController.update)
router.delete('/downloads/:id', hasPermission('downloads'), downloadController.delete)
// files
router.post('/downloads/file', hasPermission('downloads'), downloadController.addFile)
router.delete('/downloads/file/:id', hasPermission('downloads'), downloadController.deletFile)
/// ///////////// contact us
router.get('/contact', hasPermission('contact-us'), contactPageController.getAll)
router.get('/contact/:id', hasPermission('contact-us'), contactPageController.getOne)
/// ///////////// tickets
router.post('/addTicket', hasPermission('tickets'), ticketsController.add_ticket)
router.get('/tickets', hasPermission('tickets'), ticketsController.get_all_tickets_for_admin)
router.get('/ticket/:id', hasPermission('tickets'), ticketsController.get_one_ticket)
router.post('/addMessageToTicket/:id', hasPermission('tickets'), ticketsController.add_message_to_ticket)
router.get('/allUsers', hasPermission('tickets'), userController.get_all_users_for_admin)
/// ///////////// transactions
// router.get('/transactions', hasPermission('transactions'), userController.get_all_transactions_for_admin)
// router.get('/transaction/:id', hasPermission('transactions'), userController.get_one_transaction_for_admin)
/// ///////////// manage admins
router.post('/addAdmin', hasPermission('admins'), userController.register_admin)
router.put('/updateAdmin/:id', hasPermission('admins'), userController.update_admin)
router.delete('/deleteAdmin/:id', hasPermission('admins'), userController.delete_admin)
router.put('/updateAdminPassword', hasPermission('admins'), userController.update_user_password)
router.get('/admins', hasPermission('admins'), userController.get_admins)
router.get('/admin/:id', hasPermission('admins'), userController.get_one_admin)
router.get('/permissions', hasPermission('admins'), userController.permissions)
/// ///////////// manage users
router.get('/users', hasPermission('customers'), userController.get_all_users_for_admin)
router.get('/user/:id', hasPermission('customers'), userController.get_one_user_for_admin)
router.put('/user/changeVerityInfo/:id', hasPermission('customers'), userController.change_verity_info_by_admin)
router.put('/user/changePanatechInfo/:id', hasPermission('customers'), userController.change_panatech_info_by_admin)
/// ///////////// serials exel file
router.post('/addExel', hasPermission('serials-exel'), serialsExelController.addExel)
router.delete('/removeExel/:name', hasPermission('serials-exel'), serialsExelController.removeExel)
router.get('/serialExels', hasPermission('serials-exel'), serialsExelController.getAllExels)
/// ///////////// update help page
router.put('/help', hasPermission('help'), helpController.set)
/// ///////////// announcements
router.post('/announcements', hasPermission('announcements'), announcementController.create)
router.get('/announcements', hasPermission('announcements'), announcementController.getAllForAdmin)
router.get('/announcementsUsers', hasPermission('announcements'), userController.get_all_users_for_admin)
router.get('/announcements/:id', hasPermission('announcements'), announcementController.getOneForAdmin)
router.delete('/announcements/:id', hasPermission('announcements'), announcementController.deleteAnnouncement)
// router.put('/announcement/:id', hasPermission('announcements'), announcementController.updateByAdmin)
/// ///////////// lottery
router.put('/lotteryPopUp', hasPermission('lotteryPopUp'), lotteryPopUpController.modify)
router.post('/lottery', hasPermission('lottery'), lotteryController.addLottery)
router.delete('/lottery/:lotteryId', hasPermission('lottery'), lotteryController.deleteLottery)
router.put('/lottery/:lotteryId', hasPermission('lottery'), lotteryController.updateLottery)
router.get('/lottery/:lotteryId', hasPermission('lottery'), lotteryController.getOneLottery)
router.get('/lotteries', hasPermission('lottery'), lotteryController.getAllLotteries)
/// ///////////// representations (agents)
router.get('/representations', hasPermission('representations'), representationController.getAll)
router.get('/representation/:id', hasPermission('representations'), representationController.getOne)
router.put('/representationStatus/:id', hasPermission('representations'), representationController.change_form_status)
router.post('/addAgentByAdmin', hasPermission('representations'), representationController.add_agent_by_admin)
/// ///////////// pieces
router.post('/piece', hasPermission('pieces'), pieceController.add_piece)
router.put('/piece/:id', hasPermission('pieces'), pieceController.update_piece)
router.delete('/piece/:id', hasPermission('pieces'), pieceController.remove_piece)
router.get('/pieces', hasPermission('pieces'), pieceController.get_all_pieces)
router.get('/pieces/:id', hasPermission('pieces'), pieceController.get_one_pieces)
/// ///////////// piece requests
router.get('/prList', hasPermission('piece-requests'), pieceRequestController.get_all_pr_for_admin)
router.get('/pr/:id', hasPermission('piece-requests'), pieceRequestController.get_one_pr_for_admin)
router.put('/prStatus/:id', hasPermission('piece-requests'), pieceRequestController.change_pr_status_by_admin)
/// ///////////// oldPiece requests
router.get('/oprList', hasPermission('op-requests'), oldPieceRequestController.get_all_opr_for_admin)
router.get('/opr/:id', hasPermission('op-requests'), oldPieceRequestController.get_one_opr_for_admin)
router.put('/oprStatus/:id', hasPermission('op-requests'), oldPieceRequestController.change_opr_status_by_admin)
/// ///////////// buffer requests
router.get('/brList', hasPermission('buffer-requests'), bufferRequestController.get_all_br_for_admin)
router.get('/br/:id', hasPermission('buffer-requests'), bufferRequestController.get_one_br_for_admin)
router.put('/brStatus/:id', hasPermission('buffer-requests'), bufferRequestController.change_br_status_by_admin)
/// ///////////// agents guarantee jobs reports
router.get('/grList', hasPermission('guarantee-reports'), guaranteeReportController.get_all_gr_for_admin)
router.get('/gr/:id', hasPermission('guarantee-reports'), guaranteeReportController.get_one_gr_for_admin)
// router.put('/grStatus/:id', hasPermission('guarantee-reports'), guaranteeReportController.change_gr_status_by_admin)
/// ///////////// agent inbox
router.get('/allAgentsInbox', hasPermission('agentsInbox'), transactionController.get_all_agents_inbox_for_admin)
router.get('/allAgentsInbox/:id', hasPermission('agentsInbox'), transactionController.get_one_transaction_for_admin)
/// ///////////// one agent details and reports
router.get('/agentDetails/:id', hasPermission('agents'), representationController.getOne)
router.get('/agentInbox/:agent_id', hasPermission('agents'), transactionController.get_one_agent_inbox_for_admin)
router.get('/agentBr/:agent_id', hasPermission('agents'), bufferRequestController.get_oneAgent_br_for_admin)
router.get('/agentOpr/:agent_id', hasPermission('agents'), oldPieceRequestController.get_oneAgent_opr_for_admin)
router.get('/agentPr/:agent_id', hasPermission('agents'), pieceRequestController.get_oneAgent_pr_for_admin)
/// ///////////// update agent info
router.put('/updateAgent/:id', hasPermission('agentUpdate'), representationController.update_representation_by_admin)
router.post('/revokeAgent/:id', hasPermission('agentUpdate'), representationController.revoke_representation_by_admin)
router.get('/revokedAgents', representationController.get_revoked_agents_for_admin)
// update files
router.post(
'/representationImages/:userType/:representation_code',
representationController.upload_image_to_representation
)
router.delete(
'/representationImages/:userType/:representation_code/:imgId',
representationController.remove_image_from_representation
)
/// ///////////// all agents report (advance report)
router.get('/report/pieces', hasPermission('agentReports'), pieceController.get_all_pieces)
router.get(
'/report/allAgentsInbox',
hasPermission('agentReports'),
transactionController.get_all_agents_inbox_for_admin
)
router.get('/report/grList', hasPermission('agentReports'), guaranteeReportController.get_all_gr_for_admin)
router.get('/report/brList', hasPermission('agentReports'), bufferRequestController.get_all_br_for_admin)
router.get('/report/prList', hasPermission('agentReports'), pieceRequestController.get_all_pr_for_admin)
router.get('/report/oprList', hasPermission('agentReports'), oldPieceRequestController.get_all_opr_for_admin)
/// ///////////// broadcast sms for users
router.post('/broadcastSMS', hasPermission('sms'), smsBroadcastController.broadcast)
router.get('/smsBroadcasts', hasPermission('sms'), smsBroadcastController.getAllForAdmin)
router.get('/smsBroadcasts/:id', hasPermission('sms'), smsBroadcastController.getOneForAdmin)
router.get('/usersForSMS', hasPermission('sms'), userController.get_all_users_for_admin)
/// ///////////// survey
router.get('/surveys', surveyController.getAllForAdmin)
router.get('/surveys/:id', surveyController.getOneForAdmin)
module.exports = router
+59
View File
@@ -0,0 +1,59 @@
const { Router } = require('express')
const router = Router()
const transactionController = require('../controllers/transactionController')
const pieceController = require('../controllers/pieceController')
const pieceRequestController = require('../controllers/pieceRequestController')
const oldPieceRequestController = require('../controllers/oldPieceRequestController')
const bufferRequestController = require('../controllers/bufferRequestController')
const guaranteeReportController = require('../controllers/guaranteeReportController')
/// // inbox
router.get('/inbox', transactionController.get_all_transactions_for_agent)
router.get('/inbox/:id', transactionController.get_one_transaction_for_agent)
router.put('/changeTStatus/:id', transactionController.change_transaction_status_by_agent)
/// ///////////// pieces
router.get('/pieces', pieceController.get_all_pieces)
/// // piece request
router.post('/pr', pieceRequestController.add_piece_request)
router.post('/sendPr/:id', pieceRequestController.change_pr_status_to_sent_by_agent)
router.put('/prDescription/:id', pieceRequestController.update_pr_description)
router.put('/addPrItems/:prId', pieceRequestController.add_pieces_to_pr)
router.delete('/removePrItems/:pieceItemId', pieceRequestController.remove_piece_from_pr)
router.delete('/pr/:id', pieceRequestController.delete_pr)
router.get('/prList', pieceRequestController.get_all_pr_for_agent)
router.get('/pr/:id', pieceRequestController.get_one_pr_for_agent)
/// // oldPiece request
router.post('/opr', oldPieceRequestController.add_oldPiece_request)
router.post('/sendOpr/:id', oldPieceRequestController.change_opr_status_to_sent_by_agent)
router.put('/oprDescription/:id', oldPieceRequestController.update_opr_description)
router.put('/addOprItems/:oprId', oldPieceRequestController.add_oldPieces_to_opr)
router.delete('/removeOprItems/:oldPieceItemId', oldPieceRequestController.remove_oldPiece_from_opr)
router.delete('/opr/:id', oldPieceRequestController.delete_opr)
router.get('/oprList', oldPieceRequestController.get_all_opr_for_agent)
router.get('/opr/:id', oldPieceRequestController.get_one_opr_for_agent)
/// // buffer request
router.post('/br', bufferRequestController.add_buffer_request)
router.post('/sendBr/:id', bufferRequestController.change_br_status_to_sent_by_agent)
router.put('/brDescription/:id', bufferRequestController.update_br_description)
router.put('/addBrItems/:brId', bufferRequestController.add_buffer_to_br)
router.delete('/removeBrItems/:bufferItemId', bufferRequestController.remove_buffer_from_br)
router.delete('/br/:id', bufferRequestController.delete_br)
router.get('/brList', bufferRequestController.get_all_br_for_agent)
router.get('/br/:id', bufferRequestController.get_one_br_for_agent)
/// // guarantee report
router.post('/gr', guaranteeReportController.add_guaranteeReport)
router.post('/sendGr/:id', guaranteeReportController.change_gr_status_to_sent_by_agent)
router.put('/grDescription/:id', guaranteeReportController.update_gr_description)
router.put('/addGrItems/:grId', guaranteeReportController.add_report_to_gr)
router.delete('/removeGrItems/:reportItemId', guaranteeReportController.remove_report_from_gr)
router.delete('/gr/:id', guaranteeReportController.delete_gr)
router.get('/grList', guaranteeReportController.get_all_gr_for_agent)
router.get('/gr/:id', guaranteeReportController.get_one_gr_for_agent)
module.exports = router
+16
View File
@@ -0,0 +1,16 @@
const { Router } = require('express')
const router = Router()
const userController = require('../controllers/userController')
/// /////////////////// admin routes
// router.post('/register/admin', userController.register_admin)
router.post('/register/user', userController.register_user)
// router.post('/activation/:key', userController.activation)
router.post('/reset-pass-token', userController.generate_reset_user_password_link)
router.post('/set-new-pass', userController.reset_password_using_token)
router.post('/login', userController.webLogin)
router.post('/logout', userController.webLogout)
router.get('/user', userController.getUser)
module.exports = router
+10
View File
@@ -0,0 +1,10 @@
const { Router } = require('express')
const router = Router()
const arpaConnectionController = require('../controllers/arpaConnectionController')
router.post('/getRouteManager', arpaConnectionController.getRouteManager)
router.post('/postRouteManager', arpaConnectionController.postRouteManager)
router.post('/putRouteManager', arpaConnectionController.putRouteManager)
router.post('/deleteRouteManager', arpaConnectionController.deleteRouteManager)
module.exports = router
+60
View File
@@ -0,0 +1,60 @@
const { Router } = require('express')
const router = Router()
/// //////////////////////////////////////////////////////// controllers
const warrantyTermsController = require('../controllers/warrantyTermsController')
const contactPageController = require('../controllers/contactPageController')
const faqController = require('../controllers/faqController')
const learningController = require('../controllers/learningController')
const downloadCategoryController = require('../controllers/downloadCategoryController')
const downloadController = require('../controllers/downloadController')
const iranCitiesController = require('../controllers/iranCitiesController')
const serialsExelController = require('../controllers/serialsExelController')
const helpController = require('../controllers/helpController')
const lotteryPopUpController = require('../controllers/lotteryPopUpController')
const lotteryController = require('../controllers/lotteryController')
const representationController = require('../controllers/representationController')
/// //////////////////////////////////////////////////////// routes
/// ///////////// warranty terms
router.get('/warranty/page/:page', warrantyTermsController.getAll)
router.get('/warranty/:id(*)', warrantyTermsController.getOne)
/// ///////////// FAQ
router.get('/faq', faqController.getAll)
router.get('/faq/:id(*)', faqController.getOne)
/// ///////////// Learning
router.get('/learning/page/:page', learningController.getAll)
router.get('/learning/:id(*)', learningController.getOne)
/// ///////////// download category
router.get('/dCategory', downloadCategoryController.getAll)
router.get('/dCategory/:id(*)', downloadCategoryController.getOne)
/// ///////////// downloads
router.get('/downloads/page/:category/:page', downloadController.getAll)
router.get('/downloads/:id(*)', downloadController.getOne)
router.get('/downloads-newest', downloadController.getNewest)
/// ///////////// contact us
router.post('/contact', contactPageController.create)
/// ///////////// get iran cities
router.get('/iranCities', iranCitiesController.getIranCities)
/// ///////////// check device serial number
router.post('/checkSerial', serialsExelController.checkSerial)
/// ///////////// get help page
router.get('/help', helpController.get)
/// ///////////// get agents
router.get('/agents', representationController.get_agents)
/// ///////////// lottery
router.get('/lotteryPopUp', lotteryPopUpController.getPopUpInfo)
router.get('/lastLottery', lotteryController.getLastLottery)
router.post('/enrollParticipant', lotteryController.enrollParticipant)
module.exports = router
+12
View File
@@ -0,0 +1,12 @@
const { Router } = require('express')
const router = Router()
/// //////////////////////////////////////////////////////// controllers
const thirdPartyController = require('../controllers/thirdPartyController')
/// //////////////////////////////////////////////////////// routes
router.post('/reception', thirdPartyController.reception)
router.post('/repair', thirdPartyController.repair)
router.post('/sendBack', thirdPartyController.sendBack)
module.exports = router
+56
View File
@@ -0,0 +1,56 @@
const { Router } = require('express')
const router = Router()
const userController = require('../controllers/userController')
const ticketsController = require('../controllers/ticketsController')
const representationController = require('../controllers/representationController')
const transactionDraftsController = require('../controllers/transactionDraftsController')
const transactionController = require('../controllers/transactionController')
const surveyController = require('../controllers/surveyController')
/// // profile
router.put('/update_profile', userController.update_user)
router.put('/update_password', userController.update_user_password)
router.put('/changeEmail', userController.changeEmail)
router.post('/resendEmailConfirmation', userController.resendEmailConfirmation)
router.put('/confirmEmail', userController.confirmEmail)
router.put('/changeMobile', userController.changeMobile)
router.post('/resendMobileConfirmation', userController.resendMobileConfirmation)
router.put('/confirmMobile', userController.confirmMobile)
/// // transactions
router.post('/transaction', transactionController.add_transaction)
router.get('/transactions', transactionController.get_all_transactions_for_user)
router.get('/transaction/:ttn', transactionController.get_one_transaction_for_user)
/// /// transaction drafts
router.post('/transactionDraft', transactionDraftsController.add_transaction_draft)
router.get('/transactionDrafts', transactionDraftsController.get_user_drafts)
router.get('/transactionDraft/:draftId', transactionDraftsController.get_one_user_draft)
router.put('/transactionDraft/:draftId', transactionDraftsController.update_draft_description)
router.delete('/transactionDraft/:draftId', transactionDraftsController.remove_draft)
router.put('/transactionDraftItemAdd/:draftId', transactionDraftsController.add_stuff_to_draft)
router.put('/transactionDraftItemRemove/:draftId', transactionDraftsController.remove_stuff_from_draft)
/// // tickets
router.get('/ticketConversations', ticketsController.get_all_tickets)
router.get('/getTicket/:id', ticketsController.get_one_ticket)
router.post('/addTicketConversation', ticketsController.add_ticket)
router.post('/addMessageToTicket/:id', ticketsController.add_message_to_ticket)
/// // representation
router.post('/representation', representationController.add_representation)
router.put('/representation/:representation_id', representationController.edit_representation_by_user)
router.post('/checkRepresentation', representationController.check_representation)
router.post('/representationImages/:representation_code', representationController.upload_image_to_representation)
router.delete(
'/representationImages/:representation_code/:imgId',
representationController.remove_image_from_representation
)
router.get('/representation/:id', representationController.getLastUserRep)
/// // survey
router.post('/survey', surveyController.create)
router.get('/surveys', surveyController.getAllForUser)
module.exports = router