const moment = require('moment-jalaali') const { body, validationResult } = require('express-validator') const TransactionDraft = require('../models/TransactionDraft') const Transaction = require('../models/Transaction') const User = require('../models/User') const SurveyCheck = require('../models/SurveyCheck') const { _sr } = require('../plugins/serverResponses') const { saveTransactionToArpa } = require('../ArpaWebservice.js') const { res404, res406, res500, checkValidations, generateRandomDigits } = require('../plugins/controllersHelperFunctions') const sms = require('../plugins/SMS_Module') const { notifyAgent } = require('../WebSocket/controllers/agent_EventsController') const { notifyUser } = require('../WebSocket/controllers/user_EventsController') const _faSr = _sr.fa // date formatters function ArpaDateFormat(date) { return moment(date).format('YYYY-MM-DD HH:mm:ss') } /// ///////////////// users module.exports.add_transaction = [ [ body('BusinessID').notEmpty().withMessage('Enter businessID'), body('cAddress1').notEmpty().withMessage(_faSr.required.address), body('TransCCustom1').notEmpty().withMessage(_faSr.required.receiver_first_name), body('cTel1').notEmpty().withMessage(_faSr.required.receiver_mobile) ], checkValidations(validationResult), async (req, res) => { if (!req.body.termsOfUse) return res406(res, 'با متن تعهدنامه موافقت نکرده اید') if (!req.body.items?.length) return res406(res, 'هیچ کالایی به فرم اضافه نکرده اید') const { BusinessID, Description, cAddress1, TransCCustom1, cTel1, items, draftId, db_name, agent } = req.body const data = { BusinessID, Description, cAddress1, TransCCustom1, cTel1 } try { const userId = req.user_id const thisTime = Date.now() // check user id and agent status const user = await User.findById(userId) if (!user) return res406(res, 'اطلاعات کاربری صحیح نمیباشد') if (user.isAgent && agent !== 'main') return res406(res, 'نمایندگان فقط میتوانند به خود شرکت آسان سرویس فرم ارسال نمایند') if (agent === 'main') { const ArpaResponse = await saveTransactionToArpa(data, items, db_name) await TransactionDraft.findByIdAndRemove(draftId) await sms.transaction.submitted(user.mobile_number, ArpaResponse, thisTime) notifyUser('updateDraftsCount', userId) return res.json({ host: 'ar', transNumber: ArpaResponse }) } else { // get transactions count const transactions = await Transaction.find() // fill specific fields data.user_id = userId data.agent_id = agent data.db_name = db_name data.items = items data.TempReceiptTransDate = ArpaDateFormat(thisTime) data.TempReceiptTransNumber = 'AG' + transactions.length.toString().padStart(4, '0') data.statusHistory = [{ status: 'saved', date: thisTime }] const transaction = new Transaction(data) await transaction.save() await TransactionDraft.findByIdAndRemove(draftId) await sms.transaction.submitted(user.mobile_number, transaction.TempReceiptTransNumber, thisTime) notifyUser('updateDraftsCount', userId) notifyAgent('newAgentInbox', agent) notifyAgent('updateAgentInbox', agent) return res.json({ host: 'as', transNumber: transaction.TempReceiptTransNumber }) } } catch (e) { console.log('there is an error in (Post Transaction to Arpa)', e, data) return res500(res, e) } } ] module.exports.get_all_transactions_for_user = [ (req, res) => { const { user_id } = req Transaction.find({ user_id }, (err, data) => { if (err) return res500(res, err) else return res.json(data) }) } ] module.exports.get_one_transaction_for_user = [ (req, res) => { const { user_id } = req Transaction.findOne({ user_id, TempReceiptTransNumber: req.params?.ttn }) .populate('agent_id', 'full_name province_name city_name address postal_code tel_number mobile_number') .exec((err, data) => { if (err || !data) return res404(res, err) else return res.json(data) }) } ] /// ///////////////// agents module.exports.get_all_transactions_for_agent = [ async (req, res) => { try { const { agent_id } = req const transactions = await Transaction.find({ agent_id }).sort({ created_at: -1 }) return res.json(transactions) } catch (e) { return res500(res, e) } } ] module.exports.get_one_transaction_for_agent = [ async (req, res) => { try { const { agent_id } = req const transaction = await Transaction.findOne({ agent_id, _id: req.params?.id }) if (!transaction) return res404(res, 'invalid transaction id') if (!transaction.seen) { transaction.seen = true await transaction.save() notifyAgent('updateAgentInbox', agent_id) } return res.json(transaction) } catch (e) { return res500(res, e) } } ] module.exports.change_transaction_status_by_agent = [ [ body('status') .notEmpty() .withMessage('status is required') .bail() .custom((value, { req }) => { const acceptablvalues = ['recieved', 'ongoing', 'waiting', 'delivered'] if (!acceptablvalues.includes(value)) return Promise.reject(new Error('invalid status')) else return true }) ], checkValidations(validationResult), async (req, res) => { const { status, deliveryCode } = req.body const { agent_id } = req const thisTime = Date.now() try { const transaction = await Transaction.findOne({ agent_id, _id: req.params?.id }) if (!transaction) return res404(res, 'invalid transaction id') // status order check const errMsg = 'invalid status for this time' if (transaction.status === 'saved' && status !== 'recieved') return res406(res, errMsg) if (transaction.status === 'recieved' && status !== 'ongoing') return res406(res, errMsg) // avoid repeated status if (transaction.status === 'waiting' && status === 'waiting') return res406(res, errMsg) if (transaction.status === 'delivered' && status === 'delivered') return res406(res, errMsg) // save status transaction.status = status transaction.statusHistory.push({ status, date: thisTime }) // different status methods if (status === 'recieved') { const receiptTN = transaction.TempReceiptTransNumber + 'R' + generateRandomDigits(2) transaction.ItemReceptionTransNumber = receiptTN transaction.ItemReceptionTransDate = ArpaDateFormat(thisTime) await sms.transaction.received(transaction.cTel1, transaction.TempReceiptTransNumber, receiptTN, thisTime) } if (status === 'ongoing') { await sms.transaction.ongoing(transaction.cTel1, transaction.ItemReceptionTransNumber, thisTime) } if (status === 'waiting') { await sms.transaction.waiting(transaction.cTel1, transaction.ItemReceptionTransNumber, thisTime) } if (status === 'delivered') { if (deliveryCode) transaction.deliveryCode = deliveryCode await sms.transaction.delivered(transaction.cTel1, transaction.ItemReceptionTransNumber, deliveryCode, thisTime) const surveyData = { code: transaction.ItemReceptionTransNumber, user: transaction.user_id, timeAdded: Date.now() } const surveyCheck = new SurveyCheck(surveyData) surveyCheck.save(err => { if (err) console.log('surveyCheck save error', err) }) } // SMS call now handled above in the individual status methods await transaction.save() return res.json({ message: _faSr.response.success_save }) } catch (e) { return res500(res, e) } } ] /// ///////////////// admin module.exports.get_all_agents_inbox_for_admin = [ async (req, res) => { try { const transactions = await Transaction.find() .sort({ created_at: -1 }) .populate('agent_id', 'agent_code full_name') .populate('user_id', 'province_id province_name city_id city_name') return res.json(transactions) } catch (e) { return res500(res, e) } } ] module.exports.get_one_agent_inbox_for_admin = [ async (req, res) => { try { const agent_id = req.params?.agent_id const transactions = await Transaction.find({ agent_id }) return res.json(transactions) } catch (e) { return res500(res, e) } } ] module.exports.get_one_transaction_for_admin = [ (req, res) => { Transaction.findById(req.params?.id) .populate( 'agent_id', 'full_name province_name city_name address postal_code tel_number fax_number mobile_number store_name agent_code' ) .populate( 'user_id', 'first_name last_name province_name city_name panatech_businessCode verity_businessCode national_code mobile_number address postal_code' ) .exec((err, data) => { if (err || !data) return res404(res, err) else return res.json(data) }) } ]