Dealer_Onboarding_Backend/controllers/relocationController.js

239 lines
6.7 KiB
JavaScript

const { RelocationRequest, Outlet, User, Worknote } = require('../models');
const { Op } = require('sequelize');
const { v4: uuidv4 } = require('uuid');
exports.submitRequest = async (req, res) => {
try {
const {
outletId, relocationType, currentAddress, currentCity, currentState,
currentLatitude, currentLongitude, proposedAddress, proposedCity,
proposedState, proposedLatitude, proposedLongitude, reason, proposedDate
} = req.body;
const requestId = `REL-${Date.now()}-${uuidv4().substring(0, 4).toUpperCase()}`;
const request = await RelocationRequest.create({
requestId,
outletId,
dealerId: req.user.id,
relocationType,
currentAddress,
currentCity,
currentState,
currentLatitude,
currentLongitude,
proposedAddress,
proposedCity,
proposedState,
proposedLatitude,
proposedLongitude,
reason,
proposedDate,
currentStage: 'RBM Review',
status: 'Pending',
progressPercentage: 0,
timeline: [{
stage: 'Submitted',
timestamp: new Date(),
user: req.user.full_name, // Assuming req.user.full_name is available
action: 'Request submitted'
}]
});
res.status(201).json({
success: true,
message: 'Relocation request submitted successfully',
requestId: request.requestId
});
} catch (error) {
console.error('Submit relocation error:', error);
res.status(500).json({ success: false, message: 'Error submitting request' });
}
};
exports.getRequests = async (req, res) => {
try {
const where = {};
if (req.user.role === 'Dealer') {
where.dealerId = req.user.id;
}
const requests = await RelocationRequest.findAll({
where,
include: [
{
model: Outlet,
as: 'outlet',
attributes: ['code', 'name']
},
{
model: User,
as: 'dealer',
attributes: ['full_name'] // Changed 'name' to 'full_name' based on original query
}
],
order: [['createdAt', 'DESC']]
});
res.json({ success: true, requests });
} catch (error) {
console.error('Get relocation requests error:', error);
res.status(500).json({ success: false, message: 'Error fetching requests' });
}
};
exports.getRequestById = async (req, res) => {
try {
const { id } = req.params;
const request = await RelocationRequest.findOne({
where: {
[Op.or]: [
{ id },
{ requestId: id }
]
},
include: [
{
model: Outlet,
as: 'outlet'
},
{
model: User,
as: 'dealer',
attributes: ['full_name', 'email'] // Changed 'name' to 'full_name'
},
{
model: Worknote,
as: 'worknotes', // Assuming Worknote model is for workflow/comments
include: [{
model: User,
as: 'actionedBy', // Assuming Worknote has an association to User for actioned_by
attributes: ['full_name']
}],
order: [['createdAt', 'ASC']]
}
]
});
if (!request) {
return res.status(404).json({ success: false, message: 'Request not found' });
}
// Calculate distance between current and proposed location (retained from original)
if (request.currentLatitude && request.proposedLatitude) {
const distance = calculateDistance(
request.currentLatitude, request.currentLongitude,
request.proposedLatitude, request.proposedLongitude
);
request.dataValues.distance = `${distance.toFixed(2)} km`; // Add to dataValues for response
}
res.json({ success: true, request });
} catch (error) {
console.error('Get relocation details error:', error);
res.status(500).json({ success: false, message: 'Error fetching details' });
}
};
exports.takeAction = async (req, res) => {
try {
const { id } = req.params;
const { action, comments } = req.body;
const request = await RelocationRequest.findOne({
where: {
[Op.or]: [
{ id },
{ requestId: id }
]
}
});
if (!request) {
return res.status(404).json({ success: false, message: 'Request not found' });
}
// Update status and current_stage based on action
let newStatus = request.status;
let newCurrentStage = request.currentStage;
if (action === 'Approved') {
newStatus = 'Approved';
// Assuming next stage logic would be here, e.g., 'Final Approval'
} else if (action === 'Rejected') {
newStatus = 'Rejected';
} else if (action === 'Forwarded to RBM') {
newCurrentStage = 'RBM Review';
} else if (action === 'Forwarded to ZBM') {
newCurrentStage = 'ZBM Review';
} else if (action === 'Forwarded to HO') {
newCurrentStage = 'HO Review';
}
// Create a worknote entry
await Worknote.create({
requestId: request.id,
stage: newCurrentStage, // Or the specific stage where action was taken
action: action,
comments: comments,
actionedBy: req.user.id,
actionedAt: new Date()
});
// Update the request status and current stage
await request.update({
status: newStatus,
currentStage: newCurrentStage,
updatedAt: new Date()
});
res.json({ success: true, message: `Request ${action.toLowerCase()} successfully` });
} catch (error) {
console.error('Take action error:', error);
res.status(500).json({ success: false, message: 'Error processing action' });
}
};
exports.uploadDocuments = async (req, res) => {
try {
const { id } = req.params;
const { documents } = req.body;
const request = await RelocationRequest.findOne({
where: {
[Op.or]: [
{ id },
{ requestId: id }
]
}
});
if (!request) {
return res.status(404).json({ success: false, message: 'Request not found' });
}
await request.update({
documents: documents,
updatedAt: new Date()
});
res.json({ success: true, message: 'Documents uploaded successfully' });
} catch (error) {
console.error('Upload documents error:', error);
res.status(500).json({ success: false, message: 'Error uploading documents' });
}
};
// Helper function to calculate distance between two coordinates
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // Radius of Earth in km
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}