Files
asan-service/server/controllers/representationController.js
T
2025-09-14 18:25:29 +03:30

1320 lines
42 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 { _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')
// }
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 responseMsg = ['درخواست شما باموفقیت ثبت شد.', '\n', ' کد پیگیری: ', representation_code]
await sms.representation.submitted(mobile_number, representation_code, Date.now())
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'
]
const oldValues = [
'verity',
'panatech',
'both',
]
if (!Array.isArray(value)) return Promise.reject(new Error('نوع نمایندگی باید به صورت آرایه باشد'))
if (value.length === 0) return Promise.reject(new Error('حداقل یک نوع نمایندگی را انتخاب کنید'))
value = value.filter(x => !oldValues.includes(x))
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()
await sms.representation.underReview(
representation.mobile_number,
representation.representation_code,
Date.now()
)
notifyAdmin('updateNewRepresentations')
console.log("S")
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()
await sms.representation.uploadAccess(
representation.mobile_number,
representation.representation_code,
Date.now()
)
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()
await sms.representation.editAccess(representation.mobile_number, Date.now())
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 ' مورد قبول قرار گرفت. برای ادامه ی فرایند از طرف شرکت با شما تماس گرفته خواهد شد. '
}
await sms.representation.statusUpdate(
representation.mobile_number,
representation.representation_code,
statusToPhrase(),
Date.now()
)
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',
]
const oldValues = [
'verity',
'panatech',
'both',
]
if (!Array.isArray(value)) return Promise.reject(new Error('نوع نمایندگی باید به صورت آرایه باشد'))
if (value.length === 0) return Promise.reject(new Error('حداقل یک نوع نمایندگی را انتخاب کنید'))
value = value.filter(x => !oldValues.includes(x))
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)
}
}
]