Implement loan income notification

This commit is contained in:
James Grugett 2022-08-19 11:01:28 -05:00
parent 1eb208c7d7
commit 91fd2d8a2d
5 changed files with 43 additions and 11 deletions

View File

@ -38,6 +38,7 @@ export type notification_source_types =
| 'user'
| 'bonus'
| 'challenge'
| 'loan'
export type notification_source_update_types =
| 'created'
@ -66,3 +67,4 @@ export type notification_reason_types =
| 'bet_fill'
| 'user_joined_from_your_group_invite'
| 'challenge_accepted'
| 'loan_income'

View File

@ -18,6 +18,7 @@ import { TipTxn } from '../../common/txn'
import { Group, GROUP_CHAT_SLUG } from '../../common/group'
import { Challenge } from '../../common/challenge'
import { richTextToString } from '../../common/util/parse'
import { formatMoney } from 'common/util/format'
const firestore = admin.firestore()
type user_to_reason_texts = {
@ -471,6 +472,25 @@ export const createReferralNotification = async (
await notificationRef.set(removeUndefinedProps(notification))
}
export const createLoanIncomeNotification = async (
toUser: User,
idempotencyKey: string,
income: number
) => {
const notificationRef = firestore
.collection(`/users/${toUser.id}/notifications`)
.doc(idempotencyKey)
const notification: Notification = {
id: idempotencyKey,
userId: toUser.id,
reason: 'loan_income',
createdTime: Date.now(),
isSeen: false,
sourceText: formatMoney(income),
}
await notificationRef.set(removeUndefinedProps(notification))
}
const groupPath = (groupSlug: string) => `/group/${groupSlug}`
export const createChallengeAcceptedNotification = async (

View File

@ -7,6 +7,7 @@ import { PortfolioMetrics, User } from 'common/user'
import { Dictionary, groupBy, keyBy, minBy, sumBy } from 'lodash'
import { filterDefined } from 'common/util/array'
import { getContractBetMetrics } from 'common/calculate'
import { createLoanIncomeNotification } from './create-notification'
const firestore = admin.firestore()
@ -68,14 +69,22 @@ async function updateLoansCore() {
(update) => update.userId === user.id
)
return {
userId: user.id,
delta: sumBy(updates, (update) => update.newLoan),
user,
payout: sumBy(updates, (update) => update.newLoan),
}
})
.filter((update) => update.delta > 0)
.filter((update) => update.payout > 0)
await Promise.all(
userPayouts.map(({ userId, delta }) => payUser(userId, delta))
userPayouts.map(({ user, payout }) => payUser(user.id, payout))
)
const today = new Date().toDateString().replace(' ', '_')
const key = `loan-notifications/${today}`
await Promise.all(
userPayouts.map(({ user, payout }) =>
createLoanIncomeNotification(user, key, payout)
)
)
}

View File

@ -5,7 +5,7 @@ import {
getNotificationsQuery,
listenForNotifications,
} from 'web/lib/firebase/notifications'
import { groupBy, map } from 'lodash'
import { groupBy, map, partition } from 'lodash'
import { useFirestoreQueryData } from '@react-query-firebase/firestore'
import { NOTIFICATIONS_PER_PAGE } from 'web/pages/notifications'
@ -67,15 +67,14 @@ export function groupNotifications(notifications: Notification[]) {
const notificationGroupsByDay = groupBy(notifications, (notification) =>
new Date(notification.createdTime).toDateString()
)
const incomeSourceTypes = ['bonus', 'tip', 'loan']
Object.keys(notificationGroupsByDay).forEach((day) => {
const notificationsGroupedByDay = notificationGroupsByDay[day]
const incomeNotifications = notificationsGroupedByDay.filter(
const [incomeNotifications, normalNotificationsGroupedByDay] = partition(
notificationsGroupedByDay,
(notification) =>
notification.sourceType === 'bonus' || notification.sourceType === 'tip'
)
const normalNotificationsGroupedByDay = notificationsGroupedByDay.filter(
(notification) =>
notification.sourceType !== 'bonus' && notification.sourceType !== 'tip'
incomeSourceTypes.includes(notification.sourceType ?? '')
)
if (incomeNotifications.length > 0) {
notificationGroups = notificationGroups.concat({

View File

@ -966,6 +966,8 @@ function getReasonForShowingNotification(
case 'challenge':
reasonText = 'accepted your challenge'
break
case 'loan':
reasonText = 'got a portion of your bet back'
default:
reasonText = ''
}