import { Body, Controller, Post, UseGuards } from '@nestjs/common' import { parseISO } from 'date-fns' import { isNil } from 'lodash' import { BasicAuthorizationGuard } from '../../../guards/basic_authorization.guard' import { BaseEventParams } from '../../../params' import { TransactionError } from '../../../services' import { Subscription } from '../domain/subscription' import { CancelSubscriptionParams, CheckSubscriptionParams, RegularizeSubscriptionParams, SubscribeParams, } from './params' const CHECK_SUBSCRIPTION_EVENT = 'check_subscription' export type SubscribeResponse = { success: boolean subscription_id?: string error?: TransactionError } export type SubscriptionsResponse = { subscription_id: string } @UseGuards(BasicAuthorizationGuard) @Controller('subscriptions') export class SubscriptionsController { constructor(private readonly subscription: Subscription) {} @Post('subscribe') async subscribe(@Body() { input, session_variables }: SubscribeParams): Promise { const subscription = await this.subscription.subscribe({ patientId: session_variables['x-hasura-user-id'], planId: input.plan_id, paymentProvider: input.payment_provider, token: input.token, card: input.card, originalTransaction: input.original_transaction, discountCouponCode: input.discount_coupon, data: input.data, }) return { subscription_id: subscription.id, success: subscription.status === 'active' } } @Post('cancel') async cancel(@Body() data: CancelSubscriptionParams): Promise { const subscription_id = await this.subscription.cancel( data.input.patient_id, { id: data.input.cancellation_reason_id, ...(!isNil(data.input.cancellation_other_reason) ? { otherReason: data.input.cancellation_other_reason } : {}), }, { id: data.session_variables['x-hasura-user-id'] }, parseISO(data.input.cancellation_requested_by_patient_at), data.input.amountToRefund, data.input.ignore_trial, ) return { subscription_id } } @Post('check') async check(@Body() data: CheckSubscriptionParams & BaseEventParams): Promise<{ subscriber: boolean }> { const userId = data.input?.patient_id || data.session_variables?.['x-hasura-user-id'] || data.event?.data?.new?.id return { subscriber: await this.subscription.check(userId) } } @Post('upgrade') async upgrade(@Body() data: SubscribeParams): Promise { const subscription = await this.subscription.change( data.session_variables['x-hasura-user-id'], data.input.plan_id, data.input.token, data.input.original_transaction, ) return { subscription_id: subscription.id } } @Post('handle_patient_creation') async handlePatientCreation(@Body() params: BaseEventParams): Promise { if (params.trigger.name === CHECK_SUBSCRIPTION_EVENT && params.event.data.new.sign_up_at !== null) await this.subscription.check(params.event.data.new.id) } @Post('regularize-subscription') async regularizeSubscription( @Body() { session_variables, input }: RegularizeSubscriptionParams, ): Promise<{ success: boolean }> { await this.subscription.regularizeSubscription(session_variables['x-hasura-user-id'], input.token, input.kind) return { success: true } } }