Skip to content

Commit

Permalink
feat(members): notify user balance depletion on arrival
Browse files Browse the repository at this point in the history
  • Loading branch information
mtthp committed Apr 26, 2024
1 parent 43fbd05 commit 07c7f83
Showing 1 changed file with 37 additions and 5 deletions.
42 changes: 37 additions & 5 deletions lib/models/member.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import pMap from 'p-map'
import {maxBy, sumBy, sortBy, chain, pick} from 'lodash-es'
import {customAlphabet} from 'nanoid'
import {differenceInMinutes, sub} from 'date-fns'
import {add, differenceInMinutes, isSameDay, sub} from 'date-fns'

import mongo from '../util/mongo.js'
import {buildPictureUrl, getUser as getWpUser} from '../util/wordpress.js'

import {computeSubcriptionEndDate, computeBalance} from '../calc.js'
import renderPlusDeTickets from '../emails/plus-de-tickets.js'

import * as Device from './device.js'
import * as Activity from './activity.js'
import {sendMail} from '../util/sendmail.js'

const nanoid = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')
export const LAST_SEEN_DELAY = 10 // Since when a member is marked as attending the location, in minutes
Expand Down Expand Up @@ -217,10 +219,14 @@ export async function heartbeatMembers(memberIds, referenceDate) {
throw new Error('Missing referenceDate')
}

await mongo.db.collection('users').updateMany(
{_id: {$in: memberIds}},
{$set: {'profile.heartbeat': referenceDate.toISOString()}}
)
await Promise.all(memberIds.map(async memberId => {
const updatedUser = await mongo.db.collection('users').findOneAndUpdate(
{_id: memberId},
{$set: {'profile.heartbeat': referenceDate.toISOString()}}
)

notifyUserBalanceDepletionOnArrival(updatedUser.value, referenceDate)
}))
}

/* Helpers */
Expand Down Expand Up @@ -310,3 +316,29 @@ export async function computeMemberFromUser(user, options = {}) {

return member
}

/**
* Notify if the user is arriving
* and has no more tickets
* and has no ongoing subscription
*/
async function notifyUserBalanceDepletionOnArrival(user, referenceDate) {
const isArriving = !isSameDay(new Date(user.profile.heartbeat), referenceDate)
const isBalanceDepleted = user.profile.balance <= 0
if (isArriving && isBalanceDepleted) {
// Check if there is a ongoing subscription
const nextDay = add(referenceDate, {days: 1}).toISOString().slice(0, 10)
const oneMonthBeforeNextDay = sub(new Date(nextDay), {months: 1}).toISOString().slice(0, 10)
const isSubscriptionOngoing = user.profile.abos.some(
abo => oneMonthBeforeNextDay < abo.aboStart && abo.aboStart <= nextDay
)

if (!isSubscriptionOngoing) {
// Send a notification email
sendMail(
renderPlusDeTickets(),
[user.email]
)
}
}
}

0 comments on commit 07c7f83

Please sign in to comment.