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) } } ]