monacousa-portal/server/api/members/update-overdue-statuses.pos...

195 lines
6.8 KiB
TypeScript
Raw Normal View History

// server/api/members/update-overdue-statuses.post.ts
// Helper function to calculate overdue duration
function calculateOverdueDuration(dueDate: Date, today: Date): {
years: number;
months: number;
totalMonths: number;
formattedDuration: string;
} {
const diffTime = today.getTime() - dueDate.getTime();
const diffMonths = Math.floor(diffTime / (1000 * 60 * 60 * 24 * 30.44)); // Average days per month
const years = Math.floor(diffMonths / 12);
const months = diffMonths % 12;
let formattedDuration = '';
if (years > 0) {
formattedDuration += `${years} year${years !== 1 ? 's' : ''}`;
if (months > 0) {
formattedDuration += ` ${months} month${months !== 1 ? 's' : ''}`;
}
} else {
formattedDuration = `${diffMonths} month${diffMonths !== 1 ? 's' : ''}`;
}
return {
years,
months,
totalMonths: diffMonths,
formattedDuration: `${formattedDuration} overdue`
};
}
export default defineEventHandler(async (event) => {
try {
const { getMembers, updateMember } = await import('~/server/utils/nocodb');
// Get all members
const allMembers = await getMembers();
if (!allMembers?.list) {
return {
success: true,
data: { updatedCount: 0 },
message: 'No members found'
};
}
const today = new Date();
const membersToUpdate: any[] = [];
const overdueDetails: any[] = [];
for (const member of allMembers.list) {
// Skip if already inactive
if (member.membership_status === 'Inactive') {
// Still check if this inactive member is overdue to include in details
let overdueDuration = null;
if (member.current_year_dues_paid === 'true' && member.membership_date_paid) {
const lastPaidDate = new Date(member.membership_date_paid);
const oneYearFromPayment = new Date(lastPaidDate);
oneYearFromPayment.setFullYear(oneYearFromPayment.getFullYear() + 1);
if (today > oneYearFromPayment) {
overdueDuration = calculateOverdueDuration(oneYearFromPayment, today);
}
} else if (member.current_year_dues_paid !== 'true') {
let dueDate: Date;
if (member.payment_due_date) {
dueDate = new Date(member.payment_due_date);
} else if (member.member_since) {
dueDate = new Date(member.member_since);
dueDate.setFullYear(dueDate.getFullYear() + 1);
} else {
continue;
}
const oneYearOverdue = new Date(dueDate);
oneYearOverdue.setFullYear(oneYearOverdue.getFullYear() + 1);
if (today > oneYearOverdue) {
overdueDuration = calculateOverdueDuration(oneYearOverdue, today);
}
}
if (overdueDuration) {
overdueDetails.push({
id: member.Id,
name: member.FullName || `${member.first_name} ${member.last_name}`,
status: 'Inactive',
overdueDuration: overdueDuration.formattedDuration,
totalMonthsOverdue: overdueDuration.totalMonths
});
}
continue;
}
// Check if member has overdue dues (more than 1 year)
let isOverdue = false;
let overdueDuration = null;
if (member.current_year_dues_paid === 'true' && member.membership_date_paid) {
// If dues are marked as paid, check if it's been more than 1 year since payment
const lastPaidDate = new Date(member.membership_date_paid);
const oneYearFromPayment = new Date(lastPaidDate);
oneYearFromPayment.setFullYear(oneYearFromPayment.getFullYear() + 1);
if (today > oneYearFromPayment) {
isOverdue = true;
overdueDuration = calculateOverdueDuration(oneYearFromPayment, today);
}
} else if (member.current_year_dues_paid !== 'true') {
// If dues are not paid, check payment due date or member since date
let dueDate: Date;
if (member.payment_due_date) {
dueDate = new Date(member.payment_due_date);
} else if (member.member_since) {
// Fallback: 1 year from member since date
dueDate = new Date(member.member_since);
dueDate.setFullYear(dueDate.getFullYear() + 1);
} else {
// Skip if we can't determine due date
continue;
}
// Check if more than 1 year overdue
const oneYearOverdue = new Date(dueDate);
oneYearOverdue.setFullYear(oneYearOverdue.getFullYear() + 1);
if (today > oneYearOverdue) {
isOverdue = true;
overdueDuration = calculateOverdueDuration(oneYearOverdue, today);
}
}
if (isOverdue && overdueDuration) {
membersToUpdate.push({
id: member.Id,
name: member.FullName || `${member.first_name} ${member.last_name}`,
currentStatus: member.membership_status,
overdueDuration: overdueDuration.formattedDuration,
totalMonthsOverdue: overdueDuration.totalMonths
});
overdueDetails.push({
id: member.Id,
name: member.FullName || `${member.first_name} ${member.last_name}`,
status: member.membership_status,
overdueDuration: overdueDuration.formattedDuration,
totalMonthsOverdue: overdueDuration.totalMonths
});
}
}
// Update all overdue members to inactive
let updatedCount = 0;
const errors: string[] = [];
for (const memberInfo of membersToUpdate) {
try {
await updateMember(memberInfo.id, {
membership_status: 'Inactive'
});
updatedCount++;
console.log(`[API] Marked member ${memberInfo.name} (${memberInfo.id}) as inactive - ${memberInfo.overdueDuration}`);
} catch (error: any) {
console.error(`[API] Failed to update member ${memberInfo.name} (${memberInfo.id}):`, error);
errors.push(`Failed to update ${memberInfo.name}: ${error.message}`);
}
}
console.log(`[API] Updated ${updatedCount} of ${membersToUpdate.length} overdue members to inactive status`);
return {
success: true,
data: {
updatedCount,
totalOverdue: overdueDetails.length,
overdueDetails: overdueDetails.sort((a, b) => b.totalMonthsOverdue - a.totalMonthsOverdue), // Sort by most overdue first
errors: errors.length > 0 ? errors : undefined
},
message: `Successfully updated ${updatedCount} overdue member${updatedCount !== 1 ? 's' : ''} to inactive status`
};
} catch (error: any) {
console.error('[API] Error updating overdue member statuses:', error);
throw createError({
statusCode: error.statusCode || 500,
statusMessage: error.message || 'Failed to update overdue member statuses'
});
}
});