def run()

in handlers/product-move-api/src/main/scala/com/gu/productmove/endpoint/move/switchtype/ToRecurringContribution.scala [37:146]


  def run(
      subscriptionName: SubscriptionName,
      postData: ExpectedInput,
      subscription: GetSubscriptionResponse,
      account: GetAccountResponse,
  ): Task[OutputBody] =
    for {
      _ <- ZIO.log("ToRecurringContribution PostData: " + postData.toString)

      activeRatePlanAndCharge <- ZIO
        .fromOption(getActiveRatePlanAndCharge(subscription.ratePlans))
        .orElseFail(
          new Throwable(
            s"Could not find a ratePlanCharge with a non-null chargedThroughDate for subscription name ${subscriptionName.value}",
          ),
        )
      (activeRatePlan, activeRatePlanCharge) = activeRatePlanAndCharge

      currency <- ZIO
        .fromOption(activeRatePlanCharge.currencyObject)
        .orElseFail(
          new Throwable(
            s"Missing or unknown currency ${activeRatePlanCharge.currency} on rate plan charge in rate plan ${activeRatePlan.id} ",
          ),
        )

      _ <- ZIO.log(s"Performing product move update with switch type ${SwitchType.ToRecurringContribution.id}")

      identityId <- ZIO
        .fromOption(account.basicInfo.IdentityId__c)
        .orElseFail(new Throwable(s"identityId is null for subscription name ${subscriptionName.value}"))

      price = postData.price
      previousAmount = activeRatePlanCharge.price.get
      billingPeriod <- ZIO
        .fromOption(activeRatePlanCharge.billingPeriod)
        .orElseFail(new Throwable(s"billingPeriod is null for rate plan charge $activeRatePlanCharge"))

      // Make sure that price is valid and acceptable
      _ <- validateOldMembershipPrice(currency, billingPeriod, price)

      updateRequestBody <- getRatePlans(
        billingPeriod,
        previousAmount,
        subscription.ratePlans,
        activeRatePlanCharge.chargedThroughDate.get,
      ).map { case (addRatePlan, removeRatePlan) =>
        SwitchProductUpdateRequest(
          add = addRatePlan,
          remove = removeRatePlan,
          collect = Some(false),
          runBilling = Some(true),
          preview = Some(false),
          targetDate = None,
        )
      }

      _ <- subscriptionUpdate
        .update[SubscriptionUpdateResponse](SubscriptionName(subscription.id), updateRequestBody)

      todaysDate <- Clock.currentDateTime.map(_.toLocalDate)

      paidAmount = BigDecimal(0)

      emailFuture <- sqs
        .sendEmail(
          message = EmailMessage(
            EmailPayload(
              Address = Some(account.billToContact.workEmail),
              ContactAttributes = EmailPayloadContactAttributes(
                SubscriberAttributes = toRCEmailPayloadProductSwitchAttributes(
                  first_name = account.billToContact.firstName,
                  last_name = account.billToContact.lastName,
                  currency = account.basicInfo.currency.symbol,
                  price = price.setScale(2, BigDecimal.RoundingMode.FLOOR).toString,
                  start_date =
                    activeRatePlanCharge.chargedThroughDate.get.format(DateTimeFormatter.ofPattern("d MMMM uuuu")),
                  payment_frequency = stringFor(billingPeriod),
                  subscription_id = subscriptionName.value,
                ),
              ),
            ),
            "SV_MBtoRC_Switch",
            account.basicInfo.sfContactId__c,
            Some(identityId),
          ),
        )
        .fork

      salesforceTrackingFuture <- sqs
        .queueSalesforceTracking(
          SalesforceRecordInput(
            subscriptionName.value,
            previousAmount,
            price,
            activeRatePlan.productName,
            activeRatePlan.ratePlanName,
            "Recurring Contribution",
            todaysDate,
            activeRatePlanCharge.chargedThroughDate.get,
            paidAmount,
            postData.csrUserId,
            postData.caseId,
          ),
        )
        .fork

      requests = emailFuture.zip(salesforceTrackingFuture)
      _ <- requests.join
    } yield Success(