def updateContributionAmount()

in membership-attribute-service/app/controllers/AccountController.scala [245:300]


  def updateContributionAmount(subscriptionName: String): Action[AnyContent] =
    AuthorizeForScopes(requiredScopes = List(readSelf, updateSelf)).async { implicit request =>
      import request.logPrefix
      metrics.measureDuration("POST /user-attributes/me/contribution-update-amount/:subscriptionName") {

        val services = request.touchpoint
        val userId = request.user.identityId
        val email = request.user.primaryEmailAddress
        logger.info(s"Attempting to update contribution amount for $userId")
        (for {
          newPrice <- SimpleEitherT.fromEither(validateContributionAmountUpdateForm(request))
          user <- SimpleEitherT.right(userId)
          contact <- SimpleEitherT.fromFutureOption(services.contactRepository.get(user), s"No SF user $user")
          subscription <- SimpleEitherT(
            services.subscriptionService
              .current(contact)
              .map(subs => subscriptionSelector(memsub.Subscription.SubscriptionNumber(subscriptionName), s"the sfUser $contact", subs)),
          )
          catalog <- SimpleEitherT.rightT(services.futureCatalog)
          contributionPlan = subscription.plan(catalog)
          _ <- SimpleEitherT.fromEither(contributionPlan.product(catalog) match {
            case Contribution => Right(())
            case nc => Left(s"$subscriptionName plan is not a contribution: " + nc)
          })
          billingPeriod <- SimpleEitherT.fromEither(contributionPlan.billingPeriod.toEither)
          recurringPeriod <- SimpleEitherT.fromEither(billingPeriod match {
            case period: RecurringPeriod => Right(period)
            case period: BillingPeriod.OneOffPeriod => Left(s"period $period was not recurring for contribution update")
          })
          applyFromDate = contributionPlan.chargedThroughDate.getOrElse(contributionPlan.effectiveStartDate)
          currency = contributionPlan.chargesPrice.prices.head.currency
          currencyGlyph = currency.glyph
          oldPrice = contributionPlan.chargesPrice.prices.head.amount
          reasonForChange =
            s"User updated contribution via self-service MMA. Amount changed from $currencyGlyph$oldPrice to $currencyGlyph$newPrice effective from $applyFromDate"
          result <- SimpleEitherT(
            services.zuoraRestService.updateChargeAmount(
              subscription.subscriptionNumber,
              contributionPlan.ratePlanCharges.head.id,
              contributionPlan.id,
              newPrice.toDouble,
              reasonForChange,
              applyFromDate,
            ),
          ).leftMap(message => s"Error while updating contribution amount: $message")
          _ <- sendUpdateAmountEmail(newPrice, email, contact, currency, recurringPeriod, applyFromDate)
        } yield result).run.map(_.toEither) map {
          case Left(message) =>
            logger.error(scrub"Failed to update payment amount for user $userId, due to: $message")
            InternalServerError(message)
          case Right(()) =>
            logger.info(s"Contribution amount updated for user $userId")
            Ok("Success")
        }
      }
    }