in handlers/product-move-api/src/main/scala/com/gu/productmove/endpoint/move/switchtype/RecurringContributionToSupporterPlus.scala [150:307]
private def doUpdate(
subscriptionName: SubscriptionName,
account: GetAccountResponse,
price: BigDecimal,
previousAmount: BigDecimal,
ratePlanCharge: RatePlanCharge,
currency: Currency,
currentRatePlan: GetSubscription.RatePlan,
subscription: GetSubscription.GetSubscriptionResponse,
csrUserId: Option[String],
caseId: Option[String],
): Task[OutputBody] = {
import ratePlanCharge.billingPeriod
for {
_ <- ZIO.log(
s"Performing product move update with switch type ${SwitchType.RecurringContributionToSupporterPlus.id}",
)
today <- Clock.currentDateTime.map(_.toLocalDate)
billingPeriod <- ZIO
.fromOption(ratePlanCharge.billingPeriod)
.orElseFail(
new Throwable(
s"Missing billing period on rate plan charge in rate plan $currentRatePlan ",
),
)
supporterPlusRatePlanIds <- getRatePlans.getSupporterPlusRatePlanIds(billingPeriod)
// To avoid problems with charges not aligning correctly with the term and resulting in unpredictable
// billing dates and amounts, we need to start a new term subscriptions which are switched on any day other
// than a term start date.
termStartedToday = subscription.termStartDate.isEqual(today)
invoiceId <-
if (termStartedToday)
updateWithExistingTerm(
subscriptionName,
billingPeriod,
currency,
currentRatePlan.id,
price,
)
else
updateWithTermRenewal(
today,
subscription.termStartDate,
subscriptionName,
billingPeriod,
currency,
currentRatePlan.id,
price,
)
// Get the amount of the invoice with which was created by the product switch
_ <- ZIO.log(s"Invoice generated by update has id of $invoiceId")
invoiceBalance <- getInvoice.get(invoiceId).map(_.balance)
/*
If the amount payable today is less than 0.50, we don't want to collect payment because Stripe has a minimum
charge of 50 cents. Instead we write-off the invoices in the `adjustNonCollectedInvoices` function.
*/
paidAmount <-
if (invoiceBalance == 0) {
ZIO.succeed(BigDecimal(0))
} else if (invoiceBalance < 0 || invoiceBalance >= 0.5) {
// not clear why we would want to create a negative payment, but this logic was already in place
import account._
createPayment
.create(
basicInfo.id,
invoiceId,
basicInfo.defaultPaymentMethod.id,
invoiceBalance,
today,
)
.as(invoiceBalance)
} else {
adjustNonCollectedInvoice(
invoiceId,
supporterPlusRatePlanIds,
subscriptionName,
invoiceBalance,
).as(BigDecimal(0))
}
_ <- ZIO.log(s"The amount paid on switch by the customer was $paidAmount")
identityId <- ZIO
.fromOption(account.basicInfo.IdentityId__c)
.orElseFail(new Throwable(s"identityId is null for subscription name ${subscriptionName.value}"))
emailFuture <- sqs
.sendEmail(
message = EmailMessage(
EmailPayload(
Address = Some(account.billToContact.workEmail),
ContactAttributes = EmailPayloadContactAttributes(
SubscriberAttributes = RCtoSPEmailPayloadProductSwitchAttributes(
first_name = account.billToContact.firstName,
last_name = account.billToContact.lastName,
currency = account.basicInfo.currency.symbol,
price = price.setScale(2, BigDecimal.RoundingMode.FLOOR).toString,
first_payment_amount = paidAmount.setScale(2, BigDecimal.RoundingMode.FLOOR).toString,
date_of_first_payment = today.format(DateTimeFormatter.ofPattern("d MMMM uuuu")),
payment_frequency = stringFor(billingPeriod),
subscription_id = subscriptionName.value,
),
),
),
"SV_RCtoSP_Switch",
account.basicInfo.sfContactId__c,
Some(identityId),
),
)
.fork
salesforceTrackingFuture <- sqs
.queueSalesforceTracking(
SalesforceRecordInput(
subscriptionName.value,
previousAmount,
price,
currentRatePlan.productName,
currentRatePlan.ratePlanName,
"Supporter Plus",
today,
today,
paidAmount,
csrUserId,
caseId,
),
)
.fork
amendSupporterProductDynamoTableFuture <- dynamo
.writeItem(
SupporterRatePlanItem(
subscriptionName.value,
identityId = identityId.rawIdentityId,
gifteeIdentityId = None,
productRatePlanId = supporterPlusRatePlanIds.ratePlanId,
productRatePlanName = "product-move-api added Supporter Plus Monthly",
termEndDate = today.plusDays(7),
contractEffectiveDate = today,
contributionAmount = None,
),
)
.fork
requests = emailFuture
.zip(salesforceTrackingFuture)
.zip(amendSupporterProductDynamoTableFuture)
_ <- requests.join
} yield Success(
s"Product move completed successfully with subscription number ${subscriptionName.value} and switch type ${SwitchType.RecurringContributionToSupporterPlus.id}",
)
}