Skip to content

Commit

Permalink
Move holiday-stop credit calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
kelvin-chappell committed Aug 13, 2019
1 parent 6a52c30 commit 2798022
Show file tree
Hide file tree
Showing 28 changed files with 76 additions and 39 deletions.
13 changes: 11 additions & 2 deletions build.sbt
Expand Up @@ -94,8 +94,17 @@ lazy val `holiday-stops` = all(project in file("lib/holiday-stops"))
testDep
)
.settings(
libraryDependencies ++= Seq(okhttp3, scalaz, playJson, scalatest, playJsonExtensions) ++ logging
)
libraryDependencies ++=
Seq(okhttp3,
scalaz,
playJson,
scalatest,
playJsonExtensions,
circe,
circeParser,
sttp,
sttpCirce) ++ logging
)

lazy val restHttp = all(project in file("lib/restHttp"))
.settings(
Expand Down
5 changes: 0 additions & 5 deletions handlers/holiday-stop-processor/build.sbt
Expand Up @@ -12,13 +12,8 @@ riffRaffUploadManifestBucket := Option("riffraff-builds")
riffRaffManifestProjectName := s"MemSub::Membership Admin::${name.value}"
riffRaffArtifactResources += (file(s"handlers/${name.value}/cfn.yaml"), "cfn/cfn.yaml")

val sttpVersion = "1.5.17"

libraryDependencies ++= Seq(
"io.github.mkotsur" %% "aws-lambda-scala" % "0.1.1",
"com.softwaremill.sttp" %% "core" % sttpVersion,
"com.softwaremill.sttp" %% "circe" % sttpVersion,
"io.circe" %% "circe-generic" % "0.11.1",
"com.amazonaws" % "aws-java-sdk-s3" % "1.11.566",
"org.slf4j" % "slf4j-api" % "1.7.25",
"ch.qos.logback" % "logback-classic" % "1.2.3",
Expand Down
Expand Up @@ -4,6 +4,7 @@ import java.time.LocalDate

import cats.implicits._
import com.amazonaws.services.lambda.runtime.Context
import com.gu.holiday_stops.Config
import io.circe.generic.auto._
import io.github.mkotsur.aws.handler.Lambda
import io.github.mkotsur.aws.handler.Lambda._
Expand Down
@@ -1,7 +1,9 @@
package com.gu.holidaystopprocessor

import java.time.LocalDate

import cats.implicits._
import com.gu.holiday_stops._
import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequestsDetail._

object HolidayStopProcess {
Expand Down Expand Up @@ -65,7 +67,7 @@ object HolidayStopProcess {
currentGuardianWeeklySubscription <- CurrentGuardianWeeklySubscription(subscription, guardianWeeklyProductRatePlanIds)
nextInvoiceStartDate = NextBillingPeriodStartDate(currentGuardianWeeklySubscription)
maybeExtendedTerm = ExtendedTerm(nextInvoiceStartDate, subscription)
holidayCredit = HolidayCredit(currentGuardianWeeklySubscription)
holidayCredit <- CreditCalculator.guardianWeeklyCredit(guardianWeeklyProductRatePlanIds)(subscription)
holidayCreditUpdate <- HolidayCreditUpdate(holidayCreditProduct, subscription, stop.stoppedPublicationDate, nextInvoiceStartDate, maybeExtendedTerm, holidayCredit)
_ <- if (subscription.hasHolidayStop(stop)) Right(()) else updateSubscription(subscription, holidayCreditUpdate)
updatedSubscription <- getSubscription(stop.subscriptionName)
Expand Down
Expand Up @@ -2,6 +2,8 @@ package com.gu.holidaystopprocessor

import java.time.LocalDate

import com.gu.holiday_stops.CurrentGuardianWeeklySubscription

/**
* Holiday credit is applied to the next invoice on the first day of the next billing period.
*
Expand Down
@@ -1,5 +1,6 @@
package com.gu.holidaystopprocessor

import com.gu.holiday_stops.{HolidayStop, OverallFailure, ZuoraHolidayWriteError}
import com.typesafe.scalalogging.LazyLogging

case class ProcessResult(holidayStopsToApply: List[HolidayStop], holidayStopResults: List[Either[ZuoraHolidayWriteError, HolidayStopResponse]], resultsToExport: List[HolidayStopResponse], overallFailure: Option[OverallFailure])
Expand Down
Expand Up @@ -10,6 +10,7 @@ import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequestsDetail._
import com.gu.util.resthttp.JsonHttp
import scalaz.{-\/, \/-}
import com.gu.holiday_stops.ActionCalculator.suspensionConstantsByProduct
import com.gu.holiday_stops.{OverallFailure, SalesforceHolidayWriteError}

object Salesforce {

Expand Down
Expand Up @@ -2,6 +2,8 @@ package com.gu.holidaystopprocessor

import java.time.LocalDate

import com.gu.holiday_stops.Config

// This is just for functional testing locally.
object StandaloneApp extends App {

Expand Down
@@ -1,7 +1,9 @@
package com.gu.holidaystopprocessor

import java.time.LocalDate

import cats.implicits._
import com.gu.holiday_stops.{HolidayCreditUpdate, OverallFailure, SalesforceHolidayWriteError, Subscription, ZuoraHolidayWriteError}
import com.gu.holidaystopprocessor.Fixtures._
import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequestsDetail.{HolidayStopRequestsDetail, ProductName, SubscriptionName}
import org.scalatest._
Expand Down
Expand Up @@ -2,6 +2,7 @@ package com.gu.holidaystopprocessor

import java.time.LocalDate

import com.gu.holiday_stops.{Config, HolidayCreditProduct, HolidayStop, HolidayStopProcessor, Oauth, RatePlan, RatePlanCharge, Subscription, ZuoraConfig}
import com.gu.salesforce.SalesforceAuthenticate.SFAuthConfig
import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequest._
import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequestsDetail._
Expand Down
Expand Up @@ -2,6 +2,7 @@ package com.gu.holidaystopprocessor

import java.time.LocalDate

import com.gu.holiday_stops.{Config, CurrentGuardianWeeklySubscription, HolidayCredit, RatePlan, RatePlanCharge}
import org.scalacheck.Prop.forAll
import org.scalacheck._
import org.scalatest.{EitherValues, OptionValues}
Expand Down
@@ -1,5 +1,6 @@
package com.gu.holidaystopprocessor

import com.gu.holiday_stops.{CurrentGuardianWeeklySubscription, HolidayCredit, RatePlan}
import org.scalatest.{EitherValues, FlatSpec, Matchers}

class HolidayCreditTest extends FlatSpec with Matchers with EitherValues {
Expand Down
Expand Up @@ -2,6 +2,7 @@ package com.gu.holidaystopprocessor

import java.time.LocalDate

import com.gu.holiday_stops.{HolidayCreditUpdate, HolidayStop, OverallFailure, SalesforceHolidayWriteError, Subscription, ZuoraHolidayWriteError}
import com.gu.holidaystopprocessor.Fixtures.{config, mkSubscription}
import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequestsDetail.{HolidayStopRequestsDetail, HolidayStopRequestsDetailChargeCode, HolidayStopRequestsDetailChargePrice, HolidayStopRequestsDetailId, ProductName, StoppedPublicationDate, SubscriptionName}
import org.scalatest.{EitherValues, FlatSpec, Matchers, OptionValues}
Expand Down
Expand Up @@ -2,6 +2,7 @@ package com.gu.holidaystopprocessor

import java.time.LocalDate

import com.gu.holiday_stops.RatePlanCharge
import org.scalatest.{FlatSpec, Matchers, OptionValues}

class SubscriptionTest extends FlatSpec with Matchers with OptionValues {
Expand Down
Expand Up @@ -2,6 +2,7 @@ package com.gu.holidaystopprocessor

import java.time.LocalDate

import com.gu.holiday_stops.{Add, ChargeOverride, CurrentGuardianWeeklySubscription, ExtendedTerm, HolidayCredit, HolidayCreditUpdate, ZuoraHolidayWriteError}
import com.gu.holidaystopprocessor.Fixtures.config
import org.scalatest.{EitherValues, FlatSpec, Matchers}

Expand Down
@@ -1,3 +1,3 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

case class AccessToken(access_token: String)
@@ -1,8 +1,9 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import com.amazonaws.auth.profile.ProfileCredentialsProvider
import com.amazonaws.regions.Regions.EU_WEST_1
import com.amazonaws.services.s3.AmazonS3Client
import com.gu.holiday_stops.OverallFailure
import com.gu.salesforce.SalesforceAuthenticate.SFAuthConfig
import io.circe.Decoder
import io.circe.generic.auto._
Expand Down
@@ -0,0 +1,16 @@
package com.gu.holiday_stops

import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequestsDetail.SubscriptionName

object CreditCalculator {

def guardianWeeklyCredit(config: Config, subscriptionName: SubscriptionName): Either[HolidayError, Double] =
for {
accessToken <- Zuora.accessTokenGetResponse(config.zuoraConfig)
subscription <- Zuora.subscriptionGetResponse(config, accessToken)(subscriptionName)
credit <- guardianWeeklyCredit(config.guardianWeeklyProductRatePlanIds)(subscription)
} yield credit

def guardianWeeklyCredit(guardianWeeklyProductRatePlanIds: List[String])(subscription: Subscription): Either[ZuoraHolidayWriteError, Double] =
CurrentGuardianWeeklySubscription(subscription, guardianWeeklyProductRatePlanIds).map(HolidayCredit(_))
}
@@ -1,6 +1,7 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import java.time.LocalDate

import scala.util.Try

/**
Expand Down Expand Up @@ -95,6 +96,7 @@ case class CurrentInvoicedPeriod(
* attached to Guardian Weekly product that satisfies all of the CurrentGuardianWeeklyRatePlanPredicates.
*/
object CurrentGuardianWeeklySubscription {

def apply(subscription: Subscription, guardianWeeklyProductRatePlanIds: List[String]): Either[ZuoraHolidayWriteError, CurrentGuardianWeeklySubscription] =
subscription
.ratePlans
Expand Down
@@ -1,4 +1,4 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import java.time.LocalDate
import java.time.temporal.ChronoUnit.DAYS
Expand Down
@@ -1,4 +1,4 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

sealed trait HolidayError {
val reason: String
Expand Down
@@ -1,4 +1,4 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import scala.math.BigDecimal.RoundingMode

Expand Down
@@ -1,7 +1,9 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import java.time.LocalDate

import com.gu.holiday_stops

case class HolidayCreditUpdate(
currentTerm: Option[Int],
currentTermPeriodType: Option[String],
Expand All @@ -24,7 +26,7 @@ object HolidayCreditUpdate {
holidayCredit: Double
): Either[ZuoraHolidayWriteError, HolidayCreditUpdate] = {
Right(
HolidayCreditUpdate(
holiday_stops.HolidayCreditUpdate(
currentTerm = maybeExtendedTerm.map(_.length),
currentTermPeriodType = maybeExtendedTerm.map(_.unit),
List(
Expand Down
@@ -1,4 +1,4 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import java.time.LocalDate

Expand Down
@@ -1,4 +1,4 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import java.time.LocalDate

Expand All @@ -12,32 +12,22 @@ case class Subscription(
ratePlans: List[RatePlan]
) {

val originalRatePlanCharge: Option[RatePlanCharge] = {
val chronologicallyOrderedRatePlans = ratePlans.sortBy { plan =>
plan.ratePlanCharges.map(_.effectiveStartDate.toString).headOption.getOrElse("")
}
for {
ratePlan <- chronologicallyOrderedRatePlans.headOption
charge <- ratePlan.ratePlanCharges.headOption
} yield charge
}

def ratePlanCharge(stop: HolidayStop): Option[RatePlanCharge] = {

def isMatchingPlan(plan: RatePlan): Boolean = plan.productName == "Discounts"

def isMatchingCharge(charge: RatePlanCharge): Boolean =
charge.name == "Holiday Credit" &&
charge.HolidayStart__c.exists { start =>
start.isEqual(stop.stoppedPublicationDate) || start.isBefore(stop.stoppedPublicationDate)
} &&
charge.HolidayEnd__c.exists { end =>
end.isEqual(stop.stoppedPublicationDate) || end.isAfter(stop.stoppedPublicationDate)
}
charge.HolidayStart__c.exists { start =>
start.isEqual(stop.stoppedPublicationDate) || start.isBefore(stop.stoppedPublicationDate)
} &&
charge.HolidayEnd__c.exists { end =>
end.isEqual(stop.stoppedPublicationDate) || end.isAfter(stop.stoppedPublicationDate)
}

val charges = for {
plan <- ratePlans if isMatchingPlan(plan)
charge <- plan.ratePlanCharges.find(isMatchingCharge)
charge <- plan.ratePlanCharges.find(isMatchingCharge)
} yield charge
charges.headOption
}
Expand All @@ -63,5 +53,3 @@ case class RatePlanCharge(
HolidayEnd__c: Option[LocalDate],
processedThroughDate: Option[LocalDate],
)


@@ -1,4 +1,4 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

import com.gu.salesforce.holiday_stops.SalesforceHolidayStopRequestsDetail.SubscriptionName
import com.softwaremill.sttp._
Expand Down
@@ -1,4 +1,4 @@
package com.gu.holidaystopprocessor
package com.gu.holiday_stops

case class ZuoraStatusResponse(
success: Boolean,
Expand Down
7 changes: 7 additions & 0 deletions project/Dependencies.scala
Expand Up @@ -4,6 +4,9 @@ object Dependencies {

val awsVersion = "1.11.574"

val circeVersion = "0.11.1"
val sttpVersion = "1.5.17"

val okhttp3 = "com.squareup.okhttp3" % "okhttp" % "3.9.1"
val logging = Seq(
"ch.qos.logback" % "logback-classic" % "1.2.3",
Expand All @@ -19,4 +22,8 @@ object Dependencies {
val awsSES = "com.amazonaws" % "aws-java-sdk-ses" % awsVersion
val awsLambda = "com.amazonaws" % "aws-lambda-java-core" % "1.2.0"
val supportInternationalisation = "com.gu" %% "support-internationalisation" % "0.9"
val circe = "io.circe" %% "circe-generic" % circeVersion
val circeParser = "io.circe" %% "circe-parser" % circeVersion
val sttp = "com.softwaremill.sttp" %% "core" % sttpVersion
val sttpCirce = "com.softwaremill.sttp" %% "circe" % sttpVersion
}

0 comments on commit 2798022

Please sign in to comment.