Files
asan-service/server/controllers/representationController.js
T
2025-05-27 17:14:14 +03:30

1341 lines
44 KiB
JavaScript

const fs = require('fs')
const { body, validationResult } = require('express-validator')
const moment = require('moment-jalaali')
const Mongoose = require('mongoose')
const Representation = require('../models/Representation')
const User = require('../models/User')
const { SMS } = require('../plugins/SMS_Module')
const { phrases } = require('../plugins/SMS_Phrases')
const { _sr } = require('../plugins/serverResponses')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const {
res404,
res406,
res500,
checkValidations,
checkMobileNumber,
checkNationalCode,
isPersian,
isPersianWithDigits
} = require('../plugins/controllersHelperFunctions')
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')
}
module.exports.add_representation = [
[
body('representation_type')
.notEmpty()
.withMessage('نوع نمایندگی را مشخص کنید')
.bail()
.custom((value, { req }) => {
const acceptedValues = [
'mobile_accessories',
'computer_accessories',
'memory_products',
'car_audio_video',
'home_products'
]
if (!Array.isArray(value)) return Promise.reject(new Error('نوع نمایندگی باید به صورت آرایه باشد'))
if (value.length === 0) return Promise.reject(new Error('حداقل یک نوع نمایندگی را انتخاب کنید'))
const isValid = value.every(item => acceptedValues.includes(item))
if (!isValid) return Promise.reject(new Error('مقدار نامعتبر برای نوع نمایندگی'))
return true
}),
body('full_name')
.notEmpty()
.withMessage(_faSr.required.name)
.bail()
.custom((value, { req }) => {
if (!isPersian(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('birth_date').notEmpty().withMessage(_faSr.required.birthdate),
body('id_number').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('place_of_issue')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('national_code')
.notEmpty()
.withMessage(_faSr.required.national_code)
.custom((value, { req }) => {
if (!checkNationalCode(value)) return Promise.reject(_faSr.format.national_code)
else return Promise.resolve()
}),
body('fathers_name')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersian(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('education_level').notEmpty().withMessage(_faSr.required.field),
body('military_status')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('store_name').notEmpty().withMessage(_faSr.required.field),
body('province_name').notEmpty().withMessage(_faSr.required.field),
body('province_id').notEmpty().withMessage(_faSr.required.field),
body('city_name').notEmpty().withMessage(_faSr.required.field),
body('city_id').notEmpty().withMessage(_faSr.required.field),
body('postal_code').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('mobile_number')
.notEmpty()
.withMessage(_faSr.required.field)
.isNumeric()
.withMessage(_faSr.format.number)
.custom((value, { req }) => {
if (!checkMobileNumber(value)) return Promise.reject(new Error('فرمت شماره موبایل درست نمیباشد'))
else return Promise.resolve()
}),
body('tel_number').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('email').notEmpty().withMessage(_faSr.required.field).bail().isEmail().withMessage(_faSr.format.email),
body('address')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('business_license')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.isBoolean()
.withMessage(_faSr.format.boolean),
body('ownership_type').notEmpty().withMessage(_faSr.required.field),
body('total_area').notEmpty().withMessage(_faSr.required.field),
body('repair_area').notEmpty().withMessage(_faSr.required.field),
body('stock_area').notEmpty().withMessage(_faSr.required.field),
body('customer_reference_floor').notEmpty().withMessage(_faSr.required.field),
body('place_location').notEmpty().withMessage(_faSr.required.field),
body('geo_location').notEmpty().withMessage(_faSr.required.field),
body('banner_info').notEmpty().withMessage(_faSr.required.field),
body('repair_technicians').notEmpty().withMessage(_faSr.required.field),
body('repair_masters').notEmpty().withMessage(_faSr.required.field),
body('office_workers').notEmpty().withMessage(_faSr.required.field),
body('bike_deliveries').notEmpty().withMessage(_faSr.required.field),
body('computer_repair_exp').notEmpty().withMessage(_faSr.required.field),
body('multimedia_repair_exp').notEmpty().withMessage(_faSr.required.field),
body('business_exp').notEmpty().withMessage(_faSr.required.field),
body('know_asanServ_from').notEmpty().withMessage(_faSr.required.field),
body('asanServ_products_knowledge').notEmpty().withMessage(_faSr.required.field),
body('computer_saling_exp').notEmpty().withMessage(_faSr.required.field)
],
checkValidations(validationResult),
async (req, res) => {
const { user_id } = req
if (!user_id) throw new Error('invalid user id')
const {
representation_type,
full_name,
birth_date,
id_number,
place_of_issue,
national_code,
fathers_name,
education_level,
military_status,
certificates,
store_name,
province_name,
province_id,
city_name,
city_id,
postal_code,
mobile_number,
tel_number,
fax_number,
economic_code,
email,
address,
business_license,
ownership_type,
total_area,
repair_area,
stock_area,
customer_reference_floor,
place_location,
geo_location,
banner_info,
repair_technicians,
repair_masters,
office_workers,
bike_deliveries,
computer_repair_exp,
multimedia_repair_exp,
business_exp,
know_asanServ_from,
introducer_info,
asanServ_products_knowledge,
computer_saling_exp,
computer_saling_description,
other_representations,
more_descriptions
} = req.body
const data = {
user_id,
representation_type,
full_name,
birth_date,
id_number,
place_of_issue,
national_code,
fathers_name,
education_level,
military_status,
certificates,
store_name,
province_name,
province_id,
city_name,
city_id,
postal_code,
mobile_number,
tel_number,
fax_number,
economic_code,
email,
address,
business_license,
ownership_type,
total_area,
repair_area,
stock_area,
customer_reference_floor,
place_location,
geo_location,
banner_info,
repair_technicians,
repair_masters,
office_workers,
bike_deliveries,
computer_repair_exp,
multimedia_repair_exp,
business_exp,
know_asanServ_from,
introducer_info,
asanServ_products_knowledge,
computer_saling_exp,
computer_saling_description,
other_representations,
more_descriptions
}
try {
const checkUserRepresentations = await Representation.find({ user_id, archived: false })
if (checkUserRepresentations.length)
return res406(res, 'تا زمانی که درخواست قبلی توسط کارشناسان تعیین وضعیت نشود نمیتوانید درخواست جدیدی ثبت کنید.')
const allRepresentations = await Representation.find()
const representation_code =
'ASAREP' +
moment(Date.now()).format('jMMM').toUpperCase() +
allRepresentations.length.toString().padStart(4, '0')
data.representation_code = representation_code
const representation = new Representation(data)
const user = await User.findById(user_id)
if (!user) {
res404(res, 'آین کاربر در دیتای ما وجود ندارد')
} else {
await representation.save()
}
user.askedForRepresentation = true
user.representation_code = representation_code
await user.save()
const smsMessage = [
' متقاضی گرامی درخواست شما با کد پیگیری ',
representation_code,
' در تاریخ ',
SmsDateFormat(Date.now()),
' در سامانه ثبت شد. ',
'\n',
' بعد از بررسی مدارک توسط کارشناسان نتیجه از طریق پیامک برای شما ارسال خواهد شد، همچنین میتوانید با کد پیگیری از طریق نشانی زیر وضعیت درخواست خود را بررسی کند. ',
'\n',
'https://asan-service.com/representation',
'\n',
phrases.signature
]
const responseMsg = ['درخواست شما باموفقیت ثبت شد.', '\n', ' کد پیگیری: ', representation_code]
SMS([mobile_number], smsMessage.join(''))
notifyAdmin('updateNewRepresentations')
return res.json({ message: responseMsg.join('') })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.edit_representation_by_user = [
[
body('representation_type')
.notEmpty()
.withMessage('نوع نمایندگی را مشخص کنید')
.bail()
.custom((value, { req }) => {
const acceptedValues = [
'mobile_accessories',
'computer_accessories',
'memory_products',
'car_audio_video',
'home_products'
]
if (!Array.isArray(value)) return Promise.reject(new Error('نوع نمایندگی باید به صورت آرایه باشد'))
if (value.length === 0) return Promise.reject(new Error('حداقل یک نوع نمایندگی را انتخاب کنید'))
const isValid = value.every(item => acceptedValues.includes(item))
if (!isValid) return Promise.reject(new Error('مقدار نامعتبر برای نوع نمایندگی'))
return true
}),
body('full_name')
.notEmpty()
.withMessage(_faSr.required.name)
.bail()
.custom((value, { req }) => {
if (!isPersian(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('birth_date').notEmpty().withMessage(_faSr.required.birthdate),
body('id_number').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('place_of_issue')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('national_code')
.notEmpty()
.withMessage(_faSr.required.national_code)
.custom((value, { req }) => {
if (!checkNationalCode(value)) return Promise.reject(_faSr.format.national_code)
else return Promise.resolve()
}),
body('fathers_name')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersian(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('education_level').notEmpty().withMessage(_faSr.required.field),
body('military_status')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('store_name').notEmpty().withMessage(_faSr.required.field),
body('province_name').notEmpty().withMessage(_faSr.required.field),
body('province_id').notEmpty().withMessage(_faSr.required.field),
body('city_name').notEmpty().withMessage(_faSr.required.field),
body('city_id').notEmpty().withMessage(_faSr.required.field),
body('postal_code').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('mobile_number')
.notEmpty()
.withMessage(_faSr.required.field)
.isNumeric()
.withMessage(_faSr.format.number)
.custom((value, { req }) => {
if (!checkMobileNumber(value)) return Promise.reject(new Error('فرمت شماره موبایل درست نمیباشد'))
else return Promise.resolve()
}),
body('tel_number').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('email').notEmpty().withMessage(_faSr.required.field).bail().isEmail().withMessage(_faSr.format.email),
body('address')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('business_license')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.isBoolean()
.withMessage(_faSr.format.boolean),
body('ownership_type').notEmpty().withMessage(_faSr.required.field),
body('total_area').notEmpty().withMessage(_faSr.required.field),
body('repair_area').notEmpty().withMessage(_faSr.required.field),
body('stock_area').notEmpty().withMessage(_faSr.required.field),
body('customer_reference_floor').notEmpty().withMessage(_faSr.required.field),
body('place_location').notEmpty().withMessage(_faSr.required.field),
body('geo_location').notEmpty().withMessage(_faSr.required.field),
body('banner_info').notEmpty().withMessage(_faSr.required.field),
body('repair_technicians').notEmpty().withMessage(_faSr.required.field),
body('repair_masters').notEmpty().withMessage(_faSr.required.field),
body('office_workers').notEmpty().withMessage(_faSr.required.field),
body('bike_deliveries').notEmpty().withMessage(_faSr.required.field),
body('computer_repair_exp').notEmpty().withMessage(_faSr.required.field),
body('multimedia_repair_exp').notEmpty().withMessage(_faSr.required.field),
body('business_exp').notEmpty().withMessage(_faSr.required.field),
body('know_asanServ_from').notEmpty().withMessage(_faSr.required.field),
body('asanServ_products_knowledge').notEmpty().withMessage(_faSr.required.field),
body('computer_saling_exp').notEmpty().withMessage(_faSr.required.field)
],
checkValidations(validationResult),
async (req, res) => {
const { user_id } = req
const representation_id = req.params?.representation_id
if (!user_id || !representation_id) throw new Error('invalid user id')
const {
representation_type,
full_name,
birth_date,
id_number,
place_of_issue,
national_code,
fathers_name,
education_level,
military_status,
certificates,
store_name,
province_name,
province_id,
city_name,
city_id,
postal_code,
mobile_number,
tel_number,
fax_number,
economic_code,
email,
address,
business_license,
ownership_type,
total_area,
repair_area,
stock_area,
customer_reference_floor,
place_location,
geo_location,
banner_info,
repair_technicians,
repair_masters,
office_workers,
bike_deliveries,
computer_repair_exp,
multimedia_repair_exp,
business_exp,
know_asanServ_from,
introducer_info,
asanServ_products_knowledge,
computer_saling_exp,
computer_saling_description,
other_representations,
more_descriptions
} = req.body
const data = {
user_id,
representation_type,
full_name,
birth_date,
id_number,
place_of_issue,
national_code,
fathers_name,
education_level,
military_status,
certificates,
store_name,
province_name,
province_id,
city_name,
city_id,
postal_code,
mobile_number,
tel_number,
fax_number,
economic_code,
email,
address,
business_license,
ownership_type,
total_area,
repair_area,
stock_area,
customer_reference_floor,
place_location,
geo_location,
banner_info,
repair_technicians,
repair_masters,
office_workers,
bike_deliveries,
computer_repair_exp,
multimedia_repair_exp,
business_exp,
know_asanServ_from,
introducer_info,
asanServ_products_knowledge,
computer_saling_exp,
computer_saling_description,
other_representations,
more_descriptions
}
try {
const checkAccess = await Representation.findById(representation_id)
if (!checkAccess.editAccess) throw new Error('شما دسترسی ویرایش اطلاعات ندارید')
await Representation.findByIdAndUpdate(representation_id, data)
return res.json({ message: 'با موفقیت آپدیت شد' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.getAll = [
(req, res) => {
Representation.find({})
.select(
'user_id representation_code agent_code full_name national_code mobile_number province_name province_id city_name city_id status created_at representation_type'
)
.exec((err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.getOne = [
async (req, res) => {
try {
const representation = await Representation.findById(req.params?.id)
.populate('_updatedBy', 'username first_name last_name')
.populate('_revokedBy', 'username first_name last_name')
if (!representation) return res404(res, 'incorrect id')
if (representation.status === 'registered') {
representation.status = 'ongoing'
await representation.save()
const smsMsg = [
' متقاصی گرامی درخواست شما برای اخذ نمایندگی آسان سرویس به کد پیگیری ',
representation.representation_code,
' مورخ ',
SmsDateFormat(Date.now()),
' توسط کارشناسان آسان سرویس مشاهده و مورد بررسی قرار گرفت. ',
'\n',
phrases.signature
]
SMS([representation.mobile_number], smsMsg.join(''))
notifyAdmin('updateNewRepresentations')
return res.json(representation)
} else return res.json(representation)
} catch (e) {
return res500(res, e)
}
}
]
module.exports.getLastUserRep = [
async (req, res) => {
try {
const repId = req.params?.id
const isId = Mongoose.isValidObjectId(repId)
const representation = await Representation.findOne({
$or: [{ representation_code: repId }, { _id: isId ? repId : undefined }]
})
if (!representation) return res404(res, 'incorrect id')
return res.json(representation)
} catch (e) {
console.log('🚀 ~ file: representationController.js:620 ~ e', e)
return res500(res, e)
}
}
]
module.exports.change_form_status = [
async (req, res) => {
const status = req.body?.status
// status prop validation check
if (!status) return res500(res, 'status prop required')
const availableStatuses = [
'verification',
'accepted',
'rejected',
'uploadOff',
'uploadOn',
'editAccessOn',
'editAccessOff'
]
if (!availableStatuses.includes(status)) return res500(res, 'invalid status')
try {
// find representation and user
const representation = await Representation.findById(req.params.id)
if (!representation) return res404(res, 'incorrect id')
if (
status !== 'uploadOn' &&
status !== 'uploadOff' &&
status !== 'editAccessOn' &&
status !== 'editAccessOff' &&
representation.archived
) {
return res500(res, 'شما نمیتوانید وضعیت این فرم را تغییر دهید')
}
const user = await User.findById(representation.user_id)
if (!user) throw new Error('incorrect user id')
if (status === 'accepted' && user.isAgent) return res500(res, 'حساب این کاربر قبلا به حساب نماینده تبدیل شده')
// change upload ability
if (status === 'uploadOn') {
representation.upload = true
await representation.save()
const smsMsg = [
' متقاصی گرامی دسرسی آپلود مدارک برای درخواست ',
representation.representation_code,
' ایجاد شد، لطفا هرچه سریع تر نسبت به آپلود مدارک خود اقدام کنید. ',
'\n',
phrases.signature
]
SMS([representation.mobile_number], smsMsg.join(''))
return res.json({ message: 'وضعیت جدید در سیستم ثبت شد و پیامک اطلاع رسانی برای متقاضی ارسال شد' })
}
if (status === 'uploadOff') {
representation.upload = false
await representation.save()
return res.json({ message: 'وضعیت جدید در سیستم ثبت شد' })
}
// change editAccess ability
if (status === 'editAccessOn') {
representation.editAccess = true
await representation.save()
const smsMsg = [
' نماینده گرامی دسرسی ویرایش اطلاعات نمایندگی برای شما ایجاد شد، لطفا هرچه سریع تر نسبت به ویرایش اطلاعات خود اقدام کنید.',
'\n',
phrases.signature
]
SMS([representation.mobile_number], smsMsg.join(''))
return res.json({ message: 'وضعیت جدید در سیستم ثبت شد و پیامک اطلاع رسانی برای متقاضی ارسال شد' })
}
if (status === 'editAccessOff') {
representation.editAccess = false
await representation.save()
return res.json({ message: 'وضعیت جدید در سیستم ثبت شد' })
}
// change representation and user data
representation.status = status
user.askedForRepresentation = true
user.isAgent = false
if (status === 'rejected') {
user.askedForRepresentation = false
representation.archived = true
representation.upload = false
representation.editAccess = false
}
if (status === 'accepted') {
user.askedForRepresentation = false
representation.archived = true
representation.upload = false
representation.editAccess = false
user.isAgent = true
user.representation_id = representation._id
// Use agent_code from request if provided, otherwise generate a new one
if (req.body.agent_code) {
// Check if the agent code already exists
const existingRepresentation = await Representation.findOne({
agent_code: req.body.agent_code,
_id: { $ne: representation._id }
})
if (existingRepresentation) {
return res406(res, 'این کد نمایندگی قبلا برای نماینده دیگری استفاده شده است')
}
representation.agent_code = req.body.agent_code
} else {
const agentsCount = await Representation.find({ status: 'accepted' })
representation.agent_code = 'ASG' + agentsCount.length.toString().padStart(2, '0')
}
}
// save changes
await representation.save()
await user.save()
// send sms for user
function statusToPhrase() {
if (status === 'verification') return ' در وضعیت احراز هویت و بررسی مدارک قرار گرفت.'
else if (status === 'rejected') return ' رد شد. '
else return ' مورد قبول قرار گرفت. برای ادامه ی فرایند از طرف شرکت با شما تماس گرفته خواهد شد. '
}
const smsMsg = [
' متقاصی گرامی درخواست شما برای اخذ نمایندگی آسان سرویس به کد پیگیری ',
representation.representation_code,
' مورخ ',
SmsDateFormat(Date.now()),
statusToPhrase(),
'\n',
phrases.signature
]
SMS([representation.mobile_number], smsMsg.join(''))
return res.json({ message: 'وضعیت جدید در سیستم ثبت شد و پیامک اطلاع رسانی برای متقاضی ارسال شد' })
} catch (e) {
return res404(res, `there is an error here --- ${e}`)
}
}
]
module.exports.check_representation = [
[
body('representation_code')
.notEmpty()
.withMessage('کد پیگیری را وارد کنید')
.bail()
.isLength({ min: 13 })
.withMessage('فرمت کدپیگیری صحیح نمیباشد')
],
checkValidations(validationResult),
(req, res) => {
const { representation_code } = req.body
const { user_id } = req
if (!user_id) return res500(res, 'ابتدا وارد حساب کاربری خود شوید')
Representation.findOne({ user_id, representation_code: representation_code.toUpperCase() })
.select('_id status upload created_at')
.exec((err, data) => {
if (err || !data) return res404(res, 'درخواستی با این کد پیگیری ثبت نشده')
else return res.json(data)
})
}
]
module.exports.upload_image_to_representation = [
(req, res) => {
const file = req.files?.file
const fieldName = req.query?.name
const userType = req.params?.userType
const representation_code = req.params?.representation_code
if (!file) return res500(res, 'هیچ فایلی برای آپلود انتخاب نکرده اید')
if (!fieldName) return res500(res, 'هیچ دسته بندی ای انتخاب نکرده اید')
if (file.mimetype !== 'image/jpeg') return res500(res, 'فقط فرمت jpg قابل قبول است')
if (file.size / 1024 / 1024 > 2) return res500(res, 'حداکثر حجم مجاز آپلود 2 مگابایت میباشد')
Representation.findOne({ representation_code }, (err, data) => {
if (err || !data) return res500(res, 'invalid rep id')
if ((!data.upload || data.status === 'rejected') && userType !== 'admin') {
return res500(res, 'شما دسترسی آپلود ندارید')
}
const fileName = data.representation_code + '_' + Date.now() + Math.random() + fieldName + file.name
data[fieldName].push({ name: fileName })
data.markModified(fieldName)
file.mv(`./static/uploads/representation_docs/${fileName}`, err => {
if (err) console.log(err)
})
data.save((err, data) => {
if (err) console.log(err)
return res.json({ message: 'فایل مدارک در سیستم ذخیره شد' })
})
})
}
]
module.exports.remove_image_from_representation = [
(req, res) => {
const representation_code = req.params?.representation_code
const imgId = req.params?.imgId
const fieldName = req.query?.name
const userType = req.params?.userType
if (!representation_code || !imgId || !fieldName) return res500(res, 'please provide all nessesory information')
Representation.findOne({ representation_code }, (err, data) => {
if (err || !data) return res500(res, 'invalid rep id')
if ((!data.upload || data.status === 'rejected') && userType !== 'admin') {
return res500(res, 'شما دسترسی آپلود ندارید')
}
try {
const img = data[fieldName].id(imgId)
img.remove(err => {
if (err) console.log(err)
fs.unlink(`./static/uploads/representation_docs/${img.name}`, err => {
if (err) console.log(err)
})
})
data.save((err, data) => {
if (err) console.log(err)
return res.json({ message: 'file removed successfully' })
})
} catch (err) {
res500(res, 'error')
}
})
}
]
module.exports.get_agents = [
(req, res) => {
Representation.find({ status: 'accepted', _revoked: false })
.select(
'full_name province_name province_id city_name city_id address postal_code tel_number fax_number mobile_number email store_name agent_code representation_type'
)
.exec((err, agents) => {
if (err) return res404(res, err)
return res.json(agents)
})
}
]
module.exports.get_revoked_agents_for_admin = [
(req, res) => {
Representation.find({ _revoked: true })
.select(
'full_name province_name province_id city_name city_id address postal_code tel_number fax_number mobile_number email store_name agent_code representation_type'
)
.exec((err, agents) => {
if (err) return res404(res, err)
return res.json(agents)
})
}
]
module.exports.update_representation_by_admin = [
[
body('representation_type')
.notEmpty()
.withMessage('نوع نمایندگی را مشخص کنید')
.bail()
.custom((value, { req }) => {
const acceptedValues = [
'mobile_accessories',
'computer_accessories',
'memory_products',
'car_audio_video',
'home_products'
]
if (!Array.isArray(value)) return Promise.reject(new Error('نوع نمایندگی باید به صورت آرایه باشد'))
if (value.length === 0) return Promise.reject(new Error('حداقل یک نوع نمایندگی را انتخاب کنید'))
const isValid = value.every(item => acceptedValues.includes(item))
if (!isValid) return Promise.reject(new Error('مقدار نامعتبر برای نوع نمایندگی'))
return true
}),
body('full_name')
.notEmpty()
.withMessage(_faSr.required.name)
.bail()
.custom((value, { req }) => {
if (!isPersian(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('birth_date').notEmpty().withMessage(_faSr.required.birthdate),
body('id_number').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('place_of_issue')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('national_code')
.notEmpty()
.withMessage(_faSr.required.national_code)
.custom((value, { req }) => {
if (!checkNationalCode(value)) return Promise.reject(_faSr.format.national_code)
else return Promise.resolve()
}),
body('fathers_name')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersian(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('education_level').notEmpty().withMessage(_faSr.required.field),
body('military_status')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('store_name').notEmpty().withMessage(_faSr.required.field),
body('province_name').notEmpty().withMessage(_faSr.required.field),
body('province_id').notEmpty().withMessage(_faSr.required.field),
body('city_name').notEmpty().withMessage(_faSr.required.field),
body('city_id').notEmpty().withMessage(_faSr.required.field),
body('postal_code').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('mobile_number')
.notEmpty()
.withMessage(_faSr.required.field)
.isNumeric()
.withMessage(_faSr.format.number)
.custom((value, { req }) => {
if (!checkMobileNumber(value)) return Promise.reject(new Error('فرمت شماره موبایل درست نمیباشد'))
else return Promise.resolve()
}),
body('tel_number').notEmpty().withMessage(_faSr.required.field).isNumeric().withMessage(_faSr.format.number),
body('email').notEmpty().withMessage(_faSr.required.field).bail().isEmail().withMessage(_faSr.format.email),
body('address')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.custom((value, { req }) => {
if (!isPersianWithDigits(value)) return Promise.reject(new Error('با حروف فارسی تایپ کنید'))
else return Promise.resolve()
}),
body('business_license')
.notEmpty()
.withMessage(_faSr.required.field)
.bail()
.isBoolean()
.withMessage(_faSr.format.boolean),
body('ownership_type').notEmpty().withMessage(_faSr.required.field),
body('total_area').notEmpty().withMessage(_faSr.required.field),
body('repair_area').notEmpty().withMessage(_faSr.required.field),
body('stock_area').notEmpty().withMessage(_faSr.required.field),
body('customer_reference_floor').notEmpty().withMessage(_faSr.required.field),
body('place_location').notEmpty().withMessage(_faSr.required.field),
body('geo_location').notEmpty().withMessage(_faSr.required.field),
body('banner_info').notEmpty().withMessage(_faSr.required.field),
body('repair_technicians').notEmpty().withMessage(_faSr.required.field),
body('repair_masters').notEmpty().withMessage(_faSr.required.field),
body('office_workers').notEmpty().withMessage(_faSr.required.field),
body('bike_deliveries').notEmpty().withMessage(_faSr.required.field),
body('computer_repair_exp').notEmpty().withMessage(_faSr.required.field),
body('multimedia_repair_exp').notEmpty().withMessage(_faSr.required.field),
body('business_exp').notEmpty().withMessage(_faSr.required.field),
body('know_asanServ_from').notEmpty().withMessage(_faSr.required.field),
body('asanServ_products_knowledge').notEmpty().withMessage(_faSr.required.field),
body('computer_saling_exp').notEmpty().withMessage(_faSr.required.field)
],
checkValidations(validationResult),
async (req, res) => {
const { user_id } = req
const representation_id = req.params?.id
if (!user_id || !representation_id) throw new Error('invalid user id')
const {
representation_type,
full_name,
birth_date,
id_number,
place_of_issue,
national_code,
fathers_name,
education_level,
military_status,
certificates,
store_name,
province_name,
province_id,
city_name,
city_id,
postal_code,
mobile_number,
tel_number,
fax_number,
economic_code,
email,
address,
business_license,
ownership_type,
total_area,
repair_area,
stock_area,
customer_reference_floor,
place_location,
geo_location,
banner_info,
repair_technicians,
repair_masters,
office_workers,
bike_deliveries,
computer_repair_exp,
multimedia_repair_exp,
business_exp,
know_asanServ_from,
introducer_info,
asanServ_products_knowledge,
computer_saling_exp,
computer_saling_description,
other_representations,
more_descriptions,
agent_code
} = req.body
const data = {
_updatedBy: user_id,
representation_type,
full_name,
birth_date,
id_number,
place_of_issue,
national_code,
fathers_name,
education_level,
military_status,
certificates,
store_name,
province_name,
province_id,
city_name,
city_id,
postal_code,
mobile_number,
tel_number,
fax_number,
economic_code,
email,
address,
business_license,
ownership_type,
total_area,
repair_area,
stock_area,
customer_reference_floor,
place_location,
geo_location,
banner_info,
repair_technicians,
repair_masters,
office_workers,
bike_deliveries,
computer_repair_exp,
multimedia_repair_exp,
business_exp,
know_asanServ_from,
introducer_info,
asanServ_products_knowledge,
computer_saling_exp,
computer_saling_description,
other_representations,
more_descriptions,
agent_code
}
try {
// Check if agent_code is provided in the request body
if (agent_code) {
data.agent_code = agent_code
}
await Representation.findByIdAndUpdate(representation_id, data)
return res.json({ message: 'با موفقیت آپدیت شد' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.revoke_representation_by_admin = [
async (req, res) => {
try {
const { user_id } = req
if (!user_id) return res406(res, 'invalid user id')
const representation = await Representation.findOne({ _id: req.params?.id }).populate('user_id')
if (!representation) return res404(res, 'Representation not found')
const agentAccount = await User.findOne({ _id: representation.user_id })
if (!agentAccount) return res404(res, 'Agent account not found')
representation._revoked = true
representation._revokedBy = user_id
agentAccount.isAgent = false
agentAccount.representation_id = undefined
agentAccount.askedForRepresentation = false
await representation.save()
await agentAccount.save()
return res.json({ message: 'امتیاز نمایندگی صلب شد' })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.add_agent_by_admin = [
async (req, res) => {
const user_id = req.body.user
if (!user_id) throw new Error('invalid user id')
const data = {
user_id,
representation_type: [
'mobile_accessories',
'computer_accessories',
'memory_products',
'car_audio_video',
'home_products'
],
full_name: '', // todo
birth_date: '',
id_number: '',
place_of_issue: '',
national_code: '', // todo
fathers_name: '',
education_level: '',
military_status: '',
certificates: '',
store_name: '',
province_name: '', // todo
province_id: '', // todo
city_name: '', // todo
city_id: '', // todo
postal_code: '',
mobile_number: '', // todo
tel_number: '',
fax_number: '',
economic_code: '',
email: '', // todo
address: '', // todo
business_license: true,
ownership_type: 'owner',
total_area: '',
repair_area: '',
stock_area: '',
customer_reference_floor: '',
place_location: 'other',
geo_location: 'inside_passage',
banner_info: '',
repair_technicians: '',
repair_masters: '',
office_workers: '',
bike_deliveries: '',
computer_repair_exp: '',
multimedia_repair_exp: '',
business_exp: '',
know_asanServ_from: 'other',
introducer_info: '',
asanServ_products_knowledge: 4,
computer_saling_exp: true,
computer_saling_description: '',
other_representations: [],
more_descriptions: ''
}
try {
const allRepresentations = await Representation.find()
// generate rep code
const representation_code =
'ASAREP' +
moment(Date.now()).format('jMMM').toUpperCase() +
allRepresentations.length.toString().padStart(4, '0')
// generate agent code with new format or use the one provided by admin
if (req.body.agent_code) {
// Check if the agent code already exists
const existingRepresentation = await Representation.findOne({
agent_code: req.body.agent_code
})
if (existingRepresentation) {
return res406(res, 'این کد نمایندگی قبلا برای نماینده دیگری استفاده شده است')
}
data.agent_code = req.body.agent_code
} else {
const agentsCount = await Representation.find({ status: 'accepted' })
data.agent_code = 'ASG' + moment(Date.now()).format('YY') + agentsCount.length.toString().padStart(3, '0')
}
data.representation_code = representation_code
// find user and import information
const user = await User.findById(user_id)
if (user.isAgent) return res500(res, 'حساب کاربر از قبل نماینده است')
user.askedForRepresentation = false
user.isAgent = true
user.representation_code = representation_code
data.full_name = user.first_name + ' ' + user.last_name
data.national_code = user.national_code
data.province_name = user.province_name
data.province_id = user.province_id
data.city_name = user.city_name
data.city_id = user.city_id
data.mobile_number = user.mobile_number
data.email = user.email
data.address = user.address
data.archived = true
data.upload = true
data.editAccess = true
data.status = 'accepted'
const representation = new Representation(data)
await representation.save()
user.representation_id = representation._id
await user.save()
return res.json({ representationId: representation.id })
} catch (e) {
return res500(res, e)
}
}
]
module.exports.update_agent_code = [
async (req, res) => {
try {
const { user_id } = req
const representation_id = req.params?.id
const { newAgentCode } = req.body
if (!user_id || !representation_id) return res406(res, 'invalid user id')
if (!newAgentCode) return res406(res, 'کد نمایندگی جدید الزامی است')
// Check if the agent code already exists in another representation
const existingRepresentation = await Representation.findOne({
agent_code: newAgentCode,
_id: { $ne: representation_id }
})
if (existingRepresentation) {
return res406(res, 'این کد نمایندگی قبلا برای نماینده دیگری استفاده شده است')
}
const representation = await Representation.findById(representation_id)
if (!representation) return res404(res, 'نماینده مورد نظر یافت نشد')
representation.agent_code = newAgentCode
representation._updatedBy = user_id
await representation.save()
return res.json({ message: 'کد نمایندگی با موفقیت بروزرسانی شد' })
} catch (e) {
return res500(res, e)
}
}
]