From 4cf5692386b0648eae30710ae135cf44e4a61335 Mon Sep 17 00:00:00 2001 From: Sharon Dcruz Date: Fri, 8 Aug 2025 07:55:52 +0000 Subject: [PATCH] plan-expiry-in-two-days (#83) Reviewed-on: https://git.cosqnet.com/cosqnet/fitlien-services/pulls/83 Reviewed-by: Dhansh A S Co-authored-by: Sharon Dcruz Co-committed-by: Sharon Dcruz --- .../membershipStatusNotifications.ts | 37 +++++++++++-------- .../src/notifications/processNotification.ts | 4 +- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/functions/src/notifications/membershipStatusNotifications.ts b/functions/src/notifications/membershipStatusNotifications.ts index 3f6e564..3b0b61b 100644 --- a/functions/src/notifications/membershipStatusNotifications.ts +++ b/functions/src/notifications/membershipStatusNotifications.ts @@ -44,7 +44,7 @@ export const checkExpiredMemberships = onSchedule( try { const expiredMemberships = await findExpiredMemberships(); - const expiringMemberships = await findMembershipsExpiringIn2Days(); + const expiringMemberships = await findMembershipsExpiringIn10Days(); if (expiredMemberships.length === 0 && expiringMemberships.length === 0) { logger.info("No expired or expiring memberships found."); @@ -52,7 +52,7 @@ export const checkExpiredMemberships = onSchedule( } logger.info( - `Found ${expiredMemberships.length} expired memberships and ${expiringMemberships.length} memberships expiring in 2 days to process.` + `Found ${expiredMemberships.length} expired memberships and ${expiringMemberships.length} memberships expiring in 10 days to process.` ); const expiredResults = await Promise.allSettled( @@ -119,7 +119,7 @@ async function findExpiredMemberships(): Promise< } } -async function findMembershipsExpiringIn2Days(): Promise< +async function findMembershipsExpiringIn10Days(): Promise< Array<{ id: string; data: MembershipData }> > { try { @@ -139,8 +139,8 @@ async function findMembershipsExpiringIn2Days(): Promise< const batchResults = await Promise.allSettled( batch.map(async (doc) => { const data = doc.data() as MembershipData; - const isExpiringIn2Days = await checkIfMembershipExpiringIn2Days(doc.id, data); - if (isExpiringIn2Days) { + const isExpiringIn10Days = await checkIfMembershipExpiringIn10Days(doc.id, data); + if (isExpiringIn10Days) { return { id: doc.id, data }; } return null; @@ -156,7 +156,7 @@ async function findMembershipsExpiringIn2Days(): Promise< return expiring; } catch (error) { - logger.error("Error finding memberships expiring in 2 days:", error); + logger.error("Error finding memberships expiring in 10 days:", error); throw error; } } @@ -214,7 +214,7 @@ async function checkIfMembershipExpired( } } -async function checkIfMembershipExpiringIn2Days( +async function checkIfMembershipExpiringIn10Days( membershipId: string, data: MembershipData ): Promise { @@ -243,21 +243,21 @@ async function checkIfMembershipExpiringIn2Days( ); const now = new Date(); - const twoDaysFromNow = new Date(); - twoDaysFromNow.setDate(now.getDate() + 2); + const tenDaysFromNow = new Date(); + tenDaysFromNow.setDate(now.getDate() + 10); - const isExpiringIn2Days = expiryDate > now && expiryDate <= twoDaysFromNow; + const isExpiringIn10Days = expiryDate > now && expiryDate <= tenDaysFromNow; - if (isExpiringIn2Days) { + if (isExpiringIn10Days) { logger.info( - `Membership ${membershipId} will expire on ${expiryDate.toISOString()} (within 2 days)` + `Membership ${membershipId} will expire on ${expiryDate.toISOString()} (within 10 days)` ); } - return isExpiringIn2Days; + return isExpiringIn10Days; } catch (error) { logger.error( - `Error checking 2-day expiry for membership ${membershipId}:`, + `Error checking 10-day expiry for membership ${membershipId}:`, error ); return false; @@ -481,6 +481,7 @@ async function sendPlanExpiringNotification( let expiryDate: Date | undefined; let formattedDate = "Unknown Date"; + let daysUntilExpiry = 10; const payments = await getPaymentsForMembership(membershipId); if (payments.length > 0) { @@ -494,6 +495,10 @@ async function sendPlanExpiringNotification( month: "long", day: "numeric", }); + + const now = new Date(); + const timeDiff = expiryDate.getTime() - now.getTime(); + daysUntilExpiry = Math.ceil(timeDiff / (1000 * 3600 * 24)); } await app @@ -517,12 +522,12 @@ async function sendPlanExpiringNotification( expiryDate: expiryDate ? admin.firestore.Timestamp.fromDate(expiryDate) : admin.firestore.Timestamp.fromDate(new Date()), - daysUntilExpiry: 2, + daysUntilExpiry: daysUntilExpiry, }, }); logger.info( - `Expiring notification sent for membership ${membershipId} (expires on ${formattedDate})` + `Expiring notification sent for membership ${membershipId} (expires on ${formattedDate}, ${daysUntilExpiry} days remaining)` ); } catch (error) { logger.error(`Error sending expiring notification for ${membershipId}:`, error); diff --git a/functions/src/notifications/processNotification.ts b/functions/src/notifications/processNotification.ts index 418476e..3cc4811 100644 --- a/functions/src/notifications/processNotification.ts +++ b/functions/src/notifications/processNotification.ts @@ -240,14 +240,14 @@ function prepareNotificationMessage( title = notification.data?.title || "Plan Expired"; body = notification.data?.message || - `${notification.data?.clientName}'s subscription for plan ${notification.data?.planName} has expired.`; + `${notification.data?.clientName}'s membership subscription for ${notification.data?.planName} has expired.`; break; case "plan_expiring_soon": title = notification.data?.title || "Plan Expiring Soon"; body = notification.data?.message || - `${notification.data?.clientName}'s subscription for plan ${notification.data?.planName} will expire on ${notification.data?.formattedExpiryDate}.`; + `${notification.data?.clientName}'s membership subscription for ${notification.data?.planName} will expire on ${notification.data?.formattedExpiryDate}.`; break; case "schedule_update":