notification-bug-fix #111
| @ -11,6 +11,7 @@ interface MembershipData { | ||||
|   userId: string; | ||||
|   gymId: string; | ||||
|   status: string; | ||||
|   expirationDate?: admin.firestore.Timestamp; | ||||
|   subscription?: { | ||||
|     name: string; | ||||
|     frequency: string; | ||||
| @ -57,13 +58,15 @@ export const checkExpiredMemberships = onSchedule( | ||||
|       const expiredMemberships = await findExpiredMemberships(); | ||||
|       const expiringMemberships = await findMembershipsExpiringIn10Days(); | ||||
|        | ||||
|       if (expiredMemberships.length === 0 && expiringMemberships.length === 0) { | ||||
|         logger.info("No expired or expiring memberships found."); | ||||
|       const expiredMembershipsWithoutExpiryDate = await findExpiredMembershipsWithoutExpiryDate(); | ||||
| 
 | ||||
|       if (expiredMemberships.length === 0 && expiringMemberships.length === 0 && expiredMembershipsWithoutExpiryDate.length === 0) { | ||||
|         logger.info("No expired, expiring, or unprocessed expired memberships found."); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       logger.info( | ||||
|         `Found ${expiredMemberships.length} expired memberships and ${expiringMemberships.length} memberships expiring in 10 days to process.` | ||||
|         `Found ${expiredMemberships.length} expired memberships, ${expiringMemberships.length} memberships expiring in 10 days, and ${expiredMembershipsWithoutExpiryDate.length} expired memberships without expiry dates to process.` | ||||
|       ); | ||||
| 
 | ||||
|       const expiredResults = await Promise.allSettled( | ||||
| @ -74,21 +77,19 @@ export const checkExpiredMemberships = onSchedule( | ||||
|         expiringMemberships.map((m) => processExpiringMembership(m.id, m.data)) | ||||
|       ); | ||||
| 
 | ||||
|       const expiredSuccessful = expiredResults.filter( | ||||
|         (r) => r.status === "fulfilled" | ||||
|       ).length; | ||||
|       const expiredFailed = expiredResults.filter( | ||||
|         (r) => r.status === "rejected" | ||||
|       ).length; | ||||
|       const expiringSuccessful = expiringResults.filter( | ||||
|         (r) => r.status === "fulfilled" | ||||
|       ).length; | ||||
|       const expiringFailed = expiringResults.filter( | ||||
|         (r) => r.status === "rejected" | ||||
|       ).length; | ||||
|       const updateResults = await Promise.allSettled( | ||||
|         expiredMembershipsWithoutExpiryDate.map((m) => updateExpiryDateForExpiredMembership(m.id, m.data)) | ||||
|       ); | ||||
| 
 | ||||
|       const expiredSuccessful = expiredResults.filter(r => r.status === "fulfilled").length; | ||||
|       const expiredFailed = expiredResults.filter(r => r.status === "rejected").length; | ||||
|       const expiringSuccessful = expiringResults.filter(r => r.status === "fulfilled").length; | ||||
|       const expiringFailed = expiringResults.filter(r => r.status === "rejected").length; | ||||
|       const updateSuccessful = updateResults.filter(r => r.status === "fulfilled").length; | ||||
|       const updateFailed = updateResults.filter(r => r.status === "rejected").length; | ||||
| 
 | ||||
|       logger.info( | ||||
|         `Completed processing. Expired - Success: ${expiredSuccessful}, Failed: ${expiredFailed}. Expiring - Success: ${expiringSuccessful}, Failed: ${expiringFailed}` | ||||
|         `Completed processing. Expired - Success: ${expiredSuccessful}, Failed: ${expiredFailed}. Expiring - Success: ${expiringSuccessful}, Failed: ${expiringFailed}. Updates - Success: ${updateSuccessful}, Failed: ${updateFailed}` | ||||
|       ); | ||||
|     } catch (error) { | ||||
|       logger.error("Error in scheduled membership expiry check:", error); | ||||
| @ -96,6 +97,72 @@ export const checkExpiredMemberships = onSchedule( | ||||
|   } | ||||
| ); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| async function findExpiredMembershipsWithoutExpiryDate(): Promise< | ||||
|   Array<{ id: string; data: MembershipData }> | ||||
| > { | ||||
|   try { | ||||
|     const snapshot = await app | ||||
|       .firestore() | ||||
|       .collection("memberships") | ||||
|       .where("status", "==", "EXPIRED") | ||||
|       .get(); | ||||
| 
 | ||||
|     const membershipsWithoutExpiryDate: Array<{ id: string; data: MembershipData }> = []; | ||||
| 
 | ||||
|     snapshot.docs.forEach((doc) => { | ||||
|       const data = doc.data() as MembershipData; | ||||
|       if (!data.expirationDate) { | ||||
|         membershipsWithoutExpiryDate.push({ id: doc.id, data }); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     return membershipsWithoutExpiryDate; | ||||
|   } catch (error) { | ||||
|     logger.error("Error finding expired memberships without expiry date:", error); | ||||
|     throw error; | ||||
|   } | ||||
| } | ||||
| async function updateExpiryDateForExpiredMembership( | ||||
|   membershipId: string, | ||||
|   membershipData: MembershipData | ||||
| ): Promise<void> { | ||||
|   try { | ||||
|     if (!membershipData.subscription || !membershipData.subscription.frequency) { | ||||
|       logger.warn(`Skipping membership ${membershipId} - no subscription data`); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const payments = await getPaymentsForMembership(membershipId); | ||||
|     if (payments.length === 0) { | ||||
|       logger.warn(`No payments found for membership ${membershipId}`); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const latestPayment = payments[0]; | ||||
|     const expiryDate = calculateExpiryDate( | ||||
|       latestPayment.dateTimestamp, | ||||
|       membershipData.subscription.frequency | ||||
|     ); | ||||
| 
 | ||||
|     await app | ||||
|       .firestore() | ||||
|       .collection("memberships") | ||||
|       .doc(membershipId) | ||||
|       .update({ | ||||
|         expirationDate: admin.firestore.Timestamp.fromDate(expiryDate), | ||||
|         updatedAt: admin.firestore.FieldValue.serverTimestamp(), | ||||
|       }); | ||||
| 
 | ||||
|     logger.info(`Updated expiry date for expired membership ${membershipId}: ${expiryDate.toISOString()}`); | ||||
|   } catch (error) { | ||||
|     logger.error(`Error updating expiry date for membership ${membershipId}:`, error); | ||||
|     throw error; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| async function findExpiredMemberships(): Promise< | ||||
|   Array<{ id: string; data: MembershipData }> | ||||
| > { | ||||
| @ -923,6 +990,7 @@ async function sendPlanExpiringNotification( | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| async function getClientName( | ||||
|   membershipId: string, | ||||
|   clientId: string | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user