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; }