Implement grace period system for member dues management
All checks were successful
Build And Push Image / docker (push) Successful in 2m55s

- Add grace period logic for new members (1 month from join date)
- Enhance dues status computation with actual payment date validation
- Update member card to show grace period status with warning indicators
- Remove overdue dues banner from member list
- Add payment due date calculation in registration process
- Update email templates for improved member communication
This commit is contained in:
2025-08-11 15:03:44 +02:00
parent d9ef5bbdeb
commit 7a8c88c341
8 changed files with 224 additions and 44 deletions

View File

@@ -261,27 +261,81 @@ const statusColor = computed(() => {
}
});
// Helper to check if dues are actually current (paid within last 12 months)
const isDuesActuallyCurrent = computed(() => {
if (props.member.current_year_dues_paid !== 'true') return false;
if (!props.member.membership_date_paid) {
// If marked as paid but no payment date, consider it invalid/overdue
return false;
}
const paymentDate = new Date(props.member.membership_date_paid);
const oneYearAgo = new Date();
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
return paymentDate > oneYearAgo;
});
// Helper to check if member is in grace period (new members get 1 month)
const isInGracePeriod = computed(() => {
// For existing members, check if they have member_since and it's within 1 month
if (props.member.member_since) {
const memberSince = new Date(props.member.member_since);
const oneMonthLater = new Date(memberSince);
oneMonthLater.setMonth(oneMonthLater.getMonth() + 1);
return new Date() < oneMonthLater && props.member.current_year_dues_paid !== 'true';
}
// If no member_since but has payment_due_date in the future, assume in grace period
if (props.member.payment_due_date) {
const dueDate = new Date(props.member.payment_due_date);
return new Date() < dueDate && props.member.current_year_dues_paid !== 'true';
}
return false;
});
const duesColor = computed(() => {
return props.member.current_year_dues_paid === 'true' ? 'success' : 'error';
if (isDuesActuallyCurrent.value) return 'success';
if (isInGracePeriod.value) return 'warning';
return 'error';
});
const duesVariant = computed(() => {
return props.member.current_year_dues_paid === 'true' ? 'tonal' : 'flat';
if (isDuesActuallyCurrent.value) return 'tonal';
if (isInGracePeriod.value) return 'tonal';
return 'flat';
});
const duesIcon = computed(() => {
return props.member.current_year_dues_paid === 'true' ? 'mdi-check-circle' : 'mdi-alert-circle';
if (isDuesActuallyCurrent.value) return 'mdi-check-circle';
if (isInGracePeriod.value) return 'mdi-clock-alert';
return 'mdi-alert-circle';
});
const duesText = computed(() => {
return props.member.current_year_dues_paid === 'true' ? 'Dues Paid' : 'Dues Outstanding';
if (isDuesActuallyCurrent.value) return 'Dues Paid';
if (isInGracePeriod.value) return 'Grace Period';
return 'Dues Outstanding';
});
const isOverdue = computed(() => {
if (!props.member.payment_due_date) return false;
const dueDate = new Date(props.member.payment_due_date);
const today = new Date();
return dueDate < today && props.member.current_year_dues_paid !== 'true';
// If dues are current, not overdue
if (isDuesActuallyCurrent.value) return false;
// If in grace period, not yet overdue
if (isInGracePeriod.value) return false;
// Check if payment_due_date has passed
if (props.member.payment_due_date) {
const dueDate = new Date(props.member.payment_due_date);
const today = new Date();
return dueDate < today;
}
// If no due date but not paid and not in grace period, consider overdue
return props.member.current_year_dues_paid !== 'true';
});
// Calculate next dues date (1 year from when they last paid)