in handlers/product-move-api/src/main/scala/com/gu/productmove/endpoint/available/AvailableProductMovesEndpoint.scala [130:221]
private[productmove] def runWithEnvironment(
subscriptionName: SubscriptionName,
): RIO[GetSubscription with GetCatalogue with GetAccount with Stage, OutputBody] = {
val output = for {
stage <- ZIO.service[Stage]
monthlyContributionRatePlanId =
if (stage == Stage.CODE) "2c92c0f85a6b134e015a7fcd9f0c7855" else "2c92a0fc5aacfadd015ad24db4ff5e97"
_ <- ZIO.log("subscription name: " + subscriptionName)
// Kick off catalogue fetch in parallel
zuoraProductCatalogueFetch <- GetCatalogue.get.fork
subscription <- GetSubscription.get(
subscriptionName,
) // TODO add code to return 404 rather than 500 if it's not found
ratePlan <- getSingleOrNotEligible(subscription.ratePlans, s"Subscription: ${subscriptionName.value} , ratePlan")
_ <- succeedIfEligible(
ratePlan.productRatePlanId == monthlyContributionRatePlanId,
s"Subscription: ${subscriptionName.value} is not a monthly contribution",
)
charge <- getSingleOrNotEligible(
ratePlan.ratePlanCharges,
s"Subscription: ${subscriptionName.value} , ratePlan charge for ratePlan $ratePlan",
)
// Next payment date
chargedThroughDate <- ZIO.fromOption(charge.chargedThroughDate).orElse {
for {
_ <- ZIO.log(s"chargedThroughDate is null for subscription ${subscriptionName.value}.")
resp <- ZIO.fail(AvailableMoves(List()))
} yield resp
}
account <- GetAccount.get(subscription.accountNumber)
creditCardExpirationDate <- ZIO
.fromOption(account.basicInfo.defaultPaymentMethod.creditCardExpirationDate)
.orElse {
ZIO
.log(s"Payment method is not a card for subscription ${subscriptionName.value}.")
.flatMap(_ => ZIO.fail(AvailableMoves(List())))
}
paymentMethod <- GetAccount
.getPaymentMethod(account.basicInfo.defaultPaymentMethod.id)
today <- Clock.currentDateTime.map(_.toLocalDate)
/*
Only show the switch if:
credit card is not expired (according to zuora)
User is not in payment failure or has unpaid invoices
Currency is GBP (initially on day 1 only?)
Monthly contribution
Account balance is 0
*/
accountIsEligible <-
(for {
_ <- succeedIfEligible(
account.subscriptions.length == 1,
s"More than one subscription for account for subscription: ${subscriptionName.value}",
)
_ <- succeedIfEligible(
account.basicInfo.currency == Currency.GBP,
s"Subscription: ${subscriptionName.value} not in GBP",
)
_ <- succeedIfEligible(
paymentMethod.NumConsecutiveFailures == 0,
s"User is in payment failure with subscription: ${subscriptionName.value}",
)
_ <- succeedIfEligible(
creditCardExpirationDate.isAfter(today),
s"card expired for subscription: ${subscriptionName.value}",
)
_ <- succeedIfEligible(
account.basicInfo.balance == 0,
s"Account balance is not zero for subscription: ${subscriptionName.value}",
)
} yield ()).isSuccess
_ <- if (accountIsEligible) ZIO.succeed(()) else ZIO.fail(AvailableMoves(List()))
zuoraProductCatalogue <- zuoraProductCatalogueFetch.join
productRatePlans = getAvailableSwitchRatePlans(zuoraProductCatalogue, List("Digital Pack"))
moveToProduct <- ZIO.foreach(productRatePlans) { productRatePlan =>
MoveToProduct.buildResponseFromRatePlan(subscriptionName, productRatePlan, chargedThroughDate)
}
_ <- ZIO.log("done")
} yield AvailableMoves(moveToProduct)