Spaces:
Running
Running
| const VendorRequest = require('../models/vendorRequestModel'); | |
| const Provider = require('../models/providerModel'); | |
| const User = require('../models/userModel'); | |
| const { | |
| sendVendorAcceptanceEmail, | |
| sendVendorRejectionEmail, | |
| } = require('../utils/emailService'); | |
| const { deleteImage, getPublicIdFromUrl } = require('../config/cloudinary'); | |
| // 1. Submit Vendor Request (Public) | |
| exports.submitRequest = async (req, res) => { | |
| try { | |
| const requestData = { ...req.body }; | |
| if (req.file) { | |
| requestData.logo = req.file.path; | |
| } | |
| const newRequest = await VendorRequest.create(requestData); | |
| res.status(201).json({ | |
| status: 'success', | |
| message: 'Form submitted successfully', | |
| data: { request: newRequest }, | |
| }); | |
| } catch (err) { | |
| res.status(400).json({ | |
| status: 'fail', | |
| message: err.message, | |
| }); | |
| } | |
| }; | |
| // 2. Get All Requests (Admin) | |
| exports.getAllRequests = async (req, res) => { | |
| try { | |
| const requests = await VendorRequest.find().sort({ createdAt: -1 }); | |
| res.status(200).json({ | |
| status: 'success', | |
| results: requests.length, | |
| data: { requests }, | |
| }); | |
| } catch (err) { | |
| res.status(500).json({ | |
| status: 'fail', | |
| message: err.message, | |
| }); | |
| } | |
| }; | |
| // 3. Get Single Request (Admin) | |
| exports.getRequest = async (req, res) => { | |
| try { | |
| const request = await VendorRequest.findById(req.params.id); | |
| if (!request) { | |
| return res.status(404).json({ | |
| status: 'fail', | |
| message: 'No request found with that ID', | |
| }); | |
| } | |
| res.status(200).json({ | |
| status: 'success', | |
| data: { request }, | |
| }); | |
| } catch (err) { | |
| res.status(400).json({ | |
| status: 'fail', | |
| message: err.message, | |
| }); | |
| } | |
| }; | |
| // 4. Delete Request (Admin) | |
| exports.deleteRequest = async (req, res) => { | |
| try { | |
| const request = await VendorRequest.findById(req.params.id); | |
| if (!request) { | |
| return res.status(404).json({ | |
| status: 'fail', | |
| message: 'No request found with that ID', | |
| }); | |
| } | |
| // Delete logo from Cloudinary if it exists | |
| if (request.logo) { | |
| const publicId = getPublicIdFromUrl(request.logo); | |
| if (publicId) await deleteImage(publicId).catch(() => {}); | |
| } | |
| await VendorRequest.findByIdAndDelete(req.params.id); | |
| res.status(204).json({ | |
| status: 'success', | |
| data: null, | |
| }); | |
| } catch (err) { | |
| res.status(400).json({ | |
| status: 'fail', | |
| message: err.message, | |
| }); | |
| } | |
| }; | |
| // 5. Respond to Request (Admin) | |
| // This will handle both Accept and Refuse | |
| exports.respondToRequest = async (req, res) => { | |
| try { | |
| const { status, password } = req.body; | |
| const request = await VendorRequest.findById(req.params.id); | |
| if (!request) { | |
| return res.status(404).json({ | |
| status: 'fail', | |
| message: 'No request found with that ID', | |
| }); | |
| } | |
| if (status === 'accepted') { | |
| // Create Provider Account (Logic similar to AdminProviderAdd.jsx handles it on frontend, but we need backend logic too) | |
| // Actually, the user said: "if i accept it uses the info in the form and give me option to assign his password" | |
| // So the admin will submit a final form with password. | |
| // First check if user with same email or phone exists | |
| const existingUser = await User.findOne({ | |
| $or: [{ email: request.email }, { phone: request.phoneNumber }], | |
| }); | |
| if (existingUser) { | |
| const field = | |
| existingUser.email === request.email | |
| ? 'البريد الإلكتروني' | |
| : 'رقم الهاتف'; | |
| return res.status(400).json({ | |
| status: 'fail', | |
| message: `${field} مسجل بالفعل لمستخدم آخر`, | |
| }); | |
| } | |
| // Get last provider ID for auto-increment | |
| const lastProvider = await Provider.findOne().sort({ id: -1 }); | |
| const autoId = lastProvider ? lastProvider.id + 1 : 1; | |
| // 1. Create Provider document (without user link yet) | |
| const newProvider = await Provider.create({ | |
| id: autoId, | |
| name: request.ownerName, | |
| storeName: request.businessName, | |
| phoneNumber: request.phoneNumber, | |
| address: request.address, | |
| logo: request.logo, | |
| }); | |
| // 2. Create User account for vendor and link to provider | |
| try { | |
| const newUser = await User.create({ | |
| name: request.ownerName, | |
| email: request.email, | |
| phone: request.phoneNumber, | |
| password: password, | |
| role: 'vendor', | |
| provider: newProvider._id, | |
| }); | |
| // 3. Update provider with user reference | |
| newProvider.user = newUser._id; | |
| await newProvider.save(); | |
| // 4. Update Request Status | |
| request.status = 'accepted'; | |
| request.reviewedAt = Date.now(); | |
| await request.save(); | |
| // 5. Send Acceptance Email | |
| await sendVendorAcceptanceEmail({ | |
| email: request.email, | |
| name: request.ownerName, | |
| storeName: request.businessName, | |
| password: password, | |
| }); | |
| return res.status(200).json({ | |
| status: 'success', | |
| message: 'Request accepted and provider created', | |
| data: { provider: newProvider }, | |
| }); | |
| } catch (err) { | |
| // Rollback: Delete the created provider if user creation fails | |
| await Provider.findByIdAndDelete(newProvider._id); | |
| throw err; | |
| } | |
| } else if (status === 'rejected') { | |
| request.status = 'rejected'; | |
| request.reviewedAt = Date.now(); | |
| await request.save(); | |
| // Send Rejection Email | |
| await sendVendorRejectionEmail({ | |
| email: request.email, | |
| name: request.ownerName, | |
| storeName: request.businessName, | |
| }); | |
| return res.status(200).json({ | |
| status: 'success', | |
| message: 'Request rejected', | |
| }); | |
| } | |
| } catch (err) { | |
| res.status(400).json({ | |
| status: 'fail', | |
| message: err.message, | |
| }); | |
| } | |
| }; | |