Skip to content

Commit

Permalink
fix(hydration): fix calculation of subscription end date
Browse files Browse the repository at this point in the history
  • Loading branch information
stfsy committed Sep 2, 2023
1 parent 7e337dc commit 492ded3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 27 deletions.
42 changes: 22 additions & 20 deletions lib/subscription-hydration.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ class SubscriptionHydration {
async hydrateSubscriptionCancelled(ids, planId) {
const subscriptionId = await this._subscriptionInfo.findSubscriptionIdByPlanId(ids, planId)
const subscriptions = await this._api.getSubscription({ subscription_id: String(subscriptionId) })

if (!Array.isArray(subscriptions) || subscriptions.length < 1) {
return
}
Expand Down Expand Up @@ -219,42 +218,45 @@ class SubscriptionHydration {
throw new Error(SubscriptionHydration.HYDRATION_BAD_REQUEST)
}

const signUpDate = new Date(subscription.signup_date)
const lastPaymentDate = new Date(subscription.last_payment.date)
let theoreticalNextPaymentDate = new Date(lastPaymentDate.getTime())

// we use the day of sign up as base
// and add one day until to the current date
// until next payment + 1 === sign up day
while (theoreticalNextPaymentDate.getDate() !== signUpDate.getDate() - 1) {
theoreticalNextPaymentDate.setTime(theoreticalNextPaymentDate.getTime() + 1000 * 60 * 60 * 24)
}

theoreticalNextPaymentDate.setUTCHours(23)
theoreticalNextPaymentDate.setUTCMinutes(59)
theoreticalNextPaymentDate.setUTCSeconds(59)
theoreticalNextPaymentDate.setUTCMilliseconds(0)
const subscriptionValidUntil = theoreticalNextPaymentDate.toISOString()
const subscriptionValidUntil = this._calculateEndOfSubscriptionDate(subscription)

const hookPayload = {
alert_id: SubscriptionHydration.HYDRATION_SUBSCRIPTION_CANCELLED,
alert_name: SubscriptionHydration.HYDRATION_SUBSCRIPTION_CANCELLED,
cancellation_effective_date: subscriptionValidUntil,
currency: subscription.last_payment.currency,
status: subscription.state,
next_bill_date: subscription.next_payment?.date || '',
quantity: subscription.quantity,
event_time: subscription.signup_date,
event_time: subscriptionValidUntil,
update_url: subscription.update_url,
subscription_id: subscription.subscription_id,
subscription_plan_id: subscription.plan_id,
cancel_url: subscription.cancel_url,
user_id: subscription.user_id,
passthrough: JSON.stringify({ '_pi': { ids: idsFromCustomData } })
}

hookPayload.cancellation_effective_date = subscriptionValidUntil
await this._hookStorage.addSubscriptionCancelledStatus(hookPayload)
}

_calculateEndOfSubscriptionDate(subscription) {
const signUpDate = new Date(subscription.signup_date)
const lastPaymentDate = new Date(subscription.last_payment.date)
let theoreticalNextPaymentDate = new Date(lastPaymentDate.getTime() + 1000 * 60 * 60 * 24)

// we use the date of the last payment as a base
// and add one day to the last payment date
// until dayOfMonth(nextDate) === dayOfMonth(signUpDate)
for (let i = 0; i < 33 && theoreticalNextPaymentDate.getUTCDate() !== signUpDate.getUTCDate(); i++) {
theoreticalNextPaymentDate.setTime(theoreticalNextPaymentDate.getTime() + 1000 * 60 * 60 * 24)
}

// as we want the dayOfMonth(nextPayment) actually to be less than (dayOfMonth(signUpDate))
// we substract one day worth of milliseconds
theoreticalNextPaymentDate.setTime(theoreticalNextPaymentDate.getTime() - 1000 * 60 * 60 * 24)
theoreticalNextPaymentDate.setUTCHours(12, 0, 0, 0)
return theoreticalNextPaymentDate.toISOString()
}
}

module.exports = SubscriptionHydration
16 changes: 9 additions & 7 deletions test-e2e/spec/hydration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,16 +346,18 @@ test('hydrate a deleted subscription', async ({ page }) => {
expect(status.vendor_user_id).toEqual(subscriptionFromApi.user_id)

const signUpDate = new Date(subscriptionFromApi.signup_date)
const expectedEndDate = new Date(signUpDate.getTime())
const expectedEndDate = new Date(signUpDate.getTime() + 33 * 3600 * 1000 * 24)

while (expectedEndDate.getDate() !== signUpDate.getDate() - 1) {
expectedEndDate.setTime(expectedEndDate.getTime() + 1000 * 60 * 60 * 24)
for (let i = 0; i < 33 && expectedEndDate.getDate() !== signUpDate.getDate(); i++) {
expectedEndDate.setTime(expectedEndDate.getTime() - 1000 * 60 * 60 * 24)
}

expectedEndDate.setUTCHours(23)
expectedEndDate.setUTCMinutes(59)
expectedEndDate.setUTCSeconds(59)
expectedEndDate.setTime(expectedEndDate.getTime() - 1000 * 60 * 60 * 24)

expectedEndDate.setUTCHours(12)
expectedEndDate.setUTCMinutes(0)
expectedEndDate.setUTCSeconds(0)
expectedEndDate.setUTCMilliseconds(0)

expect(new Date(status.event_time).toISOString()).toEqual(expectedEndDate.toISOString())
expect(new Date(status.cancellation_effective_date).toISOString()).toEqual(expectedEndDate.toISOString())
})

0 comments on commit 492ded3

Please sign in to comment.