private def CancelError()

in membership-attribute-service/app/controllers/AccountController.scala [76:139]


  private def CancelError(details: String, code: Int): ApiError = ApiError("Failed to cancel subscription", details, code)

  def extractCancellationReason(cancelForm: Form[String])(implicit request: play.api.mvc.Request[_], logPrefix: LogPrefix): Option[String] =
    cancelForm
      .bindFromRequest()
      .value

  def cancelSubscription(subscriptionNameString: String): Action[AnyContent] =
    AuthorizeForScopes(requiredScopes = List(readSelf, updateSelf)).async { implicit request =>
      import request.logPrefix
      metrics.measureDuration("POST /user-attributes/me/cancel/:subscriptionName") {
        val services = request.touchpoint
        val subscriptionNumber = memsub.Subscription.SubscriptionNumber(subscriptionNameString)
        val cancelForm = Form {
          single("reason" -> nonEmptyText)
        }
        val identityId = request.user.identityId
        def flatten[T](future: Future[\/[String, Option[T]]], errorMessage: String): SimpleEitherT[T] =
          SimpleEitherT(future.map(_.toEither.flatMap(_.toRight(errorMessage))))

        (for {
          contact <-
            flatten(
              services.contactRepository.get(identityId),
              s"No Salesforce user: $identityId",
            ).leftMap(CancelError(_, 404))
          subscription <- SimpleEitherT(
            services.subscriptionService
              .current(contact)
              .map(subs => subscriptionSelector(subscriptionNumber, s"Salesforce user $contact", subs)),
          ).leftMap(CancelError(_, 404))
          accountId <-
            (if (subscription.subscriptionNumber == subscriptionNumber)
               SimpleEitherT.right(subscription.accountId)
             else
               SimpleEitherT.left(s"$subscriptionNumber does not belong to $identityId"))
              .leftMap(CancelError(_, 503))
          cancellationEffectiveDate <- services.subscriptionService.decideCancellationEffectiveDate(subscriptionNumber).leftMap(CancelError(_, 500))
          cancellationReason = extractCancellationReason(cancelForm)
          _ <- services.cancelSubscription.cancel(
            subscriptionNumber,
            cancellationEffectiveDate,
            cancellationReason,
            accountId,
            subscription.termEndDate,
          )
          result = cancellationEffectiveDate.getOrElse("now").toString
          catalog <- EitherT.rightT(services.futureCatalog)
          _ <- sendSubscriptionCancelledEmail(
            request.user.primaryEmailAddress,
            contact,
            subscription.plan(catalog).productType(catalog),
            cancellationEffectiveDate,
          )
        } yield result).run.map(_.toEither).map {
          case Left(apiError) =>
            logger.error(scrub"Failed to cancel subscription for user $identityId because $apiError")
            apiError
          case Right(cancellationEffectiveDate) =>
            logger.info(s"Successfully cancelled subscription $subscriptionNumber owned by $identityId")
            Ok(Json.toJson(CancellationEffectiveDate(cancellationEffectiveDate)))
        }
      }
    }