Skip to content

Commit

Permalink
Merge pull request #216 from guardian/new_product_annual_contribution
Browse files Browse the repository at this point in the history
Csr acquisition annual contribution
  • Loading branch information
pvighi committed Dec 3, 2018
2 parents 9f41ea2 + b4ecb78 commit adcf8d8
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 21 deletions.
Expand Up @@ -27,7 +27,7 @@ import com.gu.newproduct.api.addsubscription.zuora.GetContacts.BillToContact
import com.gu.newproduct.api.addsubscription.zuora.GetContacts.WireModel.GetContactsResponse
import com.gu.newproduct.api.addsubscription.zuora.GetPaymentMethod.{DirectDebit, PaymentMethod, PaymentMethodWire}
import com.gu.newproduct.api.addsubscription.zuora.{GetContacts, _}
import com.gu.newproduct.api.productcatalog.PlanId.MonthlyContribution
import com.gu.newproduct.api.productcatalog.PlanId.{AnnualContribution, MonthlyContribution}
import com.gu.newproduct.api.productcatalog.ZuoraIds.{PlanAndCharge, ProductRatePlanId}
import com.gu.newproduct.api.productcatalog._
import com.gu.util.Logging
Expand Down Expand Up @@ -89,7 +89,8 @@ object Steps {
paymentMethod = paymentMethod,
amountMinorUnits = amountMinorUnits,
firstPaymentDate = firstPaymentDate,
billTo = billToContact
billTo = billToContact,
planId = request.planId
)

def handleRequest(
Expand All @@ -100,13 +101,13 @@ object Steps {
): Future[ApiResponse] = (for {
request <- apiGatewayRequest.bodyAsCaseClass[AddSubscriptionRequest]().withLogging("parsed request").toAsync
subscriptionName <- request.planId match {
case MonthlyContribution => addContribution(request)
case MonthlyContribution | AnnualContribution => addContribution(request)
case _ => addVoucher(request)
}
} yield ApiGatewayResponse(body = AddedSubscription(subscriptionName.value), statusCode = "200")).apiResponse

def addContributionSteps(
contributionZuoraIds: PlanAndCharge,
getPlanAndCharge: PlanId => Option[PlanAndCharge],
getCustomerData: ZuoraAccountId => ApiGatewayOp[ContributionCustomerData],
contributionValidations: (ValidatableFields, Currency) => ValidationResult[AmountMinorUnits],
createSubscription: ZuoraCreateSubRequest => ClientFailableOp[SubscriptionName],
Expand All @@ -118,8 +119,9 @@ object Steps {
validatableFields = ValidatableFields(request.amountMinorUnits, request.startDate)
amountMinorUnits <- contributionValidations(validatableFields, account.currency).toApiGatewayOp.toAsync
acceptanceDate = request.startDate.plusDays(paymentDelayFor(paymentMethod))
chargeOverride = ChargeOverride(amountMinorUnits, contributionZuoraIds.productRatePlanChargeId)
zuoraCreateSubRequest = createZuoraSubRequest(request, acceptanceDate, Some(chargeOverride), contributionZuoraIds.productRatePlanId)
planAndCharge <- getPlanAndCharge(request.planId).toApiGatewayContinueProcessing(internalServerError(s"no Zuora id for ${request.planId}!")).toAsync
chargeOverride = ChargeOverride(amountMinorUnits, planAndCharge.productRatePlanChargeId)
zuoraCreateSubRequest = createZuoraSubRequest(request, acceptanceDate, Some(chargeOverride), planAndCharge.productRatePlanId)
subscriptionName <- createSubscription(zuoraCreateSubRequest).toAsyncApiGatewayOp("create monthly contribution")
contributionEmailData = toContributionEmailData(request, account.currency, paymentMethod, acceptanceDate, contacts.billTo, amountMinorUnits)
_ <- sendConfirmationEmail(account.sfContactId, contributionEmailData).recoverAndLog("send contribution confirmation email")
Expand Down Expand Up @@ -194,7 +196,8 @@ object Steps {
validateRequest = ContributionValidations(isValidContributionStartDate, AmountLimits.limitsFor) _

sendConfirmationEmail = SendConfirmationEmailContributions(contributionEtSqsSend, getCurrentDate) _
contributionSteps = addContributionSteps(zuoraIds.contributionsZuoraIds.monthly, getCustomerData, validateRequest, createSubscription, sendConfirmationEmail) _
planAndChargeForContributionPlanId = zuoraIds.contributionsZuoraIds.byApiPlanId.get _
contributionSteps = addContributionSteps(planAndChargeForContributionPlanId, getCustomerData, validateRequest, createSubscription, sendConfirmationEmail) _
voucherSqsSend = awsSQSSend(queueNames.voucher)
voucherEtSqsSend = EtSqsSend[VoucherEmailData](voucherSqsSend) _
sendVoucherEmail = SendConfirmationEmailVoucher(voucherEtSqsSend, getCurrentDate) _
Expand Down
Expand Up @@ -14,7 +14,8 @@ import com.gu.util.reader.AsyncTypes._
import com.gu.util.reader.Types.ApiGatewayOp.{ContinueProcessing, ReturnWithResponse}
import com.gu.newproduct.api.addsubscription.Formatters._
import com.gu.newproduct.api.addsubscription.zuora.GetAccount.SfContactId
import com.gu.newproduct.api.productcatalog.AmountMinorUnits
import com.gu.newproduct.api.productcatalog.PlanId.{AnnualContribution, MonthlyContribution}
import com.gu.newproduct.api.productcatalog.{AmountMinorUnits, PlanId}

import scala.concurrent.Future

Expand All @@ -26,7 +27,8 @@ object SendConfirmationEmailContributions extends Logging {
paymentMethod: PaymentMethod,
amountMinorUnits: AmountMinorUnits,
firstPaymentDate: LocalDate,
billTo: BillToContact
billTo: BillToContact,
planId: PlanId
)

def apply(
Expand Down Expand Up @@ -60,6 +62,11 @@ object SendConfirmationEmailContributions extends Logging {

def toContributionFields(currentDate: LocalDate, data: ContributionsEmailData): Option[ContributionFields] = {

val productId = data.planId match {
case AnnualContribution => "annual-contribution"
case MonthlyContribution => "monthly-contribution"
case other => other.name
}
val maybeDirectDebit = data.paymentMethod match {
case d: DirectDebit => Some(d)
case _ => None
Expand All @@ -72,7 +79,7 @@ object SendConfirmationEmailContributions extends Logging {
currency = data.currency.glyph,
edition = data.billTo.address.country.map(_.alpha2).getOrElse(""),
name = data.billTo.firstName.value,
product = "monthly-contribution",
product = productId,
`account name` = maybeDirectDebit.map(_.accountName.value),
`account number` = maybeDirectDebit.map(_.accountNumberMask.value),
`sort code` = maybeDirectDebit.map(_.sortCode.hyphenated),
Expand Down
Expand Up @@ -13,7 +13,8 @@ case class Catalog(
voucherSundayPlus: Plan,
voucherEveryDayPlus: Plan,
voucherSixDayPlus: Plan,
monthlyContribution: Plan
monthlyContribution: Plan,
annualContribution: Plan
) {
val allPlans = List(
voucherWeekend,
Expand All @@ -26,7 +27,8 @@ case class Catalog(
voucherSundayPlus,
voucherEveryDayPlus,
voucherSixDayPlus,
monthlyContribution
monthlyContribution,
annualContribution
)

val planForId: Map[PlanId, Plan] = allPlans.map(x => x.id -> x).toMap
Expand All @@ -35,6 +37,7 @@ case class Catalog(
sealed abstract class PlanId(val name: String)

object PlanId {
case object AnnualContribution extends PlanId("annual_contribution")

case object MonthlyContribution extends PlanId("monthly_contribution")

Expand All @@ -60,6 +63,7 @@ object PlanId {

val supported = List(
MonthlyContribution,
AnnualContribution,
VoucherWeekend,
VoucherEveryDay,
VoucherSixDay,
Expand Down
Expand Up @@ -29,7 +29,7 @@ object NewProductApi {
maybeCutOffDay = None,
maybeStartDelay = None
)
val monthlyContributionRules = StartDateRules(windowRule = Some(monthlyContributionWindow))
val contributionRules = StartDateRules(windowRule = Some(monthlyContributionWindow))

def planWithPayment(
planId: PlanId,
Expand All @@ -48,7 +48,8 @@ object NewProductApi {
voucherSaturdayPlus = planWithPayment(VoucherSaturdayPlus, PlanDescription("Saturday+"), voucherSaturdayDateRules),
voucherSunday = planWithPayment(VoucherSunday, PlanDescription("Sunday"), voucherSundayDateRules),
voucherSundayPlus = planWithPayment(VoucherSundayPlus, PlanDescription("Sunday+"), voucherSundayDateRules),
monthlyContribution = planWithPayment(MonthlyContribution, PlanDescription("Monthly"), monthlyContributionRules)
monthlyContribution = planWithPayment(MonthlyContribution, PlanDescription("Monthly"), contributionRules),
annualContribution = planWithPayment(AnnualContribution, PlanDescription("Annual"), contributionRules),
)
}

Expand Down
Expand Up @@ -119,7 +119,8 @@ object WireModel {
val contributionProduct = WireProduct(
label = "Contribution",
plans = List(
WirePlanInfo.fromPlan(catalog.monthlyContribution)
WirePlanInfo.fromPlan(catalog.monthlyContribution),
WirePlanInfo.fromPlan(catalog.annualContribution)
)
)
WireCatalog(List(contributionProduct, voucherProduct))
Expand Down
Expand Up @@ -12,7 +12,12 @@ object ZuoraIds {

case class PlanAndCharge(productRatePlanId: ProductRatePlanId, productRatePlanChargeId: ProductRatePlanChargeId)

case class ContributionsZuoraIds(monthly: PlanAndCharge, annual: PlanAndCharge)
case class ContributionsZuoraIds(monthly: PlanAndCharge, annual: PlanAndCharge) {
val byApiPlanId: Map[PlanId, PlanAndCharge] = Map(
MonthlyContribution -> monthly,
AnnualContribution -> annual
)
}

case class VoucherZuoraIds(
everyday: ProductRatePlanId,
Expand Down
Expand Up @@ -10,7 +10,7 @@ import com.gu.newproduct.api.addsubscription.validation.{Failed, Passed}
import com.gu.newproduct.api.addsubscription.zuora.CreateSubscription
import com.gu.newproduct.api.addsubscription.zuora.CreateSubscription.{ChargeOverride, SubscriptionName, ZuoraCreateSubRequest}
import com.gu.newproduct.api.addsubscription.zuora.GetAccount.SfContactId
import com.gu.newproduct.api.productcatalog.AmountMinorUnits
import com.gu.newproduct.api.productcatalog.{AmountMinorUnits, PlanId}
import com.gu.newproduct.api.productcatalog.ZuoraIds.{PlanAndCharge, ProductRatePlanChargeId, ProductRatePlanId}
import com.gu.test.JsonMatchers.JsonMatcher
import com.gu.util.apigateway.ApiGatewayRequest
Expand All @@ -36,6 +36,8 @@ class ContributionStepsTest extends FlatSpec with Matchers {
ProductRatePlanChargeId("ratePlanChargeId")
)

def getPlanAndCharge(planId: PlanId) = Some(planAndCharge)

val expectedIn = ZuoraCreateSubRequest(
planAndCharge.productRatePlanId,
ZuoraAccountId("acccc"),
Expand Down Expand Up @@ -79,7 +81,7 @@ class ContributionStepsTest extends FlatSpec with Matchers {
val expectedOutput = ExpectedOut("well done")

val fakeAddContributionSteps = Steps.addContributionSteps(
planAndCharge,
getPlanAndCharge,
fakeGetCustomerData,
fakeValidateRequest,
fakeCreate,
Expand Down
Expand Up @@ -12,10 +12,12 @@ import com.gu.newproduct.api.addsubscription.zuora.GetContacts._
import com.gu.newproduct.api.addsubscription.zuora.GetPaymentMethod.{BankAccountName, BankAccountNumberMask, DirectDebit, MandateId, NonDirectDebitMethod, SortCode}
import com.gu.newproduct.api.addsubscription.zuora.PaymentMethodStatus.ActivePaymentMethod
import com.gu.newproduct.api.addsubscription.zuora.PaymentMethodType.CreditCard
import com.gu.newproduct.api.productcatalog.AmountMinorUnits
import com.gu.newproduct.api.productcatalog.PlanId.{AnnualContribution, MonthlyContribution}
import com.gu.newproduct.api.productcatalog.{AmountMinorUnits, PlanId}
import com.gu.util.apigateway.ApiGatewayResponse
import com.gu.util.reader.Types.ApiGatewayOp.{ContinueProcessing, ReturnWithResponse}
import org.scalatest.{AsyncFlatSpec, Matchers}

import scala.concurrent.Future

class SendConfirmationEmailContributionsTest extends AsyncFlatSpec with Matchers {
Expand Down Expand Up @@ -51,7 +53,8 @@ class SendConfirmationEmailContributionsTest extends AsyncFlatSpec with Matchers
paymentMethod = directDebit,
amountMinorUnits = AmountMinorUnits(1234),
firstPaymentDate = LocalDate.of(2018, 8, 9),
billTo = testContact
billTo = testContact,
planId = MonthlyContribution
)

val sfContactId = Some(SfContactId("sfContactId"))
Expand Down
Expand Up @@ -22,6 +22,15 @@ class CatalogWireTest extends FlatSpec with Matchers {
| "sizeInDays": 1
| }
| }
| },
| {
| "id": "annual_contribution",
| "label": "Annual",
| "startDateRules": {
| "selectableWindow": {
| "sizeInDays": 1
| }
| }
| }
| ]
| },
Expand Down Expand Up @@ -196,6 +205,7 @@ class CatalogWireTest extends FlatSpec with Matchers {
case VoucherSixDay => Some(AmountMinorUnits(4112))
case VoucherSixDayPlus => Some(AmountMinorUnits(4762))
case MonthlyContribution => None
case AnnualContribution => None
}

val wireCatalog = WireCatalog.fromCatalog(NewProductApi.catalog(fakePricesFor))
Expand Down
Expand Up @@ -14,6 +14,7 @@ import com.gu.newproduct.api.addsubscription.zuora.{PaymentMethodStatus, Payment
import com.gu.newproduct.api.addsubscription.ZuoraAccountId
import com.gu.newproduct.api.addsubscription.zuora.GetAccount.SfContactId
import com.gu.newproduct.api.productcatalog.AmountMinorUnits
import com.gu.newproduct.api.productcatalog.PlanId.MonthlyContribution
import com.gu.util.config.Stage

import scala.concurrent.Await
Expand Down Expand Up @@ -42,7 +43,8 @@ object SendConfirmationEmailsManualTest {
NonDirectDebitMethod(PaymentMethodStatus.ActivePaymentMethod, PaymentMethodType.PayPal),
AmountMinorUnits(123),
LocalDate.of(2018, 9, 1),
billtoContact
billtoContact,
MonthlyContribution
)

val fakeDate = LocalDate.of(2018, 8, 10)
Expand Down

0 comments on commit adcf8d8

Please sign in to comment.