Files
asan-service/server/controllers/transactionController.js
T
2025-07-09 11:55:58 +03:30

273 lines
9.2 KiB
JavaScript

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