added admin features
This commit is contained in:
parent
12d5968373
commit
493e79273f
|
|
@ -393,11 +393,111 @@ const updateProfile = async (req, res) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Update member details (Manager only)
|
||||||
|
const updateMemberDetails = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { memberId } = req.params;
|
||||||
|
const { full_name, mobile_number, email, address, emergency_contact } = req.body;
|
||||||
|
const managerId = req.user.id;
|
||||||
|
|
||||||
|
// Find the member
|
||||||
|
const member = await User.findByPk(memberId);
|
||||||
|
if (!member) {
|
||||||
|
return res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Member not found'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the logged-in user is a manager
|
||||||
|
const manager = await User.findByPk(managerId);
|
||||||
|
if (manager.role !== 'manager') {
|
||||||
|
return res.status(403).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Only managers can update member details'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare updates
|
||||||
|
const updates = {};
|
||||||
|
|
||||||
|
if (full_name) {
|
||||||
|
updates.full_name = full_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mobile_number) {
|
||||||
|
// Validate mobile number format
|
||||||
|
if (!/^[0-9]{10}$/.test(mobile_number)) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Mobile number must be exactly 10 digits'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if mobile number is already taken by another user
|
||||||
|
const existingUser = await User.findOne({
|
||||||
|
where: { mobile_number }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingUser && existingUser.id !== memberId) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Mobile number is already in use'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updates.mobile_number = mobile_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (email !== undefined) {
|
||||||
|
if (email && !/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email)) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Please provide a valid email address'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updates.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address !== undefined) {
|
||||||
|
updates.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emergency_contact !== undefined) {
|
||||||
|
if (emergency_contact && !/^[0-9]{10}$/.test(emergency_contact)) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Emergency contact must be exactly 10 digits'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updates.emergency_contact = emergency_contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update member
|
||||||
|
await member.update(updates);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Member details updated successfully',
|
||||||
|
data: {
|
||||||
|
user: member.toJSON()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Update member details error:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Internal server error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
signup,
|
signup,
|
||||||
login,
|
login,
|
||||||
createMember,
|
createMember,
|
||||||
changePassword,
|
changePassword,
|
||||||
getProfile,
|
getProfile,
|
||||||
updateProfile
|
updateProfile,
|
||||||
|
updateMemberDetails
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -510,10 +510,167 @@ const getDrawStatistics = async (req, res) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Delete monthly draw (manager only, for mistakes)
|
||||||
|
const deleteMonthlyDraw = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { draw_id } = req.params;
|
||||||
|
const managerId = req.user.id;
|
||||||
|
|
||||||
|
// Find the draw
|
||||||
|
const monthlyDraw = await MonthlyDraw.findOne({
|
||||||
|
where: { id: draw_id },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: ChitGroup,
|
||||||
|
attributes: ['id', 'manager_id', 'name']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!monthlyDraw) {
|
||||||
|
return res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Monthly draw not found'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is the manager
|
||||||
|
if (monthlyDraw.ChitGroup.manager_id !== managerId) {
|
||||||
|
return res.status(403).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Only the group manager can delete draws'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store draw info for response
|
||||||
|
const drawInfo = {
|
||||||
|
month: monthlyDraw.month,
|
||||||
|
year: monthlyDraw.year,
|
||||||
|
groupName: monthlyDraw.ChitGroup.name
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delete the draw
|
||||||
|
await monthlyDraw.destroy();
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: `Draw for ${drawInfo.month}/${drawInfo.year} deleted successfully`,
|
||||||
|
data: drawInfo
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Delete monthly draw error:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Internal server error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update monthly draw (manager only, for corrections)
|
||||||
|
const updateMonthlyDraw = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { draw_id } = req.params;
|
||||||
|
const { winner_id, prize_amount, notes } = req.body;
|
||||||
|
const managerId = req.user.id;
|
||||||
|
|
||||||
|
// Find the draw
|
||||||
|
const monthlyDraw = await MonthlyDraw.findOne({
|
||||||
|
where: { id: draw_id },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: ChitGroup,
|
||||||
|
attributes: ['id', 'manager_id', 'name']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!monthlyDraw) {
|
||||||
|
return res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Monthly draw not found'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is the manager
|
||||||
|
if (monthlyDraw.ChitGroup.manager_id !== managerId) {
|
||||||
|
return res.status(403).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Only the group manager can update draws'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const updates = {};
|
||||||
|
|
||||||
|
// Update winner if provided
|
||||||
|
if (winner_id) {
|
||||||
|
// Verify the winner is a member of the group
|
||||||
|
const member = await GroupMember.findOne({
|
||||||
|
where: {
|
||||||
|
group_id: monthlyDraw.ChitGroup.id,
|
||||||
|
user_id: winner_id,
|
||||||
|
status: 'active'
|
||||||
|
},
|
||||||
|
include: [{ model: User, attributes: ['id', 'full_name'] }]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!member) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Winner must be an active member of this group'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updates.winner_id = winner_id;
|
||||||
|
if (!notes) {
|
||||||
|
updates.notes = `Winner updated to: ${member.User.full_name}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update prize amount if provided
|
||||||
|
if (prize_amount) {
|
||||||
|
updates.prize_amount = prize_amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update notes if provided
|
||||||
|
if (notes) {
|
||||||
|
updates.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform update
|
||||||
|
await monthlyDraw.update(updates);
|
||||||
|
|
||||||
|
// Fetch updated draw with winner details
|
||||||
|
const updatedDraw = await MonthlyDraw.findOne({
|
||||||
|
where: { id: draw_id },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: 'winner',
|
||||||
|
attributes: ['id', 'full_name', 'mobile_number']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Monthly draw updated successfully',
|
||||||
|
data: updatedDraw
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Update monthly draw error:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Internal server error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createMonthlyDraw,
|
createMonthlyDraw,
|
||||||
getGroupMonthlyDraws,
|
getGroupMonthlyDraws,
|
||||||
getMonthlyDrawDetails,
|
getMonthlyDrawDetails,
|
||||||
verifyDrawResult,
|
verifyDrawResult,
|
||||||
getDrawStatistics
|
getDrawStatistics,
|
||||||
|
deleteMonthlyDraw,
|
||||||
|
updateMonthlyDraw
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,6 @@ router.put('/change-password', authController.changePassword);
|
||||||
|
|
||||||
// Manager only routes
|
// Manager only routes
|
||||||
router.post('/create-member', requireManager, authController.createMember);
|
router.post('/create-member', requireManager, authController.createMember);
|
||||||
|
router.put('/member/:memberId', requireManager, authController.updateMemberDetails);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ const {
|
||||||
getGroupMonthlyDraws,
|
getGroupMonthlyDraws,
|
||||||
getMonthlyDrawDetails,
|
getMonthlyDrawDetails,
|
||||||
verifyDrawResult,
|
verifyDrawResult,
|
||||||
getDrawStatistics
|
getDrawStatistics,
|
||||||
|
deleteMonthlyDraw,
|
||||||
|
updateMonthlyDraw
|
||||||
} = require('../controllers/monthlyDrawController');
|
} = require('../controllers/monthlyDrawController');
|
||||||
|
|
||||||
// All routes require authentication
|
// All routes require authentication
|
||||||
|
|
@ -21,6 +23,12 @@ router.get('/group/:group_id', getGroupMonthlyDraws);
|
||||||
// Get monthly draw details
|
// Get monthly draw details
|
||||||
router.get('/:draw_id', getMonthlyDrawDetails);
|
router.get('/:draw_id', getMonthlyDrawDetails);
|
||||||
|
|
||||||
|
// Update monthly draw (manager only)
|
||||||
|
router.put('/:draw_id', updateMonthlyDraw);
|
||||||
|
|
||||||
|
// Delete monthly draw (manager only)
|
||||||
|
router.delete('/:draw_id', deleteMonthlyDraw);
|
||||||
|
|
||||||
// Verify provably fair result
|
// Verify provably fair result
|
||||||
router.post('/:draw_id/verify', verifyDrawResult);
|
router.post('/:draw_id/verify', verifyDrawResult);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue