monacousa-portal/server/api/admin/fix-payment-dates.post.ts

132 lines
4.8 KiB
TypeScript

// server/api/admin/fix-payment-dates.post.ts
export default defineEventHandler(async (event) => {
try {
const { getMembers, updateMember } = await import('~/server/utils/nocodb');
console.log('[api/admin/fix-payment-dates.post] Starting payment date migration...');
// Get all members
const membersResponse = await getMembers();
const members = membersResponse?.list || [];
if (members.length === 0) {
return {
success: true,
message: 'No members found to process',
stats: {
total: 0,
fixed: 0,
skipped: 0,
failed: 0
}
};
}
const results = {
total: members.length,
fixed: 0,
skipped: 0,
failed: 0,
errors: [] as any[]
};
// Process each member
for (const member of members) {
try {
// Check if member has membership_date_paid but no payment_due_date
if (member.membership_date_paid && !member.payment_due_date) {
const paymentDate = new Date(member.membership_date_paid);
// Calculate payment_due_date as 1 year from payment date
const dueDate = new Date(paymentDate);
dueDate.setFullYear(dueDate.getFullYear() + 1);
const dueDateStr = dueDate.toISOString().split('T')[0];
console.log(`[api/admin/fix-payment-dates.post] Fixing dates for ${member.first_name} ${member.last_name} (ID: ${member.Id})`);
console.log(` Payment Date: ${member.membership_date_paid}`);
console.log(` New Due Date: ${dueDateStr}`);
// Update the member
await updateMember(member.Id, {
payment_due_date: dueDateStr
});
results.fixed++;
console.log(`[api/admin/fix-payment-dates.post] ✅ Fixed payment dates for member ${member.Id}`);
} else if (member.membership_date_paid && member.payment_due_date) {
// Member already has both dates, skip
results.skipped++;
console.log(`[api/admin/fix-payment-dates.post] Skipped member ${member.Id} - already has payment_due_date`);
} else if (!member.membership_date_paid && !member.payment_due_date) {
// Member hasn't paid yet, check if they're new (within grace period)
if (member.member_since) {
const joinDate = new Date(member.member_since);
const gracePeriodEnd = new Date(joinDate);
gracePeriodEnd.setMonth(gracePeriodEnd.getMonth() + 1); // 1 month grace period
const now = new Date();
if (now < gracePeriodEnd) {
// Still in grace period, set payment_due_date to end of grace period
const dueDateStr = gracePeriodEnd.toISOString().split('T')[0];
await updateMember(member.Id, {
payment_due_date: dueDateStr
});
results.fixed++;
console.log(`[api/admin/fix-payment-dates.post] Set grace period due date for new member ${member.Id}`);
} else {
// Past grace period, set due date to 1 year from join date
const dueDate = new Date(joinDate);
dueDate.setFullYear(dueDate.getFullYear() + 1);
const dueDateStr = dueDate.toISOString().split('T')[0];
await updateMember(member.Id, {
payment_due_date: dueDateStr
});
results.fixed++;
console.log(`[api/admin/fix-payment-dates.post] Set overdue date for member ${member.Id}`);
}
} else {
results.skipped++;
console.log(`[api/admin/fix-payment-dates.post] Skipped member ${member.Id} - no payment or join date`);
}
} else {
results.skipped++;
}
} catch (error: any) {
console.error(`[api/admin/fix-payment-dates.post] ❌ Failed to fix dates for member ${member.Id}:`, error);
results.failed++;
results.errors.push({
memberId: member.Id,
name: `${member.first_name} ${member.last_name}`,
error: error.message || 'Unknown error'
});
}
}
const message = `Payment date migration complete!\n` +
`Fixed: ${results.fixed} members\n` +
`Skipped: ${results.skipped} members\n` +
`Failed: ${results.failed} members`;
console.log(`[api/admin/fix-payment-dates.post] ${message}`);
return {
success: results.failed === 0,
message,
stats: results
};
} catch (error: any) {
console.error('[api/admin/fix-payment-dates.post] Error:', error);
throw createError({
statusCode: error.statusCode || 500,
statusMessage: error.message || 'Failed to fix payment dates'
});
}
});