samoulla-backend / controllers /vendorRequestController.js
Samoulla Sync Bot
Auto-deploy Samoulla Backend: b68e45770de26ed39feb4b1c0925e5345eb3a61d
634b9bb
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,
});
}
};